omnius 1.0.163 โ†’ 1.0.165

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -570619,8 +570619,8 @@ function layout() {
570619
570619
  const headerContent = 2;
570620
570620
  const headerBottom = hh;
570621
570621
  const contentTop = headerBottom + 1;
570622
- const footerMetrics = rows;
570623
- const footerBoxBottom = footerMetrics - 1;
570622
+ const footerMetrics = _footerMetricsVisible ? rows : -1;
570623
+ const footerBoxBottom = _footerMetricsVisible ? rows - 1 : rows;
570624
570624
  const footerBoxTop = rows - fh + 1;
570625
570625
  const footerInput = footerBoxTop + 1;
570626
570626
  const FOOTER_SPACER_ROWS = 1;
@@ -570653,6 +570653,7 @@ function layout() {
570653
570653
  footerInput,
570654
570654
  footerBoxBottom,
570655
570655
  footerMetrics,
570656
+ footerMetricsVisible: _footerMetricsVisible,
570656
570657
  scrollRegionTop: contentTop,
570657
570658
  scrollRegionBottom: contentBottom,
570658
570659
  footerHeight: fh,
@@ -570664,7 +570665,12 @@ function setTermSize(rows, cols) {
570664
570665
  _termCols = cols;
570665
570666
  }
570666
570667
  function setFooterHeight(height) {
570667
- _footerHeight = Math.max(FOOTER_MIN_ROWS, height);
570668
+ const minRows = _footerMetricsVisible ? FOOTER_MIN_ROWS : FOOTER_NO_METRICS_MIN_ROWS;
570669
+ _footerHeight = Math.max(minRows, height);
570670
+ }
570671
+ function setFooterMetricsVisible(visible) {
570672
+ _footerMetricsVisible = visible;
570673
+ setFooterHeight(_footerHeight);
570668
570674
  }
570669
570675
  function setHeaderHeight(height) {
570670
570676
  _headerHeight = Math.max(1, height);
@@ -570693,17 +570699,19 @@ function notifyLayoutResize() {
570693
570699
  }
570694
570700
  }
570695
570701
  }
570696
- var HEADER_ROWS, FOOTER_MIN_ROWS, CONTENT_SPACER_ROWS, _termRows, _termCols, _footerHeight, _headerHeight, _tasksHeight, _resizeListeners;
570702
+ var HEADER_ROWS, FOOTER_MIN_ROWS, FOOTER_NO_METRICS_MIN_ROWS, CONTENT_SPACER_ROWS, _termRows, _termCols, _footerHeight, _headerHeight, _footerMetricsVisible, _tasksHeight, _resizeListeners;
570697
570703
  var init_layout2 = __esm({
570698
570704
  "packages/cli/src/tui/layout.ts"() {
570699
570705
  "use strict";
570700
570706
  HEADER_ROWS = 3;
570701
570707
  FOOTER_MIN_ROWS = 4;
570708
+ FOOTER_NO_METRICS_MIN_ROWS = 3;
570702
570709
  CONTENT_SPACER_ROWS = 1;
570703
570710
  _termRows = 24;
570704
570711
  _termCols = 80;
570705
570712
  _footerHeight = FOOTER_MIN_ROWS;
570706
570713
  _headerHeight = HEADER_ROWS;
570714
+ _footerMetricsVisible = true;
570707
570715
  _tasksHeight = 0;
570708
570716
  _resizeListeners = [];
570709
570717
  }
@@ -572836,6 +572844,7 @@ __export(render_exports, {
572836
572844
  renderAssistantText: () => renderAssistantText,
572837
572845
  renderCompactHeader: () => renderCompactHeader,
572838
572846
  renderConfig: () => renderConfig,
572847
+ renderContextIntakeBox: () => renderContextIntakeBox,
572839
572848
  renderError: () => renderError,
572840
572849
  renderHeader: () => renderHeader,
572841
572850
  renderImageAsciiPreview: () => renderImageAsciiPreview,
@@ -573247,6 +573256,54 @@ function renderToolDynamicBlock(kind, render2, opts) {
573247
573256
  }
573248
573257
  process.stdout.write(text);
573249
573258
  }
573259
+ function appendContextBoxSection(body, label, value2) {
573260
+ const text = String(value2 ?? "").trim();
573261
+ if (!text) return;
573262
+ if (body.length > 0) body.push({ text: "", mode: "wrap", kind: "plain" });
573263
+ body.push({ text: label, mode: "wrap", kind: "dim" });
573264
+ for (const line of text.split("\n")) {
573265
+ body.push({ text: line, mode: "wrap", kind: "markdown" });
573266
+ }
573267
+ }
573268
+ function appendContextBoxList(body, label, values) {
573269
+ const items = (values ?? []).map((item) => item.trim()).filter(Boolean);
573270
+ if (items.length === 0) return;
573271
+ if (body.length > 0) body.push({ text: "", mode: "wrap", kind: "plain" });
573272
+ body.push({ text: label, mode: "wrap", kind: "dim" });
573273
+ for (const item of items) {
573274
+ body.push({ text: `- ${item}`, mode: "wrap", kind: "markdown" });
573275
+ }
573276
+ }
573277
+ function renderContextIntakeBox(opts) {
573278
+ const body = [];
573279
+ appendContextBoxSection(body, "Added context:", opts.rawText);
573280
+ appendContextBoxSection(body, "Triage:", opts.inference);
573281
+ appendContextBoxSection(body, "Runner instruction:", opts.runnerInstruction);
573282
+ appendContextBoxList(body, "Conflicts:", opts.conflicts);
573283
+ appendContextBoxList(body, "Alternative interpretations:", opts.alternatives);
573284
+ if (body.length === 0) {
573285
+ body.push({
573286
+ text: "No context content recorded.",
573287
+ mode: "wrap",
573288
+ kind: "dim"
573289
+ });
573290
+ }
573291
+ const metrics2 = [
573292
+ ...opts.metadata ?? [],
573293
+ opts.packetId ? `id ${opts.packetId.slice(0, 8)}` : ""
573294
+ ].filter(Boolean).join(" ยท ");
573295
+ renderToolDynamicBlock(
573296
+ "tool-result",
573297
+ (width) => buildToolBoxLines({
573298
+ title: opts.title,
573299
+ metrics: metrics2,
573300
+ body,
573301
+ colorCode: 226,
573302
+ metricsColorCode: 222
573303
+ }, width),
573304
+ opts.host === void 0 ? {} : { host: opts.host }
573305
+ );
573306
+ }
573250
573307
  function buildToolCallBoxLines(toolName, args, verbose, width) {
573251
573308
  const icon = _emojisEnabled ? `${TOOL_ICONS[toolName] ?? "๐Ÿ”ง"} ` : "";
573252
573309
  const label = TOOL_LABELS[toolName] ?? toolName;
@@ -582641,11 +582698,13 @@ var init_status_bar = __esm({
582641
582698
  stdinHooked = false;
582642
582699
  /** COHERE distributed cognitive commons active flag */
582643
582700
  _cohereActive = false;
582644
- /** Mouse tracking state โ€” on during activity for scroll + drag selection. Use ?1002h for button-event (drag) tracking so app-level TextSelection can highlight during drag. */
582645
- _mouseTrackingEnabled = true;
582646
- /** True while the user is actively press-dragging in the content region; freezes auto-scroll so selection sticks. */
582701
+ /** Mouse tracking state for header buttons + scroll wheel. */
582702
+ _mouseTrackingEnabled = false;
582703
+ /** Enabled automatically once MouseFilterStream is installed; /mouse off is an emergency escape hatch. */
582704
+ _mouseTrackingPreferred = false;
582705
+ /** Legacy keyboard-selection guard; mouse drag selection is terminal-native. */
582647
582706
  _mouseSelecting = false;
582648
- /** Text selection state โ€” tracks click-drag selection for copy */
582707
+ /** Text selection state for keyboard/explicit copy paths; mouse drag is not owned by the TUI. */
582649
582708
  _textSelection = new TextSelection({
582650
582709
  getContentLines: () => this._contentLines,
582651
582710
  getScrollOffset: () => this._contentScrollOffset,
@@ -582803,9 +582862,11 @@ var init_status_bar = __esm({
582803
582862
  _brailleSpinner = new BrailleSpinner();
582804
582863
  /** Slow refresh timer for monitoring bar when braille spinner is off */
582805
582864
  _monitorTimer = null;
582806
- /** Current dynamic footer height (min 5: buffer + topSep + 1 input line + bottomSep + metrics) */
582865
+ /** Current dynamic footer height: box top + input rows + box bottom + optional metrics. */
582807
582866
  _currentFooterHeight = 4;
582808
582867
  // box-top(1) + input(1) + box-bottom(1) + metrics(1)
582868
+ /** Whether the bottom metrics row is visible. Ctrl+I toggles this. */
582869
+ _footerMetricsVisible = true;
582809
582870
  /** Timestamp when streaming started (for token rate calculation) */
582810
582871
  _streamStartTime = 0;
582811
582872
  /** Current package version (shown in metrics row, rightmost) */
@@ -583921,6 +583982,7 @@ var init_status_bar = __esm({
583921
583982
  });
583922
583983
  }
583923
583984
  setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
583985
+ setFooterMetricsVisible(this._footerMetricsVisible);
583924
583986
  this._prevTermRows = termRows();
583925
583987
  this._prevTermCols = termCols();
583926
583988
  this.applyScrollRegion(true);
@@ -584171,6 +584233,23 @@ var init_status_bar = __esm({
584171
584233
  this.renderFooterAndPositionInput();
584172
584234
  }
584173
584235
  }
584236
+ toggleFooterMetrics() {
584237
+ this.setFooterMetricsVisible(!this._footerMetricsVisible);
584238
+ return this._footerMetricsVisible;
584239
+ }
584240
+ setFooterMetricsVisible(visible) {
584241
+ if (this._footerMetricsVisible === visible) return;
584242
+ this._footerMetricsVisible = visible;
584243
+ setFooterMetricsVisible(visible);
584244
+ if (!this.active) {
584245
+ this.updateFooterHeight();
584246
+ return;
584247
+ }
584248
+ this.renderFooterAndPositionInput(true);
584249
+ }
584250
+ isFooterMetricsVisible() {
584251
+ return this._footerMetricsVisible;
584252
+ }
584174
584253
  /** Set/get COHERE participation state โ€” shows ๐ŸŒ in metrics when active */
584175
584254
  setCohereActive(active) {
584176
584255
  this._cohereActive = active;
@@ -584180,12 +584259,11 @@ var init_status_bar = __esm({
584180
584259
  return this._cohereActive;
584181
584260
  }
584182
584261
  // โ”€โ”€ Mouse tracking management โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
584183
- // TUI uses ?1002h (button-event tracking) so the app receives drag events and
584184
- // can highlight in-app TextSelection during click-drag. The highlight survives
584185
- // redraws because repaintContent() re-applies it. Native terminal selection
584186
- // (which gets cleared on every redraw) is not relied upon.
584187
- // Neovim mode also uses ?1002h for mouse=a drag support.
584188
- // All mode transitions check neovim focus to avoid conflicts.
584262
+ // Mouse reporting is required for header buttons and scroll-wheel routing.
584263
+ // Use click-only reporting (?1000h) instead of drag-motion reporting (?1002h)
584264
+ // so Omnius does not own click-drag selection or paint fake highlights while
584265
+ // tokens are streaming. Overlay/select UIs may temporarily suspend mouse mode
584266
+ // and then call restoreMouseTracking() on return.
584189
584267
  /** Callback to check if neovim has focus (set by interactive.ts to avoid circular import) */
584190
584268
  _isNeovimFocused = null;
584191
584269
  /** Register neovim focus checker โ€” called from interactive.ts after neovim-mode imports */
@@ -584196,27 +584274,38 @@ var init_status_bar = __esm({
584196
584274
  isMouseTrackingEnabled() {
584197
584275
  return this._mouseTrackingEnabled;
584198
584276
  }
584199
- /** Enable mouse tracking โ€” respects neovim focus state */
584277
+ /** Enable mouse tracking for header buttons + scroll wheel. */
584200
584278
  enableMouseTracking() {
584279
+ this._mouseTrackingPreferred = true;
584280
+ this.restoreMouseTracking();
584281
+ }
584282
+ /** Temporarily turn off terminal mouse reporting without changing user preference. */
584283
+ suspendMouseTracking() {
584284
+ if (!this._mouseTrackingEnabled) return;
584285
+ this._mouseTrackingEnabled = false;
584286
+ if (process.stdout.isTTY) {
584287
+ this._trueStdoutWrite.call(process.stdout, "\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?1015l");
584288
+ }
584289
+ }
584290
+ /** Re-apply the current mouse preference after overlays, password prompts, or redraws. */
584291
+ restoreMouseTracking() {
584292
+ if (!this._mouseTrackingPreferred) {
584293
+ this.suspendMouseTracking();
584294
+ return;
584295
+ }
584201
584296
  if (this._mouseTrackingEnabled || isOverlayActive()) return;
584202
584297
  if (this._isNeovimFocused?.()) return;
584203
584298
  this._mouseTrackingEnabled = true;
584204
584299
  if (process.stdout.isTTY) {
584205
- this._trueStdoutWrite.call(process.stdout, "\x1B[?1002h\x1B[?1006h");
584300
+ this._trueStdoutWrite.call(process.stdout, "\x1B[?1000h\x1B[?1006h");
584206
584301
  }
584207
584302
  }
584208
584303
  /** Disable mouse tracking entirely (overlay transitions + exit). */
584209
584304
  disableMouseTracking() {
584210
- if (!this._mouseTrackingEnabled || isOverlayActive()) return;
584211
- this._mouseTrackingEnabled = false;
584212
- if (process.stdout.isTTY) {
584213
- this._trueStdoutWrite.call(process.stdout, "\x1B[?1002l\x1B[?1006l");
584214
- }
584305
+ this._mouseTrackingPreferred = false;
584306
+ this.suspendMouseTracking();
584215
584307
  }
584216
- /** Schedule mouse tracking disable after idle timeout โ€” currently a no-op
584217
- * because mouse tracking stays active at all times. Disabling tracking would
584218
- * break scroll wheel and in-app selection highlighting. */
584219
- /** Cancel mouse idle timer (user is actively scrolling or streaming started) */
584308
+ /** Cancel mouse idle timer (legacy hook; mouse tracking is preference-driven). */
584220
584309
  cancelMouseIdle() {
584221
584310
  }
584222
584311
  // โ”€โ”€ Text Selection + Header Buttons โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
@@ -584235,7 +584324,8 @@ var init_status_bar = __esm({
584235
584324
  /**
584236
584325
  * Handle a mouse pointer event (press/drag/release).
584237
584326
  * Called by MouseFilterStream's pointer handler.
584238
- * Routes to: header button clicks, text selection, or ignored.
584327
+ * Routes to header/footer/tab clicks and scroll affordances. Content-area
584328
+ * drag selection is deliberately left to the terminal.
584239
584329
  */
584240
584330
  handlePointerEvent(type, col, row) {
584241
584331
  if (!this.active) return;
@@ -584313,26 +584403,7 @@ var init_status_bar = __esm({
584313
584403
  const L = layout();
584314
584404
  const inContent = row >= this.scrollRegionTop && row <= L.contentBottom;
584315
584405
  if (inContent) {
584316
- if (type === "press") {
584317
- this._mouseSelecting = true;
584318
- this._autoScroll = false;
584319
- this._textSelection.onMousePress(row, col);
584320
- return;
584321
- }
584322
- if (type === "drag") {
584323
- this._textSelection.onMouseDrag(row, col);
584324
- this.repaintContent();
584325
- return;
584326
- }
584327
- if (type === "release") {
584328
- this._mouseSelecting = false;
584329
- this._textSelection.onMouseRelease(row, col);
584330
- if (this._textSelection.hasSelection) {
584331
- this._textSelection.copyToClipboard();
584332
- this.repaintContent();
584333
- }
584334
- return;
584335
- }
584406
+ return;
584336
584407
  }
584337
584408
  }
584338
584409
  /** Copy current selection to clipboard. Returns true if copied. */
@@ -584343,7 +584414,8 @@ var init_status_bar = __esm({
584343
584414
  this.repaintContent();
584344
584415
  const pos = this.rowPositions(termRows());
584345
584416
  const writer = this._origWrite ?? process.stdout.write.bind(process.stdout);
584346
- if (ok3) {
584417
+ if (pos.metricsRow <= 0) {
584418
+ } else if (ok3) {
584347
584419
  writer(
584348
584420
  `\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;${TEXT_PRIMARY}m โœ“ Copied to clipboard\x1B[0m`
584349
584421
  );
@@ -584365,9 +584437,11 @@ var init_status_bar = __esm({
584365
584437
  this._textSelection.armBlockMode();
584366
584438
  const pos = this.rowPositions(termRows());
584367
584439
  const writer = this._origWrite ?? process.stdout.write.bind(process.stdout);
584368
- writer(
584369
- `\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;${TEXT_PRIMARY}m โ–  Block selection mode โ€” click and drag\x1B[0m`
584370
- );
584440
+ if (pos.metricsRow > 0) {
584441
+ writer(
584442
+ `\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;${TEXT_PRIMARY}m โ–  Block selection mode โ€” click and drag\x1B[0m`
584443
+ );
584444
+ }
584371
584445
  setTimeout(() => {
584372
584446
  if (this.active) this.renderFooterAndPositionInput();
584373
584447
  }, 1500);
@@ -584600,7 +584674,10 @@ var init_status_bar = __esm({
584600
584674
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
584601
584675
  }
584602
584676
  buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerP))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
584603
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}\x1B[?7h\x1B[${pos.inputStartRow + 1};1H`;
584677
+ if (pos.metricsRow > 0) {
584678
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
584679
+ }
584680
+ buf += `\x1B[?7h\x1B[${pos.inputStartRow + 1};1H`;
584604
584681
  this.termWrite(buf);
584605
584682
  this.rememberFooterPaint(pos.inputStartRow);
584606
584683
  if (this._bannerRefresh) this._bannerRefresh();
@@ -584739,7 +584816,7 @@ var init_status_bar = __esm({
584739
584816
  setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
584740
584817
  setFooterHeight(this._currentFooterHeight);
584741
584818
  this.cancelMouseIdle();
584742
- this.enableMouseTracking();
584819
+ this.restoreMouseTracking();
584743
584820
  const L = layout();
584744
584821
  const scrollEnd = L.scrollRegionBottom;
584745
584822
  if (this.writeDepth === 1 && !this._origWrite) {
@@ -585119,7 +585196,7 @@ ${CONTENT_BG_SEQ}`);
585119
585196
  scrollContentUp(lines = 1) {
585120
585197
  if (!this.active) return;
585121
585198
  this.cancelMouseIdle();
585122
- this.enableMouseTracking();
585199
+ this.restoreMouseTracking();
585123
585200
  this._autoScroll = false;
585124
585201
  const maxOffset = this.maxContentScrollOffset();
585125
585202
  this._contentScrollOffset = Math.min(
@@ -585133,7 +585210,7 @@ ${CONTENT_BG_SEQ}`);
585133
585210
  scrollContentDown(lines = 1) {
585134
585211
  if (!this.active) return;
585135
585212
  this.cancelMouseIdle();
585136
- this.enableMouseTracking();
585213
+ this.restoreMouseTracking();
585137
585214
  this._contentScrollOffset = Math.min(
585138
585215
  this.maxContentScrollOffset(),
585139
585216
  Math.max(0, this._contentScrollOffset - lines)
@@ -585730,7 +585807,8 @@ ${CONTENT_BG_SEQ}`);
585730
585807
  this._updateSuggestions();
585731
585808
  const inputLines = this.computeInputLineCount(termWidth);
585732
585809
  const suggestionRows = this._suggestions.length > 0 ? this._suggestions.length + 1 : 1;
585733
- const newHeight = 1 + 1 + inputLines + suggestionRows;
585810
+ const metricsRows = this._footerMetricsVisible ? 1 : 0;
585811
+ const newHeight = metricsRows + 1 + inputLines + suggestionRows;
585734
585812
  if (newHeight !== this._currentFooterHeight) {
585735
585813
  this._currentFooterHeight = newHeight;
585736
585814
  setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
@@ -585744,7 +585822,8 @@ ${CONTENT_BG_SEQ}`);
585744
585822
  this._updateSuggestions();
585745
585823
  const inputLines = this.computeInputLineCount(termWidth);
585746
585824
  const suggestionRows = this._suggestions.length > 0 ? this._suggestions.length + 1 : 1;
585747
- return 1 + 1 + inputLines + suggestionRows !== this._currentFooterHeight;
585825
+ const metricsRows = this._footerMetricsVisible ? 1 : 0;
585826
+ return metricsRows + 1 + inputLines + suggestionRows !== this._currentFooterHeight;
585748
585827
  }
585749
585828
  /** Compute absolute row positions for all footer elements.
585750
585829
  * DELEGATES TO layout() โ€” the centralized layout manager.
@@ -585928,7 +586007,9 @@ ${CONTENT_BG_SEQ}`);
585928
586007
  } else {
585929
586008
  buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInner))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
585930
586009
  }
585931
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
586010
+ if (pos.metricsRow > 0) {
586011
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
586012
+ }
585932
586013
  buf += "\x1B[?7h";
585933
586014
  if (this.writeDepth === 0) {
585934
586015
  buf += `\x1B[${cursorTermRow};${inputWrap.cursorCol}H${CURSOR_BLINK_BLOCK}\x1B[?25h`;
@@ -585979,7 +586060,10 @@ ${CONTENT_BG_SEQ}`);
585979
586060
  } else {
585980
586061
  buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerR))}${BOX_BR3}${RESET4}`;
585981
586062
  }
585982
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}\x1B[?7h\x1B8` + // DEC restore cursor
586063
+ if (pos.metricsRow > 0) {
586064
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
586065
+ }
586066
+ buf += "\x1B[?7h\x1B8" + // DEC restore cursor
585983
586067
  (this.writeDepth === 0 ? `${CURSOR_BLINK_BLOCK}\x1B[?25h` : "");
585984
586068
  this.termWrite(buf);
585985
586069
  this.rememberFooterPaint(pos.inputStartRow);
@@ -586046,7 +586130,9 @@ ${CONTENT_BG_SEQ}`);
586046
586130
  }
586047
586131
  const boxInnerS = w - 2;
586048
586132
  buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerS))}${BOX_BR3}${RESET4}`;
586049
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}`;
586133
+ if (pos.metricsRow > 0) {
586134
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}`;
586135
+ }
586050
586136
  buf += "\x1B[?7h";
586051
586137
  buf += "\x1B8";
586052
586138
  if (heightDelta > 0) {
@@ -586085,7 +586171,9 @@ ${CONTENT_BG_SEQ}`);
586085
586171
  }
586086
586172
  }
586087
586173
  buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerH))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
586088
- buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
586174
+ if (pos.metricsRow > 0) {
586175
+ buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
586176
+ }
586089
586177
  buf += "\x1B[?7h\x1B8\x1B[?25l";
586090
586178
  this.termWrite(buf);
586091
586179
  this.rememberFooterPaint(pos.inputStartRow);
@@ -586288,6 +586376,7 @@ ${CONTENT_BG_SEQ}`);
586288
586376
  if (onEscape) di.on("escape", () => onEscape());
586289
586377
  if (onCtrlO) di.on("ctrl-o", () => onCtrlO());
586290
586378
  if (onCtrlL) di.on("ctrl-l", () => onCtrlL());
586379
+ di.on("ctrl-i", () => self2.toggleFooterMetrics());
586291
586380
  di.on("pageup", () => self2.pageUpContent());
586292
586381
  di.on("pagedown", () => self2.pageDownContent());
586293
586382
  di.on("shiftup", () => self2.scrollContentUp(3));
@@ -599470,7 +599559,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
599470
599559
  }
599471
599560
  }
599472
599561
  if (process.stdout.isTTY) {
599473
- process.stdout.write("\x1B[?1002h\x1B[?1006h");
599562
+ process.stdout.write("\x1B[?1000h\x1B[?1006h");
599474
599563
  }
599475
599564
  if (process.stdout.isTTY) {
599476
599565
  process.stdout.write("\x1B[?1003l");
@@ -600703,9 +600792,9 @@ ${reason}
600703
600792
  try {
600704
600793
  if (hadMouse) {
600705
600794
  ctx3.enableMouse?.();
600706
- writeDirectTerminal("\x1B[?1002h\x1B[?1006h");
600795
+ writeDirectTerminal("\x1B[?1000h\x1B[?1006h");
600707
600796
  } else {
600708
- writeDirectTerminal("\x1B[?1002l\x1B[?1006l");
600797
+ writeDirectTerminal("\x1B[?1000l\x1B[?1002l\x1B[?1006l");
600709
600798
  }
600710
600799
  } catch {
600711
600800
  }
@@ -603854,14 +603943,14 @@ Clone a new voice: /voice clone <wav-file> [name]`);
603854
603943
  if (t2 === "off" || t2 === "0" || t2 === "false" || t2 === "no") {
603855
603944
  ctx3.disableMouse?.();
603856
603945
  renderInfo(
603857
- "Mouse tracking: off โ€” click-drag to select text natively. Re-enable with /mouse on."
603946
+ "Mouse tracking: off โ€” app header buttons and scroll wheel are paused. Re-enable with /mouse on."
603858
603947
  );
603859
603948
  return "handled";
603860
603949
  }
603861
603950
  if (t2 === "on" || t2 === "1" || t2 === "true" || t2 === "yes") {
603862
603951
  ctx3.enableMouse?.();
603863
603952
  renderInfo(
603864
- "Mouse tracking: on โ€” header buttons + scroll wheel active. Disable with /mouse off for native text selection."
603953
+ "Mouse tracking: on โ€” header buttons + scroll wheel active; drag-motion capture remains disabled."
603865
603954
  );
603866
603955
  return "handled";
603867
603956
  }
@@ -603872,7 +603961,7 @@ Clone a new voice: /voice clone <wav-file> [name]`);
603872
603961
  if (isOnNow) {
603873
603962
  ctx3.disableMouse?.();
603874
603963
  renderInfo(
603875
- "Mouse tracking: off โ€” click-drag to select text natively. Re-enable with /mouse on."
603964
+ "Mouse tracking: off โ€” app header buttons and scroll wheel are paused. Re-enable with /mouse on."
603876
603965
  );
603877
603966
  } else {
603878
603967
  ctx3.enableMouse?.();
@@ -613902,7 +613991,7 @@ async function showExposeDashboard(gateway, rl, ctx3) {
613902
613991
  stopped = true;
613903
613992
  process.stdin.removeListener("data", onData);
613904
613993
  if (process.stdout.isTTY) {
613905
- process.stdout.write("\x1B[?1002h\x1B[?1006h");
613994
+ process.stdout.write("\x1B[?1000h\x1B[?1006h");
613906
613995
  }
613907
613996
  };
613908
613997
  const origResolve = resolve57;
@@ -638988,7 +639077,6 @@ var init_mouse_filter = __esm({
638988
639077
  const hasShift = (btn & 4) !== 0 && btn < 32;
638989
639078
  if (btn === 2) {
638990
639079
  } else if (hasShift) {
638991
- process.stdout.write("\x1B[?1002l\x1B[?1006l");
638992
639080
  } else if ((btn === 0 || btn === 1) && suffix === "M") {
638993
639081
  this.onPointer("press", col, row);
638994
639082
  } else if (btn >= 32 && btn <= 35 && suffix === "M") {
@@ -639459,6 +639547,10 @@ var init_direct_input = __esm({
639459
639547
  return;
639460
639548
  }
639461
639549
  }
639550
+ if (hasCtrl && !hasShift && (codepoint === 73 || codepoint === 105)) {
639551
+ this.emit("ctrl-i");
639552
+ return;
639553
+ }
639462
639554
  return;
639463
639555
  }
639464
639556
  }
@@ -639570,7 +639662,7 @@ var init_direct_input = __esm({
639570
639662
  /** Handle Tab completion */
639571
639663
  _handleTab() {
639572
639664
  if (this.line.length === 0) {
639573
- this.emit("tab-empty");
639665
+ this.emit("ctrl-i");
639574
639666
  return;
639575
639667
  }
639576
639668
  if (!this._completer) return;
@@ -664269,6 +664361,70 @@ async function createSteeringIntakeBackend(config, repoRoot) {
664269
664361
  false
664270
664362
  );
664271
664363
  }
664364
+ function formatTaskCompletionMeta(meta) {
664365
+ if (!meta) return "no prior task metrics recorded";
664366
+ const dur = meta.durationMs < 6e4 ? `${(meta.durationMs / 1e3).toFixed(1)}s` : `${Math.floor(meta.durationMs / 6e4)}m ${Math.floor(meta.durationMs % 6e4 / 1e3)}s`;
664367
+ return `${meta.turns} turns, ${meta.toolCalls} tool calls, ${dur}, ${meta.model}`;
664368
+ }
664369
+ function buildNewTaskIntakePacket(ingress, interpretation, previousPrompt, previousSummary, previousMeta) {
664370
+ const lines = [
664371
+ "[NEW_TASK_INTAKE v1]",
664372
+ `id: ${ingress.id}`,
664373
+ `sourceSurface: ${ingress.sourceSurface}`,
664374
+ `feedbackKind: next_user_task`,
664375
+ `authority: ${ingress.authority}`,
664376
+ `timestamp: ${ingress.timestamp}`,
664377
+ "",
664378
+ "Instruction hierarchy:",
664379
+ "- Treat this as user-level task intent, below system/developer/tool safety and above older task assumptions when they conflict.",
664380
+ "",
664381
+ "Previous task prompt:",
664382
+ previousPrompt.trim() || "(not recorded)",
664383
+ "",
664384
+ "Previous task completion:",
664385
+ previousSummary.trim() || "(not recorded)",
664386
+ "",
664387
+ "Previous task metrics:",
664388
+ formatTaskCompletionMeta(previousMeta),
664389
+ "",
664390
+ "New task:",
664391
+ ingress.rawText,
664392
+ ""
664393
+ ];
664394
+ if (interpretation) {
664395
+ lines.push(
664396
+ "Model-derived task transition assessment:",
664397
+ `inference: ${interpretation.inference}`,
664398
+ `runnerInstruction: ${interpretation.runnerInstruction}`
664399
+ );
664400
+ if (interpretation.conflicts?.length) {
664401
+ lines.push(
664402
+ "conflicts:",
664403
+ ...interpretation.conflicts.map((item) => `- ${item}`)
664404
+ );
664405
+ }
664406
+ if (interpretation.alternatives?.length) {
664407
+ lines.push(
664408
+ "alternative interpretations:",
664409
+ ...interpretation.alternatives.map((item) => `- ${item}`)
664410
+ );
664411
+ }
664412
+ if (interpretation.memoryNote) {
664413
+ lines.push(`memoryNote: ${interpretation.memoryNote}`);
664414
+ }
664415
+ lines.push("");
664416
+ } else {
664417
+ lines.push("Model-derived task transition assessment: unavailable", "");
664418
+ }
664419
+ lines.push(
664420
+ "Interleave contract:",
664421
+ "- Consume this before the first assistant/tool decision for the new task.",
664422
+ "- Decide whether the new task continues, corrects, or pivots away from the previous task.",
664423
+ "- Use the new task as the active objective; prior-task context is only relevant when it changes the next action.",
664424
+ "[/NEW_TASK_INTAKE]"
664425
+ );
664426
+ return lines.join("\n");
664427
+ }
664272
664428
  function createDMNEventHandler(verbose, writeContent) {
664273
664429
  return (event) => {
664274
664430
  switch (event.type) {
@@ -666590,7 +666746,7 @@ async function startInteractive(config, repoPath) {
666590
666746
  tuiBgSeq() + // theme bg for content area
666591
666747
  `\x1B[2J\x1B[3J\x1B[H\x1B[1;${termRows()}r\x1B[?25l`
666592
666748
  // hide cursor during setup
666593
- // NOTE: mouse tracking (?1002h ?1006h) is deferred until AFTER setup
666749
+ // NOTE: mouse tracking (?1000h ?1006h) is deferred until AFTER setup
666594
666750
  // wizard completes and MouseFilterStream is created. Enabling mouse
666595
666751
  // here would leak SGR coordinate sequences into readline prompts.
666596
666752
  );
@@ -667631,6 +667787,7 @@ This is an independent background session started from /background.`
667631
667787
  let lastSteeringRetracted = false;
667632
667788
  let _recallText = null;
667633
667789
  let _recallTimer = null;
667790
+ let promptRecallCancelled = false;
667634
667791
  const RECALL_WINDOW_MS = 1500;
667635
667792
  let sessionSudoPassword = null;
667636
667793
  let sudoPromptPending = false;
@@ -667828,12 +667985,7 @@ This is an independent background session started from /background.`
667828
667985
  if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
667829
667986
  process.stdin.setRawMode(true);
667830
667987
  }
667831
- if (process.stdout.isTTY) {
667832
- process.stdout.write(
667833
- "\x1B[?1002h\x1B[?1006h"
667834
- // enable SGR mouse mode
667835
- );
667836
- }
667988
+ statusBar.enableMouseTracking();
667837
667989
  function persistHistoryLine(line) {
667838
667990
  if (!line.trim()) return;
667839
667991
  try {
@@ -668436,9 +668588,7 @@ Log: ${nexusLogPath}`)
668436
668588
  return;
668437
668589
  }
668438
668590
  sudoPromptPending = true;
668439
- if (process.stdout.isTTY) {
668440
- process.stdout.write("\x1B[?1000l\x1B[?1002l\x1B[?1006l");
668441
- }
668591
+ statusBar.suspendMouseTracking();
668442
668592
  writeContent(() => {
668443
668593
  process.stdout.write(
668444
668594
  `
@@ -670943,9 +671093,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
670943
671093
  passwordShowPlain = false;
670944
671094
  sessionSudoPassword = input;
670945
671095
  activeTask.runner.setSudoPassword(input);
670946
- if (process.stdout.isTTY) {
670947
- process.stdout.write("\x1B[?1002h\x1B[?1006h");
670948
- }
671096
+ statusBar.enableMouseTracking();
670949
671097
  statusBar.setInputStateProvider(() => ({
670950
671098
  line: rl.line ?? "",
670951
671099
  cursor: rl.cursor ?? 0
@@ -671188,8 +671336,26 @@ ${result.text}`;
671188
671336
  injected: true,
671189
671337
  rawOnly: interpretation === null
671190
671338
  });
671339
+ const activeToolCallCount = activeTask.toolCallCount;
671340
+ const activeFilesTouchedCount = activeTask.filesTouched.size;
671341
+ writeContent(
671342
+ () => renderContextIntakeBox({
671343
+ title: isReplacement ? "Context Intake (replacement)" : "Context Intake",
671344
+ rawText: input,
671345
+ inference: interpretation?.inference,
671346
+ runnerInstruction: interpretation?.runnerInstruction,
671347
+ conflicts: interpretation?.conflicts,
671348
+ alternatives: interpretation?.alternatives,
671349
+ packetId: ingress.id,
671350
+ metadata: [
671351
+ "mid-task",
671352
+ `${activeToolCallCount} calls`,
671353
+ `${activeFilesTouchedCount} files`,
671354
+ interpretation ? "triaged" : "raw"
671355
+ ]
671356
+ })
671357
+ );
671191
671358
  if (interpretation?.inference) {
671192
- writeContent(() => renderSteeringIntake(interpretation.inference));
671193
671359
  if (voiceEngine.enabled && voiceEngine.voiceMode === "verbose") {
671194
671360
  const emoState = emotionEngine.getState();
671195
671361
  const emoCtx = emoState ? {
@@ -671353,12 +671519,82 @@ Summarize or analyze this transcription as appropriate.`;
671353
671519
  const inputLineCount = fullInput.split("\n").length;
671354
671520
  const displayText = isImage ? `[Image: ${cleanPath}]` : inputLineCount > 1 ? `[pasted ${inputLineCount} lines]` : fullInput;
671355
671521
  writeContent(() => renderUserMessage(displayText));
671522
+ promptRecallCancelled = false;
671356
671523
  _recallText = input;
671357
671524
  if (_recallTimer) clearTimeout(_recallTimer);
671358
671525
  _recallTimer = setTimeout(() => {
671359
671526
  _recallText = null;
671360
671527
  _recallTimer = null;
671361
671528
  }, RECALL_WINDOW_MS);
671529
+ const previousPromptForIntake = lastSubmittedPrompt;
671530
+ const previousSummaryForIntake = lastCompletedSummary;
671531
+ const previousMetaForIntake = lastTaskMeta;
671532
+ let taskIntakePacket = "";
671533
+ if (previousSummaryForIntake.trim()) {
671534
+ const priorContext = [
671535
+ previousPromptForIntake.trim() ? `Previous task prompt:
671536
+ ${previousPromptForIntake.trim()}` : "",
671537
+ `Previous task completion:
671538
+ ${previousSummaryForIntake.trim()}`,
671539
+ `Previous task metrics:
671540
+ ${formatTaskCompletionMeta(previousMetaForIntake)}`
671541
+ ].filter(Boolean).join("\n\n");
671542
+ const ingress = createSteeringIngress({
671543
+ rawText: fullInput,
671544
+ sourceSurface: "tui",
671545
+ currentTaskGoal: priorContext,
671546
+ recentActivity: previousMetaForIntake ? formatTaskCompletionMeta(previousMetaForIntake) : void 0,
671547
+ filesTouched: sessionFilesTouched,
671548
+ toolCallCount: previousMetaForIntake?.toolCalls ?? sessionToolCallCount
671549
+ });
671550
+ let interpretation = null;
671551
+ try {
671552
+ const intakeBackend = await createSteeringIntakeBackend(
671553
+ currentConfig,
671554
+ repoRoot
671555
+ );
671556
+ interpretation = await interpretSteeringIngress(
671557
+ intakeBackend,
671558
+ ingress,
671559
+ Math.min(currentConfig.timeoutMs || 15e3, 15e3)
671560
+ );
671561
+ } catch {
671562
+ interpretation = null;
671563
+ }
671564
+ taskIntakePacket = buildNewTaskIntakePacket(
671565
+ ingress,
671566
+ interpretation,
671567
+ previousPromptForIntake,
671568
+ previousSummaryForIntake,
671569
+ previousMetaForIntake
671570
+ );
671571
+ appendSteeringLedgerEntry(repoRoot, {
671572
+ type: "ingress",
671573
+ packetId: ingress.id,
671574
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
671575
+ ingress,
671576
+ interpretation,
671577
+ injected: true,
671578
+ rawOnly: interpretation === null
671579
+ });
671580
+ writeContent(
671581
+ () => renderContextIntakeBox({
671582
+ title: "Task Intake",
671583
+ rawText: fullInput,
671584
+ inference: interpretation?.inference,
671585
+ runnerInstruction: interpretation?.runnerInstruction,
671586
+ conflicts: interpretation?.conflicts,
671587
+ alternatives: interpretation?.alternatives,
671588
+ packetId: ingress.id,
671589
+ metadata: [
671590
+ "new task",
671591
+ previousMetaForIntake ? `${previousMetaForIntake.toolCalls} prior calls` : "prior task",
671592
+ interpretation ? "triaged" : "raw"
671593
+ ]
671594
+ })
671595
+ );
671596
+ }
671597
+ if (promptRecallCancelled) return;
671362
671598
  lastSubmittedPrompt = fullInput;
671363
671599
  const taskPreview = fullInput.length > 100 ? fullInput.slice(0, 100) + "..." : fullInput;
671364
671600
  emotionEngine.setCurrentTask(taskPreview);
@@ -671383,6 +671619,13 @@ Summarize or analyze this transcription as appropriate.`;
671383
671619
  NEW TASK: ${fullInput}`;
671384
671620
  restoredSessionContext = null;
671385
671621
  }
671622
+ if (taskIntakePacket) {
671623
+ taskInput = `${taskIntakePacket}
671624
+
671625
+ ---
671626
+
671627
+ ${taskInput}`;
671628
+ }
671386
671629
  try {
671387
671630
  statusBar.setProcessing(true);
671388
671631
  statusBar.recordSpeedTaskStart();
@@ -671691,6 +671934,7 @@ ${c3.dim("(Use /quit to exit)")}
671691
671934
  if (_recallText !== null) {
671692
671935
  const recalled = _recallText;
671693
671936
  _recallText = null;
671937
+ promptRecallCancelled = true;
671694
671938
  if (_recallTimer) {
671695
671939
  clearTimeout(_recallTimer);
671696
671940
  _recallTimer = null;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.163",
3
+ "version": "1.0.165",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.163",
9
+ "version": "1.0.165",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.163",
3
+ "version": "1.0.165",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) โ€” interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",