open-agents-ai 0.138.83 → 0.138.85

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 +158 -41
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -37878,7 +37878,8 @@ function tuiSelect(opts) {
37878
37878
  }
37879
37879
  stdin.resume();
37880
37880
  enterOverlay();
37881
- overlayWrite("\x1B[?1049h\x1B[48;5;234m\x1B[2J\x1B[H\x1B[?25l");
37881
+ overlayWrite("\x1B[?1049h\x1B[48;5;234m\x1B[2J\x1B[H\x1B[?25l\x1B[?1002h\x1B[?1006h");
37882
+ let listRowOffset = 0;
37882
37883
  function clampScroll(displayList) {
37883
37884
  const cursorPos = displayList.indexOf(cursor);
37884
37885
  if (cursorPos < 0)
@@ -37891,12 +37892,17 @@ function tuiSelect(opts) {
37891
37892
  const maxOffset = Math.max(0, displayList.length - maxVisible);
37892
37893
  scrollOffset = Math.max(0, Math.min(maxOffset, scrollOffset));
37893
37894
  }
37895
+ const hasBreadcrumbs = opts.breadcrumbs && opts.breadcrumbs.length > 0;
37894
37896
  function render() {
37895
37897
  overlayWrite("\x1B[48;5;234m\x1B[H\x1B[2J");
37896
37898
  const lines = [];
37897
- if (title) {
37899
+ if (hasBreadcrumbs) {
37900
+ const trail = opts.breadcrumbs.map((b) => selectColors.dim(b)).join(selectColors.dim(" \u203A "));
37898
37901
  lines.push(`
37899
- ${selectColors.bold(title)}`);
37902
+ ${selectColors.cyan("\u2190")} ${trail}`);
37903
+ }
37904
+ if (title) {
37905
+ lines.push(`${hasBreadcrumbs ? "" : "\n"} ${selectColors.bold(title)}`);
37900
37906
  }
37901
37907
  if (filter) {
37902
37908
  const count = matchSet.size;
@@ -37932,6 +37938,7 @@ function tuiSelect(opts) {
37932
37938
  if (visibleStart > 0) {
37933
37939
  lines.push(` ${selectColors.dim(` \u25B2 ${visibleStart} more`)}`);
37934
37940
  }
37941
+ listRowOffset = lines.length;
37935
37942
  for (let vi = visibleStart; vi < visibleEnd; vi++) {
37936
37943
  const idx = displayList[vi];
37937
37944
  const item = items[idx];
@@ -37962,17 +37969,18 @@ function tuiSelect(opts) {
37962
37969
  const actionHint = opts.onAction ? " \u2190/\u2192/Space toggle" : "";
37963
37970
  const deleteHint = opts.onDelete ? " Del remove" : "";
37964
37971
  const customHint = opts.customKeyHint ?? "";
37965
- lines.push(` ${selectColors.dim("\u2191/\u2193 navigate Enter select" + actionHint + deleteHint + customHint + " Esc " + (filter ? "clear filter" : "cancel") + " Type to filter")}`);
37972
+ const escLabel = filter ? "clear filter" : hasBreadcrumbs ? "\u2190 back" : "cancel";
37973
+ lines.push(` ${selectColors.dim("\u2191/\u2193 navigate Enter/Click select" + actionHint + deleteHint + customHint + " Esc " + escLabel + " Type to filter")}`);
37966
37974
  }
37967
37975
  lines.push("");
37968
- const output = lines.join("\n").replace(/\x1B\[0m/g, "\x1B[0m\x1B[48;5;234m");
37969
- overlayWrite("\x1B[48;5;234m" + output);
37976
+ let output = lines.join("\n").replace(/\x1B\[0m/g, "\x1B[0m\x1B[48;5;234m").replace(/\n/g, "\x1B[K\n\x1B[48;5;234m");
37977
+ overlayWrite("\x1B[48;5;234m" + output + "\x1B[K");
37970
37978
  lastRenderedLines = lines.length;
37971
37979
  }
37972
37980
  function cleanup() {
37973
37981
  stdin.removeListener("data", onData);
37974
37982
  process.stdout.removeListener("resize", onResize);
37975
- overlayWrite("\x1B[?1049l\x1B[?25h");
37983
+ overlayWrite("\x1B[?1002l\x1B[?1006l\x1B[?1049l\x1B[?25h");
37976
37984
  leaveOverlay();
37977
37985
  if (typeof stdin.setRawMode === "function") {
37978
37986
  stdin.setRawMode(hadRawMode ?? false);
@@ -37987,6 +37995,51 @@ function tuiSelect(opts) {
37987
37995
  }
37988
37996
  function onData(chunk) {
37989
37997
  const seq = chunk.toString("utf8");
37998
+ const mouseMatch = seq.match(/\x1B\[<(\d+);(\d+);(\d+)([Mm])/);
37999
+ if (mouseMatch) {
38000
+ const btn = parseInt(mouseMatch[1]);
38001
+ const mRow = parseInt(mouseMatch[3]);
38002
+ const suffix = mouseMatch[4];
38003
+ if (btn === 0 && suffix === "M") {
38004
+ const listIdx = mRow - listRowOffset - 1;
38005
+ if (listIdx >= 0 && listIdx < maxVisible) {
38006
+ let displayList;
38007
+ if (filter) {
38008
+ displayList = [];
38009
+ for (let i = 0; i < items.length; i++) {
38010
+ if (matchSet.has(i) || isSkippable(i))
38011
+ displayList.push(i);
38012
+ }
38013
+ displayList = displayList.filter((idx, pos) => {
38014
+ if (!isSkippable(idx))
38015
+ return true;
38016
+ for (let j = pos + 1; j < displayList.length; j++) {
38017
+ if (!isSkippable(displayList[j]))
38018
+ return true;
38019
+ break;
38020
+ }
38021
+ return false;
38022
+ });
38023
+ } else {
38024
+ displayList = items.map((_, i) => i);
38025
+ }
38026
+ const vi = scrollOffset + listIdx;
38027
+ if (vi < displayList.length) {
38028
+ const itemIdx = displayList[vi];
38029
+ if (!isSkippable(itemIdx) && matchSet.has(itemIdx)) {
38030
+ cursor = itemIdx;
38031
+ cleanup();
38032
+ resolve32({ confirmed: true, key: items[cursor].key, index: cursor });
38033
+ return;
38034
+ } else if (!isSkippable(itemIdx)) {
38035
+ cursor = itemIdx;
38036
+ render();
38037
+ }
38038
+ }
38039
+ }
38040
+ }
38041
+ return;
38042
+ }
37990
38043
  if (deleteConfirmIdx >= 0) {
37991
38044
  if (seq === "\x1B[D") {
37992
38045
  deleteConfirmSel = true;
@@ -38104,6 +38157,9 @@ function tuiSelect(opts) {
38104
38157
  cursor = valid;
38105
38158
  scrollOffset = 0;
38106
38159
  render();
38160
+ } else if (hasBreadcrumbs) {
38161
+ cleanup();
38162
+ resolve32({ confirmed: false, key: "__back__", index: cursor });
38107
38163
  } else {
38108
38164
  cleanup();
38109
38165
  resolve32({ confirmed: false, key: null, index: cursor });
@@ -38122,6 +38178,9 @@ function tuiSelect(opts) {
38122
38178
  }
38123
38179
  scrollOffset = 0;
38124
38180
  render();
38181
+ } else if (hasBreadcrumbs) {
38182
+ cleanup();
38183
+ resolve32({ confirmed: false, key: "__back__", index: cursor });
38125
38184
  }
38126
38185
  } else if (seq.length === 1 && seq.charCodeAt(0) >= 32 && seq.charCodeAt(0) < 127) {
38127
38186
  if (opts.onCustomKey && !isSkippable(cursor) && matchSet.has(cursor)) {
@@ -46035,11 +46094,17 @@ function createDefaultBanner(version = "0.120.0") {
46035
46094
  for (let i = 0; i < infoText.length && i < Math.floor(width * 0.44); i++) {
46036
46095
  grid[1][i] = { char: infoText[i], fg: 245, bg: bgDark, bold: false };
46037
46096
  }
46038
- const hints = " /help /voice /cohere /model";
46039
- for (let i = 0; i < hints.length && i < Math.floor(width * 0.44); i++) {
46040
- grid[2][i] = { char: hints[i], fg: 240, bg: bgDark, bold: false };
46097
+ const btnLabels = ["help", "voice", "cohere", "model"];
46098
+ const btnBg = 236;
46099
+ let bCol = 2;
46100
+ for (const lbl of btnLabels) {
46101
+ const padded = ` ${lbl} `;
46102
+ for (let ci = 0; ci < padded.length && bCol + ci < Math.floor(width * 0.44); ci++) {
46103
+ grid[2][bCol + ci] = { char: padded[ci], fg: 245, bg: btnBg, bold: false };
46104
+ }
46105
+ bCol += padded.length + 1;
46041
46106
  }
46042
- frames.push({ grid, durationMs: 200 });
46107
+ frames.push({ grid, durationMs: 120 });
46043
46108
  }
46044
46109
  return {
46045
46110
  id: "default-header",
@@ -46182,6 +46247,8 @@ var init_banner = __esm({
46182
46247
  frameTick = 0;
46183
46248
  width;
46184
46249
  rows = 3;
46250
+ /** Callback fired after every frame render — used for header button overlay */
46251
+ onAfterRender = null;
46185
46252
  constructor() {
46186
46253
  this.width = process.stdout.columns ?? 80;
46187
46254
  }
@@ -46226,12 +46293,12 @@ var init_banner = __esm({
46226
46293
  this.timer = setInterval(() => {
46227
46294
  this.frameTick++;
46228
46295
  const frame = this.currentDesign.frames[this.currentFrame];
46229
- if (frame.durationMs > 0 && this.frameTick * 66 >= frame.durationMs) {
46296
+ if (frame.durationMs > 0 && this.frameTick * 80 >= frame.durationMs) {
46230
46297
  this.currentFrame = (this.currentFrame + 1) % this.currentDesign.frames.length;
46231
46298
  this.frameTick = 0;
46232
46299
  this.renderCurrentFrame();
46233
46300
  }
46234
- }, 66);
46301
+ }, 80);
46235
46302
  }
46236
46303
  return this.rows + 1;
46237
46304
  }
@@ -46289,6 +46356,8 @@ var init_banner = __esm({
46289
46356
  }
46290
46357
  buf += "\x1B8";
46291
46358
  process.stdout.write(buf);
46359
+ if (this.onAfterRender)
46360
+ this.onAfterRender();
46292
46361
  }
46293
46362
  /** Handle terminal resize */
46294
46363
  handleResize() {
@@ -52225,35 +52294,55 @@ function copyText(text) {
52225
52294
  return false;
52226
52295
  }
52227
52296
  function computeHeaderButtons(termWidth) {
52228
- const buttons = ["/help", "/voice", "/cohere", "/model"];
52229
- const GAP = 2;
52297
+ const buttons = [
52298
+ { display: "help", command: "/help" },
52299
+ { display: "voice", command: "/voice" },
52300
+ { display: "cohere", command: "/cohere" },
52301
+ { display: "model", command: "/model" }
52302
+ ];
52303
+ const GAP = 1;
52230
52304
  const result = [];
52231
- let col = termWidth - 1;
52232
- for (let i = buttons.length - 1; i >= 0; i--) {
52233
- const label = ` ${buttons[i]} `;
52234
- const endCol = col;
52235
- const startCol = col - label.length + 1;
52236
- if (startCol < 1)
52305
+ let col = 3;
52306
+ for (const btn of buttons) {
52307
+ const label = ` ${btn.display} `;
52308
+ const startCol = col;
52309
+ const endCol = col + label.length - 1;
52310
+ if (endCol >= termWidth)
52237
52311
  break;
52238
- result.unshift({
52312
+ result.push({
52239
52313
  label,
52240
- command: buttons[i],
52314
+ command: btn.command,
52241
52315
  startCol,
52242
52316
  endCol,
52243
52317
  row: 3
52244
52318
  });
52245
- col = startCol - GAP - 1;
52319
+ col = endCol + GAP + 1;
52246
52320
  }
52247
52321
  return result;
52248
52322
  }
52323
+ function setHoveredButton(cmd) {
52324
+ _hoveredButtonCmd = cmd;
52325
+ }
52326
+ function setPressedButton(cmd) {
52327
+ _pressedButtonCmd = cmd;
52328
+ }
52249
52329
  function renderHeaderButtons(termWidth) {
52250
52330
  const buttons = computeHeaderButtons(termWidth);
52251
52331
  if (buttons.length === 0)
52252
52332
  return "";
52253
52333
  let out = "";
52254
52334
  for (const btn of buttons) {
52335
+ let bg = BTN_REST_BG;
52336
+ let fg2 = BTN_REST_FG;
52337
+ if (_pressedButtonCmd === btn.command) {
52338
+ bg = BTN_PRESS_BG;
52339
+ fg2 = BTN_PRESS_FG;
52340
+ } else if (_hoveredButtonCmd === btn.command) {
52341
+ bg = BTN_HOVER_BG;
52342
+ fg2 = BTN_HOVER_FG;
52343
+ }
52255
52344
  out += `\x1B[${btn.row};${btn.startCol}H`;
52256
- out += `\x1B[1;${SEL_FG}m\x1B[48;5;${SEL_BG}m${btn.label}\x1B[0m`;
52345
+ out += `\x1B[38;5;${fg2}m\x1B[48;5;${bg}m${btn.label}\x1B[0m`;
52257
52346
  }
52258
52347
  return out;
52259
52348
  }
@@ -52266,7 +52355,7 @@ function hitTestHeaderButton(row, col, termWidth) {
52266
52355
  }
52267
52356
  return null;
52268
52357
  }
52269
- var SEL_BG, SEL_FG, SEL_START, SEL_END, TextSelection;
52358
+ var SEL_BG, SEL_FG, SEL_START, SEL_END, TextSelection, _hoveredButtonCmd, _pressedButtonCmd, BTN_REST_BG, BTN_REST_FG, BTN_HOVER_BG, BTN_HOVER_FG, BTN_PRESS_BG, BTN_PRESS_FG;
52270
52359
  var init_text_selection = __esm({
52271
52360
  "packages/cli/dist/tui/text-selection.js"() {
52272
52361
  "use strict";
@@ -52469,6 +52558,14 @@ var init_text_selection = __esm({
52469
52558
  return copyText(text);
52470
52559
  }
52471
52560
  };
52561
+ _hoveredButtonCmd = null;
52562
+ _pressedButtonCmd = null;
52563
+ BTN_REST_BG = 236;
52564
+ BTN_REST_FG = 245;
52565
+ BTN_HOVER_BG = 238;
52566
+ BTN_HOVER_FG = 252;
52567
+ BTN_PRESS_BG = 249;
52568
+ BTN_PRESS_FG = 234;
52472
52569
  }
52473
52570
  });
52474
52571
 
@@ -53304,15 +53401,14 @@ var init_status_bar = __esm({
53304
53401
  }
53305
53402
  }
53306
53403
  /** Schedule mouse tracking disable after idle timeout.
53307
- * Called after each content write or stream end. Cancelled by scroll/stream start. */
53404
+ * Called after each content write or stream end. Cancelled by scroll/stream start.
53405
+ *
53406
+ * NOTE: Now a no-op. Mouse tracking stays enabled permanently because:
53407
+ * 1. Header buttons (/help /voice /cohere /model) need click events at all times
53408
+ * 2. Text selection (Ctrl+Shift+C) needs mouse press/drag/release events
53409
+ * 3. Users can still hold Shift for native terminal text selection (universal fallback)
53410
+ */
53308
53411
  scheduleMouseIdle() {
53309
- if (this._mouseIdleTimer)
53310
- clearTimeout(this._mouseIdleTimer);
53311
- this._mouseIdleTimer = setTimeout(() => {
53312
- if (!this.isStreaming && !this.isScrolledBack) {
53313
- this.disableMouseTracking();
53314
- }
53315
- }, _StatusBar.MOUSE_IDLE_MS);
53316
53412
  }
53317
53413
  /** Cancel mouse idle timer (user is actively scrolling or streaming started) */
53318
53414
  cancelMouseIdle() {
@@ -53338,16 +53434,37 @@ var init_status_bar = __esm({
53338
53434
  handlePointerEvent(type, col, row) {
53339
53435
  if (!this.active)
53340
53436
  return;
53341
- if (type === "press" && row < this.scrollRegionTop) {
53342
- const w = process.stdout.columns ?? 80;
53437
+ const w = process.stdout.columns ?? 80;
53438
+ if (row < this.scrollRegionTop) {
53343
53439
  const cmd = hitTestHeaderButton(row, col, w);
53344
- if (cmd && this._headerButtonHandler) {
53345
- this._headerButtonHandler(cmd);
53440
+ if (type === "press" && cmd) {
53441
+ setPressedButton(cmd);
53442
+ this.renderHeaderButtons();
53443
+ setTimeout(() => {
53444
+ setPressedButton(null);
53445
+ this.renderHeaderButtons();
53446
+ if (this._headerButtonHandler)
53447
+ this._headerButtonHandler(cmd);
53448
+ }, 100);
53449
+ return;
53450
+ }
53451
+ if (type === "drag") {
53452
+ const prev = globalThis.__oaHoveredBtn;
53453
+ setHoveredButton(cmd);
53454
+ if (cmd !== prev) {
53455
+ globalThis.__oaHoveredBtn = cmd;
53456
+ this.renderHeaderButtons();
53457
+ }
53458
+ return;
53459
+ }
53460
+ if (type === "release") {
53461
+ setHoveredButton(null);
53462
+ globalThis.__oaHoveredBtn = null;
53463
+ this.renderHeaderButtons();
53346
53464
  return;
53347
53465
  }
53348
- }
53349
- if (row < this.scrollRegionTop)
53350
53466
  return;
53467
+ }
53351
53468
  const rows = process.stdout.rows ?? 24;
53352
53469
  const fh = this._currentFooterHeight;
53353
53470
  const footerStart = rows - fh + 1;
@@ -55942,9 +56059,9 @@ async function startInteractive(config, repoPath) {
55942
56059
  if (process.stdout.isTTY) {
55943
56060
  const scrollTop = carouselLines > 0 ? carouselLines : 1;
55944
56061
  statusBar.activate(scrollTop);
56062
+ banner.onAfterRender = () => statusBar.renderHeaderButtons();
55945
56063
  statusBar.setBannerRefresh(() => {
55946
56064
  banner.renderCurrentFrame();
55947
- statusBar.renderHeaderButtons();
55948
56065
  });
55949
56066
  const { onOverlayLeave: onOverlayLeave2 } = await Promise.resolve().then(() => (init_overlay_lock(), overlay_lock_exports));
55950
56067
  onOverlayLeave2(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.83",
3
+ "version": "0.138.85",
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",