open-agents-ai 0.187.211 → 0.187.213

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 (2) hide show
  1. package/dist/index.js +793 -638
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -288395,12 +288395,16 @@ __export(overlay_lock_exports, {
288395
288395
  enterOverlay: () => enterOverlay,
288396
288396
  isOverlayActive: () => isOverlayActive,
288397
288397
  leaveOverlay: () => leaveOverlay,
288398
+ onOverlayEnter: () => onOverlayEnter,
288398
288399
  onOverlayLeave: () => onOverlayLeave,
288399
288400
  overlayWrite: () => overlayWrite
288400
288401
  });
288401
288402
  function onOverlayLeave(cb) {
288402
288403
  _onLeaveCallback = cb;
288403
288404
  }
288405
+ function onOverlayEnter(cb) {
288406
+ _onEnterCallback = cb;
288407
+ }
288404
288408
  function isOverlayActive() {
288405
288409
  return _overlayActive;
288406
288410
  }
@@ -288419,6 +288423,12 @@ function enterOverlay() {
288419
288423
  _depth++;
288420
288424
  if (_depth === 1) {
288421
288425
  _overlayActive = true;
288426
+ if (_onEnterCallback) {
288427
+ try {
288428
+ _onEnterCallback();
288429
+ } catch {
288430
+ }
288431
+ }
288422
288432
  _origStdoutWrite = process.stdout.write.bind(process.stdout);
288423
288433
  _origStderrWrite = process.stderr.write.bind(process.stderr);
288424
288434
  process.stdout.write = function(chunk, ...args) {
@@ -288456,7 +288466,7 @@ function leaveOverlay() {
288456
288466
  _buffer = [];
288457
288467
  }
288458
288468
  }
288459
- var _overlayActive, _depth, _buffer, _origStdoutWrite, _origStderrWrite, _onLeaveCallback;
288469
+ var _overlayActive, _depth, _buffer, _origStdoutWrite, _origStderrWrite, _onLeaveCallback, _onEnterCallback;
288460
288470
  var init_overlay_lock = __esm({
288461
288471
  "packages/cli/src/tui/overlay-lock.ts"() {
288462
288472
  "use strict";
@@ -288466,6 +288476,288 @@ var init_overlay_lock = __esm({
288466
288476
  _origStdoutWrite = null;
288467
288477
  _origStderrWrite = null;
288468
288478
  _onLeaveCallback = null;
288479
+ _onEnterCallback = null;
288480
+ }
288481
+ });
288482
+
288483
+ // packages/cli/src/tui/tui-tasks-renderer.ts
288484
+ var tui_tasks_renderer_exports = {};
288485
+ __export(tui_tasks_renderer_exports, {
288486
+ getTuiTasksScope: () => getTuiTasksScope,
288487
+ onTuiTasksHeightChange: () => onTuiTasksHeightChange,
288488
+ refreshTuiTasks: () => refreshTuiTasks,
288489
+ refreshTuiTasksSync: () => refreshTuiTasksSync,
288490
+ setTuiTasksEnabled: () => setTuiTasksEnabled,
288491
+ setTuiTasksScope: () => setTuiTasksScope,
288492
+ setTuiTasksSession: () => setTuiTasksSession,
288493
+ teardownTuiTasks: () => teardownTuiTasks
288494
+ });
288495
+ import { existsSync as existsSync57, readFileSync as readFileSync43, watch as fsWatch2 } from "node:fs";
288496
+ import { join as join74 } from "node:path";
288497
+ import { homedir as homedir24 } from "node:os";
288498
+ function panelEffectivelyVisible() {
288499
+ return _enabled && !_scopeOverlayActive && !_scopeNeovimActive && _scopeMainViewActive;
288500
+ }
288501
+ function todoDir2() {
288502
+ return join74(homedir24(), ".open-agents", "todos");
288503
+ }
288504
+ function todoPath2(sessionId) {
288505
+ const safe = sessionId.replace(/[^a-zA-Z0-9_.-]/g, "_");
288506
+ return join74(todoDir2(), `${safe}.json`);
288507
+ }
288508
+ function setTuiTasksSession(sessionId) {
288509
+ if (sessionId === _activeSessionId) return;
288510
+ _activeSessionId = sessionId || null;
288511
+ if (_watcher) {
288512
+ try {
288513
+ _watcher.close();
288514
+ } catch {
288515
+ }
288516
+ _watcher = null;
288517
+ }
288518
+ if (!_activeSessionId) {
288519
+ _lastTodos = [];
288520
+ applyHeightChange(0);
288521
+ return;
288522
+ }
288523
+ loadTodos();
288524
+ installWatcher();
288525
+ scheduleRedraw();
288526
+ }
288527
+ function onTuiTasksHeightChange(cb) {
288528
+ _onResizeChange = cb;
288529
+ }
288530
+ function setTuiTasksEnabled(enabled2) {
288531
+ _enabled = enabled2;
288532
+ scheduleRedraw();
288533
+ }
288534
+ function setTuiTasksScope(scope) {
288535
+ let changed = false;
288536
+ if (scope.overlayActive !== void 0 && scope.overlayActive !== _scopeOverlayActive) {
288537
+ _scopeOverlayActive = scope.overlayActive;
288538
+ changed = true;
288539
+ }
288540
+ if (scope.mainViewActive !== void 0 && scope.mainViewActive !== _scopeMainViewActive) {
288541
+ _scopeMainViewActive = scope.mainViewActive;
288542
+ changed = true;
288543
+ }
288544
+ if (scope.neovimActive !== void 0 && scope.neovimActive !== _scopeNeovimActive) {
288545
+ _scopeNeovimActive = scope.neovimActive;
288546
+ changed = true;
288547
+ }
288548
+ if (changed) {
288549
+ if (!panelEffectivelyVisible()) {
288550
+ clearLastPaintedRows();
288551
+ applyHeightChange(0);
288552
+ } else {
288553
+ scheduleRedraw();
288554
+ }
288555
+ }
288556
+ }
288557
+ function getTuiTasksScope() {
288558
+ return {
288559
+ enabled: _enabled,
288560
+ overlayActive: _scopeOverlayActive,
288561
+ mainViewActive: _scopeMainViewActive,
288562
+ neovimActive: _scopeNeovimActive,
288563
+ visible: panelEffectivelyVisible()
288564
+ };
288565
+ }
288566
+ function refreshTuiTasks() {
288567
+ if (!_activeSessionId) return;
288568
+ loadTodos();
288569
+ scheduleRedraw();
288570
+ }
288571
+ function refreshTuiTasksSync() {
288572
+ if (!_activeSessionId) return;
288573
+ loadTodos();
288574
+ if (!_enabled) return;
288575
+ _redrawScheduled = false;
288576
+ render();
288577
+ }
288578
+ function teardownTuiTasks() {
288579
+ if (_watcher) {
288580
+ try {
288581
+ _watcher.close();
288582
+ } catch {
288583
+ }
288584
+ _watcher = null;
288585
+ }
288586
+ _activeSessionId = null;
288587
+ _lastTodos = [];
288588
+ applyHeightChange(0);
288589
+ }
288590
+ function installWatcher() {
288591
+ if (!_activeSessionId) return;
288592
+ try {
288593
+ _watcher = fsWatch2(todoDir2(), { persistent: false }, (_evt, fname) => {
288594
+ if (!fname || !_activeSessionId) return;
288595
+ const expected = `${_activeSessionId.replace(/[^a-zA-Z0-9_.-]/g, "_")}.json`;
288596
+ if (fname !== expected) return;
288597
+ loadTodos();
288598
+ scheduleRedraw();
288599
+ });
288600
+ } catch {
288601
+ }
288602
+ }
288603
+ function loadTodos() {
288604
+ if (!_activeSessionId) {
288605
+ _lastTodos = [];
288606
+ return;
288607
+ }
288608
+ try {
288609
+ const fp = todoPath2(_activeSessionId);
288610
+ if (!existsSync57(fp)) {
288611
+ _lastTodos = [];
288612
+ return;
288613
+ }
288614
+ const parsed = JSON.parse(readFileSync43(fp, "utf-8"));
288615
+ _lastTodos = Array.isArray(parsed) ? parsed : [];
288616
+ } catch {
288617
+ _lastTodos = [];
288618
+ }
288619
+ }
288620
+ function scheduleRedraw() {
288621
+ if (_redrawScheduled || !_enabled) return;
288622
+ _redrawScheduled = true;
288623
+ setImmediate(() => {
288624
+ _redrawScheduled = false;
288625
+ render();
288626
+ });
288627
+ }
288628
+ function computeTargetHeight() {
288629
+ if (!panelEffectivelyVisible()) return 0;
288630
+ if (!_lastTodos || _lastTodos.length === 0) return 0;
288631
+ const itemRows = Math.min(_lastTodos.length, MAX_VISIBLE_ROWS - 1);
288632
+ return 1 + itemRows;
288633
+ }
288634
+ function applyHeightChange(nextHeight) {
288635
+ const changed = setTasksHeight(nextHeight);
288636
+ if (changed) {
288637
+ notifyLayoutResize();
288638
+ }
288639
+ if (_onResizeChange) {
288640
+ try {
288641
+ _onResizeChange(nextHeight);
288642
+ } catch {
288643
+ }
288644
+ }
288645
+ }
288646
+ function statusToAnsi(status) {
288647
+ switch (status) {
288648
+ case "completed":
288649
+ return { mark: "◉", color: MUTED_GREEN, box: GREEN };
288650
+ case "in_progress":
288651
+ return { mark: "◐", color: GOLD, box: GOLD };
288652
+ case "blocked":
288653
+ return { mark: "◍", color: RED, box: RED };
288654
+ default:
288655
+ return { mark: "〇", color: GREY, box: GREY };
288656
+ }
288657
+ }
288658
+ function truncate2(s2, max) {
288659
+ if (s2.length <= max) return s2.padEnd(max, " ");
288660
+ return s2.slice(0, Math.max(0, max - 1)) + "…";
288661
+ }
288662
+ function render() {
288663
+ if (!_enabled) return;
288664
+ if (!panelEffectivelyVisible()) {
288665
+ clearLastPaintedRows();
288666
+ applyHeightChange(0);
288667
+ return;
288668
+ }
288669
+ const target = computeTargetHeight();
288670
+ applyHeightChange(target);
288671
+ if (target === 0) {
288672
+ clearLastPaintedRows();
288673
+ return;
288674
+ }
288675
+ const L = layout();
288676
+ const cols = Math.max(20, termCols());
288677
+ const completed = _lastTodos.filter((t2) => t2.status === "completed").length;
288678
+ const total = _lastTodos.length;
288679
+ const headerColor = completed === total ? GREEN : GOLD;
288680
+ const lines = [];
288681
+ const headerText = `tasks ${headerColor}${completed}/${total}${RESET}${DIM_LABEL} (todo_write)${RESET}`;
288682
+ lines.push(headerText);
288683
+ const visible = _lastTodos.slice(0, MAX_VISIBLE_ROWS - 1);
288684
+ for (const t2 of visible) {
288685
+ const { mark, color } = statusToAnsi(t2.status);
288686
+ const contentWidth = Math.max(4, cols - 8);
288687
+ const contentText = t2.content + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
288688
+ const truncated = truncate2(contentText, contentWidth);
288689
+ lines.push(`${color}${mark}${RESET} ${color}${truncated}${RESET}`);
288690
+ }
288691
+ if (_lastTodos.length > visible.length) {
288692
+ const more = _lastTodos.length - visible.length;
288693
+ lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${RESET}`;
288694
+ }
288695
+ let out = HIDE + SAVE;
288696
+ const newTop = L.tasksTop;
288697
+ const newBottom = Math.min(L.tasksBottom, L.tasksTop + lines.length - 1);
288698
+ if (_lastPaintedTop >= 0 && _lastPaintedBottom >= _lastPaintedTop) {
288699
+ for (let row = _lastPaintedTop; row <= _lastPaintedBottom; row++) {
288700
+ if (row >= newTop && row <= newBottom) continue;
288701
+ out += `\x1B[${row};1H${CLEAR_LINE}`;
288702
+ }
288703
+ }
288704
+ for (let i2 = 0; i2 < lines.length; i2++) {
288705
+ const row = L.tasksTop + i2;
288706
+ if (row > L.tasksBottom) break;
288707
+ out += `\x1B[${row};1H${CLEAR_LINE}${BG}${" ".repeat(cols)}\x1B[${row};2H${lines[i2]}${RESET}`;
288708
+ }
288709
+ out += RESTORE + SHOW;
288710
+ try {
288711
+ process.stdout.write(out);
288712
+ } catch {
288713
+ }
288714
+ _lastPaintedTop = newTop;
288715
+ _lastPaintedBottom = newBottom;
288716
+ }
288717
+ function clearLastPaintedRows() {
288718
+ if (_lastPaintedTop < 0 || _lastPaintedBottom < _lastPaintedTop) return;
288719
+ let out = HIDE + SAVE;
288720
+ for (let row = _lastPaintedTop; row <= _lastPaintedBottom; row++) {
288721
+ out += `\x1B[${row};1H${CLEAR_LINE}`;
288722
+ }
288723
+ out += RESTORE + SHOW;
288724
+ try {
288725
+ process.stdout.write(out);
288726
+ } catch {
288727
+ }
288728
+ _lastPaintedTop = -1;
288729
+ _lastPaintedBottom = -1;
288730
+ }
288731
+ var _activeSessionId, _watcher, _lastTodos, _enabled, _redrawScheduled, _onResizeChange, _scopeOverlayActive, _scopeMainViewActive, _scopeNeovimActive, _lastPaintedTop, _lastPaintedBottom, MAX_VISIBLE_ROWS, SAVE, RESTORE, HIDE, SHOW, CLEAR_LINE, RESET, BG, DIM_LABEL, GOLD, GREEN, MUTED_GREEN, GREY, RED;
288732
+ var init_tui_tasks_renderer = __esm({
288733
+ "packages/cli/src/tui/tui-tasks-renderer.ts"() {
288734
+ "use strict";
288735
+ init_layout2();
288736
+ _activeSessionId = null;
288737
+ _watcher = null;
288738
+ _lastTodos = [];
288739
+ _enabled = true;
288740
+ _redrawScheduled = false;
288741
+ _onResizeChange = null;
288742
+ _scopeOverlayActive = false;
288743
+ _scopeMainViewActive = true;
288744
+ _scopeNeovimActive = false;
288745
+ _lastPaintedTop = -1;
288746
+ _lastPaintedBottom = -1;
288747
+ MAX_VISIBLE_ROWS = 8;
288748
+ SAVE = "\x1B[s";
288749
+ RESTORE = "\x1B[u";
288750
+ HIDE = "\x1B[?25l";
288751
+ SHOW = "\x1B[?25h";
288752
+ CLEAR_LINE = "\x1B[2K";
288753
+ RESET = "\x1B[0m";
288754
+ BG = "\x1B[48;2;23;23;26m";
288755
+ DIM_LABEL = "\x1B[38;2;68;68;68m";
288756
+ GOLD = "\x1B[38;2;178;146;10m";
288757
+ GREEN = "\x1B[38;2;95;165;95m";
288758
+ MUTED_GREEN = "\x1B[38;2;74;122;74m";
288759
+ GREY = "\x1B[38;2;102;102;102m";
288760
+ RED = "\x1B[38;2;178;95;95m";
288469
288761
  }
288470
288762
  });
288471
288763
 
@@ -288479,7 +288771,7 @@ __export(status_bar_exports, {
288479
288771
  setTerminalTitle: () => setTerminalTitle,
288480
288772
  unlockFooterRedraws: () => unlockFooterRedraws
288481
288773
  });
288482
- import { readFileSync as readFileSync43 } from "node:fs";
288774
+ import { readFileSync as readFileSync44 } from "node:fs";
288483
288775
  function lockFooterRedraws() {
288484
288776
  _globalFooterLock = true;
288485
288777
  }
@@ -288499,7 +288791,7 @@ function setTerminalTitle(task, version4) {
288499
288791
  const title = task ? `${task.slice(0, 60)} · ${ver}` : ver;
288500
288792
  process.stdout.write(`\x1B]2;${title}\x07`);
288501
288793
  }
288502
- var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, _globalFooterLock, RESET, CURSOR_BLINK_BLOCK, _isWindows, StatusBar;
288794
+ var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, _globalFooterLock, RESET2, CURSOR_BLINK_BLOCK, _isWindows, StatusBar;
288503
288795
  var init_status_bar = __esm({
288504
288796
  "packages/cli/src/tui/status-bar.ts"() {
288505
288797
  "use strict";
@@ -288677,7 +288969,7 @@ var init_status_bar = __esm({
288677
288969
  BOX_H = "─";
288678
288970
  BOX_V = "│";
288679
288971
  _globalFooterLock = false;
288680
- RESET = "\x1B[0m";
288972
+ RESET2 = "\x1B[0m";
288681
288973
  CURSOR_BLINK_BLOCK = "\x1B[1 q";
288682
288974
  _isWindows = process.platform === "win32";
288683
288975
  StatusBar = class _StatusBar {
@@ -288731,6 +289023,12 @@ var init_status_bar = __esm({
288731
289023
  _prevTermCols = 0;
288732
289024
  /** Debounce timer for resize events — prevents separator stacking during drag */
288733
289025
  _resizeTimer = null;
289026
+ /** WO-TASK-02 — callback fired at the END of _handleResizeImmediate so
289027
+ * the tasks renderer can repaint AFTER the clear loop wipes the zone.
289028
+ * Without this, refreshTuiTasks() called from interactive.ts's resize
289029
+ * handler runs BEFORE the debounced _handleResizeImmediate and gets
289030
+ * clobbered. Wired in interactive.ts via setOnResizeFinalized(). */
289031
+ _onResizeFinalized = null;
288734
289032
  /** True while resize is in-flight (between first SIGWINCH and debounce settle).
288735
289033
  * Suppresses ALL footer renders to prevent separator debris at intermediate sizes. */
288736
289034
  _resizing = false;
@@ -289036,14 +289334,14 @@ var init_status_bar = __esm({
289036
289334
  const hdrRow = layout().headerContent;
289037
289335
  let buf = "\x1B7";
289038
289336
  buf += `\x1B[${hdrRow};1H${PANEL_BG_SEQ}\x1B[2K`;
289039
- buf += `${BOX_FG}│${RESET}${PANEL_BG_SEQ}`;
289337
+ buf += `${BOX_FG}│${RESET2}${PANEL_BG_SEQ}`;
289040
289338
  buf += leftArrow;
289041
289339
  buf += ` `;
289042
289340
  buf += `\x1B[38;5;${TEXT_PRIMARY}m${PANEL_BG_SEQ}`;
289043
289341
  buf += content;
289044
289342
  buf += `\x1B[${hdrRow};${w - 1}H`;
289045
289343
  buf += rightArrow;
289046
- buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${RESET}`;
289344
+ buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${RESET2}`;
289047
289345
  buf += "\x1B8";
289048
289346
  this.termWrite(buf);
289049
289347
  }
@@ -289433,7 +289731,7 @@ var init_status_bar = __esm({
289433
289731
  if (nexusDir) {
289434
289732
  try {
289435
289733
  const metricsPath = nexusDir + "/remote-metrics.json";
289436
- const raw = readFileSync43(metricsPath, "utf8");
289734
+ const raw = readFileSync44(metricsPath, "utf8");
289437
289735
  const cached = JSON.parse(raw);
289438
289736
  if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
289439
289737
  const m2 = cached.data;
@@ -289968,6 +290266,8 @@ var init_status_bar = __esm({
289968
290266
  this._activeViewId = id;
289969
290267
  this._contentLines = view.contentLines;
289970
290268
  this._contentScrollOffset = view.scrollOffset;
290269
+ Promise.resolve().then(() => (init_tui_tasks_renderer(), tui_tasks_renderer_exports)).then((m2) => m2.setTuiTasksScope({ mainViewActive: id === "main" })).catch(() => {
290270
+ });
289971
290271
  this.repaintContent();
289972
290272
  this.renderAgentTabs();
289973
290273
  }
@@ -290116,11 +290416,11 @@ var init_status_bar = __esm({
290116
290416
  for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
290117
290417
  const row = pos.inputStartRow + i2;
290118
290418
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
290119
- buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${prefix}${inputWrap.lines[i2]}${RESET}`;
290419
+ buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${prefix}${inputWrap.lines[i2]}${RESET2}`;
290120
290420
  }
290121
290421
  const boxInnerP = w - 2;
290122
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerP))}${BOX_BR}${RESET}`;
290123
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET}\x1B[?7h\x1B[${pos.scrollEnd};1H`;
290422
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerP))}${BOX_BR}${RESET2}`;
290423
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET2}\x1B[?7h\x1B[${pos.scrollEnd};1H`;
290124
290424
  this.termWrite(buf);
290125
290425
  } else {
290126
290426
  this.applyScrollRegion(true);
@@ -290135,6 +290435,18 @@ var init_status_bar = __esm({
290135
290435
  this.renderFooterAndPositionInput();
290136
290436
  if (this._bannerRefresh) this._bannerRefresh();
290137
290437
  }
290438
+ if (this._onResizeFinalized) {
290439
+ try {
290440
+ this._onResizeFinalized();
290441
+ } catch {
290442
+ }
290443
+ }
290444
+ }
290445
+ /** Register a callback that fires AT THE END of _handleResizeImmediate.
290446
+ * Use this from interactive.ts to repaint the tasks panel after the
290447
+ * debounced clear/redraw cycle finishes. */
290448
+ setOnResizeFinalized(cb) {
290449
+ this._onResizeFinalized = cb;
290138
290450
  }
290139
290451
  /**
290140
290452
  * Update the top boundary of the scroll region (e.g. after carousel retirement).
@@ -290262,7 +290574,7 @@ ${CONTENT_BG_SEQ}`);
290262
290574
  process.stdout.write = this._origWrite;
290263
290575
  this._origWrite = null;
290264
290576
  }
290265
- process.stdout.write(RESET);
290577
+ process.stdout.write(RESET2);
290266
290578
  this._brailleSpinner.setMetrics({ isStreaming: false });
290267
290579
  this.renderFooterAndPositionInput();
290268
290580
  this.scheduleMouseIdle();
@@ -290918,19 +291230,19 @@ ${CONTENT_BG_SEQ}`);
290918
291230
  const inputWrap = this.wrapInput(w);
290919
291231
  let buf = "\x1B[?7l";
290920
291232
  const boxInner = w - 2;
290921
- buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL}${BOX_H.repeat(Math.max(0, boxInner))}${BOX_TR}${RESET}`;
291233
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL}${BOX_H.repeat(Math.max(0, boxInner))}${BOX_TR}${RESET2}`;
290922
291234
  const spacerRow = pos.inputStartRow - 1;
290923
291235
  if (spacerRow >= this.scrollRegionTop) {
290924
- buf += `\x1B[${spacerRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET}`;
291236
+ buf += `\x1B[${spacerRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET2}`;
290925
291237
  }
290926
291238
  for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
290927
291239
  const row = pos.inputStartRow + 1 + i2;
290928
291240
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
290929
291241
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
290930
291242
  buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
290931
- buf += `${BOX_FG}${BOX_V}${RESET}${PANEL_BG_SEQ}${lineContent}`;
291243
+ buf += `${BOX_FG}${BOX_V}${RESET2}${PANEL_BG_SEQ}${lineContent}`;
290932
291244
  buf += `${PANEL_BG_SEQ}\x1B[K`;
290933
- buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET}`;
291245
+ buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET2}`;
290934
291246
  }
290935
291247
  const cursorTermRow = pos.inputStartRow + 1 + inputWrap.cursorRow;
290936
291248
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
@@ -290942,17 +291254,17 @@ ${CONTENT_BG_SEQ}`);
290942
291254
  const fg2 = isHighlighted ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
290943
291255
  const slash = isHighlighted ? `\x1B[38;5;245m` : `\x1B[38;5;${TEXT_DIM}m`;
290944
291256
  const marker = isHighlighted ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
290945
- buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V}${RESET}`;
291257
+ buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V}${RESET2}`;
290946
291258
  buf += `${bg} ${marker}${slash}/${fg2}${cmd}`;
290947
291259
  buf += `${PANEL_BG_SEQ}\x1B[K`;
290948
- buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET}`;
291260
+ buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET2}`;
290949
291261
  }
290950
291262
  const suggestBottomRow = pos.suggestStartRow + this._suggestions.length;
290951
- buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInner))}${BOX_BR}${RESET}`;
291263
+ buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInner))}${BOX_BR}${RESET2}`;
290952
291264
  } else {
290953
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInner))}${BOX_BR}${RESET}`;
291265
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInner))}${BOX_BR}${RESET2}`;
290954
291266
  }
290955
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET}`;
291267
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET2}`;
290956
291268
  buf += "\x1B[?7h";
290957
291269
  if (this.writeDepth === 0) {
290958
291270
  buf += `\x1B[${cursorTermRow};${inputWrap.cursorCol}H${CURSOR_BLINK_BLOCK}\x1B[?25h`;
@@ -290985,7 +291297,7 @@ ${CONTENT_BG_SEQ}`);
290985
291297
  const pos = this.rowPositions(termRows());
290986
291298
  let buf = "\x1B7\x1B[?7l";
290987
291299
  if (pos.tabBarRow > 0) {
290988
- buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET}`;
291300
+ buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET2}`;
290989
291301
  }
290990
291302
  const boxInnerR = w - 2;
290991
291303
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
@@ -290995,14 +291307,14 @@ ${CONTENT_BG_SEQ}`);
290995
291307
  const isHl = si === this._suggestIndex;
290996
291308
  const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
290997
291309
  const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
290998
- buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V}${RESET}${PANEL_BG_SEQ} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
290999
- buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET}`;
291310
+ buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V}${RESET2}${PANEL_BG_SEQ} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
291311
+ buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET2}`;
291000
291312
  }
291001
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerR))}${BOX_BR}${RESET}`;
291313
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerR))}${BOX_BR}${RESET2}`;
291002
291314
  } else {
291003
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerR))}${BOX_BR}${RESET}`;
291315
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerR))}${BOX_BR}${RESET2}`;
291004
291316
  }
291005
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET}\x1B[?7h\x1B8` + // DEC restore cursor
291317
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET2}\x1B[?7h\x1B8` + // DEC restore cursor
291006
291318
  (this.writeDepth === 0 ? `${CURSOR_BLINK_BLOCK}\x1B[?25h` : "");
291007
291319
  this.termWrite(buf);
291008
291320
  if (pos.tabBarRow > 0) this.renderAgentTabs();
@@ -291036,16 +291348,16 @@ ${CONTENT_BG_SEQ}`);
291036
291348
  }
291037
291349
  buf += "\x1B[?7l";
291038
291350
  const boxInnerH = w - 2;
291039
- buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL}${BOX_H.repeat(Math.max(0, boxInnerH))}${BOX_TR}${RESET}`;
291351
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL}${BOX_H.repeat(Math.max(0, boxInnerH))}${BOX_TR}${RESET2}`;
291040
291352
  for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
291041
291353
  const row = pos.inputStartRow + 1 + i2;
291042
291354
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
291043
291355
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
291044
- buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V}${RESET}${PANEL_BG_SEQ}${lineContent}${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET}`;
291356
+ buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V}${RESET2}${PANEL_BG_SEQ}${lineContent}${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET2}`;
291045
291357
  }
291046
291358
  const boxInnerS = w - 2;
291047
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerS))}${BOX_BR}${RESET}`;
291048
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET}`;
291359
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL}${BOX_H.repeat(Math.max(0, boxInnerS))}${BOX_BR}${RESET2}`;
291360
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET2}`;
291049
291361
  buf += "\x1B[?7h";
291050
291362
  buf += "\x1B8";
291051
291363
  if (heightDelta > 0) {
@@ -291062,9 +291374,9 @@ ${CONTENT_BG_SEQ}`);
291062
291374
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
291063
291375
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
291064
291376
  buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
291065
- buf += `${BOX_FG}${BOX_V}${RESET}${PANEL_BG_SEQ}${lineContent}`;
291377
+ buf += `${BOX_FG}${BOX_V}${RESET2}${PANEL_BG_SEQ}${lineContent}`;
291066
291378
  buf += `${PANEL_BG_SEQ}\x1B[K`;
291067
- buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET}`;
291379
+ buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V}${RESET2}`;
291068
291380
  }
291069
291381
  buf += "\x1B[?7h";
291070
291382
  this.termWrite(buf);
@@ -291920,9 +292232,9 @@ __export(personaplex_exports, {
291920
292232
  startPersonaPlexDaemon: () => startPersonaPlexDaemon,
291921
292233
  stopPersonaPlex: () => stopPersonaPlex
291922
292234
  });
291923
- import { existsSync as existsSync57, writeFileSync as writeFileSync29, readFileSync as readFileSync44, mkdirSync as mkdirSync32, copyFileSync as copyFileSync2, readdirSync as readdirSync15, statSync as statSync17 } from "node:fs";
291924
- import { join as join74, dirname as dirname21 } from "node:path";
291925
- import { homedir as homedir24 } from "node:os";
292235
+ import { existsSync as existsSync58, writeFileSync as writeFileSync29, readFileSync as readFileSync45, mkdirSync as mkdirSync32, copyFileSync as copyFileSync2, readdirSync as readdirSync15, statSync as statSync17 } from "node:fs";
292236
+ import { join as join75, dirname as dirname21 } from "node:path";
292237
+ import { homedir as homedir25 } from "node:os";
291926
292238
  import { execSync as execSync47, spawn as spawn21 } from "node:child_process";
291927
292239
  import { fileURLToPath as fileURLToPath12 } from "node:url";
291928
292240
  function execAsync(cmd, opts = {}) {
@@ -291954,7 +292266,7 @@ function selectWeightTier(vramGB) {
291954
292266
  }
291955
292267
  function detectJetson() {
291956
292268
  try {
291957
- const model = readFileSync44("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
292269
+ const model = readFileSync45("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
291958
292270
  if (/jetson|orin|tegra/i.test(model)) {
291959
292271
  const memInfo = execSync47("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
291960
292272
  const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
@@ -292031,8 +292343,8 @@ function fileLink2(filePath, label) {
292031
292343
  return `\x1B]8;;${url}\x1B\\${text}\x1B]8;;\x1B\\`;
292032
292344
  }
292033
292345
  function isPersonaPlexRunning() {
292034
- if (!existsSync57(PID_FILE)) return false;
292035
- const pid = parseInt(readFileSync44(PID_FILE, "utf8").trim(), 10);
292346
+ if (!existsSync58(PID_FILE)) return false;
292347
+ const pid = parseInt(readFileSync45(PID_FILE, "utf8").trim(), 10);
292036
292348
  if (isNaN(pid) || pid <= 0) return false;
292037
292349
  try {
292038
292350
  process.kill(pid, 0);
@@ -292043,18 +292355,18 @@ function isPersonaPlexRunning() {
292043
292355
  }
292044
292356
  function getPersonaPlexWSUrl() {
292045
292357
  if (!isPersonaPlexRunning()) return null;
292046
- if (!existsSync57(PORT_FILE)) return null;
292047
- const port = parseInt(readFileSync44(PORT_FILE, "utf8").trim(), 10);
292358
+ if (!existsSync58(PORT_FILE)) return null;
292359
+ const port = parseInt(readFileSync45(PORT_FILE, "utf8").trim(), 10);
292048
292360
  return isNaN(port) ? null : `wss://127.0.0.1:${port}`;
292049
292361
  }
292050
292362
  function isPersonaPlexInstalled() {
292051
- return existsSync57(join74(PERSONAPLEX_DIR, "model_ready"));
292363
+ return existsSync58(join75(PERSONAPLEX_DIR, "model_ready"));
292052
292364
  }
292053
292365
  function getWeightTier() {
292054
292366
  const detected = detectPersonaPlexCapability();
292055
- const tierFile = join74(PERSONAPLEX_DIR, "weight_tier");
292056
- if (existsSync57(tierFile)) {
292057
- const saved = readFileSync44(tierFile, "utf8").trim();
292367
+ const tierFile = join75(PERSONAPLEX_DIR, "weight_tier");
292368
+ if (existsSync58(tierFile)) {
292369
+ const saved = readFileSync45(tierFile, "utf8").trim();
292058
292370
  if (saved in WEIGHT_REPOS) {
292059
292371
  const vram = detected.vramGB;
292060
292372
  if (saved === "nf4-distilled" && vram < 24) {
@@ -292080,8 +292392,8 @@ async function installPersonaPlex(onInfo, weightTier) {
292080
292392
  }
292081
292393
  const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
292082
292394
  if (isAarch64) log22(`Detected ARM64 platform (${arch2}) — Jetson/ARM install path`);
292083
- const venvDir = join74(PERSONAPLEX_DIR, "venv");
292084
- if (!existsSync57(venvDir)) {
292395
+ const venvDir = join75(PERSONAPLEX_DIR, "venv");
292396
+ if (!existsSync58(venvDir)) {
292085
292397
  log22("Creating Python virtual environment...");
292086
292398
  try {
292087
292399
  const ssp = isAarch64 ? " --system-site-packages" : "";
@@ -292091,8 +292403,8 @@ async function installPersonaPlex(onInfo, weightTier) {
292091
292403
  return false;
292092
292404
  }
292093
292405
  }
292094
- const pip = process.platform === "win32" ? join74(venvDir, "Scripts", "pip.exe") : join74(venvDir, "bin", "pip");
292095
- const python = process.platform === "win32" ? join74(venvDir, "Scripts", "python.exe") : join74(venvDir, "bin", "python3");
292406
+ const pip = process.platform === "win32" ? join75(venvDir, "Scripts", "pip.exe") : join75(venvDir, "bin", "pip");
292407
+ const python = process.platform === "win32" ? join75(venvDir, "Scripts", "python.exe") : join75(venvDir, "bin", "python3");
292096
292408
  log22("Checking system dependencies (libopus)...");
292097
292409
  try {
292098
292410
  if (process.platform === "linux") {
@@ -292122,9 +292434,9 @@ async function installPersonaPlex(onInfo, weightTier) {
292122
292434
  }
292123
292435
  }
292124
292436
  log22("Installing PersonaPlex (moshi package)...");
292125
- const repoDir = join74(PERSONAPLEX_DIR, "personaplex-repo");
292437
+ const repoDir = join75(PERSONAPLEX_DIR, "personaplex-repo");
292126
292438
  try {
292127
- if (!existsSync57(repoDir)) {
292439
+ if (!existsSync58(repoDir)) {
292128
292440
  await execAsync(
292129
292441
  `git clone https://github.com/NVIDIA/personaplex.git "${repoDir}"`,
292130
292442
  { timeout: 12e4 }
@@ -292148,7 +292460,7 @@ async function installPersonaPlex(onInfo, weightTier) {
292148
292460
  if (isAarch64) {
292149
292461
  log22("ARM64: Installing moshi (--no-deps to preserve JetPack torch)...");
292150
292462
  await execAsync(
292151
- `"${pip}" install --quiet --no-deps "${join74(repoDir, "moshi")}/."`,
292463
+ `"${pip}" install --quiet --no-deps "${join75(repoDir, "moshi")}/."`,
292152
292464
  { timeout: 3e5 }
292153
292465
  );
292154
292466
  log22("ARM64: Installing remaining moshi dependencies...");
@@ -292158,7 +292470,7 @@ async function installPersonaPlex(onInfo, weightTier) {
292158
292470
  );
292159
292471
  } else {
292160
292472
  await execAsync(
292161
- `"${pip}" install --quiet "${join74(repoDir, "moshi")}/."`,
292473
+ `"${pip}" install --quiet "${join75(repoDir, "moshi")}/."`,
292162
292474
  { timeout: 6e5 }
292163
292475
  // 10 min — torch download is ~2.5GB
292164
292476
  );
@@ -292176,16 +292488,16 @@ async function installPersonaPlex(onInfo, weightTier) {
292176
292488
  }
292177
292489
  return false;
292178
292490
  }
292179
- const serverPy = join74(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
292491
+ const serverPy = join75(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
292180
292492
  try {
292181
292493
  const sitePackages = execSync47(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
292182
292494
  encoding: "utf8",
292183
292495
  timeout: 5e3,
292184
292496
  stdio: "pipe"
292185
292497
  }).trim();
292186
- const serverFile = join74(sitePackages, "server.py");
292187
- if (existsSync57(serverFile)) {
292188
- let src2 = readFileSync44(serverFile, "utf8");
292498
+ const serverFile = join75(sitePackages, "server.py");
292499
+ if (existsSync58(serverFile)) {
292500
+ let src2 = readFileSync45(serverFile, "utf8");
292189
292501
  if (src2.includes('int(request["seed"])')) {
292190
292502
  src2 = src2.replace('int(request["seed"])', 'int(request.query["seed"])');
292191
292503
  writeFileSync29(serverFile, src2);
@@ -292200,9 +292512,9 @@ async function installPersonaPlex(onInfo, weightTier) {
292200
292512
  timeout: 5e3,
292201
292513
  stdio: "pipe"
292202
292514
  }).trim();
292203
- const loadersFile = join74(sitePackages, "models", "loaders.py");
292204
- if (existsSync57(loadersFile)) {
292205
- let src2 = readFileSync44(loadersFile, "utf8");
292515
+ const loadersFile = join75(sitePackages, "models", "loaders.py");
292516
+ if (existsSync58(loadersFile)) {
292517
+ let src2 = readFileSync45(loadersFile, "utf8");
292206
292518
  if (!src2.includes("_dequantize_2bit_state_dict")) {
292207
292519
  const dequantPatch = `
292208
292520
  import math
@@ -292304,30 +292616,30 @@ $2if filename.endswith(".safetensors"):`
292304
292616
  timeout: 5e3,
292305
292617
  stdio: "pipe"
292306
292618
  }).trim();
292307
- const hybridDest = join74(sitePackages2, "hybrid_agent.py");
292308
- const serverDest = join74(sitePackages2, "server.py");
292309
- if (!existsSync57(hybridDest) || !readFileSync44(hybridDest, "utf8").includes("OA_API_BASE")) {
292619
+ const hybridDest = join75(sitePackages2, "hybrid_agent.py");
292620
+ const serverDest = join75(sitePackages2, "server.py");
292621
+ if (!existsSync58(hybridDest) || !readFileSync45(hybridDest, "utf8").includes("OA_API_BASE")) {
292310
292622
  log22("Deploying hybrid_agent.py (OA API integration)...");
292311
292623
  try {
292312
292624
  await execAsync(
292313
292625
  `curl -sL "https://raw.githubusercontent.com/robit-man/personaplex/main/personaplex-setup/moshi/moshi/hybrid_agent.py" -o "${hybridDest}"`,
292314
292626
  { timeout: 3e4 }
292315
292627
  );
292316
- if (existsSync57(hybridDest) && readFileSync44(hybridDest, "utf8").includes("OA_API_BASE")) {
292628
+ if (existsSync58(hybridDest) && readFileSync45(hybridDest, "utf8").includes("OA_API_BASE")) {
292317
292629
  log22("hybrid_agent.py deployed (OA API + Ollama fallback).");
292318
292630
  }
292319
292631
  } catch {
292320
292632
  log22("hybrid_agent.py download failed — hybrid mode will be disabled.");
292321
292633
  }
292322
292634
  }
292323
- if (!readFileSync44(serverDest, "utf8").includes("hybrid_agent")) {
292635
+ if (!readFileSync45(serverDest, "utf8").includes("hybrid_agent")) {
292324
292636
  log22("Deploying patched server.py (hybrid mode + API endpoints)...");
292325
292637
  try {
292326
292638
  await execAsync(
292327
292639
  `curl -sL "https://raw.githubusercontent.com/robit-man/personaplex/main/personaplex-setup/moshi/moshi/server.py" -o "${serverDest}"`,
292328
292640
  { timeout: 3e4 }
292329
292641
  );
292330
- if (readFileSync44(serverDest, "utf8").includes("hybrid_agent")) {
292642
+ if (readFileSync45(serverDest, "utf8").includes("hybrid_agent")) {
292331
292643
  log22("server.py patched with hybrid intercept + REST APIs.");
292332
292644
  }
292333
292645
  } catch {
@@ -292390,7 +292702,7 @@ $2if filename.endswith(".safetensors"):`
292390
292702
  await execAsync(`"${python}" -c "from huggingface_hub import hf_hub_download; hf_hub_download('${nf4.repo}', '${nf4.file}', token=False)"`, {
292391
292703
  timeout: 6e5
292392
292704
  });
292393
- writeFileSync29(join74(PERSONAPLEX_DIR, "weight_tier"), "nf4");
292705
+ writeFileSync29(join75(PERSONAPLEX_DIR, "weight_tier"), "nf4");
292394
292706
  log22(`Downloaded INT4 weights instead (${nf4.sizeGB}GB, public).`);
292395
292707
  } catch {
292396
292708
  log22("Weight download failed.");
@@ -292402,8 +292714,8 @@ $2if filename.endswith(".safetensors"):`
292402
292714
  log22("Weights will download on first server launch.");
292403
292715
  }
292404
292716
  }
292405
- writeFileSync29(join74(PERSONAPLEX_DIR, "weight_tier"), tier);
292406
- writeFileSync29(join74(PERSONAPLEX_DIR, "model_ready"), (/* @__PURE__ */ new Date()).toISOString());
292717
+ writeFileSync29(join75(PERSONAPLEX_DIR, "weight_tier"), tier);
292718
+ writeFileSync29(join75(PERSONAPLEX_DIR, "model_ready"), (/* @__PURE__ */ new Date()).toISOString());
292407
292719
  log22(`PersonaPlex installed (${tier} tier). Use /call to start voice session.`);
292408
292720
  return true;
292409
292721
  }
@@ -292423,14 +292735,14 @@ async function startPersonaPlexDaemon(onInfo) {
292423
292735
  return null;
292424
292736
  }
292425
292737
  mkdirSync32(PERSONAPLEX_DIR, { recursive: true });
292426
- const venvPython2 = process.platform === "win32" ? join74(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join74(PERSONAPLEX_DIR, "venv", "bin", "python3");
292427
- const sslDir = join74(PERSONAPLEX_DIR, "ssl");
292738
+ const venvPython2 = process.platform === "win32" ? join75(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join75(PERSONAPLEX_DIR, "venv", "bin", "python3");
292739
+ const sslDir = join75(PERSONAPLEX_DIR, "ssl");
292428
292740
  mkdirSync32(sslDir, { recursive: true });
292429
292741
  const tier = getWeightTier();
292430
292742
  const repoInfo = WEIGHT_REPOS[tier];
292431
292743
  const extraArgs = [];
292432
292744
  if (tier !== "original") {
292433
- const cachedBf16 = join74(PERSONAPLEX_DIR, "model-bf16-cache.safetensors");
292745
+ const cachedBf16 = join75(PERSONAPLEX_DIR, "model-bf16-cache.safetensors");
292434
292746
  if (tier === "nf4-distilled") {
292435
292747
  log22(`Weight tier: ${tier} — distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
292436
292748
  try {
@@ -292438,8 +292750,8 @@ async function startPersonaPlexDaemon(onInfo) {
292438
292750
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
292439
292751
  { encoding: "utf8", timeout: 6e4, stdio: "pipe" }
292440
292752
  ).trim();
292441
- if (existsSync57(weightPath)) {
292442
- if (!existsSync57(cachedBf16)) {
292753
+ if (existsSync58(weightPath)) {
292754
+ if (!existsSync58(cachedBf16)) {
292443
292755
  log22("Converting .pt checkpoint to safetensors (one-time)...");
292444
292756
  execSync47(
292445
292757
  `"${venvPython2}" -c "
@@ -292452,7 +292764,7 @@ print('Converted')
292452
292764
  { timeout: 18e4, stdio: "pipe" }
292453
292765
  );
292454
292766
  }
292455
- if (existsSync57(cachedBf16)) {
292767
+ if (existsSync58(cachedBf16)) {
292456
292768
  extraArgs.push("--moshi-weight", cachedBf16);
292457
292769
  log22(`Using distilled weights: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
292458
292770
  } else {
@@ -292464,12 +292776,12 @@ print('Converted')
292464
292776
  }
292465
292777
  } else {
292466
292778
  log22(`Weight tier: ${tier} (${repoInfo.sizeGB}GB) — dequantizing to bf16 cache...`);
292467
- const dequantScript = join74(PERSONAPLEX_DIR, "dequant-loader.py");
292468
- if (!existsSync57(dequantScript)) {
292779
+ const dequantScript = join75(PERSONAPLEX_DIR, "dequant-loader.py");
292780
+ if (!existsSync58(dequantScript)) {
292469
292781
  const shipped = getShippedVoicesDir();
292470
292782
  if (shipped) {
292471
- const src2 = join74(shipped, "dequant-loader.py");
292472
- if (existsSync57(src2)) copyFileSync2(src2, dequantScript);
292783
+ const src2 = join75(shipped, "dequant-loader.py");
292784
+ if (existsSync58(src2)) copyFileSync2(src2, dequantScript);
292473
292785
  }
292474
292786
  }
292475
292787
  try {
@@ -292477,13 +292789,13 @@ print('Converted')
292477
292789
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
292478
292790
  { encoding: "utf8", timeout: 3e4, stdio: "pipe" }
292479
292791
  ).trim();
292480
- if (existsSync57(dequantScript) && existsSync57(weightPath)) {
292792
+ if (existsSync58(dequantScript) && existsSync58(weightPath)) {
292481
292793
  try {
292482
292794
  execSync47(
292483
292795
  `"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
292484
292796
  { timeout: 3e5, stdio: "pipe" }
292485
292797
  );
292486
- if (existsSync57(cachedBf16)) {
292798
+ if (existsSync58(cachedBf16)) {
292487
292799
  extraArgs.push("--moshi-weight", cachedBf16);
292488
292800
  log22(`Using dequantized cache: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
292489
292801
  }
@@ -292496,7 +292808,7 @@ print('Converted')
292496
292808
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
292497
292809
  { encoding: "utf8", timeout: 3e4, stdio: "pipe" }
292498
292810
  ).trim();
292499
- if (existsSync57(mimiPath)) extraArgs.push("--mimi-weight", mimiPath);
292811
+ if (existsSync58(mimiPath)) extraArgs.push("--mimi-weight", mimiPath);
292500
292812
  } catch {
292501
292813
  }
292502
292814
  try {
@@ -292504,7 +292816,7 @@ print('Converted')
292504
292816
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
292505
292817
  { encoding: "utf8", timeout: 3e4, stdio: "pipe" }
292506
292818
  ).trim();
292507
- if (existsSync57(tokPath)) extraArgs.push("--tokenizer", tokPath);
292819
+ if (existsSync58(tokPath)) extraArgs.push("--tokenizer", tokPath);
292508
292820
  } catch {
292509
292821
  }
292510
292822
  } catch {
@@ -292517,7 +292829,7 @@ print('Converted')
292517
292829
  let ollamaModel = process.env["HYBRID_LLM_MODEL"] || "";
292518
292830
  if (!ollamaModel) {
292519
292831
  try {
292520
- const oaConfig = JSON.parse(readFileSync44(join74(homedir24(), ".open-agents", "config.json"), "utf8"));
292832
+ const oaConfig = JSON.parse(readFileSync45(join75(homedir25(), ".open-agents", "config.json"), "utf8"));
292521
292833
  if (oaConfig.model) ollamaModel = oaConfig.model;
292522
292834
  } catch {
292523
292835
  }
@@ -292616,8 +292928,8 @@ print('Converted')
292616
292928
  return null;
292617
292929
  }
292618
292930
  function stopPersonaPlex() {
292619
- if (!existsSync57(PID_FILE)) return;
292620
- const pid = parseInt(readFileSync44(PID_FILE, "utf8").trim(), 10);
292931
+ if (!existsSync58(PID_FILE)) return;
292932
+ const pid = parseInt(readFileSync45(PID_FILE, "utf8").trim(), 10);
292621
292933
  if (isNaN(pid) || pid <= 0) return;
292622
292934
  try {
292623
292935
  if (process.platform === "win32") {
@@ -292653,12 +292965,12 @@ function listPersonaPlexVoices() {
292653
292965
  for (const name10 of builtins) {
292654
292966
  voices.push({ name: name10, type: "builtin", path: `${name10}.pt` });
292655
292967
  }
292656
- if (existsSync57(CUSTOM_VOICES_DIR)) {
292968
+ if (existsSync58(CUSTOM_VOICES_DIR)) {
292657
292969
  try {
292658
292970
  for (const f2 of readdirSync15(CUSTOM_VOICES_DIR)) {
292659
292971
  if (f2.endsWith(".pt")) {
292660
292972
  const name10 = f2.replace(/\.pt$/, "");
292661
- voices.push({ name: name10, type: "custom", path: join74(CUSTOM_VOICES_DIR, f2) });
292973
+ voices.push({ name: name10, type: "custom", path: join75(CUSTOM_VOICES_DIR, f2) });
292662
292974
  }
292663
292975
  }
292664
292976
  } catch {
@@ -292673,19 +292985,19 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
292673
292985
  log22("PersonaPlex not installed. Run /voice personaplex first.");
292674
292986
  return null;
292675
292987
  }
292676
- if (!existsSync57(inputWav)) {
292988
+ if (!existsSync58(inputWav)) {
292677
292989
  log22(`Input WAV not found: ${inputWav}`);
292678
292990
  return null;
292679
292991
  }
292680
292992
  mkdirSync32(CUSTOM_VOICES_DIR, { recursive: true });
292681
- const outputPt = join74(CUSTOM_VOICES_DIR, `${voiceName}.pt`);
292682
- if (existsSync57(outputPt)) {
292993
+ const outputPt = join75(CUSTOM_VOICES_DIR, `${voiceName}.pt`);
292994
+ if (existsSync58(outputPt)) {
292683
292995
  log22(`Voice "${voiceName}" already exists. Delete ${outputPt} to re-clone.`);
292684
292996
  return outputPt;
292685
292997
  }
292686
- const venvPython2 = process.platform === "win32" ? join74(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join74(PERSONAPLEX_DIR, "venv", "bin", "python3");
292687
- const cloneScript = join74(PERSONAPLEX_DIR, "clone-voice.py");
292688
- if (!existsSync57(cloneScript)) {
292998
+ const venvPython2 = process.platform === "win32" ? join75(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join75(PERSONAPLEX_DIR, "venv", "bin", "python3");
292999
+ const cloneScript = join75(PERSONAPLEX_DIR, "clone-voice.py");
293000
+ if (!existsSync58(cloneScript)) {
292689
293001
  log22("clone-voice.py not found. Reinstall PersonaPlex.");
292690
293002
  return null;
292691
293003
  }
@@ -292717,7 +293029,7 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
292717
293029
  output += d2.toString();
292718
293030
  });
292719
293031
  child.on("close", (code8) => {
292720
- if (code8 === 0 && existsSync57(outputPt)) {
293032
+ if (code8 === 0 && existsSync58(outputPt)) {
292721
293033
  log22(`Voice "${voiceName}" cloned successfully.`);
292722
293034
  resolve39(outputPt);
292723
293035
  } else {
@@ -292729,19 +293041,19 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
292729
293041
  }
292730
293042
  function getShippedVoicesDir() {
292731
293043
  const candidates = [
292732
- join74(PERSONAPLEX_DIR, "shipped_voices"),
293044
+ join75(PERSONAPLEX_DIR, "shipped_voices"),
292733
293045
  // cached copy
292734
- join74(process.cwd(), "voices", "personaplex")
293046
+ join75(process.cwd(), "voices", "personaplex")
292735
293047
  // repo root
292736
293048
  ];
292737
293049
  try {
292738
293050
  const modDir = dirname21(fileURLToPath12(import.meta.url));
292739
- candidates.push(join74(modDir, "..", "..", "..", "voices", "personaplex"));
292740
- candidates.push(join74(modDir, "..", "..", "..", "..", "voices", "personaplex"));
293051
+ candidates.push(join75(modDir, "..", "..", "..", "voices", "personaplex"));
293052
+ candidates.push(join75(modDir, "..", "..", "..", "..", "voices", "personaplex"));
292741
293053
  } catch {
292742
293054
  }
292743
293055
  for (const dir of candidates) {
292744
- if (existsSync57(dir)) {
293056
+ if (existsSync58(dir)) {
292745
293057
  try {
292746
293058
  const files = readdirSync15(dir);
292747
293059
  if (files.some((f2) => f2.endsWith(".pt"))) return dir;
@@ -292762,14 +293074,14 @@ function provisionShippedVoices(onInfo) {
292762
293074
  try {
292763
293075
  for (const f2 of readdirSync15(shippedDir)) {
292764
293076
  if (!f2.endsWith(".pt")) continue;
292765
- const customDst = join74(CUSTOM_VOICES_DIR, f2);
292766
- if (!existsSync57(customDst)) {
292767
- copyFileSync2(join74(shippedDir, f2), customDst);
293077
+ const customDst = join75(CUSTOM_VOICES_DIR, f2);
293078
+ if (!existsSync58(customDst)) {
293079
+ copyFileSync2(join75(shippedDir, f2), customDst);
292768
293080
  }
292769
293081
  if (hfVoicesDir) {
292770
- const hfDst = join74(hfVoicesDir, f2);
292771
- if (!existsSync57(hfDst)) {
292772
- copyFileSync2(join74(shippedDir, f2), hfDst);
293082
+ const hfDst = join75(hfVoicesDir, f2);
293083
+ if (!existsSync58(hfDst)) {
293084
+ copyFileSync2(join75(shippedDir, f2), hfDst);
292773
293085
  log22(`Deployed voice: ${f2.replace(".pt", "")}`);
292774
293086
  deployed++;
292775
293087
  }
@@ -292777,9 +293089,9 @@ function provisionShippedVoices(onInfo) {
292777
293089
  }
292778
293090
  } catch {
292779
293091
  }
292780
- const shippedScript = join74(shippedDir, "clone-voice.py");
292781
- const targetScript = join74(PERSONAPLEX_DIR, "clone-voice.py");
292782
- if (existsSync57(shippedScript) && !existsSync57(targetScript)) {
293092
+ const shippedScript = join75(shippedDir, "clone-voice.py");
293093
+ const targetScript = join75(PERSONAPLEX_DIR, "clone-voice.py");
293094
+ if (existsSync58(shippedScript) && !existsSync58(targetScript)) {
292783
293095
  try {
292784
293096
  copyFileSync2(shippedScript, targetScript);
292785
293097
  } catch {
@@ -292788,14 +293100,14 @@ function provisionShippedVoices(onInfo) {
292788
293100
  return deployed;
292789
293101
  }
292790
293102
  function getHFVoicesDir() {
292791
- const hfBase = join74(homedir24(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
292792
- if (!existsSync57(hfBase)) return null;
293103
+ const hfBase = join75(homedir25(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
293104
+ if (!existsSync58(hfBase)) return null;
292793
293105
  try {
292794
- const snapshots = join74(hfBase, "snapshots");
292795
- if (!existsSync57(snapshots)) return null;
293106
+ const snapshots = join75(hfBase, "snapshots");
293107
+ if (!existsSync58(snapshots)) return null;
292796
293108
  for (const snap of readdirSync15(snapshots)) {
292797
- const voicesDir = join74(snapshots, snap, "voices");
292798
- if (existsSync57(voicesDir)) return voicesDir;
293109
+ const voicesDir = join75(snapshots, snap, "voices");
293110
+ if (existsSync58(voicesDir)) return voicesDir;
292799
293111
  }
292800
293112
  } catch {
292801
293113
  }
@@ -292804,19 +293116,19 @@ function getHFVoicesDir() {
292804
293116
  function patchFrontendVoiceList(onInfo) {
292805
293117
  const log22 = onInfo ?? (() => {
292806
293118
  });
292807
- const hfBase = join74(homedir24(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
292808
- if (!existsSync57(hfBase)) return;
293119
+ const hfBase = join75(homedir25(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
293120
+ if (!existsSync58(hfBase)) return;
292809
293121
  try {
292810
- const snapshots = join74(hfBase, "snapshots");
293122
+ const snapshots = join75(hfBase, "snapshots");
292811
293123
  for (const snap of readdirSync15(snapshots)) {
292812
- const distDir = join74(snapshots, snap, "dist", "assets");
292813
- if (!existsSync57(distDir)) continue;
293124
+ const distDir = join75(snapshots, snap, "dist", "assets");
293125
+ if (!existsSync58(distDir)) continue;
292814
293126
  for (const f2 of readdirSync15(distDir)) {
292815
293127
  if (!f2.startsWith("index-") || !f2.endsWith(".js")) continue;
292816
- const jsPath = join74(distDir, f2);
292817
- let js = readFileSync44(jsPath, "utf8");
293128
+ const jsPath = join75(distDir, f2);
293129
+ let js = readFileSync45(jsPath, "utf8");
292818
293130
  const customVoices = [];
292819
- if (existsSync57(CUSTOM_VOICES_DIR)) {
293131
+ if (existsSync58(CUSTOM_VOICES_DIR)) {
292820
293132
  for (const vf of readdirSync15(CUSTOM_VOICES_DIR)) {
292821
293133
  if (vf.endsWith(".pt")) {
292822
293134
  const name10 = vf.replace(".pt", "");
@@ -292882,11 +293194,11 @@ var init_personaplex = __esm({
292882
293194
  nf4: { repo: "cudabenchmarktest/personaplex-7b-nf4", file: "model-nf4.safetensors", sizeGB: 4.1, needsToken: false },
292883
293195
  "nf4-distilled": { repo: "cudabenchmarktest/personaplex-7b-nf4-distilled", file: "student_best.pt", sizeGB: 16.7, needsToken: false }
292884
293196
  };
292885
- PERSONAPLEX_DIR = join74(homedir24(), ".open-agents", "voice", "personaplex");
292886
- PID_FILE = join74(PERSONAPLEX_DIR, "daemon.pid");
292887
- PORT_FILE = join74(PERSONAPLEX_DIR, "daemon.port");
292888
- LOG_FILE = join74(PERSONAPLEX_DIR, "daemon.log");
292889
- CUSTOM_VOICES_DIR = join74(PERSONAPLEX_DIR, "custom_voices");
293197
+ PERSONAPLEX_DIR = join75(homedir25(), ".open-agents", "voice", "personaplex");
293198
+ PID_FILE = join75(PERSONAPLEX_DIR, "daemon.pid");
293199
+ PORT_FILE = join75(PERSONAPLEX_DIR, "daemon.port");
293200
+ LOG_FILE = join75(PERSONAPLEX_DIR, "daemon.log");
293201
+ CUSTOM_VOICES_DIR = join75(PERSONAPLEX_DIR, "custom_voices");
292890
293202
  }
292891
293203
  });
292892
293204
 
@@ -292927,9 +293239,9 @@ __export(setup_exports, {
292927
293239
  import * as readline from "node:readline";
292928
293240
  import { execSync as execSync48, spawn as spawn22, exec as exec4 } from "node:child_process";
292929
293241
  import { promisify as promisify7 } from "node:util";
292930
- import { existsSync as existsSync58, writeFileSync as writeFileSync30, readFileSync as readFileSync45, appendFileSync as appendFileSync2, mkdirSync as mkdirSync33 } from "node:fs";
292931
- import { join as join75 } from "node:path";
292932
- import { homedir as homedir25, platform as platform3 } from "node:os";
293242
+ import { existsSync as existsSync59, writeFileSync as writeFileSync30, readFileSync as readFileSync46, appendFileSync as appendFileSync2, mkdirSync as mkdirSync33 } from "node:fs";
293243
+ import { join as join76 } from "node:path";
293244
+ import { homedir as homedir26, platform as platform3 } from "node:os";
292933
293245
  async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
292934
293246
  if (_toolSupportCache.has(modelName)) return _toolSupportCache.get(modelName);
292935
293247
  try {
@@ -293321,7 +293633,7 @@ async function installOllamaMac(_rl) {
293321
293633
  );
293322
293634
  if (!hasCmd("brew")) {
293323
293635
  try {
293324
- const brewPrefix = existsSync58("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
293636
+ const brewPrefix = existsSync59("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
293325
293637
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
293326
293638
  } catch {
293327
293639
  }
@@ -294106,9 +294418,9 @@ async function doSetup(config, rl) {
294106
294418
  `PARAMETER num_predict ${numPredict}`,
294107
294419
  `PARAMETER stop "<|endoftext|>"`
294108
294420
  ].join("\n");
294109
- const modelDir2 = join75(homedir25(), ".open-agents", "models");
294421
+ const modelDir2 = join76(homedir26(), ".open-agents", "models");
294110
294422
  mkdirSync33(modelDir2, { recursive: true });
294111
- const modelfilePath = join75(modelDir2, `Modelfile.${customName}`);
294423
+ const modelfilePath = join76(modelDir2, `Modelfile.${customName}`);
294112
294424
  writeFileSync30(modelfilePath, modelfileContent + "\n", "utf8");
294113
294425
  process.stdout.write(` ${c3.dim("Creating model...")} `);
294114
294426
  execSync48(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -294154,7 +294466,7 @@ async function isModelAvailable(config) {
294154
294466
  }
294155
294467
  function isFirstRun() {
294156
294468
  try {
294157
- return !existsSync58(join75(homedir25(), ".open-agents", "config.json"));
294469
+ return !existsSync59(join76(homedir26(), ".open-agents", "config.json"));
294158
294470
  } catch {
294159
294471
  return true;
294160
294472
  }
@@ -294202,7 +294514,7 @@ function detectPkgManager() {
294202
294514
  return null;
294203
294515
  }
294204
294516
  function getVenvDir() {
294205
- return join75(homedir25(), ".open-agents", "venv");
294517
+ return join76(homedir26(), ".open-agents", "venv");
294206
294518
  }
294207
294519
  function hasVenvModule() {
294208
294520
  try {
@@ -294215,10 +294527,10 @@ function hasVenvModule() {
294215
294527
  function ensureVenv(log22) {
294216
294528
  const venvDir = getVenvDir();
294217
294529
  const isWin2 = process.platform === "win32";
294218
- const pipPath = isWin2 ? join75(venvDir, "Scripts", "pip.exe") : join75(venvDir, "bin", "pip");
294219
- const venvPyPath = isWin2 ? join75(venvDir, "Scripts", "python.exe") : join75(venvDir, "bin", "python3");
294530
+ const pipPath = isWin2 ? join76(venvDir, "Scripts", "pip.exe") : join76(venvDir, "bin", "pip");
294531
+ const venvPyPath = isWin2 ? join76(venvDir, "Scripts", "python.exe") : join76(venvDir, "bin", "python3");
294220
294532
  const pythonCmd = isWin2 ? "python" : "python3";
294221
- if (existsSync58(pipPath)) {
294533
+ if (existsSync59(pipPath)) {
294222
294534
  try {
294223
294535
  execSync48(`"${venvPyPath}" -m pip --version`, { stdio: "pipe", timeout: 1e4 });
294224
294536
  return venvDir;
@@ -294249,7 +294561,7 @@ function ensureVenv(log22) {
294249
294561
  return null;
294250
294562
  }
294251
294563
  try {
294252
- mkdirSync33(join75(homedir25(), ".open-agents"), { recursive: true });
294564
+ mkdirSync33(join76(homedir26(), ".open-agents"), { recursive: true });
294253
294565
  const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
294254
294566
  execSync48(`${pyCmd} -m venv --clear "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
294255
294567
  try {
@@ -294358,12 +294670,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
294358
294670
  ];
294359
294671
  {
294360
294672
  const pm2 = detectPkgManager();
294361
- const _visionMarkerDir = join75(homedir25(), ".open-agents");
294362
- const _visionMarkerFile = join75(_visionMarkerDir, "vision-deps-installed.json");
294673
+ const _visionMarkerDir = join76(homedir26(), ".open-agents");
294674
+ const _visionMarkerFile = join76(_visionMarkerDir, "vision-deps-installed.json");
294363
294675
  let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
294364
294676
  try {
294365
- if (existsSync58(_visionMarkerFile)) {
294366
- const _vm = JSON.parse(readFileSync45(_visionMarkerFile, "utf8"));
294677
+ if (existsSync59(_visionMarkerFile)) {
294678
+ const _vm = JSON.parse(readFileSync46(_visionMarkerFile, "utf8"));
294367
294679
  _visionPreviouslyInstalled = new Set(_vm.installed || []);
294368
294680
  }
294369
294681
  } catch {
@@ -294529,15 +294841,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
294529
294841
  }
294530
294842
  const venvDir = getVenvDir();
294531
294843
  const isWin2 = process.platform === "win32";
294532
- const venvBin = join75(venvDir, isWin2 ? "Scripts" : "bin");
294533
- const venvMoondream = join75(venvBin, isWin2 ? "moondream-station.exe" : "moondream-station");
294844
+ const venvBin = join76(venvDir, isWin2 ? "Scripts" : "bin");
294845
+ const venvMoondream = join76(venvBin, isWin2 ? "moondream-station.exe" : "moondream-station");
294534
294846
  const venv = ensureVenv(log22);
294535
- if (venv && !hasCmd("moondream-station") && !existsSync58(venvMoondream)) {
294536
- const venvPip2 = join75(venvBin, "pip");
294847
+ if (venv && !hasCmd("moondream-station") && !existsSync59(venvMoondream)) {
294848
+ const venvPip2 = join76(venvBin, "pip");
294537
294849
  log22("Installing moondream-station in ~/.open-agents/venv...");
294538
294850
  try {
294539
294851
  execSync48(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
294540
- if (existsSync58(venvMoondream)) {
294852
+ if (existsSync59(venvMoondream)) {
294541
294853
  log22("moondream-station installed successfully.");
294542
294854
  } else {
294543
294855
  try {
@@ -294554,8 +294866,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
294554
294866
  }
294555
294867
  }
294556
294868
  if (venv) {
294557
- const venvPython2 = join75(venvBin, isWin2 ? "python.exe" : "python");
294558
- const venvPip2 = join75(venvBin, isWin2 ? "pip.exe" : "pip");
294869
+ const venvPython2 = join76(venvBin, isWin2 ? "python.exe" : "python");
294870
+ const venvPip2 = join76(venvBin, isWin2 ? "pip.exe" : "pip");
294559
294871
  let ocrStackInstalled = false;
294560
294872
  try {
294561
294873
  execSync48(
@@ -294611,11 +294923,11 @@ function ensureCloudflaredBackground(onInfo) {
294611
294923
  const cfArch = archMap[arch2] ?? "amd64";
294612
294924
  try {
294613
294925
  execSync48(
294614
- `curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir25()}/.local/bin" && mv /tmp/cloudflared "${homedir25()}/.local/bin/cloudflared"`,
294926
+ `curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir26()}/.local/bin" && mv /tmp/cloudflared "${homedir26()}/.local/bin/cloudflared"`,
294615
294927
  { stdio: "pipe", timeout: 6e4 }
294616
294928
  );
294617
- if (!process.env.PATH?.includes(`${homedir25()}/.local/bin`)) {
294618
- process.env.PATH = `${homedir25()}/.local/bin:${process.env.PATH}`;
294929
+ if (!process.env.PATH?.includes(`${homedir26()}/.local/bin`)) {
294930
+ process.env.PATH = `${homedir26()}/.local/bin:${process.env.PATH}`;
294619
294931
  }
294620
294932
  if (hasCmd("cloudflared")) {
294621
294933
  log22("cloudflared installed.");
@@ -294712,9 +295024,9 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
294712
295024
  `PARAMETER num_predict ${numPredict}`,
294713
295025
  `PARAMETER stop "<|endoftext|>"`
294714
295026
  ].join("\n");
294715
- const modelDir2 = join75(homedir25(), ".open-agents", "models");
295027
+ const modelDir2 = join76(homedir26(), ".open-agents", "models");
294716
295028
  mkdirSync33(modelDir2, { recursive: true });
294717
- const modelfilePath = join75(modelDir2, `Modelfile.${customName}`);
295029
+ const modelfilePath = join76(modelDir2, `Modelfile.${customName}`);
294718
295030
  writeFileSync30(modelfilePath, modelfileContent + "\n", "utf8");
294719
295031
  execSync48(`ollama create ${customName} -f ${modelfilePath}`, {
294720
295032
  stdio: "pipe",
@@ -294737,9 +295049,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
294737
295049
  `PARAMETER num_predict ${numPredict}`,
294738
295050
  `PARAMETER stop "<|endoftext|>"`
294739
295051
  ].join("\n");
294740
- const modelDir2 = join75(homedir25(), ".open-agents", "models");
295052
+ const modelDir2 = join76(homedir26(), ".open-agents", "models");
294741
295053
  mkdirSync33(modelDir2, { recursive: true });
294742
- const modelfilePath = join75(modelDir2, `Modelfile.${customName}`);
295054
+ const modelfilePath = join76(modelDir2, `Modelfile.${customName}`);
294743
295055
  writeFileSync30(modelfilePath, modelfileContent + "\n", "utf8");
294744
295056
  await execAsync2(`ollama create ${customName} -f ${modelfilePath}`, {
294745
295057
  timeout: 12e4
@@ -294813,8 +295125,8 @@ async function ensureNeovim() {
294813
295125
  const platform6 = process.platform;
294814
295126
  const arch2 = process.arch;
294815
295127
  if (platform6 === "linux") {
294816
- const binDir = join75(homedir25(), ".local", "bin");
294817
- const nvimDest = join75(binDir, "nvim");
295128
+ const binDir = join76(homedir26(), ".local", "bin");
295129
+ const nvimDest = join76(binDir, "nvim");
294818
295130
  try {
294819
295131
  mkdirSync33(binDir, { recursive: true });
294820
295132
  } catch {
@@ -294885,9 +295197,9 @@ async function ensureNeovim() {
294885
295197
  }
294886
295198
  function ensurePathInShellRc(binDir) {
294887
295199
  const shell = process.env.SHELL ?? "";
294888
- const rcFile = shell.includes("zsh") ? join75(homedir25(), ".zshrc") : join75(homedir25(), ".bashrc");
295200
+ const rcFile = shell.includes("zsh") ? join76(homedir26(), ".zshrc") : join76(homedir26(), ".bashrc");
294889
295201
  try {
294890
- const rcContent = existsSync58(rcFile) ? readFileSync45(rcFile, "utf8") : "";
295202
+ const rcContent = existsSync59(rcFile) ? readFileSync46(rcFile, "utf8") : "";
294891
295203
  if (rcContent.includes(binDir)) return;
294892
295204
  const exportLine = `
294893
295205
  export PATH="${binDir}:$PATH" # Added by open-agents for nvim
@@ -294924,7 +295236,7 @@ var init_setup = __esm({
294924
295236
  });
294925
295237
 
294926
295238
  // packages/cli/src/tui/drop-panel.ts
294927
- import { existsSync as existsSync59 } from "node:fs";
295239
+ import { existsSync as existsSync60 } from "node:fs";
294928
295240
  import { extname as extname10, resolve as resolve31 } from "node:path";
294929
295241
  function ansi4(code8, text) {
294930
295242
  return isTTY4 ? `\x1B[${code8}m${text}\x1B[0m` : text;
@@ -295045,7 +295357,7 @@ function showDropPanel(opts) {
295045
295357
  filePath = decodeURIComponent(filePath.slice(7));
295046
295358
  }
295047
295359
  filePath = resolve31(filePath);
295048
- if (!existsSync59(filePath)) {
295360
+ if (!existsSync60(filePath)) {
295049
295361
  errorMsg = `File not found: ${filePath}`;
295050
295362
  render2();
295051
295363
  return;
@@ -295117,9 +295429,9 @@ var init_drop_panel = __esm({
295117
295429
  });
295118
295430
 
295119
295431
  // packages/cli/src/tui/neovim-mode.ts
295120
- import { existsSync as existsSync60, unlinkSync as unlinkSync15 } from "node:fs";
295432
+ import { existsSync as existsSync61, unlinkSync as unlinkSync15 } from "node:fs";
295121
295433
  import { tmpdir as tmpdir18 } from "node:os";
295122
- import { join as join76 } from "node:path";
295434
+ import { join as join77 } from "node:path";
295123
295435
  import { execSync as execSync49 } from "node:child_process";
295124
295436
  function isNeovimActive() {
295125
295437
  return _state !== null && !_state.cleanedUp;
@@ -295165,9 +295477,9 @@ async function startNeovimMode(opts) {
295165
295477
  );
295166
295478
  } catch {
295167
295479
  }
295168
- const socketPath = join76(tmpdir18(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
295480
+ const socketPath = join77(tmpdir18(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
295169
295481
  try {
295170
- if (existsSync60(socketPath)) unlinkSync15(socketPath);
295482
+ if (existsSync61(socketPath)) unlinkSync15(socketPath);
295171
295483
  } catch {
295172
295484
  }
295173
295485
  const ptyCols = opts.cols;
@@ -295414,12 +295726,12 @@ function resizeNeovim(cols, contentRows) {
295414
295726
  }
295415
295727
  async function connectRPC(state, neovimPkg, cols) {
295416
295728
  let attempts = 0;
295417
- while (!existsSync60(state.socketPath) && attempts < 30) {
295729
+ while (!existsSync61(state.socketPath) && attempts < 30) {
295418
295730
  await new Promise((r2) => setTimeout(r2, 200));
295419
295731
  attempts++;
295420
295732
  if (state.cleanedUp) return;
295421
295733
  }
295422
- if (!existsSync60(state.socketPath)) return;
295734
+ if (!existsSync61(state.socketPath)) return;
295423
295735
  const nvim = neovimPkg.attach({ socket: state.socketPath });
295424
295736
  state.nvim = nvim;
295425
295737
  await new Promise((r2) => setTimeout(r2, 300));
@@ -295556,7 +295868,7 @@ function doCleanup(state) {
295556
295868
  state.pty = null;
295557
295869
  }
295558
295870
  try {
295559
- if (existsSync60(state.socketPath)) unlinkSync15(state.socketPath);
295871
+ if (existsSync61(state.socketPath)) unlinkSync15(state.socketPath);
295560
295872
  } catch {
295561
295873
  }
295562
295874
  if (state.stdinHandler) {
@@ -295626,9 +295938,9 @@ __export(daemon_exports, {
295626
295938
  stopDaemon: () => stopDaemon
295627
295939
  });
295628
295940
  import { spawn as spawn23 } from "node:child_process";
295629
- import { existsSync as existsSync61, readFileSync as readFileSync46, writeFileSync as writeFileSync31, mkdirSync as mkdirSync34, unlinkSync as unlinkSync16 } from "node:fs";
295630
- import { join as join77 } from "node:path";
295631
- import { homedir as homedir26 } from "node:os";
295941
+ import { existsSync as existsSync62, readFileSync as readFileSync47, writeFileSync as writeFileSync31, mkdirSync as mkdirSync34, unlinkSync as unlinkSync16 } from "node:fs";
295942
+ import { join as join78 } from "node:path";
295943
+ import { homedir as homedir27 } from "node:os";
295632
295944
  import { fileURLToPath as fileURLToPath13 } from "node:url";
295633
295945
  import { dirname as dirname22 } from "node:path";
295634
295946
  function getDaemonPort() {
@@ -295652,9 +295964,9 @@ async function isDaemonRunning(port) {
295652
295964
  }
295653
295965
  }
295654
295966
  function getDaemonPid() {
295655
- if (!existsSync61(PID_FILE2)) return null;
295967
+ if (!existsSync62(PID_FILE2)) return null;
295656
295968
  try {
295657
- const pid = parseInt(readFileSync46(PID_FILE2, "utf8").trim(), 10);
295969
+ const pid = parseInt(readFileSync47(PID_FILE2, "utf8").trim(), 10);
295658
295970
  if (!pid || pid <= 0) return null;
295659
295971
  process.kill(pid, 0);
295660
295972
  return pid;
@@ -295680,8 +295992,8 @@ async function startDaemon() {
295680
295992
  }
295681
295993
  if (!oaScript) {
295682
295994
  const thisDir = dirname22(fileURLToPath13(import.meta.url));
295683
- const indexJs = join77(thisDir, "index.js");
295684
- if (existsSync61(indexJs)) oaScript = indexJs;
295995
+ const indexJs = join78(thisDir, "index.js");
295996
+ if (existsSync62(indexJs)) oaScript = indexJs;
295685
295997
  }
295686
295998
  if (!oaScript) return null;
295687
295999
  try {
@@ -295779,8 +296091,8 @@ var OA_DIR2, PID_FILE2, DEFAULT_PORT2;
295779
296091
  var init_daemon = __esm({
295780
296092
  "packages/cli/src/daemon.ts"() {
295781
296093
  "use strict";
295782
- OA_DIR2 = join77(homedir26(), ".open-agents");
295783
- PID_FILE2 = join77(OA_DIR2, "daemon.pid");
296094
+ OA_DIR2 = join78(homedir27(), ".open-agents");
296095
+ PID_FILE2 = join78(OA_DIR2, "daemon.pid");
295784
296096
  DEFAULT_PORT2 = 11435;
295785
296097
  }
295786
296098
  });
@@ -296165,8 +296477,8 @@ __export(sponsor_wizard_exports, {
296165
296477
  saveSponsorConfig: () => saveSponsorConfig,
296166
296478
  showSponsorDashboard: () => showSponsorDashboard
296167
296479
  });
296168
- import { existsSync as existsSync62, readFileSync as readFileSync47, writeFileSync as writeFileSync32, mkdirSync as mkdirSync35 } from "node:fs";
296169
- import { join as join78 } from "node:path";
296480
+ import { existsSync as existsSync63, readFileSync as readFileSync48, writeFileSync as writeFileSync32, mkdirSync as mkdirSync35 } from "node:fs";
296481
+ import { join as join79 } from "node:path";
296170
296482
  function colorPreview(code8) {
296171
296483
  return `\x1B[38;5;${code8}m████\x1B[0m (${code8})`;
296172
296484
  }
@@ -296179,16 +296491,16 @@ function gradientPreview(start2, end) {
296179
296491
  return s2;
296180
296492
  }
296181
296493
  function sponsorDir(projectDir) {
296182
- return join78(projectDir, ".oa", "sponsor");
296494
+ return join79(projectDir, ".oa", "sponsor");
296183
296495
  }
296184
296496
  function configPath(projectDir) {
296185
- return join78(sponsorDir(projectDir), "config.json");
296497
+ return join79(sponsorDir(projectDir), "config.json");
296186
296498
  }
296187
296499
  function loadSponsorConfig(projectDir) {
296188
296500
  const p2 = configPath(projectDir);
296189
- if (!existsSync62(p2)) return null;
296501
+ if (!existsSync63(p2)) return null;
296190
296502
  try {
296191
- return JSON.parse(readFileSync47(p2, "utf8"));
296503
+ return JSON.parse(readFileSync48(p2, "utf8"));
296192
296504
  } catch {
296193
296505
  return null;
296194
296506
  }
@@ -297077,9 +297389,9 @@ __export(voice_exports, {
297077
297389
  registerCustomOnnxModel: () => registerCustomOnnxModel,
297078
297390
  resetNarrationContext: () => resetNarrationContext
297079
297391
  });
297080
- import { existsSync as existsSync63, mkdirSync as mkdirSync36, writeFileSync as writeFileSync33, readFileSync as readFileSync48, unlinkSync as unlinkSync17, readdirSync as readdirSync16, statSync as statSync18 } from "node:fs";
297081
- import { join as join79, dirname as dirname23 } from "node:path";
297082
- import { homedir as homedir27, tmpdir as tmpdir19, platform as platform4 } from "node:os";
297392
+ import { existsSync as existsSync64, mkdirSync as mkdirSync36, writeFileSync as writeFileSync33, readFileSync as readFileSync49, unlinkSync as unlinkSync17, readdirSync as readdirSync16, statSync as statSync18 } from "node:fs";
297393
+ import { join as join80, dirname as dirname23 } from "node:path";
297394
+ import { homedir as homedir28, tmpdir as tmpdir19, platform as platform4 } from "node:os";
297083
297395
  import { execSync as execSync50, spawn as nodeSpawn } from "node:child_process";
297084
297396
  import { createRequire as createRequire3 } from "node:module";
297085
297397
  function sanitizeForTTS(text) {
@@ -297103,37 +297415,37 @@ function listVoiceModels() {
297103
297415
  }));
297104
297416
  }
297105
297417
  function voiceDir() {
297106
- return join79(homedir27(), ".open-agents", "voice");
297418
+ return join80(homedir28(), ".open-agents", "voice");
297107
297419
  }
297108
297420
  function modelsDir() {
297109
- return join79(voiceDir(), "models");
297421
+ return join80(voiceDir(), "models");
297110
297422
  }
297111
297423
  function modelDir(id) {
297112
- return join79(modelsDir(), id);
297424
+ return join80(modelsDir(), id);
297113
297425
  }
297114
297426
  function modelOnnxPath(id) {
297115
- return join79(modelDir(id), "model.onnx");
297427
+ return join80(modelDir(id), "model.onnx");
297116
297428
  }
297117
297429
  function modelConfigPath(id) {
297118
- return join79(modelDir(id), "config.json");
297430
+ return join80(modelDir(id), "config.json");
297119
297431
  }
297120
297432
  function luxttsVenvDir() {
297121
- return join79(voiceDir(), "luxtts-venv");
297433
+ return join80(voiceDir(), "luxtts-venv");
297122
297434
  }
297123
297435
  function luxttsVenvPy() {
297124
- return platform4() === "win32" ? join79(luxttsVenvDir(), "Scripts", "python.exe") : join79(luxttsVenvDir(), "bin", "python3");
297436
+ return platform4() === "win32" ? join80(luxttsVenvDir(), "Scripts", "python.exe") : join80(luxttsVenvDir(), "bin", "python3");
297125
297437
  }
297126
297438
  function luxttsRepoDir() {
297127
- return join79(voiceDir(), "LuxTTS");
297439
+ return join80(voiceDir(), "LuxTTS");
297128
297440
  }
297129
297441
  function luxttsCloneRefsDir() {
297130
- return join79(voiceDir(), "clone-refs");
297442
+ return join80(voiceDir(), "clone-refs");
297131
297443
  }
297132
297444
  function luxttsInferScript() {
297133
- return join79(voiceDir(), "luxtts-infer.py");
297445
+ return join80(voiceDir(), "luxtts-infer.py");
297134
297446
  }
297135
297447
  function writeDetectTorchScript(targetPath) {
297136
- if (existsSync63(targetPath)) return;
297448
+ if (existsSync64(targetPath)) return;
297137
297449
  try {
297138
297450
  mkdirSync36(dirname23(targetPath), { recursive: true });
297139
297451
  } catch {
@@ -297958,8 +298270,8 @@ var init_voice = __esm({
297958
298270
  const refsDir = luxttsCloneRefsDir();
297959
298271
  const targets = ["glados", "overwatch"];
297960
298272
  for (const modelId of targets) {
297961
- const refFile = join79(refsDir, `${modelId}-ref.wav`);
297962
- if (existsSync63(refFile)) continue;
298273
+ const refFile = join80(refsDir, `${modelId}-ref.wav`);
298274
+ if (existsSync64(refFile)) continue;
297963
298275
  try {
297964
298276
  await this.generateCloneRef(modelId);
297965
298277
  const meta = this.loadCloneMeta();
@@ -298035,22 +298347,22 @@ var init_voice = __esm({
298035
298347
  }
298036
298348
  p2 = p2.replace(/\\ /g, " ");
298037
298349
  if (p2.startsWith("~/") || p2 === "~") {
298038
- p2 = join79(homedir27(), p2.slice(1));
298350
+ p2 = join80(homedir28(), p2.slice(1));
298039
298351
  }
298040
- if (!existsSync63(p2)) {
298352
+ if (!existsSync64(p2)) {
298041
298353
  return `File not found: ${p2}
298042
298354
  (original input: ${audioPath})`;
298043
298355
  }
298044
298356
  audioPath = p2;
298045
298357
  const refsDir = luxttsCloneRefsDir();
298046
- if (!existsSync63(refsDir)) mkdirSync36(refsDir, { recursive: true });
298358
+ if (!existsSync64(refsDir)) mkdirSync36(refsDir, { recursive: true });
298047
298359
  const ext = audioPath.split(".").pop() || "wav";
298048
298360
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
298049
298361
  const ts = Date.now().toString(36);
298050
298362
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
298051
- const destPath = join79(refsDir, destFilename);
298363
+ const destPath = join80(refsDir, destFilename);
298052
298364
  try {
298053
- const data = readFileSync48(audioPath);
298365
+ const data = readFileSync49(audioPath);
298054
298366
  writeFileSync33(destPath, data);
298055
298367
  } catch (err) {
298056
298368
  return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
@@ -298091,8 +298403,8 @@ var init_voice = __esm({
298091
298403
  return `Failed to synthesize reference audio from ${source.label}.`;
298092
298404
  }
298093
298405
  const refsDir = luxttsCloneRefsDir();
298094
- if (!existsSync63(refsDir)) mkdirSync36(refsDir, { recursive: true });
298095
- const destPath = join79(refsDir, `${sourceModelId}-ref.wav`);
298406
+ if (!existsSync64(refsDir)) mkdirSync36(refsDir, { recursive: true });
298407
+ const destPath = join80(refsDir, `${sourceModelId}-ref.wav`);
298096
298408
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
298097
298409
  this.writeWav(audioData, sampleRate, destPath);
298098
298410
  this.luxttsCloneRef = destPath;
@@ -298108,20 +298420,20 @@ var init_voice = __esm({
298108
298420
  // -------------------------------------------------------------------------
298109
298421
  /** Metadata file for friendly names of clone refs */
298110
298422
  static cloneMetaFile() {
298111
- return join79(luxttsCloneRefsDir(), "meta.json");
298423
+ return join80(luxttsCloneRefsDir(), "meta.json");
298112
298424
  }
298113
298425
  loadCloneMeta() {
298114
298426
  const p2 = _VoiceEngine.cloneMetaFile();
298115
- if (!existsSync63(p2)) return {};
298427
+ if (!existsSync64(p2)) return {};
298116
298428
  try {
298117
- return JSON.parse(readFileSync48(p2, "utf8"));
298429
+ return JSON.parse(readFileSync49(p2, "utf8"));
298118
298430
  } catch {
298119
298431
  return {};
298120
298432
  }
298121
298433
  }
298122
298434
  saveCloneMeta(meta) {
298123
298435
  const dir = luxttsCloneRefsDir();
298124
- if (!existsSync63(dir)) mkdirSync36(dir, { recursive: true });
298436
+ if (!existsSync64(dir)) mkdirSync36(dir, { recursive: true });
298125
298437
  writeFileSync33(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
298126
298438
  }
298127
298439
  /** Audio file extensions recognized as clone references */
@@ -298132,14 +298444,14 @@ var init_voice = __esm({
298132
298444
  */
298133
298445
  listCloneRefs() {
298134
298446
  const dir = luxttsCloneRefsDir();
298135
- if (!existsSync63(dir)) return [];
298447
+ if (!existsSync64(dir)) return [];
298136
298448
  const meta = this.loadCloneMeta();
298137
298449
  const files = readdirSync16(dir).filter((f2) => {
298138
298450
  const ext = f2.split(".").pop()?.toLowerCase() ?? "";
298139
298451
  return _VoiceEngine.AUDIO_EXTS.has(ext);
298140
298452
  });
298141
298453
  return files.map((f2) => {
298142
- const p2 = join79(dir, f2);
298454
+ const p2 = join80(dir, f2);
298143
298455
  let size = 0;
298144
298456
  try {
298145
298457
  size = statSync18(p2).size;
@@ -298156,8 +298468,8 @@ var init_voice = __esm({
298156
298468
  }
298157
298469
  /** Delete a clone reference file by filename. Returns true if deleted. */
298158
298470
  deleteCloneRef(filename) {
298159
- const p2 = join79(luxttsCloneRefsDir(), filename);
298160
- if (!existsSync63(p2)) return false;
298471
+ const p2 = join80(luxttsCloneRefsDir(), filename);
298472
+ if (!existsSync64(p2)) return false;
298161
298473
  try {
298162
298474
  unlinkSync17(p2);
298163
298475
  const meta = this.loadCloneMeta();
@@ -298180,8 +298492,8 @@ var init_voice = __esm({
298180
298492
  }
298181
298493
  /** Set the active clone reference by filename. */
298182
298494
  setActiveCloneRef(filename) {
298183
- const p2 = join79(luxttsCloneRefsDir(), filename);
298184
- if (!existsSync63(p2)) return `File not found: ${filename}`;
298495
+ const p2 = join80(luxttsCloneRefsDir(), filename);
298496
+ if (!existsSync64(p2)) return `File not found: ${filename}`;
298185
298497
  this.luxttsCloneRef = p2;
298186
298498
  return `Active clone voice set to: ${filename}`;
298187
298499
  }
@@ -298518,7 +298830,7 @@ var init_voice = __esm({
298518
298830
  }
298519
298831
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
298520
298832
  }
298521
- const wavPath = join79(tmpdir19(), `oa-voice-${Date.now()}.wav`);
298833
+ const wavPath = join80(tmpdir19(), `oa-voice-${Date.now()}.wav`);
298522
298834
  this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
298523
298835
  await this.playWav(wavPath);
298524
298836
  try {
@@ -298914,7 +299226,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
298914
299226
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
298915
299227
  const mlxVoice = model.mlxVoice ?? "af_heart";
298916
299228
  const mlxLangCode = model.mlxLangCode ?? "a";
298917
- const wavPath = join79(tmpdir19(), `oa-mlx-${Date.now()}.wav`);
299229
+ const wavPath = join80(tmpdir19(), `oa-mlx-${Date.now()}.wav`);
298918
299230
  const pyScript = [
298919
299231
  "import sys, json",
298920
299232
  "from mlx_audio.tts import generate as tts_gen",
@@ -298937,10 +299249,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
298937
299249
  return;
298938
299250
  }
298939
299251
  }
298940
- if (!existsSync63(wavPath)) return;
299252
+ if (!existsSync64(wavPath)) return;
298941
299253
  if (volume !== 1) {
298942
299254
  try {
298943
- const wavData = readFileSync48(wavPath);
299255
+ const wavData = readFileSync49(wavPath);
298944
299256
  if (wavData.length > 44) {
298945
299257
  const header = wavData.subarray(0, 44);
298946
299258
  const samples = new Int16Array(
@@ -298959,7 +299271,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
298959
299271
  }
298960
299272
  if (this.onPCMOutput) {
298961
299273
  try {
298962
- const wavData = readFileSync48(wavPath);
299274
+ const wavData = readFileSync49(wavPath);
298963
299275
  if (wavData.length > 44) {
298964
299276
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
298965
299277
  const sampleRate = wavData.readUInt32LE(24);
@@ -298988,7 +299300,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
298988
299300
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
298989
299301
  const mlxVoice = model.mlxVoice ?? "af_heart";
298990
299302
  const mlxLangCode = model.mlxLangCode ?? "a";
298991
- const wavPath = join79(tmpdir19(), `oa-mlx-buf-${Date.now()}.wav`);
299303
+ const wavPath = join80(tmpdir19(), `oa-mlx-buf-${Date.now()}.wav`);
298992
299304
  const pyScript = [
298993
299305
  "import sys, json",
298994
299306
  "from mlx_audio.tts import generate as tts_gen",
@@ -299011,9 +299323,9 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299011
299323
  return null;
299012
299324
  }
299013
299325
  }
299014
- if (!existsSync63(wavPath)) return null;
299326
+ if (!existsSync64(wavPath)) return null;
299015
299327
  try {
299016
- const data = readFileSync48(wavPath);
299328
+ const data = readFileSync49(wavPath);
299017
299329
  unlinkSync17(wavPath);
299018
299330
  return data;
299019
299331
  } catch {
@@ -299038,7 +299350,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299038
299350
  }
299039
299351
  const venvDir = luxttsVenvDir();
299040
299352
  const venvPy = luxttsVenvPy();
299041
- if (existsSync63(venvPy)) {
299353
+ if (existsSync64(venvPy)) {
299042
299354
  try {
299043
299355
  const quotedPy = `"${venvPy}"`;
299044
299356
  const repoPath = luxttsRepoDir().replace(/\\/g, "/");
@@ -299060,7 +299372,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299060
299372
  if (torchCheck === "cpu") {
299061
299373
  renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
299062
299374
  try {
299063
- const detectScript = join79(voiceDir(), "detect-torch.py");
299375
+ const detectScript = join80(voiceDir(), "detect-torch.py");
299064
299376
  writeDetectTorchScript(detectScript);
299065
299377
  let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
299066
299378
  try {
@@ -299087,7 +299399,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299087
299399
  }
299088
299400
  }
299089
299401
  renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
299090
- if (!existsSync63(venvDir)) {
299402
+ if (!existsSync64(venvDir)) {
299091
299403
  renderInfo(" Creating Python virtual environment...");
299092
299404
  try {
299093
299405
  await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
@@ -299098,7 +299410,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299098
299410
  }
299099
299411
  }
299100
299412
  {
299101
- const detectScript = join79(voiceDir(), "detect-torch.py");
299413
+ const detectScript = join80(voiceDir(), "detect-torch.py");
299102
299414
  writeDetectTorchScript(detectScript);
299103
299415
  let pipArgsStr = "torch torchaudio";
299104
299416
  let torchDesc = "unknown platform";
@@ -299143,10 +299455,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299143
299455
  }
299144
299456
  }
299145
299457
  const repoDir = luxttsRepoDir();
299146
- if (!existsSync63(join79(repoDir, "zipvoice", "luxvoice.py"))) {
299458
+ if (!existsSync64(join80(repoDir, "zipvoice", "luxvoice.py"))) {
299147
299459
  renderInfo(" Cloning LuxTTS repository...");
299148
299460
  try {
299149
- if (existsSync63(repoDir)) {
299461
+ if (existsSync64(repoDir)) {
299150
299462
  const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
299151
299463
  await this.asyncShell(rmCmd, 3e4);
299152
299464
  }
@@ -299235,7 +299547,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299235
299547
  renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
299236
299548
  }
299237
299549
  }
299238
- const isJetson = isArm && (existsSync63("/etc/nv_tegra_release") || existsSync63("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
299550
+ const isJetson = isArm && (existsSync64("/etc/nv_tegra_release") || existsSync64("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
299239
299551
  const installSteps = isArm ? [
299240
299552
  // ARM: install individually so we get clear error messages per package.
299241
299553
  // ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
@@ -299248,7 +299560,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299248
299560
  ...isJetson ? (() => {
299249
299561
  let jpVer = "v60";
299250
299562
  try {
299251
- const tegra = existsSync63("/etc/nv_tegra_release") ? execSync50("cat /etc/nv_tegra_release 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim() : "";
299563
+ const tegra = existsSync64("/etc/nv_tegra_release") ? execSync50("cat /etc/nv_tegra_release 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim() : "";
299252
299564
  const dpkg = execSync50("dpkg -l nvidia-jetpack 2>/dev/null | grep nvidia-jetpack | awk '{print $3}'", { encoding: "utf8", timeout: 5e3 }).trim();
299253
299565
  const ver = dpkg || process.env.JETSON_L4T_VERSION || "";
299254
299566
  if (ver.startsWith("5.") || tegra.includes("R35") || tegra.includes("R34")) jpVer = "v51";
@@ -299328,12 +299640,12 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
299328
299640
  }
299329
299641
  /** Auto-detect an existing clone reference in the refs directory */
299330
299642
  autoDetectCloneRef() {
299331
- if (this.luxttsCloneRef && existsSync63(this.luxttsCloneRef)) return;
299643
+ if (this.luxttsCloneRef && existsSync64(this.luxttsCloneRef)) return;
299332
299644
  const refsDir = luxttsCloneRefsDir();
299333
- if (!existsSync63(refsDir)) return;
299645
+ if (!existsSync64(refsDir)) return;
299334
299646
  for (const name10 of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
299335
- const p2 = join79(refsDir, name10);
299336
- if (existsSync63(p2)) {
299647
+ const p2 = join80(refsDir, name10);
299648
+ if (existsSync64(p2)) {
299337
299649
  this.luxttsCloneRef = p2;
299338
299650
  return;
299339
299651
  }
@@ -299440,7 +299752,7 @@ if __name__ == '__main__':
299440
299752
  async ensureLuxttsDaemon() {
299441
299753
  if (this._luxttsDaemon && !this._luxttsDaemon.killed) return true;
299442
299754
  const venvPy = luxttsVenvPy();
299443
- if (!existsSync63(venvPy)) return false;
299755
+ if (!existsSync64(venvPy)) return false;
299444
299756
  return new Promise((resolve39) => {
299445
299757
  const env2 = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
299446
299758
  const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
@@ -299529,12 +299841,12 @@ if __name__ == '__main__':
299529
299841
  * Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
299530
299842
  */
299531
299843
  async synthesizeLuxttsWav(text, speedFactor = 1) {
299532
- if (!this.luxttsCloneRef || !existsSync63(this.luxttsCloneRef)) return null;
299844
+ if (!this.luxttsCloneRef || !existsSync64(this.luxttsCloneRef)) return null;
299533
299845
  const cleaned = text.replace(/\*/g, "").trim();
299534
299846
  if (!cleaned) return null;
299535
299847
  const ready = await this.ensureLuxttsDaemon();
299536
299848
  if (!ready) return null;
299537
- const wavPath = join79(tmpdir19(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
299849
+ const wavPath = join80(tmpdir19(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
299538
299850
  try {
299539
299851
  await this.luxttsRequest({
299540
299852
  action: "synthesize",
@@ -299546,16 +299858,16 @@ if __name__ == '__main__':
299546
299858
  } catch {
299547
299859
  return null;
299548
299860
  }
299549
- return existsSync63(wavPath) ? wavPath : null;
299861
+ return existsSync64(wavPath) ? wavPath : null;
299550
299862
  }
299551
299863
  /**
299552
299864
  * Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
299553
299865
  * Cleans up the WAV file after playback.
299554
299866
  */
299555
299867
  async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
299556
- if (!existsSync63(wavPath)) return;
299868
+ if (!existsSync64(wavPath)) return;
299557
299869
  try {
299558
- const wavData = readFileSync48(wavPath);
299870
+ const wavData = readFileSync49(wavPath);
299559
299871
  if (wavData.length > 44) {
299560
299872
  const sampleRate = wavData.readUInt32LE(24);
299561
299873
  const samples = new Int16Array(
@@ -299580,7 +299892,7 @@ if __name__ == '__main__':
299580
299892
  }
299581
299893
  if (pitchFactor !== 1) {
299582
299894
  try {
299583
- const wavData = readFileSync48(wavPath);
299895
+ const wavData = readFileSync49(wavPath);
299584
299896
  if (wavData.length > 44) {
299585
299897
  const int16 = new Int16Array(
299586
299898
  wavData.buffer,
@@ -299599,7 +299911,7 @@ if __name__ == '__main__':
299599
299911
  }
299600
299912
  if (this.onPCMOutput) {
299601
299913
  try {
299602
- const wavData = readFileSync48(wavPath);
299914
+ const wavData = readFileSync49(wavPath);
299603
299915
  if (wavData.length > 44) {
299604
299916
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
299605
299917
  const sampleRate = wavData.readUInt32LE(24);
@@ -299610,7 +299922,7 @@ if __name__ == '__main__':
299610
299922
  }
299611
299923
  if (stereoDelayMs > 0) {
299612
299924
  try {
299613
- const wavData = readFileSync48(wavPath);
299925
+ const wavData = readFileSync49(wavPath);
299614
299926
  if (wavData.length > 44) {
299615
299927
  const sampleRate = wavData.readUInt32LE(24);
299616
299928
  const numChannels = wavData.readUInt16LE(22);
@@ -299649,12 +299961,12 @@ if __name__ == '__main__':
299649
299961
  * Used for Telegram voice messages and WebSocket streaming.
299650
299962
  */
299651
299963
  async synthesizeLuxttsToBuffer(text) {
299652
- if (!this.luxttsCloneRef || !existsSync63(this.luxttsCloneRef)) return null;
299964
+ if (!this.luxttsCloneRef || !existsSync64(this.luxttsCloneRef)) return null;
299653
299965
  const cleaned = text.replace(/\*/g, "").trim();
299654
299966
  if (!cleaned) return null;
299655
299967
  const ready = await this.ensureLuxttsDaemon();
299656
299968
  if (!ready) return null;
299657
- const wavPath = join79(tmpdir19(), `oa-luxtts-buf-${Date.now()}.wav`);
299969
+ const wavPath = join80(tmpdir19(), `oa-luxtts-buf-${Date.now()}.wav`);
299658
299970
  try {
299659
299971
  await this.luxttsRequest({
299660
299972
  action: "synthesize",
@@ -299666,9 +299978,9 @@ if __name__ == '__main__':
299666
299978
  } catch {
299667
299979
  return null;
299668
299980
  }
299669
- if (!existsSync63(wavPath)) return null;
299981
+ if (!existsSync64(wavPath)) return null;
299670
299982
  try {
299671
- const data = readFileSync48(wavPath);
299983
+ const data = readFileSync49(wavPath);
299672
299984
  unlinkSync17(wavPath);
299673
299985
  return data;
299674
299986
  } catch {
@@ -299682,14 +299994,14 @@ if __name__ == '__main__':
299682
299994
  if (this.ort) return;
299683
299995
  const arch2 = process.arch;
299684
299996
  mkdirSync36(voiceDir(), { recursive: true });
299685
- const pkgPath = join79(voiceDir(), "package.json");
299997
+ const pkgPath = join80(voiceDir(), "package.json");
299686
299998
  const expectedDeps = {
299687
299999
  "onnxruntime-node": "^1.21.0",
299688
300000
  "phonemizer": "^1.2.1"
299689
300001
  };
299690
- if (existsSync63(pkgPath)) {
300002
+ if (existsSync64(pkgPath)) {
299691
300003
  try {
299692
- const existing = JSON.parse(readFileSync48(pkgPath, "utf8"));
300004
+ const existing = JSON.parse(readFileSync49(pkgPath, "utf8"));
299693
300005
  if (!existing.dependencies?.["phonemizer"]) {
299694
300006
  existing.dependencies = { ...existing.dependencies, ...expectedDeps };
299695
300007
  writeFileSync33(pkgPath, JSON.stringify(existing, null, 2));
@@ -299697,18 +300009,18 @@ if __name__ == '__main__':
299697
300009
  } catch {
299698
300010
  }
299699
300011
  }
299700
- if (!existsSync63(pkgPath)) {
300012
+ if (!existsSync64(pkgPath)) {
299701
300013
  writeFileSync33(pkgPath, JSON.stringify({
299702
300014
  name: "open-agents-voice",
299703
300015
  private: true,
299704
300016
  dependencies: expectedDeps
299705
300017
  }, null, 2));
299706
300018
  }
299707
- const voiceRequire = createRequire3(join79(voiceDir(), "index.js"));
300019
+ const voiceRequire = createRequire3(join80(voiceDir(), "index.js"));
299708
300020
  const probeOnnx = async () => {
299709
300021
  try {
299710
300022
  const output = await this.asyncShell(
299711
- `NODE_PATH="${join79(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`,
300023
+ `NODE_PATH="${join80(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`,
299712
300024
  15e3
299713
300025
  );
299714
300026
  return output.trim() === "OK";
@@ -299716,8 +300028,8 @@ if __name__ == '__main__':
299716
300028
  return false;
299717
300029
  }
299718
300030
  };
299719
- const onnxNodeModules = join79(voiceDir(), "node_modules", "onnxruntime-node");
299720
- const onnxInstalled = existsSync63(onnxNodeModules);
300031
+ const onnxNodeModules = join80(voiceDir(), "node_modules", "onnxruntime-node");
300032
+ const onnxInstalled = existsSync64(onnxNodeModules);
299721
300033
  if (onnxInstalled && !await probeOnnx()) {
299722
300034
  throw new Error(
299723
300035
  `Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`
@@ -299776,16 +300088,16 @@ Error: ${err instanceof Error ? err.message : String(err)}`
299776
300088
  const dir = modelDir(id);
299777
300089
  const onnxPath = modelOnnxPath(id);
299778
300090
  const configPath2 = modelConfigPath(id);
299779
- if (existsSync63(onnxPath) && existsSync63(configPath2)) return;
300091
+ if (existsSync64(onnxPath) && existsSync64(configPath2)) return;
299780
300092
  mkdirSync36(dir, { recursive: true });
299781
- if (!existsSync63(configPath2)) {
300093
+ if (!existsSync64(configPath2)) {
299782
300094
  renderInfo(`Downloading ${model.label} voice config...`);
299783
300095
  const configResp = await fetch(model.configUrl);
299784
300096
  if (!configResp.ok) throw new Error(`Failed to download config: HTTP ${configResp.status}`);
299785
300097
  const configText = await configResp.text();
299786
300098
  writeFileSync33(configPath2, configText);
299787
300099
  }
299788
- if (!existsSync63(onnxPath)) {
300100
+ if (!existsSync64(onnxPath)) {
299789
300101
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
299790
300102
  const onnxResp = await fetch(model.onnxUrl);
299791
300103
  if (!onnxResp.ok) throw new Error(`Failed to download model: HTTP ${onnxResp.status}`);
@@ -299818,10 +300130,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`
299818
300130
  if (!this.ort) throw new Error("ONNX runtime not loaded");
299819
300131
  const onnxPath = modelOnnxPath(this.modelId);
299820
300132
  const configPath2 = modelConfigPath(this.modelId);
299821
- if (!existsSync63(onnxPath) || !existsSync63(configPath2)) {
300133
+ if (!existsSync64(onnxPath) || !existsSync64(configPath2)) {
299822
300134
  throw new Error(`Model files not found for ${this.modelId}`);
299823
300135
  }
299824
- this.config = JSON.parse(readFileSync48(configPath2, "utf8"));
300136
+ this.config = JSON.parse(readFileSync49(configPath2, "utf8"));
299825
300137
  this.session = await this.ort.InferenceSession.create(onnxPath, {
299826
300138
  executionProviders: ["cpu"],
299827
300139
  graphOptimizationLevel: "all"
@@ -299848,8 +300160,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`
299848
300160
  // packages/cli/src/tui/commands.ts
299849
300161
  import * as nodeOs from "node:os";
299850
300162
  import { execSync as nodeExecSync } from "node:child_process";
299851
- import { existsSync as existsSync64, readFileSync as readFileSync49, writeFileSync as writeFileSync34, mkdirSync as mkdirSync37, readdirSync as readdirSync17, statSync as statSync19, rmSync as rmSync2, appendFileSync as appendFileSync3 } from "node:fs";
299852
- import { join as join80 } from "node:path";
300163
+ import { existsSync as existsSync65, readFileSync as readFileSync50, writeFileSync as writeFileSync34, mkdirSync as mkdirSync37, readdirSync as readdirSync17, statSync as statSync19, rmSync as rmSync2, appendFileSync as appendFileSync3 } from "node:fs";
300164
+ import { join as join81 } from "node:path";
299853
300165
  async function _immediateReregister(newUrl) {
299854
300166
  if (!_lastRegisteredSponsorPayload) return;
299855
300167
  _lastRegisteredSponsorPayload.tunnelUrl = newUrl;
@@ -300362,9 +300674,9 @@ async function handleSlashCommand(input, ctx3) {
300362
300674
  if (out.includes("Connected") || out.includes("Already connected")) {
300363
300675
  renderInfo(out.split("\n").slice(0, 4).join("\n"));
300364
300676
  try {
300365
- const pidFile = join80(ctx3.repoRoot ?? process.cwd(), ".oa", "nexus", "daemon.pid");
300366
- if (existsSync64(pidFile)) {
300367
- const pid = parseInt(readFileSync49(pidFile, "utf8").trim(), 10);
300677
+ const pidFile = join81(ctx3.repoRoot ?? process.cwd(), ".oa", "nexus", "daemon.pid");
300678
+ if (existsSync65(pidFile)) {
300679
+ const pid = parseInt(readFileSync50(pidFile, "utf8").trim(), 10);
300368
300680
  if (pid > 0 && !registry2.daemons.has("Nexus")) {
300369
300681
  registry2.register({ name: "Nexus", pid, startedAt: Date.now(), status: "running" });
300370
300682
  }
@@ -300668,22 +300980,22 @@ async function handleSlashCommand(input, ctx3) {
300668
300980
  let content = "";
300669
300981
  let metadata = {};
300670
300982
  if (shareType === "tool") {
300671
- const toolDir = join80(ctx3.repoRoot, ".oa", "tools");
300672
- const toolFile = join80(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
300673
- if (!existsSync64(toolFile)) {
300983
+ const toolDir = join81(ctx3.repoRoot, ".oa", "tools");
300984
+ const toolFile = join81(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
300985
+ if (!existsSync65(toolFile)) {
300674
300986
  renderWarning(`Tool not found: ${toolFile}`);
300675
300987
  return "handled";
300676
300988
  }
300677
- content = readFileSync49(toolFile, "utf8");
300989
+ content = readFileSync50(toolFile, "utf8");
300678
300990
  metadata = { type: "tool", name: shareName };
300679
300991
  } else if (shareType === "skill") {
300680
- const skillDir = join80(ctx3.repoRoot, ".oa", "skills", shareName);
300681
- const skillFile = join80(skillDir, "SKILL.md");
300682
- if (!existsSync64(skillFile)) {
300992
+ const skillDir = join81(ctx3.repoRoot, ".oa", "skills", shareName);
300993
+ const skillFile = join81(skillDir, "SKILL.md");
300994
+ if (!existsSync65(skillFile)) {
300683
300995
  renderWarning(`Skill not found: ${skillFile}`);
300684
300996
  return "handled";
300685
300997
  }
300686
- content = readFileSync49(skillFile, "utf8");
300998
+ content = readFileSync50(skillFile, "utf8");
300687
300999
  metadata = { type: "skill", name: shareName };
300688
301000
  } else {
300689
301001
  renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
@@ -300720,9 +301032,9 @@ async function handleSlashCommand(input, ctx3) {
300720
301032
  try {
300721
301033
  const nexus = new NexusTool(ctx3.repoRoot);
300722
301034
  await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
300723
- const regFile = join80(ctx3.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
300724
- if (existsSync64(regFile)) {
300725
- const reg = JSON.parse(readFileSync49(regFile, "utf8"));
301035
+ const regFile = join81(ctx3.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
301036
+ if (existsSync65(regFile)) {
301037
+ const reg = JSON.parse(readFileSync50(regFile, "utf8"));
300726
301038
  const pinned = Object.values(reg).some((e2) => e2.cid === importCid && e2.pinned);
300727
301039
  if (pinned) {
300728
301040
  renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
@@ -300773,32 +301085,32 @@ async function handleSlashCommand(input, ctx3) {
300773
301085
  lines.push(`
300774
301086
  ${c3.bold("IPFS / Helia Status")}
300775
301087
  `);
300776
- const ipfsDir = join80(ctx3.repoRoot, ".oa", "ipfs");
300777
- const ipfsLocalDir = join80(ipfsDir, "local");
301088
+ const ipfsDir = join81(ctx3.repoRoot, ".oa", "ipfs");
301089
+ const ipfsLocalDir = join81(ipfsDir, "local");
300778
301090
  let ipfsFiles = 0;
300779
301091
  let ipfsBytes = 0;
300780
301092
  let heliaBlocks = 0;
300781
301093
  let heliaBytes = 0;
300782
301094
  try {
300783
- if (existsSync64(ipfsLocalDir)) {
301095
+ if (existsSync65(ipfsLocalDir)) {
300784
301096
  const files = readdirSync17(ipfsLocalDir).filter((f2) => f2.endsWith(".json"));
300785
301097
  ipfsFiles = files.length;
300786
301098
  for (const f2 of files) {
300787
301099
  try {
300788
- ipfsBytes += statSync19(join80(ipfsLocalDir, f2)).size;
301100
+ ipfsBytes += statSync19(join81(ipfsLocalDir, f2)).size;
300789
301101
  } catch {
300790
301102
  }
300791
301103
  }
300792
301104
  }
300793
- const heliaBlockDir = join80(ipfsDir, "blocks");
300794
- if (existsSync64(heliaBlockDir)) {
301105
+ const heliaBlockDir = join81(ipfsDir, "blocks");
301106
+ if (existsSync65(heliaBlockDir)) {
300795
301107
  const walkDir = (dir) => {
300796
301108
  for (const entry of readdirSync17(dir, { withFileTypes: true })) {
300797
- if (entry.isDirectory()) walkDir(join80(dir, entry.name));
301109
+ if (entry.isDirectory()) walkDir(join81(dir, entry.name));
300798
301110
  else {
300799
301111
  heliaBlocks++;
300800
301112
  try {
300801
- heliaBytes += statSync19(join80(dir, entry.name)).size;
301113
+ heliaBytes += statSync19(join81(dir, entry.name)).size;
300802
301114
  } catch {
300803
301115
  }
300804
301116
  }
@@ -300814,9 +301126,9 @@ async function handleSlashCommand(input, ctx3) {
300814
301126
  lines.push(` Blocks: ${c3.bold(String(heliaBlocks))} Size: ${c3.bold(formatFileSize(heliaBytes))}`);
300815
301127
  lines.push(` Backend: ${heliaBlocks > 0 ? c3.green("helia-ipfs") : c3.yellow("sha256-local (Helia not initialized)")}`);
300816
301128
  try {
300817
- const statusFile = join80(ctx3.repoRoot, ".oa", "nexus", "status.json");
300818
- if (existsSync64(statusFile)) {
300819
- const status = JSON.parse(readFileSync49(statusFile, "utf8"));
301129
+ const statusFile = join81(ctx3.repoRoot, ".oa", "nexus", "status.json");
301130
+ if (existsSync65(statusFile)) {
301131
+ const status = JSON.parse(readFileSync50(statusFile, "utf8"));
300820
301132
  if (status.peerId) {
300821
301133
  lines.push(`
300822
301134
  ${c3.bold("Peer Info")}`);
@@ -300835,11 +301147,11 @@ async function handleSlashCommand(input, ctx3) {
300835
301147
  ${c3.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
300836
301148
  lines.push(`
300837
301149
  ${c3.bold("Identity Kernel")}`);
300838
- const idDir = join80(ctx3.repoRoot, ".oa", "identity");
301150
+ const idDir = join81(ctx3.repoRoot, ".oa", "identity");
300839
301151
  try {
300840
- const stateFile = join80(idDir, "self-state.json");
300841
- if (existsSync64(stateFile)) {
300842
- const state = JSON.parse(readFileSync49(stateFile, "utf8"));
301152
+ const stateFile = join81(idDir, "self-state.json");
301153
+ if (existsSync65(stateFile)) {
301154
+ const state = JSON.parse(readFileSync50(stateFile, "utf8"));
300843
301155
  lines.push(` Version: ${c3.bold("v" + (state.version ?? "?"))} Sessions: ${c3.bold(String(state.session_count ?? 0))}`);
300844
301156
  if (state.narrative_summary) {
300845
301157
  lines.push(` Narrative: ${c3.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
@@ -300848,9 +301160,9 @@ async function handleSlashCommand(input, ctx3) {
300848
301160
  const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
300849
301161
  lines.push(` Traits: ${c3.dim(traits.slice(0, 60))}`);
300850
301162
  }
300851
- const cidFile = join80(idDir, "cids.json");
300852
- if (existsSync64(cidFile)) {
300853
- const cids = JSON.parse(readFileSync49(cidFile, "utf8"));
301163
+ const cidFile = join81(idDir, "cids.json");
301164
+ if (existsSync65(cidFile)) {
301165
+ const cids = JSON.parse(readFileSync50(cidFile, "utf8"));
300854
301166
  const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
300855
301167
  if (lastCid) lines.push(` Last CID: ${c3.dim(String(lastCid).slice(0, 50))}`);
300856
301168
  }
@@ -300862,9 +301174,9 @@ async function handleSlashCommand(input, ctx3) {
300862
301174
  lines.push(`
300863
301175
  ${c3.bold("Memory Sentiment")}`);
300864
301176
  try {
300865
- const metaFile = join80(ctx3.repoRoot, ".oa", "memory", "metabolism", "store.json");
300866
- if (existsSync64(metaFile)) {
300867
- const store2 = JSON.parse(readFileSync49(metaFile, "utf8"));
301177
+ const metaFile = join81(ctx3.repoRoot, ".oa", "memory", "metabolism", "store.json");
301178
+ if (existsSync65(metaFile)) {
301179
+ const store2 = JSON.parse(readFileSync50(metaFile, "utf8"));
300868
301180
  const active = store2.filter((m2) => m2.type !== "quarantine");
300869
301181
  const recoveries = active.filter((m2) => m2.content?.startsWith("[recovery]")).length;
300870
301182
  const strategies = active.filter((m2) => m2.content?.startsWith("[strategy]")).length;
@@ -300882,8 +301194,8 @@ async function handleSlashCommand(input, ctx3) {
300882
301194
  } catch {
300883
301195
  }
300884
301196
  try {
300885
- const dbPath = join80(ctx3.repoRoot, ".oa", "memory", "structured.db");
300886
- if (existsSync64(dbPath)) {
301197
+ const dbPath = join81(ctx3.repoRoot, ".oa", "memory", "structured.db");
301198
+ if (existsSync65(dbPath)) {
300887
301199
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
300888
301200
  const db = initDb2(dbPath);
300889
301201
  const memStore = new ProceduralMemoryStore2(db);
@@ -300904,8 +301216,8 @@ async function handleSlashCommand(input, ctx3) {
300904
301216
  lines.push(`
300905
301217
  ${c3.bold("Storage Overview")}
300906
301218
  `);
300907
- const oaDir = join80(ctx3.repoRoot, ".oa");
300908
- if (!existsSync64(oaDir)) {
301219
+ const oaDir = join81(ctx3.repoRoot, ".oa");
301220
+ if (!existsSync65(oaDir)) {
300909
301221
  lines.push(` ${c3.dim("No .oa/ directory found.")}`);
300910
301222
  safeLog(lines.join("\n") + "\n");
300911
301223
  return "handled";
@@ -300915,7 +301227,7 @@ async function handleSlashCommand(input, ctx3) {
300915
301227
  const walkStorage = (dir, category) => {
300916
301228
  try {
300917
301229
  for (const entry of readdirSync17(dir, { withFileTypes: true })) {
300918
- const full = join80(dir, entry.name);
301230
+ const full = join81(dir, entry.name);
300919
301231
  if (entry.isDirectory()) {
300920
301232
  const subCat = category || entry.name;
300921
301233
  walkStorage(full, subCat);
@@ -300950,9 +301262,9 @@ async function handleSlashCommand(input, ctx3) {
300950
301262
  for (const entry of readdirSync17(dir, { withFileTypes: true })) {
300951
301263
  const name10 = entry.name.toLowerCase();
300952
301264
  if (sensitivePatterns.some((p2) => name10.includes(p2))) {
300953
- sensitiveFound.push(join80(dir, entry.name).replace(oaDir + "/", ""));
301265
+ sensitiveFound.push(join81(dir, entry.name).replace(oaDir + "/", ""));
300954
301266
  }
300955
- if (entry.isDirectory()) checkSensitive(join80(dir, entry.name));
301267
+ if (entry.isDirectory()) checkSensitive(join81(dir, entry.name));
300956
301268
  }
300957
301269
  } catch {
300958
301270
  }
@@ -300980,8 +301292,8 @@ async function handleSlashCommand(input, ctx3) {
300980
301292
  renderInfo("Supported: .wav .mp3 .flac .ogg (audio→transcribe) | .pdf .txt .md (text→chunk)");
300981
301293
  return "handled";
300982
301294
  }
300983
- const resolvedPath = join80(ctx3.repoRoot, filePath);
300984
- if (!existsSync64(resolvedPath)) {
301295
+ const resolvedPath = join81(ctx3.repoRoot, filePath);
301296
+ if (!existsSync65(resolvedPath)) {
300985
301297
  renderWarning(`File not found: ${resolvedPath}`);
300986
301298
  return "handled";
300987
301299
  }
@@ -300997,9 +301309,9 @@ async function handleSlashCommand(input, ctx3) {
300997
301309
  }
300998
301310
  try {
300999
301311
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
301000
- const dbDir = join80(ctx3.repoRoot, ".oa", "memory");
301312
+ const dbDir = join81(ctx3.repoRoot, ".oa", "memory");
301001
301313
  mkdirSync37(dbDir, { recursive: true });
301002
- const db = initDb2(join80(dbDir, "structured.db"));
301314
+ const db = initDb2(join81(dbDir, "structured.db"));
301003
301315
  const memStore = new ProceduralMemoryStore2(db);
301004
301316
  if (isAudio) {
301005
301317
  renderInfo(`Transcribing: ${filePath}...`);
@@ -301043,7 +301355,7 @@ async function handleSlashCommand(input, ctx3) {
301043
301355
  return "handled";
301044
301356
  }
301045
301357
  } else {
301046
- content = readFileSync49(resolvedPath, "utf8");
301358
+ content = readFileSync50(resolvedPath, "utf8");
301047
301359
  }
301048
301360
  if (!content.trim()) {
301049
301361
  renderWarning("No content extracted.");
@@ -301081,9 +301393,9 @@ async function handleSlashCommand(input, ctx3) {
301081
301393
  }
301082
301394
  case "fortemi": {
301083
301395
  const fortemiSubCmd = (arg || "").trim().toLowerCase();
301084
- const fortemiDir = join80(ctx3.repoRoot, "..", "fortemi-react");
301085
- const altFortemiDir = join80(nodeOs.homedir(), "fortemi-react");
301086
- const fDir = existsSync64(fortemiDir) ? fortemiDir : existsSync64(altFortemiDir) ? altFortemiDir : null;
301396
+ const fortemiDir = join81(ctx3.repoRoot, "..", "fortemi-react");
301397
+ const altFortemiDir = join81(nodeOs.homedir(), "fortemi-react");
301398
+ const fDir = existsSync65(fortemiDir) ? fortemiDir : existsSync65(altFortemiDir) ? altFortemiDir : null;
301087
301399
  if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
301088
301400
  if (!fDir) {
301089
301401
  renderWarning("fortemi-react not found adjacent or in home directory.");
@@ -301098,14 +301410,14 @@ async function handleSlashCommand(input, ctx3) {
301098
301410
  // 24h
301099
301411
  nonce: Math.random().toString(36).slice(2, 10)
301100
301412
  };
301101
- const jwtFile = join80(ctx3.repoRoot, ".oa", "fortemi-jwt.json");
301102
- mkdirSync37(join80(ctx3.repoRoot, ".oa"), { recursive: true });
301413
+ const jwtFile = join81(ctx3.repoRoot, ".oa", "fortemi-jwt.json");
301414
+ mkdirSync37(join81(ctx3.repoRoot, ".oa"), { recursive: true });
301103
301415
  writeFileSync34(jwtFile, JSON.stringify(jwtPayload, null, 2));
301104
301416
  renderInfo(`Launching fortemi-react from ${fDir}...`);
301105
301417
  try {
301106
301418
  const { spawn: spawn27 } = __require("node:child_process");
301107
301419
  const child = spawn27("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
301108
- cwd: join80(fDir, "apps", "standalone"),
301420
+ cwd: join81(fDir, "apps", "standalone"),
301109
301421
  stdio: "ignore",
301110
301422
  detached: true,
301111
301423
  env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
@@ -301114,7 +301426,7 @@ async function handleSlashCommand(input, ctx3) {
301114
301426
  renderInfo("Fortemi-React starting on http://localhost:3000");
301115
301427
  renderInfo(`JWT saved to ${jwtFile}`);
301116
301428
  renderInfo("Memory operations will proxy to fortemi when available.");
301117
- const bridgeFile = join80(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
301429
+ const bridgeFile = join81(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
301118
301430
  writeFileSync34(bridgeFile, JSON.stringify({
301119
301431
  url: "http://localhost:3000",
301120
301432
  pid: child.pid,
@@ -301127,12 +301439,12 @@ async function handleSlashCommand(input, ctx3) {
301127
301439
  return "handled";
301128
301440
  }
301129
301441
  if (fortemiSubCmd === "status") {
301130
- const bridgeFile = join80(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
301131
- if (!existsSync64(bridgeFile)) {
301442
+ const bridgeFile = join81(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
301443
+ if (!existsSync65(bridgeFile)) {
301132
301444
  renderInfo("Fortemi bridge: not connected. Run /fortemi start");
301133
301445
  return "handled";
301134
301446
  }
301135
- const bridge = JSON.parse(readFileSync49(bridgeFile, "utf8"));
301447
+ const bridge = JSON.parse(readFileSync50(bridgeFile, "utf8"));
301136
301448
  let alive = false;
301137
301449
  try {
301138
301450
  process.kill(bridge.pid, 0);
@@ -301152,15 +301464,15 @@ async function handleSlashCommand(input, ctx3) {
301152
301464
  lines.push(` Process: ${alive ? c3.green("running") : c3.yellow("not running")} (PID ${bridge.pid})`);
301153
301465
  lines.push(` HTTP: ${httpOk ? c3.green("connected") : c3.yellow("unreachable")}`);
301154
301466
  lines.push(` Started: ${bridge.startedAt}`);
301155
- lines.push(` JWT: ${existsSync64(bridge.jwtFile) ? c3.green("valid") : c3.yellow("missing")}`);
301467
+ lines.push(` JWT: ${existsSync65(bridge.jwtFile) ? c3.green("valid") : c3.yellow("missing")}`);
301156
301468
  lines.push("");
301157
301469
  safeLog(lines.join("\n"));
301158
301470
  return "handled";
301159
301471
  }
301160
301472
  if (fortemiSubCmd === "stop") {
301161
- const bridgeFile = join80(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
301162
- if (existsSync64(bridgeFile)) {
301163
- const bridge = JSON.parse(readFileSync49(bridgeFile, "utf8"));
301473
+ const bridgeFile = join81(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
301474
+ if (existsSync65(bridgeFile)) {
301475
+ const bridge = JSON.parse(readFileSync50(bridgeFile, "utf8"));
301164
301476
  try {
301165
301477
  process.kill(bridge.pid, "SIGTERM");
301166
301478
  } catch {
@@ -301612,11 +301924,24 @@ Clone a new voice: /voice clone <wav-file> [name]`);
301612
301924
  case "neovim":
301613
301925
  case "nvim":
301614
301926
  case "vim": {
301927
+ const tasksRenderer = await Promise.resolve().then(() => (init_tui_tasks_renderer(), tui_tasks_renderer_exports)).catch(() => null);
301615
301928
  if (isNeovimActive()) {
301616
301929
  await stopNeovimMode();
301617
301930
  ctx3.clearScreen();
301618
301931
  renderInfo("Neovim mode stopped. Main waterfall restored.");
301932
+ try {
301933
+ tasksRenderer?.setTuiTasksScope({ neovimActive: false });
301934
+ } catch {
301935
+ }
301936
+ try {
301937
+ tasksRenderer?.refreshTuiTasks();
301938
+ } catch {
301939
+ }
301619
301940
  } else {
301941
+ try {
301942
+ tasksRenderer?.setTuiTasksScope({ neovimActive: true });
301943
+ } catch {
301944
+ }
301620
301945
  ctx3.retireCarousel?.();
301621
301946
  const L = layout();
301622
301947
  const contentRows = ctx3.availableContentRows?.() ?? Math.max(5, L.contentHeight);
@@ -301970,9 +302295,9 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
301970
302295
  }
301971
302296
  }
301972
302297
  }
301973
- const _spLogDir = join80(projectDir, ".oa", "sponsor");
302298
+ const _spLogDir = join81(projectDir, ".oa", "sponsor");
301974
302299
  mkdirSync37(_spLogDir, { recursive: true });
301975
- const _spLogFile = join80(_spLogDir, "sponsor-startup.log");
302300
+ const _spLogFile = join81(_spLogDir, "sponsor-startup.log");
301976
302301
  const _spLog = (msg) => {
301977
302302
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}
301978
302303
  `;
@@ -302082,17 +302407,17 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
302082
302407
  }
302083
302408
  if (!sponsorUrl && !sponsorPeerId) {
302084
302409
  _spLog("FAILED — no tunnelUrl and no peerId");
302085
- _spLog(`nexusDir checked: ${join80(projectDir, ".oa", "nexus")}`);
302086
- _spLog(`status.json exists: ${existsSync64(join80(projectDir, ".oa", "nexus", "status.json"))}`);
302087
- _spLog(`daemon.pid exists: ${existsSync64(join80(projectDir, ".oa", "nexus", "daemon.pid"))}`);
302410
+ _spLog(`nexusDir checked: ${join81(projectDir, ".oa", "nexus")}`);
302411
+ _spLog(`status.json exists: ${existsSync65(join81(projectDir, ".oa", "nexus", "status.json"))}`);
302412
+ _spLog(`daemon.pid exists: ${existsSync65(join81(projectDir, ".oa", "nexus", "daemon.pid"))}`);
302088
302413
  try {
302089
- const _statusRaw = readFileSync49(join80(projectDir, ".oa", "nexus", "status.json"), "utf8");
302414
+ const _statusRaw = readFileSync50(join81(projectDir, ".oa", "nexus", "status.json"), "utf8");
302090
302415
  _spLog(`status.json content: ${_statusRaw.slice(0, 300)}`);
302091
302416
  } catch (e2) {
302092
302417
  _spLog(`status.json read error: ${e2}`);
302093
302418
  }
302094
302419
  try {
302095
- const _errRaw = readFileSync49(join80(projectDir, ".oa", "nexus", "daemon.err"), "utf8");
302420
+ const _errRaw = readFileSync50(join81(projectDir, ".oa", "nexus", "daemon.err"), "utf8");
302096
302421
  _spLog(`daemon.err (last 500): ${_errRaw.slice(-500)}`);
302097
302422
  } catch (e2) {
302098
302423
  _spLog(`daemon.err read error: ${e2}`);
@@ -302111,7 +302436,7 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
302111
302436
  try {
302112
302437
  const { homedir: homedir39 } = __require("os");
302113
302438
  const namePath = __require("path").join(homedir39(), ".open-agents", "agent-name");
302114
- if (existsSync64(namePath)) sponsorName = readFileSync49(namePath, "utf8").trim();
302439
+ if (existsSync65(namePath)) sponsorName = readFileSync50(namePath, "utf8").trim();
302115
302440
  } catch {
302116
302441
  }
302117
302442
  if (!sponsorName) sponsorName = "OA Sponsor";
@@ -302186,9 +302511,9 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
302186
302511
  if (result) {
302187
302512
  renderInfo("Sponsor wizard completed.");
302188
302513
  try {
302189
- const nexusPidFile = join80(projectDir, ".oa", "nexus", "daemon.pid");
302190
- if (existsSync64(nexusPidFile)) {
302191
- const nPid = parseInt(readFileSync49(nexusPidFile, "utf8").trim(), 10);
302514
+ const nexusPidFile = join81(projectDir, ".oa", "nexus", "daemon.pid");
302515
+ if (existsSync65(nexusPidFile)) {
302516
+ const nPid = parseInt(readFileSync50(nexusPidFile, "utf8").trim(), 10);
302192
302517
  if (nPid > 0) {
302193
302518
  registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
302194
302519
  }
@@ -303252,13 +303577,13 @@ async function showCohereDashboard(ctx3) {
303252
303577
  } else if (idResult.key === "view") {
303253
303578
  await ik.execute({ operation: "hydrate" });
303254
303579
  } else if (idResult.key === "history") {
303255
- const snapDir = join80(ctx3.repoRoot, ".oa", "identity", "snapshots");
303256
- if (existsSync64(snapDir)) {
303580
+ const snapDir = join81(ctx3.repoRoot, ".oa", "identity", "snapshots");
303581
+ if (existsSync65(snapDir)) {
303257
303582
  const snaps = readdirSync17(snapDir).filter((f2) => f2.endsWith(".json")).sort().reverse();
303258
303583
  const snapItems = snaps.slice(0, 20).map((f2) => ({
303259
303584
  key: f2,
303260
303585
  label: f2.replace(".json", ""),
303261
- detail: `${formatFileSize(statSync19(join80(snapDir, f2)).size)}`
303586
+ detail: `${formatFileSize(statSync19(join81(snapDir, f2)).size)}`
303262
303587
  }));
303263
303588
  if (snapItems.length > 0) {
303264
303589
  await tuiSelect({
@@ -304261,11 +304586,11 @@ async function handleSponsoredEndpoint(ctx3, local) {
304261
304586
  }
304262
304587
  } catch {
304263
304588
  }
304264
- const sponsorDir2 = join80(ctx3.repoRoot ?? process.cwd(), ".oa", "sponsor");
304265
- const knownFile = join80(sponsorDir2, "known-sponsors.json");
304589
+ const sponsorDir2 = join81(ctx3.repoRoot ?? process.cwd(), ".oa", "sponsor");
304590
+ const knownFile = join81(sponsorDir2, "known-sponsors.json");
304266
304591
  try {
304267
- if (existsSync64(knownFile)) {
304268
- const saved = JSON.parse(readFileSync49(knownFile, "utf8"));
304592
+ if (existsSync65(knownFile)) {
304593
+ const saved = JSON.parse(readFileSync50(knownFile, "utf8"));
304269
304594
  for (const s2 of saved) {
304270
304595
  if (!sponsors.some((sp) => sp.url === s2.url)) {
304271
304596
  sponsors.push({ ...s2, source: "saved" });
@@ -304416,7 +304741,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
304416
304741
  const saveKey = selected.url || selected.peerId || selected.name;
304417
304742
  try {
304418
304743
  mkdirSync37(sponsorDir2, { recursive: true });
304419
- const existing = existsSync64(knownFile) ? JSON.parse(readFileSync49(knownFile, "utf8")) : [];
304744
+ const existing = existsSync65(knownFile) ? JSON.parse(readFileSync50(knownFile, "utf8")) : [];
304420
304745
  const updated = existing.filter((s2) => (s2.url || s2.peerId || s2.name) !== saveKey);
304421
304746
  updated.push(selected);
304422
304747
  writeFileSync34(knownFile, JSON.stringify(updated, null, 2), "utf8");
@@ -306161,10 +306486,10 @@ var init_commands = __esm({
306161
306486
  });
306162
306487
 
306163
306488
  // packages/cli/src/tui/project-context.ts
306164
- import { existsSync as existsSync65, readFileSync as readFileSync50, readdirSync as readdirSync18 } from "node:fs";
306165
- import { join as join81, basename as basename13 } from "node:path";
306489
+ import { existsSync as existsSync66, readFileSync as readFileSync51, readdirSync as readdirSync18 } from "node:fs";
306490
+ import { join as join82, basename as basename13 } from "node:path";
306166
306491
  import { execSync as execSync51 } from "node:child_process";
306167
- import { homedir as homedir29, platform as platform5, release } from "node:os";
306492
+ import { homedir as homedir30, platform as platform5, release } from "node:os";
306168
306493
  function getModelTier(modelName) {
306169
306494
  const m2 = modelName.toLowerCase();
306170
306495
  const sizeMatch = m2.match(/\b(\d+)b\b/);
@@ -306193,10 +306518,10 @@ function loadProjectMap(repoRoot) {
306193
306518
  if (!hasOaDirectory(repoRoot)) {
306194
306519
  initOaDirectory(repoRoot);
306195
306520
  }
306196
- const mapPath2 = join81(repoRoot, OA_DIR, "context", "project-map.md");
306197
- if (existsSync65(mapPath2)) {
306521
+ const mapPath2 = join82(repoRoot, OA_DIR, "context", "project-map.md");
306522
+ if (existsSync66(mapPath2)) {
306198
306523
  try {
306199
- const content = readFileSync50(mapPath2, "utf-8");
306524
+ const content = readFileSync51(mapPath2, "utf-8");
306200
306525
  return content;
306201
306526
  } catch {
306202
306527
  }
@@ -306235,27 +306560,27 @@ ${log22}`);
306235
306560
  }
306236
306561
  function loadMemoryContext(repoRoot) {
306237
306562
  const sections = [];
306238
- const oaMemDir = join81(repoRoot, OA_DIR, "memory");
306563
+ const oaMemDir = join82(repoRoot, OA_DIR, "memory");
306239
306564
  const oaEntries = loadMemoryDir(oaMemDir, "project");
306240
306565
  if (oaEntries) sections.push(oaEntries);
306241
- const legacyMemDir = join81(repoRoot, ".open-agents", "memory");
306242
- if (legacyMemDir !== oaMemDir && existsSync65(legacyMemDir)) {
306566
+ const legacyMemDir = join82(repoRoot, ".open-agents", "memory");
306567
+ if (legacyMemDir !== oaMemDir && existsSync66(legacyMemDir)) {
306243
306568
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
306244
306569
  if (legacyEntries) sections.push(legacyEntries);
306245
306570
  }
306246
- const globalMemDir = join81(homedir29(), ".open-agents", "memory");
306571
+ const globalMemDir = join82(homedir30(), ".open-agents", "memory");
306247
306572
  const globalEntries = loadMemoryDir(globalMemDir, "global");
306248
306573
  if (globalEntries) sections.push(globalEntries);
306249
306574
  return sections.join("\n\n");
306250
306575
  }
306251
306576
  function loadMemoryDir(memDir, scope) {
306252
- if (!existsSync65(memDir)) return "";
306577
+ if (!existsSync66(memDir)) return "";
306253
306578
  const lines = [];
306254
306579
  try {
306255
306580
  const files = readdirSync18(memDir).filter((f2) => f2.endsWith(".json"));
306256
306581
  for (const file of files.slice(0, 10)) {
306257
306582
  try {
306258
- const raw = readFileSync50(join81(memDir, file), "utf-8");
306583
+ const raw = readFileSync51(join82(memDir, file), "utf-8");
306259
306584
  const entries = JSON.parse(raw);
306260
306585
  const topic = basename13(file, ".json");
306261
306586
  const keys = Object.keys(entries);
@@ -306760,8 +307085,8 @@ __export(banner_exports, {
306760
307085
  saveBannerDesign: () => saveBannerDesign,
306761
307086
  setGridText: () => setGridText
306762
307087
  });
306763
- import { existsSync as existsSync66, readFileSync as readFileSync51, writeFileSync as writeFileSync35, mkdirSync as mkdirSync38 } from "node:fs";
306764
- import { join as join82 } from "node:path";
307088
+ import { existsSync as existsSync67, readFileSync as readFileSync52, writeFileSync as writeFileSync35, mkdirSync as mkdirSync38 } from "node:fs";
307089
+ import { join as join83 } from "node:path";
306765
307090
  function generateMnemonic(seed) {
306766
307091
  let h = 2166136261;
306767
307092
  for (let i2 = 0; i2 < seed.length; i2++) {
@@ -306891,22 +307216,22 @@ function createSponsorBanner(sponsorName, tagline, primaryColor = 214, bgColor =
306891
307216
  };
306892
307217
  }
306893
307218
  function saveBannerDesign(workDir, design) {
306894
- const dir = join82(workDir, ".oa", "banners");
307219
+ const dir = join83(workDir, ".oa", "banners");
306895
307220
  mkdirSync38(dir, { recursive: true });
306896
- writeFileSync35(join82(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
307221
+ writeFileSync35(join83(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
306897
307222
  }
306898
307223
  function loadBannerDesign(workDir, id) {
306899
- const file = join82(workDir, ".oa", "banners", `${id}.json`);
306900
- if (!existsSync66(file)) return null;
307224
+ const file = join83(workDir, ".oa", "banners", `${id}.json`);
307225
+ if (!existsSync67(file)) return null;
306901
307226
  try {
306902
- return JSON.parse(readFileSync51(file, "utf8"));
307227
+ return JSON.parse(readFileSync52(file, "utf8"));
306903
307228
  } catch {
306904
307229
  return null;
306905
307230
  }
306906
307231
  }
306907
307232
  function listBannerDesigns(workDir) {
306908
- const dir = join82(workDir, ".oa", "banners");
306909
- if (!existsSync66(dir)) return [];
307233
+ const dir = join83(workDir, ".oa", "banners");
307234
+ if (!existsSync67(dir)) return [];
306910
307235
  try {
306911
307236
  const { readdirSync: readdirSync31 } = __require("node:fs");
306912
307237
  return readdirSync31(dir).filter((f2) => f2.endsWith(".json")).map((f2) => f2.replace(".json", ""));
@@ -307213,21 +307538,21 @@ var init_banner = __esm({
307213
307538
  });
307214
307539
 
307215
307540
  // packages/cli/src/tui/carousel-descriptors.ts
307216
- import { existsSync as existsSync67, readFileSync as readFileSync52, writeFileSync as writeFileSync36, mkdirSync as mkdirSync39, readdirSync as readdirSync19 } from "node:fs";
307217
- import { join as join83, basename as basename14 } from "node:path";
307541
+ import { existsSync as existsSync68, readFileSync as readFileSync53, writeFileSync as writeFileSync36, mkdirSync as mkdirSync39, readdirSync as readdirSync19 } from "node:fs";
307542
+ import { join as join84, basename as basename14 } from "node:path";
307218
307543
  function loadToolProfile(repoRoot) {
307219
- const filePath = join83(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
307544
+ const filePath = join84(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
307220
307545
  try {
307221
- if (!existsSync67(filePath)) return null;
307222
- return JSON.parse(readFileSync52(filePath, "utf-8"));
307546
+ if (!existsSync68(filePath)) return null;
307547
+ return JSON.parse(readFileSync53(filePath, "utf-8"));
307223
307548
  } catch {
307224
307549
  return null;
307225
307550
  }
307226
307551
  }
307227
307552
  function saveToolProfile(repoRoot, profile) {
307228
- const contextDir = join83(repoRoot, OA_DIR, "context");
307553
+ const contextDir = join84(repoRoot, OA_DIR, "context");
307229
307554
  mkdirSync39(contextDir, { recursive: true });
307230
- writeFileSync36(join83(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
307555
+ writeFileSync36(join84(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
307231
307556
  }
307232
307557
  function categorizeToolCall(toolName) {
307233
307558
  for (const cat2 of TOOL_CATEGORIES) {
@@ -307282,24 +307607,24 @@ function weightedColor(profile) {
307282
307607
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
307283
307608
  }
307284
307609
  function loadCachedDescriptors(repoRoot) {
307285
- const filePath = join83(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
307610
+ const filePath = join84(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
307286
307611
  try {
307287
- if (!existsSync67(filePath)) return null;
307288
- const cached = JSON.parse(readFileSync52(filePath, "utf-8"));
307612
+ if (!existsSync68(filePath)) return null;
307613
+ const cached = JSON.parse(readFileSync53(filePath, "utf-8"));
307289
307614
  return cached.phrases.length > 0 ? cached.phrases : null;
307290
307615
  } catch {
307291
307616
  return null;
307292
307617
  }
307293
307618
  }
307294
307619
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
307295
- const contextDir = join83(repoRoot, OA_DIR, "context");
307620
+ const contextDir = join84(repoRoot, OA_DIR, "context");
307296
307621
  mkdirSync39(contextDir, { recursive: true });
307297
307622
  const cached = {
307298
307623
  phrases,
307299
307624
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
307300
307625
  sourceHash
307301
307626
  };
307302
- writeFileSync36(join83(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
307627
+ writeFileSync36(join84(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
307303
307628
  }
307304
307629
  function generateDescriptors(repoRoot) {
307305
307630
  const profile = loadToolProfile(repoRoot);
@@ -307346,10 +307671,10 @@ function generateDescriptors(repoRoot) {
307346
307671
  return phrases;
307347
307672
  }
307348
307673
  function extractFromPackageJson(repoRoot, tags) {
307349
- const pkgPath = join83(repoRoot, "package.json");
307674
+ const pkgPath = join84(repoRoot, "package.json");
307350
307675
  try {
307351
- if (!existsSync67(pkgPath)) return;
307352
- const pkg = JSON.parse(readFileSync52(pkgPath, "utf-8"));
307676
+ if (!existsSync68(pkgPath)) return;
307677
+ const pkg = JSON.parse(readFileSync53(pkgPath, "utf-8"));
307353
307678
  if (pkg.name && typeof pkg.name === "string") {
307354
307679
  const parts = pkg.name.replace(/^@/, "").split("/");
307355
307680
  for (const p2 of parts) tags.push(p2);
@@ -307390,7 +307715,7 @@ function extractFromManifests(repoRoot, tags) {
307390
307715
  { file: ".github/workflows", tag: "ci/cd" }
307391
307716
  ];
307392
307717
  for (const check of manifestChecks) {
307393
- if (existsSync67(join83(repoRoot, check.file))) {
307718
+ if (existsSync68(join84(repoRoot, check.file))) {
307394
307719
  tags.push(check.tag);
307395
307720
  }
307396
307721
  }
@@ -307412,15 +307737,15 @@ function extractFromSessions(repoRoot, tags) {
307412
307737
  }
307413
307738
  }
307414
307739
  function extractFromMemory(repoRoot, tags) {
307415
- const memoryDir = join83(repoRoot, OA_DIR, "memory");
307740
+ const memoryDir = join84(repoRoot, OA_DIR, "memory");
307416
307741
  try {
307417
- if (!existsSync67(memoryDir)) return;
307742
+ if (!existsSync68(memoryDir)) return;
307418
307743
  const files = readdirSync19(memoryDir).filter((f2) => f2.endsWith(".json"));
307419
307744
  for (const file of files) {
307420
307745
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
307421
307746
  tags.push(topic);
307422
307747
  try {
307423
- const data = JSON.parse(readFileSync52(join83(memoryDir, file), "utf-8"));
307748
+ const data = JSON.parse(readFileSync53(join84(memoryDir, file), "utf-8"));
307424
307749
  if (data && typeof data === "object") {
307425
307750
  const keys = Object.keys(data).slice(0, 3);
307426
307751
  for (const key of keys) {
@@ -308115,10 +308440,10 @@ var init_stream_renderer = __esm({
308115
308440
 
308116
308441
  // packages/cli/src/tui/edit-history.ts
308117
308442
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync40 } from "node:fs";
308118
- import { join as join84 } from "node:path";
308443
+ import { join as join85 } from "node:path";
308119
308444
  function createEditHistoryLogger(repoRoot, sessionId) {
308120
- const historyDir = join84(repoRoot, ".oa", "history");
308121
- const logPath2 = join84(historyDir, "edits.jsonl");
308445
+ const historyDir = join85(repoRoot, ".oa", "history");
308446
+ const logPath2 = join85(historyDir, "edits.jsonl");
308122
308447
  try {
308123
308448
  mkdirSync40(historyDir, { recursive: true });
308124
308449
  } catch {
@@ -308228,17 +308553,17 @@ var init_edit_history = __esm({
308228
308553
  });
308229
308554
 
308230
308555
  // packages/cli/src/tui/promptLoader.ts
308231
- import { readFileSync as readFileSync53, existsSync as existsSync68 } from "node:fs";
308232
- import { join as join85, dirname as dirname24 } from "node:path";
308556
+ import { readFileSync as readFileSync54, existsSync as existsSync69 } from "node:fs";
308557
+ import { join as join86, dirname as dirname24 } from "node:path";
308233
308558
  import { fileURLToPath as fileURLToPath14 } from "node:url";
308234
308559
  function loadPrompt3(promptPath, vars) {
308235
308560
  let content = cache6.get(promptPath);
308236
308561
  if (content === void 0) {
308237
- const fullPath = join85(PROMPTS_DIR3, promptPath);
308238
- if (!existsSync68(fullPath)) {
308562
+ const fullPath = join86(PROMPTS_DIR3, promptPath);
308563
+ if (!existsSync69(fullPath)) {
308239
308564
  throw new Error(`Prompt file not found: ${fullPath}`);
308240
308565
  }
308241
- content = readFileSync53(fullPath, "utf-8");
308566
+ content = readFileSync54(fullPath, "utf-8");
308242
308567
  cache6.set(promptPath, content);
308243
308568
  }
308244
308569
  if (!vars) return content;
@@ -308250,16 +308575,16 @@ var init_promptLoader3 = __esm({
308250
308575
  "use strict";
308251
308576
  __filename5 = fileURLToPath14(import.meta.url);
308252
308577
  __dirname7 = dirname24(__filename5);
308253
- devPath2 = join85(__dirname7, "..", "..", "prompts");
308254
- publishedPath2 = join85(__dirname7, "..", "prompts");
308255
- PROMPTS_DIR3 = existsSync68(devPath2) ? devPath2 : publishedPath2;
308578
+ devPath2 = join86(__dirname7, "..", "..", "prompts");
308579
+ publishedPath2 = join86(__dirname7, "..", "prompts");
308580
+ PROMPTS_DIR3 = existsSync69(devPath2) ? devPath2 : publishedPath2;
308256
308581
  cache6 = /* @__PURE__ */ new Map();
308257
308582
  }
308258
308583
  });
308259
308584
 
308260
308585
  // packages/cli/src/tui/dream-engine.ts
308261
- import { mkdirSync as mkdirSync41, writeFileSync as writeFileSync37, readFileSync as readFileSync54, existsSync as existsSync69, readdirSync as readdirSync20 } from "node:fs";
308262
- import { join as join86, basename as basename15 } from "node:path";
308586
+ import { mkdirSync as mkdirSync41, writeFileSync as writeFileSync37, readFileSync as readFileSync55, existsSync as existsSync70, readdirSync as readdirSync20 } from "node:fs";
308587
+ import { join as join87, basename as basename15 } from "node:path";
308263
308588
  import { execSync as execSync52 } from "node:child_process";
308264
308589
  function setDreamWriteContent(fn) {
308265
308590
  _dreamWriteContent = fn;
@@ -308272,10 +308597,10 @@ function dreamWrite(fn) {
308272
308597
  }
308273
308598
  }
308274
308599
  function loadAutoresearchMemory(repoRoot) {
308275
- const memoryPath = join86(repoRoot, ".oa", "memory", "autoresearch.json");
308276
- if (!existsSync69(memoryPath)) return "";
308600
+ const memoryPath = join87(repoRoot, ".oa", "memory", "autoresearch.json");
308601
+ if (!existsSync70(memoryPath)) return "";
308277
308602
  try {
308278
- const raw = readFileSync54(memoryPath, "utf-8");
308603
+ const raw = readFileSync55(memoryPath, "utf-8");
308279
308604
  const data = JSON.parse(raw);
308280
308605
  const sections = [];
308281
308606
  for (const key of AUTORESEARCH_MEMORY_KEYS) {
@@ -308471,12 +308796,12 @@ var init_dream_engine = __esm({
308471
308796
  const rawPath = String(args["path"] ?? "");
308472
308797
  const content = String(args["content"] ?? "");
308473
308798
  if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
308474
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join86(this.autoresearchDir, basename15(rawPath)) : join86(this.autoresearchDir, rawPath);
308799
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join87(this.autoresearchDir, basename15(rawPath)) : join87(this.autoresearchDir, rawPath);
308475
308800
  if (!targetPath.startsWith(this.autoresearchDir)) {
308476
308801
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
308477
308802
  }
308478
308803
  try {
308479
- const dir = join86(targetPath, "..");
308804
+ const dir = join87(targetPath, "..");
308480
308805
  mkdirSync41(dir, { recursive: true });
308481
308806
  writeFileSync37(targetPath, content, "utf-8");
308482
308807
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
@@ -308505,15 +308830,15 @@ var init_dream_engine = __esm({
308505
308830
  const rawPath = String(args["path"] ?? "");
308506
308831
  const oldStr = String(args["old_string"] ?? "");
308507
308832
  const newStr = String(args["new_string"] ?? "");
308508
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join86(this.autoresearchDir, basename15(rawPath)) : join86(this.autoresearchDir, rawPath);
308833
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join87(this.autoresearchDir, basename15(rawPath)) : join87(this.autoresearchDir, rawPath);
308509
308834
  if (!targetPath.startsWith(this.autoresearchDir)) {
308510
308835
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
308511
308836
  }
308512
308837
  try {
308513
- if (!existsSync69(targetPath)) {
308838
+ if (!existsSync70(targetPath)) {
308514
308839
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
308515
308840
  }
308516
- let content = readFileSync54(targetPath, "utf-8");
308841
+ let content = readFileSync55(targetPath, "utf-8");
308517
308842
  if (!content.includes(oldStr)) {
308518
308843
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start2 };
308519
308844
  }
@@ -308557,12 +308882,12 @@ var init_dream_engine = __esm({
308557
308882
  const rawPath = String(args["path"] ?? "");
308558
308883
  const content = String(args["content"] ?? "");
308559
308884
  if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
308560
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join86(this.dreamsDir, basename15(rawPath)) : join86(this.dreamsDir, rawPath);
308885
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join87(this.dreamsDir, basename15(rawPath)) : join87(this.dreamsDir, rawPath);
308561
308886
  if (!targetPath.startsWith(this.dreamsDir)) {
308562
308887
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start2 };
308563
308888
  }
308564
308889
  try {
308565
- const dir = join86(targetPath, "..");
308890
+ const dir = join87(targetPath, "..");
308566
308891
  mkdirSync41(dir, { recursive: true });
308567
308892
  writeFileSync37(targetPath, content, "utf-8");
308568
308893
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
@@ -308591,15 +308916,15 @@ var init_dream_engine = __esm({
308591
308916
  const rawPath = String(args["path"] ?? "");
308592
308917
  const oldStr = String(args["old_string"] ?? "");
308593
308918
  const newStr = String(args["new_string"] ?? "");
308594
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join86(this.dreamsDir, basename15(rawPath)) : join86(this.dreamsDir, rawPath);
308919
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join87(this.dreamsDir, basename15(rawPath)) : join87(this.dreamsDir, rawPath);
308595
308920
  if (!targetPath.startsWith(this.dreamsDir)) {
308596
308921
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start2 };
308597
308922
  }
308598
308923
  try {
308599
- if (!existsSync69(targetPath)) {
308924
+ if (!existsSync70(targetPath)) {
308600
308925
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
308601
308926
  }
308602
- let content = readFileSync54(targetPath, "utf-8");
308927
+ let content = readFileSync55(targetPath, "utf-8");
308603
308928
  if (!content.includes(oldStr)) {
308604
308929
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start2 };
308605
308930
  }
@@ -308652,7 +308977,7 @@ var init_dream_engine = __esm({
308652
308977
  constructor(config, repoRoot) {
308653
308978
  this.config = config;
308654
308979
  this.repoRoot = repoRoot;
308655
- this.dreamsDir = join86(repoRoot, ".oa", "dreams");
308980
+ this.dreamsDir = join87(repoRoot, ".oa", "dreams");
308656
308981
  this.state = {
308657
308982
  mode: "default",
308658
308983
  active: false,
@@ -308761,7 +309086,7 @@ ${result.summary}`;
308761
309086
  if (mode !== "default" || cycle === totalCycles) {
308762
309087
  renderDreamContraction(cycle);
308763
309088
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
308764
- const summaryPath = join86(this.dreamsDir, `cycle-${cycle}-summary.md`);
309089
+ const summaryPath = join87(this.dreamsDir, `cycle-${cycle}-summary.md`);
308765
309090
  writeFileSync37(summaryPath, cycleSummary, "utf-8");
308766
309091
  }
308767
309092
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -309001,7 +309326,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
309001
309326
  }
309002
309327
  /** Build role-specific tool sets for swarm agents */
309003
309328
  buildSwarmTools(role, _workspace) {
309004
- const autoresearchDir = join86(this.repoRoot, ".oa", "autoresearch");
309329
+ const autoresearchDir = join87(this.repoRoot, ".oa", "autoresearch");
309005
309330
  const taskComplete = this.createSwarmTaskCompleteTool(role);
309006
309331
  switch (role) {
309007
309332
  case "researcher": {
@@ -309400,7 +309725,7 @@ Call task_complete with a human-readable summary of the autoresearch session.`,
309400
309725
  workspace,
309401
309726
  onEvent
309402
309727
  );
309403
- const reportPath = join86(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
309728
+ const reportPath = join87(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
309404
309729
  const report = `# Autoresearch Swarm Report — Cycle ${cycleNum}
309405
309730
 
309406
309731
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -309489,7 +309814,7 @@ ${summaryResult}
309489
309814
  }
309490
309815
  /** Save workspace backup for lucid mode */
309491
309816
  saveVersionCheckpoint(cycle) {
309492
- const checkpointDir = join86(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
309817
+ const checkpointDir = join87(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
309493
309818
  try {
309494
309819
  mkdirSync41(checkpointDir, { recursive: true });
309495
309820
  try {
@@ -309508,11 +309833,11 @@ ${summaryResult}
309508
309833
  encoding: "utf-8",
309509
309834
  timeout: 5e3
309510
309835
  }).trim();
309511
- writeFileSync37(join86(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
309512
- writeFileSync37(join86(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
309513
- writeFileSync37(join86(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
309836
+ writeFileSync37(join87(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
309837
+ writeFileSync37(join87(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
309838
+ writeFileSync37(join87(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
309514
309839
  writeFileSync37(
309515
- join86(checkpointDir, "checkpoint.json"),
309840
+ join87(checkpointDir, "checkpoint.json"),
309516
309841
  JSON.stringify({
309517
309842
  cycle,
309518
309843
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -309524,7 +309849,7 @@ ${summaryResult}
309524
309849
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
309525
309850
  } catch {
309526
309851
  writeFileSync37(
309527
- join86(checkpointDir, "checkpoint.json"),
309852
+ join87(checkpointDir, "checkpoint.json"),
309528
309853
  JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2),
309529
309854
  "utf-8"
309530
309855
  );
@@ -309585,7 +309910,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
309585
309910
  ---
309586
309911
  *Auto-generated by open-agents dream engine*
309587
309912
  `;
309588
- writeFileSync37(join86(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
309913
+ writeFileSync37(join87(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
309589
309914
  } catch {
309590
309915
  }
309591
309916
  }
@@ -309606,7 +309931,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
309606
309931
  results: []
309607
309932
  };
309608
309933
  renderInfo("Memory consolidation starting — Phase 1: Orient → Phase 2: Gather → Phase 3: Consolidate → Phase 4: Prune");
309609
- const memoryDir = join86(this.repoRoot, ".oa", "memory");
309934
+ const memoryDir = join87(this.repoRoot, ".oa", "memory");
309610
309935
  mkdirSync41(memoryDir, { recursive: true });
309611
309936
  let prompt;
309612
309937
  try {
@@ -309672,7 +309997,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
309672
309997
  });
309673
309998
  try {
309674
309999
  writeFileSync37(
309675
- join86(memoryDir, ".last-consolidation"),
310000
+ join87(memoryDir, ".last-consolidation"),
309676
310001
  JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), summary: result.summary?.slice(0, 500) }) + "\n"
309677
310002
  );
309678
310003
  } catch {
@@ -309690,7 +310015,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
309690
310015
  saveDreamState() {
309691
310016
  try {
309692
310017
  writeFileSync37(
309693
- join86(this.dreamsDir, "dream-state.json"),
310018
+ join87(this.dreamsDir, "dream-state.json"),
309694
310019
  JSON.stringify(this.state, null, 2) + "\n",
309695
310020
  "utf-8"
309696
310021
  );
@@ -310060,8 +310385,8 @@ var init_bless_engine = __esm({
310060
310385
  });
310061
310386
 
310062
310387
  // packages/cli/src/tui/dmn-engine.ts
310063
- import { existsSync as existsSync70, readFileSync as readFileSync55, writeFileSync as writeFileSync38, mkdirSync as mkdirSync42, readdirSync as readdirSync21, unlinkSync as unlinkSync18 } from "node:fs";
310064
- import { join as join87, basename as basename16 } from "node:path";
310388
+ import { existsSync as existsSync71, readFileSync as readFileSync56, writeFileSync as writeFileSync38, mkdirSync as mkdirSync42, readdirSync as readdirSync21, unlinkSync as unlinkSync18 } from "node:fs";
310389
+ import { join as join88, basename as basename16 } from "node:path";
310065
310390
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
310066
310391
  const competenceReport = competence.length > 0 ? competence.map((c7) => {
310067
310392
  const rate = c7.attempts > 0 ? Math.round(c7.successes / c7.attempts * 100) : 0;
@@ -310166,8 +310491,8 @@ var init_dmn_engine = __esm({
310166
310491
  constructor(config, repoRoot) {
310167
310492
  this.config = config;
310168
310493
  this.repoRoot = repoRoot;
310169
- this.stateDir = join87(repoRoot, ".oa", "dmn");
310170
- this.historyDir = join87(repoRoot, ".oa", "dmn", "cycles");
310494
+ this.stateDir = join88(repoRoot, ".oa", "dmn");
310495
+ this.historyDir = join88(repoRoot, ".oa", "dmn", "cycles");
310171
310496
  mkdirSync42(this.historyDir, { recursive: true });
310172
310497
  this.loadState();
310173
310498
  }
@@ -310802,11 +311127,11 @@ OUTPUT: Call task_complete with JSON:
310802
311127
  async gatherMemoryTopics() {
310803
311128
  const topics = [];
310804
311129
  const dirs = [
310805
- join87(this.repoRoot, ".oa", "memory"),
310806
- join87(this.repoRoot, ".open-agents", "memory")
311130
+ join88(this.repoRoot, ".oa", "memory"),
311131
+ join88(this.repoRoot, ".open-agents", "memory")
310807
311132
  ];
310808
311133
  for (const dir of dirs) {
310809
- if (!existsSync70(dir)) continue;
311134
+ if (!existsSync71(dir)) continue;
310810
311135
  try {
310811
311136
  const files = readdirSync21(dir).filter((f2) => f2.endsWith(".json"));
310812
311137
  for (const f2 of files) {
@@ -310820,10 +311145,10 @@ OUTPUT: Call task_complete with JSON:
310820
311145
  }
310821
311146
  // ── State persistence ─────────────────────────────────────────────────
310822
311147
  loadState() {
310823
- const path5 = join87(this.stateDir, "state.json");
310824
- if (existsSync70(path5)) {
311148
+ const path5 = join88(this.stateDir, "state.json");
311149
+ if (existsSync71(path5)) {
310825
311150
  try {
310826
- this.state = JSON.parse(readFileSync55(path5, "utf-8"));
311151
+ this.state = JSON.parse(readFileSync56(path5, "utf-8"));
310827
311152
  } catch {
310828
311153
  }
310829
311154
  }
@@ -310831,7 +311156,7 @@ OUTPUT: Call task_complete with JSON:
310831
311156
  saveState() {
310832
311157
  try {
310833
311158
  writeFileSync38(
310834
- join87(this.stateDir, "state.json"),
311159
+ join88(this.stateDir, "state.json"),
310835
311160
  JSON.stringify(this.state, null, 2) + "\n",
310836
311161
  "utf-8"
310837
311162
  );
@@ -310842,7 +311167,7 @@ OUTPUT: Call task_complete with JSON:
310842
311167
  try {
310843
311168
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
310844
311169
  writeFileSync38(
310845
- join87(this.historyDir, filename),
311170
+ join88(this.historyDir, filename),
310846
311171
  JSON.stringify(result, null, 2) + "\n",
310847
311172
  "utf-8"
310848
311173
  );
@@ -310850,7 +311175,7 @@ OUTPUT: Call task_complete with JSON:
310850
311175
  if (files.length > 50) {
310851
311176
  for (const old of files.slice(0, files.length - 50)) {
310852
311177
  try {
310853
- unlinkSync18(join87(this.historyDir, old));
311178
+ unlinkSync18(join88(this.historyDir, old));
310854
311179
  } catch {
310855
311180
  }
310856
311181
  }
@@ -310863,8 +311188,8 @@ OUTPUT: Call task_complete with JSON:
310863
311188
  });
310864
311189
 
310865
311190
  // packages/cli/src/tui/snr-engine.ts
310866
- import { existsSync as existsSync71, readdirSync as readdirSync22, readFileSync as readFileSync56 } from "node:fs";
310867
- import { join as join88, basename as basename17 } from "node:path";
311191
+ import { existsSync as existsSync72, readdirSync as readdirSync22, readFileSync as readFileSync57 } from "node:fs";
311192
+ import { join as join89, basename as basename17 } from "node:path";
310868
311193
  function computeDPrime(signalScores, noiseScores) {
310869
311194
  if (signalScores.length === 0 || noiseScores.length === 0) return 0;
310870
311195
  const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
@@ -311148,18 +311473,18 @@ Call task_complete with the JSON array when done.`,
311148
311473
  loadMemoryEntries(topics) {
311149
311474
  const entries = [];
311150
311475
  const dirs = [
311151
- join88(this.repoRoot, ".oa", "memory"),
311152
- join88(this.repoRoot, ".open-agents", "memory")
311476
+ join89(this.repoRoot, ".oa", "memory"),
311477
+ join89(this.repoRoot, ".open-agents", "memory")
311153
311478
  ];
311154
311479
  for (const dir of dirs) {
311155
- if (!existsSync71(dir)) continue;
311480
+ if (!existsSync72(dir)) continue;
311156
311481
  try {
311157
311482
  const files = readdirSync22(dir).filter((f2) => f2.endsWith(".json"));
311158
311483
  for (const f2 of files) {
311159
311484
  const topic = basename17(f2, ".json");
311160
311485
  if (topics.length > 0 && !topics.includes(topic)) continue;
311161
311486
  try {
311162
- const data = JSON.parse(readFileSync56(join88(dir, f2), "utf-8"));
311487
+ const data = JSON.parse(readFileSync57(join89(dir, f2), "utf-8"));
311163
311488
  for (const [key, val] of Object.entries(data)) {
311164
311489
  const value2 = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
311165
311490
  entries.push({ topic, key, value: value2 });
@@ -311704,7 +312029,7 @@ var init_tool_policy = __esm({
311704
312029
 
311705
312030
  // packages/cli/src/tui/telegram-bridge.ts
311706
312031
  import { mkdirSync as mkdirSync43, unlinkSync as unlinkSync19 } from "node:fs";
311707
- import { join as join89, resolve as resolve32 } from "node:path";
312032
+ import { join as join90, resolve as resolve32 } from "node:path";
311708
312033
  import { writeFile as writeFileAsync } from "node:fs/promises";
311709
312034
  function convertMarkdownToTelegramHTML(md) {
311710
312035
  let html = md;
@@ -312460,7 +312785,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
312460
312785
  if (!res.ok) return null;
312461
312786
  const buffer2 = Buffer.from(await res.arrayBuffer());
312462
312787
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension2}`;
312463
- const localPath = join89(this.mediaCacheDir, fileName);
312788
+ const localPath = join90(this.mediaCacheDir, fileName);
312464
312789
  await writeFileAsync(localPath, buffer2);
312465
312790
  return localPath;
312466
312791
  } catch {
@@ -312880,192 +313205,6 @@ var init_task_manager_singleton = __esm({
312880
313205
  }
312881
313206
  });
312882
313207
 
312883
- // packages/cli/src/tui/tui-tasks-renderer.ts
312884
- import { existsSync as existsSync73, readFileSync as readFileSync57, watch as fsWatch2 } from "node:fs";
312885
- import { join as join90 } from "node:path";
312886
- import { homedir as homedir30 } from "node:os";
312887
- function todoDir2() {
312888
- return join90(homedir30(), ".open-agents", "todos");
312889
- }
312890
- function todoPath2(sessionId) {
312891
- const safe = sessionId.replace(/[^a-zA-Z0-9_.-]/g, "_");
312892
- return join90(todoDir2(), `${safe}.json`);
312893
- }
312894
- function setTuiTasksSession(sessionId) {
312895
- if (sessionId === _activeSessionId) return;
312896
- _activeSessionId = sessionId || null;
312897
- if (_watcher) {
312898
- try {
312899
- _watcher.close();
312900
- } catch {
312901
- }
312902
- _watcher = null;
312903
- }
312904
- if (!_activeSessionId) {
312905
- _lastTodos = [];
312906
- applyHeightChange(0);
312907
- return;
312908
- }
312909
- loadTodos();
312910
- installWatcher();
312911
- scheduleRedraw();
312912
- }
312913
- function onTuiTasksHeightChange(cb) {
312914
- _onResizeChange = cb;
312915
- }
312916
- function refreshTuiTasks() {
312917
- if (!_activeSessionId) return;
312918
- loadTodos();
312919
- scheduleRedraw();
312920
- }
312921
- function teardownTuiTasks() {
312922
- if (_watcher) {
312923
- try {
312924
- _watcher.close();
312925
- } catch {
312926
- }
312927
- _watcher = null;
312928
- }
312929
- _activeSessionId = null;
312930
- _lastTodos = [];
312931
- applyHeightChange(0);
312932
- }
312933
- function installWatcher() {
312934
- if (!_activeSessionId) return;
312935
- try {
312936
- _watcher = fsWatch2(todoDir2(), { persistent: false }, (_evt, fname) => {
312937
- if (!fname || !_activeSessionId) return;
312938
- const expected = `${_activeSessionId.replace(/[^a-zA-Z0-9_.-]/g, "_")}.json`;
312939
- if (fname !== expected) return;
312940
- loadTodos();
312941
- scheduleRedraw();
312942
- });
312943
- } catch {
312944
- }
312945
- }
312946
- function loadTodos() {
312947
- if (!_activeSessionId) {
312948
- _lastTodos = [];
312949
- return;
312950
- }
312951
- try {
312952
- const fp = todoPath2(_activeSessionId);
312953
- if (!existsSync73(fp)) {
312954
- _lastTodos = [];
312955
- return;
312956
- }
312957
- const parsed = JSON.parse(readFileSync57(fp, "utf-8"));
312958
- _lastTodos = Array.isArray(parsed) ? parsed : [];
312959
- } catch {
312960
- _lastTodos = [];
312961
- }
312962
- }
312963
- function scheduleRedraw() {
312964
- if (_redrawScheduled || !_enabled) return;
312965
- _redrawScheduled = true;
312966
- setImmediate(() => {
312967
- _redrawScheduled = false;
312968
- render();
312969
- });
312970
- }
312971
- function computeTargetHeight() {
312972
- if (!_lastTodos || _lastTodos.length === 0) return 0;
312973
- const itemRows = Math.min(_lastTodos.length, MAX_VISIBLE_ROWS - 1);
312974
- return 1 + itemRows;
312975
- }
312976
- function applyHeightChange(nextHeight) {
312977
- const changed = setTasksHeight(nextHeight);
312978
- if (changed) {
312979
- notifyLayoutResize();
312980
- }
312981
- if (_onResizeChange) {
312982
- try {
312983
- _onResizeChange(nextHeight);
312984
- } catch {
312985
- }
312986
- }
312987
- }
312988
- function statusToAnsi(status) {
312989
- switch (status) {
312990
- case "completed":
312991
- return { mark: "◉", color: MUTED_GREEN, box: GREEN };
312992
- case "in_progress":
312993
- return { mark: "◐", color: GOLD, box: GOLD };
312994
- case "blocked":
312995
- return { mark: "◍", color: RED, box: RED };
312996
- default:
312997
- return { mark: "〇", color: GREY, box: GREY };
312998
- }
312999
- }
313000
- function truncate2(s2, max) {
313001
- if (s2.length <= max) return s2.padEnd(max, " ");
313002
- return s2.slice(0, Math.max(0, max - 1)) + "…";
313003
- }
313004
- function render() {
313005
- if (!_enabled) return;
313006
- const target = computeTargetHeight();
313007
- applyHeightChange(target);
313008
- if (target === 0) return;
313009
- const L = layout();
313010
- const cols = Math.max(20, termCols());
313011
- const completed = _lastTodos.filter((t2) => t2.status === "completed").length;
313012
- const total = _lastTodos.length;
313013
- const headerColor = completed === total ? GREEN : GOLD;
313014
- const lines = [];
313015
- const headerText = `tasks ${headerColor}${completed}/${total}${RESET2}${DIM_LABEL} (todo_write)${RESET2}`;
313016
- lines.push(headerText);
313017
- const visible = _lastTodos.slice(0, MAX_VISIBLE_ROWS - 1);
313018
- for (const t2 of visible) {
313019
- const { mark, color } = statusToAnsi(t2.status);
313020
- const contentWidth = Math.max(4, cols - 8);
313021
- const contentText = t2.content + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
313022
- const truncated = truncate2(contentText, contentWidth);
313023
- lines.push(`${color}${mark}${RESET2} ${color}${truncated}${RESET2}`);
313024
- }
313025
- if (_lastTodos.length > visible.length) {
313026
- const more = _lastTodos.length - visible.length;
313027
- lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${RESET2}`;
313028
- }
313029
- let out = HIDE + SAVE;
313030
- for (let i2 = 0; i2 < lines.length; i2++) {
313031
- const row = L.tasksTop + i2;
313032
- if (row > L.tasksBottom) break;
313033
- out += `\x1B[${row};1H${CLEAR_LINE}${BG}${" ".repeat(cols)}\x1B[${row};2H${lines[i2]}${RESET2}`;
313034
- }
313035
- out += RESTORE + SHOW;
313036
- try {
313037
- process.stdout.write(out);
313038
- } catch {
313039
- }
313040
- }
313041
- var _activeSessionId, _watcher, _lastTodos, _enabled, _redrawScheduled, _onResizeChange, MAX_VISIBLE_ROWS, SAVE, RESTORE, HIDE, SHOW, CLEAR_LINE, RESET2, BG, DIM_LABEL, GOLD, GREEN, MUTED_GREEN, GREY, RED;
313042
- var init_tui_tasks_renderer = __esm({
313043
- "packages/cli/src/tui/tui-tasks-renderer.ts"() {
313044
- "use strict";
313045
- init_layout2();
313046
- _activeSessionId = null;
313047
- _watcher = null;
313048
- _lastTodos = [];
313049
- _enabled = true;
313050
- _redrawScheduled = false;
313051
- _onResizeChange = null;
313052
- MAX_VISIBLE_ROWS = 8;
313053
- SAVE = "\x1B[s";
313054
- RESTORE = "\x1B[u";
313055
- HIDE = "\x1B[?25l";
313056
- SHOW = "\x1B[?25h";
313057
- CLEAR_LINE = "\x1B[2K";
313058
- RESET2 = "\x1B[0m";
313059
- BG = "\x1B[48;2;23;23;26m";
313060
- DIM_LABEL = "\x1B[38;2;68;68;68m";
313061
- GOLD = "\x1B[38;2;178;146;10m";
313062
- GREEN = "\x1B[38;2;95;165;95m";
313063
- MUTED_GREEN = "\x1B[38;2;74;122;74m";
313064
- GREY = "\x1B[38;2;102;102;102m";
313065
- RED = "\x1B[38;2;178;95;95m";
313066
- }
313067
- });
313068
-
313069
313208
  // packages/cli/src/tui/mouse-filter.ts
313070
313209
  var mouse_filter_exports = {};
313071
313210
  __export(mouse_filter_exports, {
@@ -326283,6 +326422,12 @@ async function startInteractive(config, repoPath) {
326283
326422
  } catch {
326284
326423
  }
326285
326424
  });
326425
+ statusBar.setOnResizeFinalized(() => {
326426
+ try {
326427
+ refreshTuiTasksSync();
326428
+ } catch {
326429
+ }
326430
+ });
326286
326431
  if (process.stdout.isTTY) {
326287
326432
  const scrollTop = carouselLines > 0 ? carouselLines : 1;
326288
326433
  statusBar.activate(scrollTop);
@@ -326503,8 +326648,18 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
326503
326648
  banner.setFocused(focused);
326504
326649
  banner.renderCurrentFrame();
326505
326650
  });
326506
- const { onOverlayLeave: onOverlayLeave2 } = await Promise.resolve().then(() => (init_overlay_lock(), overlay_lock_exports));
326651
+ const { onOverlayLeave: onOverlayLeave2, onOverlayEnter: onOverlayEnter2 } = await Promise.resolve().then(() => (init_overlay_lock(), overlay_lock_exports));
326652
+ onOverlayEnter2(() => {
326653
+ try {
326654
+ setTuiTasksScope({ overlayActive: true });
326655
+ } catch {
326656
+ }
326657
+ });
326507
326658
  onOverlayLeave2(() => {
326659
+ try {
326660
+ setTuiTasksScope({ overlayActive: false });
326661
+ } catch {
326662
+ }
326508
326663
  statusBar.suspendContentLayer();
326509
326664
  banner.renderCurrentFrame();
326510
326665
  statusBar.resumeContentLayer();
@@ -326513,6 +326668,10 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
326513
326668
  if (statusBar.isActive) {
326514
326669
  statusBar.refreshDisplay();
326515
326670
  }
326671
+ try {
326672
+ refreshTuiTasks();
326673
+ } catch {
326674
+ }
326516
326675
  });
326517
326676
  if (cohereEnabled) {
326518
326677
  statusBar.setCohereActive(true);
@@ -327041,10 +327200,6 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
327041
327200
  process.stdout.on("resize", () => {
327042
327201
  statusBar.handleResize();
327043
327202
  setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
327044
- try {
327045
- refreshTuiTasks();
327046
- } catch {
327047
- }
327048
327203
  if (isNeovimActive()) {
327049
327204
  const contentRows = statusBar.isActive ? statusBar.availableContentRows : Math.max(5, termRows() - 6);
327050
327205
  resizeNeovim(termCols(), contentRows);