open-agents-ai 0.185.1 → 0.185.3

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 +105 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -60372,8 +60372,12 @@ var init_status_bar = __esm({
60372
60372
  _focusFrame = 0;
60373
60373
  /** Slash command suggestion list (shown when user types /) */
60374
60374
  _suggestions = [];
60375
+ /** Currently highlighted suggestion index (-1 = none) */
60376
+ _suggestIndex = -1;
60375
60377
  /** Callback to get available slash commands for suggestion matching */
60376
60378
  _commandListProvider = null;
60379
+ /** Callback to apply a selected suggestion to the input line */
60380
+ _suggestApply = null;
60377
60381
  /** Whether agent is actively processing (braille animation) */
60378
60382
  _processing = false;
60379
60383
  _brailleSpinner = new BrailleSpinner();
@@ -60979,6 +60983,55 @@ var init_status_bar = __esm({
60979
60983
  setCommandListProvider(provider) {
60980
60984
  this._commandListProvider = provider;
60981
60985
  }
60986
+ /** Set callback to apply a selected suggestion to the input line */
60987
+ setSuggestApply(apply) {
60988
+ this._suggestApply = apply;
60989
+ }
60990
+ /** Whether suggestions are currently visible */
60991
+ get hasSuggestions() {
60992
+ return this._suggestions.length > 0;
60993
+ }
60994
+ /** Move suggestion highlight up */
60995
+ suggestUp() {
60996
+ if (this._suggestions.length === 0)
60997
+ return;
60998
+ this._suggestIndex = this._suggestIndex <= 0 ? this._suggestions.length - 1 : this._suggestIndex - 1;
60999
+ if (this.active)
61000
+ this.renderFooterPreserveCursor();
61001
+ }
61002
+ /** Move suggestion highlight down */
61003
+ suggestDown() {
61004
+ if (this._suggestions.length === 0)
61005
+ return;
61006
+ this._suggestIndex = this._suggestIndex >= this._suggestions.length - 1 ? 0 : this._suggestIndex + 1;
61007
+ if (this.active)
61008
+ this.renderFooterPreserveCursor();
61009
+ }
61010
+ /** Accept the currently highlighted suggestion */
61011
+ suggestAccept() {
61012
+ if (this._suggestions.length === 0 || this._suggestIndex < 0)
61013
+ return false;
61014
+ const cmd = this._suggestions[this._suggestIndex];
61015
+ if (cmd && this._suggestApply) {
61016
+ this._suggestApply("/" + cmd + " ");
61017
+ this._suggestIndex = -1;
61018
+ return true;
61019
+ }
61020
+ return false;
61021
+ }
61022
+ /** Handle mouse click on a suggestion row */
61023
+ suggestClickAt(row) {
61024
+ const rows = process.stdout.rows ?? 24;
61025
+ const pos = this.rowPositions(rows);
61026
+ if (pos.suggestStartRow <= 0 || this._suggestions.length === 0)
61027
+ return false;
61028
+ const idx = row - pos.suggestStartRow;
61029
+ if (idx >= 0 && idx < this._suggestions.length) {
61030
+ this._suggestIndex = idx;
61031
+ return this.suggestAccept();
61032
+ }
61033
+ return false;
61034
+ }
60982
61035
  /** Update the suggestion list based on current input. Called on every render. */
60983
61036
  _updateSuggestions() {
60984
61037
  if (!this.inputStateProvider || !this._commandListProvider) {
@@ -60993,6 +61046,9 @@ var init_status_bar = __esm({
60993
61046
  const query = line.slice(1).toLowerCase();
60994
61047
  const commands = this._commandListProvider();
60995
61048
  const matches = commands.filter((c3) => c3.toLowerCase().startsWith(query)).slice(0, 5);
61049
+ if (matches.join(",") !== this._suggestions.join(",")) {
61050
+ this._suggestIndex = -1;
61051
+ }
60996
61052
  this._suggestions = matches;
60997
61053
  }
60998
61054
  /** Cycle focus: footer → header → content → footer */
@@ -61081,6 +61137,10 @@ var init_status_bar = __esm({
61081
61137
  if (!this.active)
61082
61138
  return;
61083
61139
  const w = process.stdout.columns ?? 80;
61140
+ if (type === "press" && this._suggestions.length > 0) {
61141
+ if (this.suggestClickAt(row))
61142
+ return;
61143
+ }
61084
61144
  if (row < this.scrollRegionTop) {
61085
61145
  const cmd = hitTestHeaderButton(row, col, w);
61086
61146
  if (type === "press" && cmd) {
@@ -62091,9 +62151,13 @@ ${CONTENT_BG_SEQ}`);
62091
62151
  for (let si = 0; si < this._suggestions.length; si++) {
62092
62152
  const row = pos.suggestStartRow + si;
62093
62153
  const cmd = this._suggestions[si];
62094
- buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
62095
- buf += `${PANEL_BG_SEQ}\x1B[38;5;${TEXT_DIM}m /`;
62096
- buf += `\x1B[38;5;${TEXT_PRIMARY}m${cmd}`;
62154
+ const isHighlighted = si === this._suggestIndex;
62155
+ const bg = isHighlighted ? `\x1B[48;5;236m` : PANEL_BG_SEQ;
62156
+ const fg2 = isHighlighted ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
62157
+ const slash = isHighlighted ? `\x1B[38;5;245m` : `\x1B[38;5;${TEXT_DIM}m`;
62158
+ const marker = isHighlighted ? `\x1B[38;5;${TEXT_PRIMARY}m\u203A ` : " ";
62159
+ buf += `\x1B[${row};1H${bg}\x1B[2K`;
62160
+ buf += `${bg}${marker}${slash}/${fg2}${cmd}`;
62097
62161
  buf += `${RESET}`;
62098
62162
  }
62099
62163
  } else {
@@ -62411,14 +62475,18 @@ ${CONTENT_BG_SEQ}`);
62411
62475
  di.on("tab-empty", () => self.cycleFocus());
62412
62476
  di.on("ctrl-backslash", () => self.cycleFocus());
62413
62477
  di.on("up", () => {
62414
- if (self.writeDepth > 0 || self._contentScrollOffset > 0) {
62478
+ if (self._suggestions.length > 0) {
62479
+ self.suggestUp();
62480
+ } else if (self.writeDepth > 0 || self._contentScrollOffset > 0) {
62415
62481
  self.scrollContentUp(1);
62416
62482
  } else {
62417
62483
  di.historyUp();
62418
62484
  }
62419
62485
  });
62420
62486
  di.on("down", () => {
62421
- if (self.writeDepth > 0 || self._contentScrollOffset > 0) {
62487
+ if (self._suggestions.length > 0) {
62488
+ self.suggestDown();
62489
+ } else if (self.writeDepth > 0 || self._contentScrollOffset > 0) {
62422
62490
  self.scrollContentDown(1);
62423
62491
  } else {
62424
62492
  di.historyDown();
@@ -62633,11 +62701,16 @@ var init_direct_input = __esm({
62633
62701
  /** No-op — readline compat */
62634
62702
  prompt(_preserveCursor) {
62635
62703
  }
62636
- /** Set the line content and cursor position (for Esc-to-recall) */
62704
+ /** Set the line content and cursor position (for Esc-to-recall or suggestion apply) */
62637
62705
  setLine(text, cursorPos) {
62638
62706
  this.line = text;
62639
62707
  this.cursor = cursorPos ?? text.length;
62640
62708
  }
62709
+ /** Pre-submit hook — called before Enter submits. Return true to consume Enter. */
62710
+ _preSubmit = null;
62711
+ setPreSubmit(hook) {
62712
+ this._preSubmit = hook;
62713
+ }
62641
62714
  /** Navigate history up (older) */
62642
62715
  historyUp() {
62643
62716
  if (this._history.length === 0)
@@ -62844,6 +62917,8 @@ var init_direct_input = __esm({
62844
62917
  case 13:
62845
62918
  // Enter (CR)
62846
62919
  case 10:
62920
+ if (this._preSubmit?.())
62921
+ return;
62847
62922
  this._submit();
62848
62923
  return;
62849
62924
  case 127:
@@ -64409,6 +64484,8 @@ async function handleRequest(req, res, ollamaUrl, verbose) {
64409
64484
  }
64410
64485
  }
64411
64486
  function startApiServer(options = {}) {
64487
+ const log = options.quiet ? (_msg) => {
64488
+ } : (msg) => process.stderr.write(msg);
64412
64489
  let host = "127.0.0.1";
64413
64490
  let port = 11435;
64414
64491
  const envHost = process.env["OA_HOST"];
@@ -64446,7 +64523,7 @@ function startApiServer(options = {}) {
64446
64523
  server.on("error", (err) => {
64447
64524
  if (err.code === "EADDRINUSE" && !retried) {
64448
64525
  retried = true;
64449
- process.stderr.write(` Port ${port} in use \u2014 reclaiming...
64526
+ log(` Port ${port} in use \u2014 reclaiming...
64450
64527
  `);
64451
64528
  try {
64452
64529
  const { execSync: es } = __require("node:child_process");
@@ -64472,10 +64549,10 @@ function startApiServer(options = {}) {
64472
64549
  server.listen(port, host);
64473
64550
  }, 2e3);
64474
64551
  } else if (err.code === "EADDRINUSE" && retried) {
64475
- process.stderr.write(` Port ${port} still in use after reclaim attempt \u2014 API server skipped (non-fatal).
64552
+ log(` Port ${port} still in use after reclaim attempt \u2014 API server skipped (non-fatal).
64476
64553
  `);
64477
64554
  } else {
64478
- process.stderr.write(` API server error (non-fatal): ${err.message}
64555
+ log(` API server error (non-fatal): ${err.message}
64479
64556
  `);
64480
64557
  }
64481
64558
  });
@@ -64496,43 +64573,43 @@ function startApiServer(options = {}) {
64496
64573
  });
64497
64574
  server.listen(port, host, () => {
64498
64575
  const version = getVersion3();
64499
- process.stderr.write(`
64576
+ log(`
64500
64577
  open-agents API server v${version}
64501
64578
  `);
64502
- process.stderr.write(` Listening on http://${host}:${port}
64579
+ log(` Listening on http://${host}:${port}
64503
64580
  `);
64504
- process.stderr.write(` Primary: ${config.backendUrl} (${config.backendType || "ollama"})
64581
+ log(` Primary: ${config.backendUrl} (${config.backendType || "ollama"})
64505
64582
  `);
64506
64583
  if (process.env["OA_API_KEYS"]) {
64507
64584
  const keyCount = process.env["OA_API_KEYS"].split(",").length;
64508
- process.stderr.write(` Auth: ${keyCount} scoped key(s) (read/run/admin)
64585
+ log(` Auth: ${keyCount} scoped key(s) (read/run/admin)
64509
64586
  `);
64510
64587
  } else if (process.env["OA_API_KEY"]) {
64511
- process.stderr.write(` Auth: single Bearer token (admin scope)
64588
+ log(` Auth: single Bearer token (admin scope)
64512
64589
  `);
64513
64590
  } else {
64514
- process.stderr.write(` Auth: disabled (set OA_API_KEY or OA_API_KEYS to enable)
64591
+ log(` Auth: disabled (set OA_API_KEY or OA_API_KEYS to enable)
64515
64592
  `);
64516
64593
  }
64517
- process.stderr.write(` Discovering sponsors in background...
64594
+ log(` Discovering sponsors in background...
64518
64595
 
64519
64596
  `);
64520
64597
  refreshEndpointRegistry().then(() => {
64521
64598
  if (endpointRegistry.length > 1) {
64522
- process.stderr.write(` Sponsors: ${endpointRegistry.length - 1} endpoint(s) discovered
64599
+ log(` Sponsors: ${endpointRegistry.length - 1} endpoint(s) discovered
64523
64600
  `);
64524
64601
  for (const ep of endpointRegistry.slice(1)) {
64525
- process.stderr.write(` ${ep.label}: ${ep.url} (${ep.type})${ep.authKey ? " [auth]" : ""}
64602
+ log(` ${ep.label}: ${ep.url} (${ep.type})${ep.authKey ? " [auth]" : ""}
64526
64603
  `);
64527
64604
  }
64528
- process.stderr.write(`
64605
+ log(`
64529
64606
  `);
64530
64607
  }
64531
64608
  }).catch(() => {
64532
64609
  });
64533
64610
  });
64534
64611
  const shutdown = () => {
64535
- process.stderr.write("\n Shutting down API server...\n");
64612
+ log("\n Shutting down API server...\n");
64536
64613
  for (const [id, child] of runningProcesses) {
64537
64614
  if (!child.killed) {
64538
64615
  child.kill("SIGTERM");
@@ -64540,7 +64617,7 @@ function startApiServer(options = {}) {
64540
64617
  runningProcesses.delete(id);
64541
64618
  }
64542
64619
  server.close(() => {
64543
- process.stderr.write(" Server stopped.\n");
64620
+ log(" Server stopped.\n");
64544
64621
  process.exit(0);
64545
64622
  });
64546
64623
  setTimeout(() => process.exit(1), 5e3).unref();
@@ -66599,6 +66676,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
66599
66676
  cursor: rl.cursor ?? 0
66600
66677
  }));
66601
66678
  statusBar.setCommandListProvider(() => allCompletions.map((c3) => c3.startsWith("/") ? c3.slice(1) : c3));
66679
+ statusBar.setSuggestApply((cmd) => {
66680
+ rl.setLine(cmd, cmd.length);
66681
+ });
66682
+ rl.setPreSubmit(() => statusBar.suggestAccept());
66602
66683
  }
66603
66684
  process.stdout.on("resize", () => {
66604
66685
  statusBar.handleResize();
@@ -66928,7 +67009,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
66928
67009
  const apiPort = parseInt(process.env["OA_PORT"] || "11435", 10);
66929
67010
  const apiServer = startApiServer2({
66930
67011
  port: apiPort,
66931
- ollamaUrl: currentConfig.backendUrl || "http://127.0.0.1:11434"
67012
+ ollamaUrl: currentConfig.backendUrl || "http://127.0.0.1:11434",
67013
+ quiet: true
67014
+ // TUI mode — suppress all direct stderr/stdout output
66932
67015
  });
66933
67016
  apiServer.on?.("listening", () => {
66934
67017
  setTimeout(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.185.1",
3
+ "version": "0.185.3",
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",