open-agents-ai 0.187.39 → 0.187.41

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 +112 -61
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -292370,26 +292370,9 @@ function createDefaultBanner(version4 = "0.120.0") {
292370
292370
  }
292371
292371
  topRow.push({ char: "\u256E", fg: yellow, bg: bgBlack, bold: false });
292372
292372
  grid.push(topRow);
292373
- const mnemonic = getNodeMnemonic();
292374
- const versionText = ` OA v${version4} \xB7 ${mnemonic}`;
292375
- const btnLabels = ["help", "voice", "model", "cohere"];
292376
- const btnText = btnLabels.map((b) => ` ${b} `).join(" ");
292377
- const gapSize = Math.max(1, innerW - versionText.length - btnText.length);
292378
292373
  const midRow = [];
292379
292374
  midRow.push({ char: "\u2502", fg: yellow, bg: bgBlack, bold: false });
292380
- for (let i2 = 0; i2 < versionText.length && midRow.length <= innerW; i2++) {
292381
- midRow.push({ char: versionText[i2], fg: yellow, bg: bgBlack, bold: true });
292382
- }
292383
- for (let i2 = 0; i2 < gapSize && midRow.length <= innerW; i2++) {
292384
- midRow.push({ char: " ", fg: 0, bg: bgBlack, bold: false });
292385
- }
292386
- const dimYellow = 240;
292387
- for (const ch of btnText) {
292388
- if (midRow.length > innerW)
292389
- break;
292390
- midRow.push({ char: ch, fg: dimYellow, bg: bgBlack, bold: false });
292391
- }
292392
- while (midRow.length <= innerW) {
292375
+ for (let c4 = 0; c4 < innerW; c4++) {
292393
292376
  midRow.push({ char: " ", fg: 0, bg: bgBlack, bold: false });
292394
292377
  }
292395
292378
  midRow.push({ char: "\u2502", fg: yellow, bg: bgBlack, bold: false });
@@ -292745,9 +292728,6 @@ var init_banner = __esm({
292745
292728
  const row = frame.grid[r2];
292746
292729
  if (!row)
292747
292730
  continue;
292748
- if (r2 === 1 && this.currentDesign?.type === "default") {
292749
- buf += `\x1B]8;;file://${process.cwd()}\x07`;
292750
- }
292751
292731
  let prevFg = -1, prevBg = -1, prevBold = false;
292752
292732
  for (let c4 = 0; c4 < Math.min(this.width, row.length); c4++) {
292753
292733
  const cell = row[c4];
@@ -292767,9 +292747,6 @@ var init_banner = __esm({
292767
292747
  buf += seq + cell.char;
292768
292748
  }
292769
292749
  buf += "\x1B[0m";
292770
- if (r2 === 1 && this.currentDesign?.type === "default") {
292771
- buf += "\x1B]8;;\x07";
292772
- }
292773
292750
  }
292774
292751
  if (this._focused) {
292775
292752
  const FOCUS = [
@@ -292799,7 +292776,7 @@ var init_banner = __esm({
292799
292776
  const updateIdx = Math.round((1 - t2) * (ramp.length - 1));
292800
292777
  const versionFg = ramp[versionIdx];
292801
292778
  const updateFg = ramp[updateIdx];
292802
- const bgDark = 234;
292779
+ const bgDark = 0;
292803
292780
  const storedVersion = this.currentDesign.version ?? "";
292804
292781
  const vText = ` OA v${storedVersion}`;
292805
292782
  const vStart = 3;
@@ -299641,6 +299618,69 @@ var init_status_bar = __esm({
299641
299618
  _streamStartTime = 0;
299642
299619
  /** Current package version (shown in metrics row, rightmost) */
299643
299620
  _version = "";
299621
+ // ── Header Panel System ──────────────────────────────────────────────
299622
+ // Extensible dual-state (N-state) header: the content row inside the
299623
+ // ╭│╰ box cycles between registered panels via arrow buttons.
299624
+ // Page 0 = "main" (version + menu buttons) — always registered.
299625
+ // Page 1 = "agents" (agent tabs, voice, nexus) — registered on demand.
299626
+ // Future pages added via registerHeaderPanel().
299627
+ /** Registered header panels. Each has a unique id and a render function. */
299628
+ _headerPanels = [];
299629
+ /** Index of the currently visible panel (0 = main) */
299630
+ _headerPanelIndex = 0;
299631
+ /** Register a header panel. Returns its index. */
299632
+ registerHeaderPanel(id, render) {
299633
+ const existing = this._headerPanels.findIndex((p2) => p2.id === id);
299634
+ if (existing >= 0) {
299635
+ this._headerPanels[existing] = { id, render };
299636
+ return existing;
299637
+ }
299638
+ this._headerPanels.push({ id, render });
299639
+ return this._headerPanels.length - 1;
299640
+ }
299641
+ /** Switch to the next header panel (wraps around) */
299642
+ nextHeaderPanel() {
299643
+ if (this._headerPanels.length <= 1)
299644
+ return;
299645
+ this._headerPanelIndex = (this._headerPanelIndex + 1) % this._headerPanels.length;
299646
+ this.refreshHeaderContent();
299647
+ }
299648
+ /** Switch to the previous header panel (wraps around) */
299649
+ prevHeaderPanel() {
299650
+ if (this._headerPanels.length <= 1)
299651
+ return;
299652
+ this._headerPanelIndex = (this._headerPanelIndex - 1 + this._headerPanels.length) % this._headerPanels.length;
299653
+ this.refreshHeaderContent();
299654
+ }
299655
+ /** Get current panel id */
299656
+ get currentHeaderPanel() {
299657
+ return this._headerPanels[this._headerPanelIndex]?.id ?? "main";
299658
+ }
299659
+ /** Render the current header panel content onto terminal row 2 (inside box) */
299660
+ refreshHeaderContent() {
299661
+ if (!this.active)
299662
+ return;
299663
+ const w = process.stdout.columns ?? 80;
299664
+ const innerW = w - 2;
299665
+ const panel = this._headerPanels[this._headerPanelIndex];
299666
+ if (!panel)
299667
+ return;
299668
+ const content = panel.render(innerW);
299669
+ const hasMultiple = this._headerPanels.length > 1;
299670
+ const leftArrow = hasMultiple ? `\x1B]8;;oa-cmd:header-prev\x07\x1B[38;5;${TEXT_DIM}m${this._headerPanelIndex > 0 ? "\u25C0" : " "}\x1B]8;;\x07` : " ";
299671
+ const rightArrow = hasMultiple ? `\x1B]8;;oa-cmd:header-next\x07\x1B[38;5;${TEXT_DIM}m${this._headerPanelIndex < this._headerPanels.length - 1 ? "\u25B6" : " "}\x1B]8;;\x07` : " ";
299672
+ let buf = "\x1B7";
299673
+ buf += `\x1B[2;1H\x1B[48;5;0m\x1B[2K`;
299674
+ buf += `${BOX_FG}\u2502${RESET}\x1B[48;5;0m`;
299675
+ buf += leftArrow;
299676
+ buf += `\x1B[38;5;${TEXT_PRIMARY}m\x1B[48;5;0m`;
299677
+ buf += content;
299678
+ buf += `\x1B[2;${w - 1}H`;
299679
+ buf += rightArrow;
299680
+ buf += `${BOX_FG}\u2502${RESET}`;
299681
+ buf += "\x1B8";
299682
+ this.termWrite(buf);
299683
+ }
299644
299684
  /**
299645
299685
  * Provide a callback that returns readline's current input state.
299646
299686
  * StatusBar uses this to render typed text and position the cursor
@@ -300188,6 +300228,39 @@ var init_status_bar = __esm({
300188
300228
  activate(scrollRegionTop) {
300189
300229
  this.scrollRegionTop = scrollRegionTop ?? 1;
300190
300230
  this.active = true;
300231
+ if (this._headerPanels.length === 0) {
300232
+ this.registerHeaderPanel("main", (innerW) => {
300233
+ const verText = ` OA v${this._version}`;
300234
+ const btnLabels = [" help ", " voice ", " model ", " cohere "];
300235
+ const btnText = btnLabels.join(" ");
300236
+ const gap = Math.max(1, innerW - verText.length - btnText.length - 4);
300237
+ let out = `\x1B[1;38;5;${TEXT_PRIMARY}m${verText}`;
300238
+ out += `\x1B[38;5;${TEXT_DIM}m${" ".repeat(gap)}`;
300239
+ for (const btn of btnLabels) {
300240
+ out += `\x1B]8;;oa-cmd:${btn.trim()}\x07\x1B[38;5;${TEXT_DIM}m${btn}\x1B]8;;\x07 `;
300241
+ }
300242
+ return out;
300243
+ });
300244
+ this.registerHeaderPanel("systems", (_innerW) => {
300245
+ let out = "";
300246
+ if (this._agentViews.size > 1) {
300247
+ for (const view of this._agentViews.values()) {
300248
+ if (view.id === "main" && this._activeViewId === "main")
300249
+ continue;
300250
+ const icon = view.status === "running" ? "\u25CF" : view.status === "completed" ? "\u2713" : view.status === "failed" ? "\u2717" : "\u25CB";
300251
+ const isActive = view.id === this._activeViewId;
300252
+ const fg2 = isActive ? 252 : 245;
300253
+ out += `\x1B]8;;oa-view:${view.id}\x07\x1B[38;5;${fg2}m ${view.label} ${icon} \x1B]8;;\x07 `;
300254
+ }
300255
+ } else {
300256
+ out += `\x1B[38;5;${TEXT_DIM}m no sub-agents `;
300257
+ }
300258
+ out += `\x1B[38;5;${TEXT_DIM}m\u2502 `;
300259
+ out += `\x1B]8;;oa-cmd:voice\x07\x1B[38;5;${TEXT_DIM}m voice \x1B]8;;\x07 `;
300260
+ out += `\x1B]8;;oa-cmd:nexus\x07\x1B[38;5;${TEXT_DIM}m nexus \x1B]8;;\x07`;
300261
+ return out;
300262
+ });
300263
+ }
300191
300264
  if (!this._agentViews.has("main")) {
300192
300265
  this._agentViews.set("main", {
300193
300266
  id: "main",
@@ -300205,6 +300278,7 @@ var init_status_bar = __esm({
300205
300278
  this.applyScrollRegion();
300206
300279
  this.fillContentArea();
300207
300280
  this.renderFooterAndPositionInput();
300281
+ this.refreshHeaderContent();
300208
300282
  this.hookStdin();
300209
300283
  if (!this._metricsCollector.isActive) {
300210
300284
  this.startLocalMetrics();
@@ -300458,6 +300532,14 @@ var init_status_bar = __esm({
300458
300532
  if (row < this.scrollRegionTop) {
300459
300533
  const cmd = hitTestHeaderButton(row, col, w);
300460
300534
  if (type === "press" && cmd) {
300535
+ if (cmd === "header-prev") {
300536
+ this.prevHeaderPanel();
300537
+ return;
300538
+ }
300539
+ if (cmd === "header-next") {
300540
+ this.nextHeaderPanel();
300541
+ return;
300542
+ }
300461
300543
  setPressedButton(cmd);
300462
300544
  setHoveredButton(null);
300463
300545
  this.renderHeaderButtons();
@@ -300609,45 +300691,14 @@ var init_status_bar = __esm({
300609
300691
  return this._agentViews.size > 1;
300610
300692
  }
300611
300693
  // ── Agent Tab Bar (WO-NA2) ───────────────────────────────────
300612
- /** Render the agent tab bar in the HEADER area (row 2, right-aligned).
300613
- * Moved from footer to header so agents are visible alongside version info. */
300694
+ /** Refresh agent tabs in header delegates to the header panel system.
300695
+ * If currently on the "systems" panel, re-render to show updated agent list. */
300614
300696
  renderAgentTabs() {
300615
- if (!this.active || !this.hasSubAgents)
300697
+ if (!this.active)
300616
300698
  return;
300617
- const w = process.stdout.columns ?? 80;
300618
- const headerContentRow = 2;
300619
- const tabs = [];
300620
- let totalLen = 0;
300621
- for (const view of this._agentViews.values()) {
300622
- const isActive = view.id === this._activeViewId;
300623
- if (view.id === "main" && this._activeViewId === "main")
300624
- continue;
300625
- const icon = view.status === "running" ? "\u25CF" : (
300626
- // ●
300627
- view.status === "completed" ? "\u2713" : (
300628
- // ✓
300629
- view.status === "failed" ? "\u2717" : (
300630
- // ✗
300631
- view.status === "paused" ? "\u25CB" : "?"
300632
- )
300633
- )
300634
- );
300635
- const label = ` ${view.label} ${icon} `;
300636
- const bg = isActive ? 235 : 0;
300637
- const fg2 = isActive ? 252 : 245;
300638
- const tabStr = `\x1B]8;;oa-view:${view.id}\x07\x1B[38;5;${fg2}m\x1B[48;5;${bg}m${label}\x1B[0m\x1B[48;5;0m\x1B]8;;\x07`;
300639
- tabs.push(tabStr);
300640
- totalLen += label.length + 1;
300641
- if (totalLen >= Math.floor(w * 0.4))
300642
- break;
300699
+ if (this.currentHeaderPanel === "systems") {
300700
+ this.refreshHeaderContent();
300643
300701
  }
300644
- if (tabs.length === 0)
300645
- return;
300646
- const startCol = Math.max(2, w - totalLen - 2);
300647
- let buf = `\x1B[${headerContentRow};${startCol}H\x1B[48;5;0m`;
300648
- buf += tabs.join(" ");
300649
- buf += RESET;
300650
- this.termWrite(buf);
300651
300702
  }
300652
300703
  /** Hit-test the tab bar for click events. Returns view ID or null. */
300653
300704
  hitTestTabBar(col) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.39",
3
+ "version": "0.187.41",
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",