open-agents-ai 0.138.1 → 0.138.2

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 +127 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -45151,6 +45151,8 @@ var init_stream_renderer = __esm({
45151
45151
  startTime = 0;
45152
45152
  /** Track if we're mid-tool-arg display */
45153
45153
  inToolArgs = false;
45154
+ /** Optional callback to capture rendered lines for scrollback buffer */
45155
+ onRenderedLine = null;
45154
45156
  /**
45155
45157
  * Track accumulated content size for JSON blob detection.
45156
45158
  * When a non-newline JSON blob exceeds this threshold, suppress rendering.
@@ -45338,9 +45340,18 @@ var init_stream_renderer = __esm({
45338
45340
  this.writeRaw(dimText(prefix) + rendered + (hasNewline ? "\n" : ""));
45339
45341
  this.lineStarted = !hasNewline;
45340
45342
  }
45341
- /** Write raw ANSI text to stdout */
45343
+ /** Write raw ANSI text to stdout and capture for scrollback */
45342
45344
  writeRaw(text) {
45343
45345
  process.stdout.write(text);
45346
+ if (this.onRenderedLine) {
45347
+ const parts = text.split("\n");
45348
+ for (let i = 0; i < parts.length - 1; i++) {
45349
+ this.onRenderedLine(parts[i]);
45350
+ }
45351
+ if (parts.length === 1 && parts[0].length > 0) {
45352
+ this.onRenderedLine(parts[0]);
45353
+ }
45354
+ }
45344
45355
  }
45345
45356
  /** Flush partial buffer (non-newline-terminated tokens) */
45346
45357
  flushPartial(kind) {
@@ -50755,6 +50766,12 @@ var init_status_bar = __esm({
50755
50766
  };
50756
50767
  active = false;
50757
50768
  scrollRegionTop = 1;
50769
+ // Virtual scrollback buffer — stores content lines for Page Up/Down scrolling.
50770
+ // Since we're in alternate screen buffer, there's no native scrollback.
50771
+ _contentLines = [];
50772
+ _contentScrollOffset = 0;
50773
+ // 0 = live (bottom), >0 = scrolled back
50774
+ _contentMaxLines = 1e4;
50758
50775
  stdinHooked = false;
50759
50776
  /** COHERE distributed cognitive commons active flag */
50760
50777
  _cohereActive = false;
@@ -51496,6 +51513,76 @@ var init_status_bar = __esm({
51496
51513
  this.renderFooterAndPositionInput();
51497
51514
  }
51498
51515
  }
51516
+ // -----------------------------------------------------------------------
51517
+ // Content scrollback — virtual scroll through buffered output lines
51518
+ // -----------------------------------------------------------------------
51519
+ /** Record a content line for scrollback. Called by the stream renderer intercept. */
51520
+ bufferContentLine(line) {
51521
+ this._contentLines.push(line);
51522
+ if (this._contentLines.length > this._contentMaxLines) {
51523
+ this._contentLines.splice(0, this._contentLines.length - this._contentMaxLines);
51524
+ if (this._contentScrollOffset > 0) {
51525
+ this._contentScrollOffset = Math.min(this._contentScrollOffset, Math.max(0, this._contentLines.length - this.contentHeight));
51526
+ }
51527
+ }
51528
+ }
51529
+ /** Number of visible content rows */
51530
+ get contentHeight() {
51531
+ const rows = process.stdout.rows ?? 24;
51532
+ return Math.max(1, rows - (this.scrollRegionTop - 1) - this._currentFooterHeight);
51533
+ }
51534
+ /** Whether user has scrolled back from live */
51535
+ get isScrolledBack() {
51536
+ return this._contentScrollOffset > 0;
51537
+ }
51538
+ /** Scroll up through content history */
51539
+ scrollContentUp(lines = 1) {
51540
+ if (!this.active)
51541
+ return;
51542
+ const maxOffset = Math.max(0, this._contentLines.length - this.contentHeight);
51543
+ this._contentScrollOffset = Math.min(maxOffset, this._contentScrollOffset + lines);
51544
+ this.repaintContent();
51545
+ }
51546
+ /** Scroll down through content history */
51547
+ scrollContentDown(lines = 1) {
51548
+ if (!this.active)
51549
+ return;
51550
+ this._contentScrollOffset = Math.max(0, this._contentScrollOffset - lines);
51551
+ this.repaintContent();
51552
+ }
51553
+ /** Page up — scroll by visible height */
51554
+ pageUpContent() {
51555
+ this.scrollContentUp(Math.max(1, this.contentHeight - 2));
51556
+ }
51557
+ /** Page down — scroll by visible height */
51558
+ pageDownContent() {
51559
+ this.scrollContentDown(Math.max(1, this.contentHeight - 2));
51560
+ }
51561
+ /** Jump to live (End key) */
51562
+ jumpToLive() {
51563
+ this._contentScrollOffset = 0;
51564
+ this.repaintContent();
51565
+ }
51566
+ /** Repaint content area from buffer at current scroll position.
51567
+ * Uses direct cursor positioning (btop-style) — no DECSTBM scrolling. */
51568
+ repaintContent() {
51569
+ const h = this.contentHeight;
51570
+ const totalLines = this._contentLines.length;
51571
+ const startIdx = Math.max(0, totalLines - h - this._contentScrollOffset);
51572
+ let buf = "\x1B7\x1B[?25l";
51573
+ for (let row = 0; row < h; row++) {
51574
+ const lineIdx = startIdx + row;
51575
+ const line = lineIdx < totalLines ? this._contentLines[lineIdx] : "";
51576
+ const screenRow = this.scrollRegionTop + row;
51577
+ buf += `\x1B[${screenRow};1H\x1B[2K${line}`;
51578
+ }
51579
+ if (this._contentScrollOffset > 0) {
51580
+ const linesAbove = Math.max(0, totalLines - h - this._contentScrollOffset);
51581
+ buf += `\x1B[${this.scrollRegionTop};1H\x1B[7m \u2191 ${linesAbove} lines above (PgDn/End to return) \x1B[0m`;
51582
+ }
51583
+ buf += "\x1B8\x1B[?25h";
51584
+ process.stdout.write(buf);
51585
+ }
51499
51586
  /**
51500
51587
  * Clear the input row and position cursor there at column 1.
51501
51588
  * Used by showPrompt() before readline writes the prompt.
@@ -52914,9 +53001,23 @@ ${entry.fullContent}`
52914
53001
  return;
52915
53002
  }
52916
53003
  if (statusBar?.isActive) {
53004
+ const origWrite = process.stdout.write;
53005
+ const boundWrite = origWrite.bind(process.stdout);
53006
+ process.stdout.write = ((chunk, ...args) => {
53007
+ const text = typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk);
53008
+ for (const line of text.split("\n")) {
53009
+ if (line.length > 0)
53010
+ statusBar.bufferContentLine(line);
53011
+ }
53012
+ return boundWrite(chunk, ...args);
53013
+ });
52917
53014
  statusBar.beginContentWrite();
52918
- fn();
52919
- statusBar.endContentWrite();
53015
+ try {
53016
+ fn();
53017
+ } finally {
53018
+ process.stdout.write = origWrite;
53019
+ statusBar.endContentWrite();
53020
+ }
52920
53021
  } else {
52921
53022
  fn();
52922
53023
  }
@@ -53481,6 +53582,7 @@ async function startInteractive(config, repoPath) {
53481
53582
  let adminSessionKey = null;
53482
53583
  const callSubAgents = /* @__PURE__ */ new Map();
53483
53584
  const streamRenderer = new StreamRenderer();
53585
+ streamRenderer.onRenderedLine = (line) => statusBar.bufferContentLine(line);
53484
53586
  if (savedSettings.voice) {
53485
53587
  voiceEngine.toggle().catch((err) => {
53486
53588
  const msg = err instanceof Error ? err.message : String(err);
@@ -55844,6 +55946,28 @@ ${c2.dim("(Use /quit to exit)")}
55844
55946
  process.stdin.on("keypress", (_str, key) => {
55845
55947
  if (!key)
55846
55948
  return;
55949
+ if (key.name === "pageup" || key.shift && key.name === "up") {
55950
+ statusBar.pageUpContent();
55951
+ return;
55952
+ }
55953
+ if (key.name === "pagedown" || key.shift && key.name === "down") {
55954
+ statusBar.pageDownContent();
55955
+ return;
55956
+ }
55957
+ if (key.name === "end" && key.ctrl) {
55958
+ statusBar.jumpToLive();
55959
+ return;
55960
+ }
55961
+ if (key.sequence) {
55962
+ if (key.sequence.includes("[<65;") || key.sequence === "\x1B[A" && key.shift) {
55963
+ statusBar.scrollContentUp(3);
55964
+ return;
55965
+ }
55966
+ if (key.sequence.includes("[<64;") || key.sequence === "\x1B[B" && key.shift) {
55967
+ statusBar.scrollContentDown(3);
55968
+ return;
55969
+ }
55970
+ }
55847
55971
  if (key.name === "escape" && activeTask) {
55848
55972
  if (!activeTask.runner.isPaused) {
55849
55973
  activeTask.runner.pause();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.1",
3
+ "version": "0.138.2",
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",