open-agents-ai 0.184.96 → 0.184.98

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 +86 -24
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -53625,6 +53625,7 @@ var init_banner = __esm({
53625
53625
  if (this.currentDesign.frames.length > 1) {
53626
53626
  this.timer = setInterval(() => {
53627
53627
  this.currentFrame = (this.currentFrame + 1) % this.currentDesign.frames.length;
53628
+ this.frameTick++;
53628
53629
  this.renderCurrentFrame();
53629
53630
  }, 200);
53630
53631
  }
@@ -53683,8 +53684,10 @@ var init_banner = __esm({
53683
53684
  }
53684
53685
  }
53685
53686
  if (this._focused) {
53687
+ const QUAD = ["\u2598", "\u259D", "\u2597", "\u2596"];
53686
53688
  for (let r = 0; r < this.rows; r++) {
53687
- buf += `\x1B[${r + 1};1H\x1B[38;5;178m\x1B[48;5;234m\u258E\x1B[0m`;
53689
+ const ch = QUAD[(this.frameTick + r) % QUAD.length];
53690
+ buf += `\x1B[${r + 1};1H\x1B[38;5;178m\x1B[48;5;234m${ch}\x1B[0m`;
53688
53691
  }
53689
53692
  }
53690
53693
  if (this._updateAvailable && this.currentDesign?.type === "default") {
@@ -60113,7 +60116,7 @@ function setTerminalTitle(task, version) {
60113
60116
  const title = task ? `${task.slice(0, 60)} \xB7 ${ver}` : ver;
60114
60117
  process.stdout.write(`\x1B]2;${title}\x07`);
60115
60118
  }
60116
- 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, CONTENT_BG, TEXT_PRIMARY, PANEL_BG_SEQ, CONTENT_BG_SEQ, RESET, StatusBar;
60119
+ 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, CONTENT_BG, TEXT_PRIMARY, TEXT_DIM, PANEL_BG_SEQ, CONTENT_BG_SEQ, RESET, StatusBar;
60117
60120
  var init_status_bar = __esm({
60118
60121
  "packages/cli/dist/tui/status-bar.js"() {
60119
60122
  "use strict";
@@ -60281,6 +60284,7 @@ var init_status_bar = __esm({
60281
60284
  PANEL_BG = 234;
60282
60285
  CONTENT_BG = 233;
60283
60286
  TEXT_PRIMARY = 178;
60287
+ TEXT_DIM = 240;
60284
60288
  PANEL_BG_SEQ = `\x1B[48;5;${PANEL_BG}m`;
60285
60289
  CONTENT_BG_SEQ = `\x1B[48;5;${CONTENT_BG}m`;
60286
60290
  RESET = "\x1B[0m";
@@ -60364,6 +60368,12 @@ var init_status_bar = __esm({
60364
60368
  _focusedZone = "footer";
60365
60369
  /** Callback to notify header (banner) of focus changes */
60366
60370
  _headerFocusHandler = null;
60371
+ /** Focus indicator animation frame counter — driven by braille spinner timer */
60372
+ _focusFrame = 0;
60373
+ /** Slash command suggestion list (shown when user types /) */
60374
+ _suggestions = [];
60375
+ /** Callback to get available slash commands for suggestion matching */
60376
+ _commandListProvider = null;
60367
60377
  /** Whether agent is actively processing (braille animation) */
60368
60378
  _processing = false;
60369
60379
  _brailleSpinner = new BrailleSpinner();
@@ -60942,11 +60952,55 @@ var init_status_bar = __esm({
60942
60952
  setHeaderFocusHandler(handler) {
60943
60953
  this._headerFocusHandler = handler;
60944
60954
  }
60955
+ /**
60956
+ * Get the animated quadrant block character for the focus indicator.
60957
+ * The animation pattern varies by activity state:
60958
+ * - Idle: slow clockwise rotation (breathing)
60959
+ * - Processing: fast diagonal sweep (energetic)
60960
+ * - Streaming: rapid fill/unfill (pulsing)
60961
+ */
60962
+ _getFocusQuadrant() {
60963
+ this._focusFrame++;
60964
+ const IDLE_CYCLE = ["\u2598", "\u259D", "\u2597", "\u2596"];
60965
+ const ACTIVE_CYCLE = ["\u2598", "\u259A", "\u2597", "\u259E"];
60966
+ const STREAM_CYCLE = ["\u2596", "\u259F", "\u259B", "\u2598", "\u259C", "\u2599"];
60967
+ const FULL = "\u2588";
60968
+ if (this._focusFrame < 3)
60969
+ return FULL;
60970
+ if (this._processing) {
60971
+ return STREAM_CYCLE[Math.floor(this._focusFrame / 2) % STREAM_CYCLE.length];
60972
+ }
60973
+ if (this.writeDepth > 0) {
60974
+ return ACTIVE_CYCLE[Math.floor(this._focusFrame / 3) % ACTIVE_CYCLE.length];
60975
+ }
60976
+ return IDLE_CYCLE[Math.floor(this._focusFrame / 6) % IDLE_CYCLE.length];
60977
+ }
60978
+ /** Set the provider for slash command names (used for inline suggestions) */
60979
+ setCommandListProvider(provider) {
60980
+ this._commandListProvider = provider;
60981
+ }
60982
+ /** Update the suggestion list based on current input. Called on every render. */
60983
+ _updateSuggestions() {
60984
+ if (!this.inputStateProvider || !this._commandListProvider) {
60985
+ this._suggestions = [];
60986
+ return;
60987
+ }
60988
+ const { line } = this.inputStateProvider();
60989
+ if (!line.startsWith("/") || line.length < 2 || line.includes(" ")) {
60990
+ this._suggestions = [];
60991
+ return;
60992
+ }
60993
+ const query = line.slice(1).toLowerCase();
60994
+ const commands = this._commandListProvider();
60995
+ const matches = commands.filter((c3) => c3.toLowerCase().startsWith(query)).slice(0, 5);
60996
+ this._suggestions = matches;
60997
+ }
60945
60998
  /** Cycle focus: footer → header → content → footer */
60946
60999
  cycleFocus() {
60947
61000
  const order = ["footer", "header", "content"];
60948
61001
  const idx = order.indexOf(this._focusedZone);
60949
61002
  this._focusedZone = order[(idx + 1) % order.length];
61003
+ this._focusFrame = 0;
60950
61004
  this._headerFocusHandler?.(this._focusedZone === "header");
60951
61005
  if (this.active) {
60952
61006
  this._bannerRefresh?.();
@@ -61595,13 +61649,6 @@ ${CONTENT_BG_SEQ}`);
61595
61649
  const compactOrder = [];
61596
61650
  let modelSectionIdx = -1;
61597
61651
  let versionSectionIdx = -1;
61598
- {
61599
- const zoneLabels = { header: "hdr", content: "cnt", footer: "ftr" };
61600
- const zoneLabel = zoneLabels[this._focusedZone];
61601
- const focusStr = pastel2(TEXT_PRIMARY, `\u258E${zoneLabel}`);
61602
- const focusW = 1 + zoneLabel.length;
61603
- sections.push({ expanded: focusStr, compact: focusStr, expandedW: focusW, compactW: focusW, empty: false });
61604
- }
61605
61652
  if (this._cohereActive) {
61606
61653
  const cohereExpanded = "\x1B[38;5;214m\u{1F310}\x1B[0m";
61607
61654
  sections.push({ expanded: cohereExpanded, compact: cohereExpanded, expandedW: 2, compactW: 2, empty: false });
@@ -61894,10 +61941,12 @@ ${CONTENT_BG_SEQ}`);
61894
61941
  return 1;
61895
61942
  return Math.ceil(line.length / availWidth);
61896
61943
  }
61897
- /** Update _currentFooterHeight based on current input. Returns true if height changed. */
61944
+ /** Update _currentFooterHeight based on current input + suggestions. Returns true if height changed. */
61898
61945
  updateFooterHeight(termWidth) {
61946
+ this._updateSuggestions();
61899
61947
  const inputLines = this.computeInputLineCount(termWidth);
61900
- const newHeight = 2 + inputLines;
61948
+ const suggestionRows = this._suggestions.length > 0 ? this._suggestions.length : 1;
61949
+ const newHeight = 1 + inputLines + suggestionRows;
61901
61950
  if (newHeight !== this._currentFooterHeight) {
61902
61951
  this._currentFooterHeight = newHeight;
61903
61952
  return true;
@@ -61906,28 +61955,30 @@ ${CONTENT_BG_SEQ}`);
61906
61955
  }
61907
61956
  /** Check if footer height would change, WITHOUT actually updating it */
61908
61957
  footerHeightChanged(termWidth) {
61958
+ this._updateSuggestions();
61909
61959
  const inputLines = this.computeInputLineCount(termWidth);
61910
- return 2 + inputLines !== this._currentFooterHeight;
61960
+ const suggestionRows = this._suggestions.length > 0 ? this._suggestions.length : 1;
61961
+ return 1 + inputLines + suggestionRows !== this._currentFooterHeight;
61911
61962
  }
61912
61963
  /** Compute absolute row positions for all footer elements.
61913
- * New layout (top to bottom): input → braille → metrics.
61914
- * No separator lines, no blank rows. */
61964
+ * Layout (top to bottom): input → suggestions/braille → metrics.
61965
+ * When suggestions are active, they replace the braille row and expand upward. */
61915
61966
  rowPositions(rows) {
61916
61967
  const fh = this._currentFooterHeight;
61917
- const inputLines = fh - 2;
61968
+ const suggestionRows = this._suggestions.length > 0 ? this._suggestions.length : 1;
61969
+ const inputLines = fh - 1 - suggestionRows;
61918
61970
  const tabBarH = this.hasSubAgents ? 1 : 0;
61919
61971
  const totalFooter = fh + tabBarH;
61920
61972
  return {
61921
61973
  scrollEnd: Math.max(rows - totalFooter, this.scrollRegionTop + 1),
61922
61974
  inputStartRow: rows - totalFooter + 1,
61923
- // input at TOP of footer
61924
- tabBarRow: tabBarH > 0 ? rows - 2 : -1,
61925
- // tab bar ABOVE braille (if visible)
61975
+ tabBarRow: tabBarH > 0 ? rows - suggestionRows - 1 : -1,
61976
+ // When suggestions active: multiple rows between input and metrics
61977
+ // When no suggestions: single braille row at N-1
61926
61978
  bufferRow: rows - 1,
61927
- // braille always at N-1
61979
+ // braille (only used when no suggestions)
61980
+ suggestStartRow: this._suggestions.length > 0 ? rows - suggestionRows : -1,
61928
61981
  metricsRow: rows,
61929
- // metrics at BOTTOM
61930
- // Legacy (unused but keeps TS happy for any remaining refs)
61931
61982
  topSepRow: -1,
61932
61983
  bottomSepRow: -1
61933
61984
  };
@@ -62036,12 +62087,22 @@ ${CONTENT_BG_SEQ}`);
62036
62087
  if (pos.tabBarRow > 0) {
62037
62088
  buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET}`;
62038
62089
  }
62039
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildBufferContent(w)}${RESET}`;
62090
+ if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
62091
+ for (let si = 0; si < this._suggestions.length; si++) {
62092
+ const row = pos.suggestStartRow + si;
62093
+ const cmd = this._suggestions[si];
62094
+ const prefix = si === 0 ? `\x1B[38;5;${TEXT_DIM}m/` : `\x1B[38;5;${TEXT_DIM}m `;
62095
+ buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K ${prefix}\x1B[38;5;${TEXT_PRIMARY}m${cmd}\x1B[0m${RESET}`;
62096
+ }
62097
+ } else {
62098
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildBufferContent(w)}${RESET}`;
62099
+ }
62040
62100
  buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET}`;
62101
+ const focusChar = this._getFocusQuadrant();
62041
62102
  if (this._focusedZone === "footer") {
62042
- buf += `\x1B[${pos.inputStartRow};1H\x1B[38;5;${TEXT_PRIMARY}m\x1B[48;5;${PANEL_BG}m\u258E\x1B[0m`;
62103
+ buf += `\x1B[${pos.inputStartRow};1H\x1B[38;5;${TEXT_PRIMARY}m\x1B[48;5;${PANEL_BG}m${focusChar}\x1B[0m`;
62043
62104
  } else if (this._focusedZone === "content") {
62044
- buf += `\x1B[${this.scrollRegionTop};1H\x1B[38;5;${TEXT_PRIMARY}m\x1B[48;5;${CONTENT_BG}m\u258E\x1B[0m`;
62105
+ buf += `\x1B[${this.scrollRegionTop};1H\x1B[38;5;${TEXT_PRIMARY}m\x1B[48;5;${CONTENT_BG}m${focusChar}\x1B[0m`;
62045
62106
  }
62046
62107
  buf += `\x1B[?7h\x1B[${cursorTermRow};${inputWrap.cursorCol}H\x1B[?25h`;
62047
62108
  this.termWrite(buf);
@@ -66492,6 +66553,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
66492
66553
  line: rl.line ?? "",
66493
66554
  cursor: rl.cursor ?? 0
66494
66555
  }));
66556
+ statusBar.setCommandListProvider(() => allCompletions.map((c3) => c3.startsWith("/") ? c3.slice(1) : c3));
66495
66557
  }
66496
66558
  process.stdout.on("resize", () => {
66497
66559
  statusBar.handleResize();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.184.96",
3
+ "version": "0.184.98",
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",