open-agents-ai 0.138.87 → 0.138.89

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 +135 -70
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -37854,8 +37854,9 @@ function tuiSelect(opts) {
37854
37854
  const first = findSelectable(0, 1);
37855
37855
  cursor = first >= 0 ? first : 0;
37856
37856
  }
37857
+ const reservedTopBottom = 6;
37857
37858
  const selectChrome = 3;
37858
- const contentArea = opts.availableRows ?? process.stdout.rows ?? 24;
37859
+ const contentArea = opts.availableRows ?? Math.max(6, (process.stdout.rows ?? 24) - reservedTopBottom);
37859
37860
  const maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
37860
37861
  let scrollOffset = 0;
37861
37862
  let lastRenderedLines = 0;
@@ -44126,6 +44127,81 @@ async function handleUpdate(subcommand, ctx) {
44126
44127
  process.stdout.write(text);
44127
44128
  }
44128
44129
  };
44130
+ const particles = [" ", "\u2801", "\u2802", "\u2840", "\u2804", "\u2820", "\u2812", "\u28C0", "\u2824", "\u28C4", "\xB7", "\u2591", "\u28E4", "\u2592", "\u28F6", "\u2593", "\u28FF", "\u2588"];
44131
+ const hash = (r, c3, f) => {
44132
+ const x = r * 7 + c3 * 13 + f * 3 + 37;
44133
+ return (x * x * 31 + x * 17 + 59) % 97 / 97;
44134
+ };
44135
+ function renderInstallFrame(version, frame, statusLine) {
44136
+ const cols = process.stdout.columns ?? 80;
44137
+ const rows = process.stdout.rows ?? 24;
44138
+ const bgDark = 234;
44139
+ const yellow = 178;
44140
+ let buf = `\x1B[48;5;${bgDark}m\x1B[H\x1B[2J`;
44141
+ const centerRow = Math.floor(rows / 2);
44142
+ const centerCol = Math.floor(cols / 2);
44143
+ const boxW = Math.min(44, cols - 4);
44144
+ const boxH = 7;
44145
+ const boxTop = centerRow - Math.floor(boxH / 2);
44146
+ const boxLeft = centerCol - Math.floor(boxW / 2);
44147
+ buf += `\x1B[${boxTop};${boxLeft}H\x1B[38;5;${yellow}m\u250C`;
44148
+ buf += `\x1B[${boxTop};${boxLeft + boxW - 1}H\u2510`;
44149
+ buf += `\x1B[${boxTop + boxH - 1};${boxLeft}H\u2514`;
44150
+ buf += `\x1B[${boxTop + boxH - 1};${boxLeft + boxW - 1}H\u2518`;
44151
+ for (let c3 = 1; c3 < boxW - 1; c3++) {
44152
+ const density = Math.sin(c3 * 0.3 + frame * 0.4) * 0.5 + 0.5;
44153
+ const noise = hash(0, c3, frame);
44154
+ const charIdx = noise < density ? Math.min(particles.length - 1, Math.floor(density * particles.length)) : 0;
44155
+ const ch = particles[charIdx];
44156
+ buf += `\x1B[${boxTop};${boxLeft + c3}H\x1B[38;5;${yellow}m${ch}`;
44157
+ const density2 = Math.sin(c3 * 0.3 + frame * 0.4 + 1.5) * 0.5 + 0.5;
44158
+ const noise2 = hash(boxH, c3, frame);
44159
+ const charIdx2 = noise2 < density2 ? Math.min(particles.length - 1, Math.floor(density2 * particles.length)) : 0;
44160
+ buf += `\x1B[${boxTop + boxH - 1};${boxLeft + c3}H${particles[charIdx2]}`;
44161
+ }
44162
+ for (let r = 1; r < boxH - 1; r++) {
44163
+ const density = Math.sin(r * 0.5 + frame * 0.35) * 0.5 + 0.5;
44164
+ const noise = hash(r, 0, frame);
44165
+ const charIdx = noise < density ? Math.min(particles.length - 1, Math.floor(density * particles.length)) : 0;
44166
+ buf += `\x1B[${boxTop + r};${boxLeft}H\x1B[38;5;${yellow}m${particles[charIdx]}`;
44167
+ const density2 = Math.sin(r * 0.5 + frame * 0.35 + 2) * 0.5 + 0.5;
44168
+ const noise2 = hash(r, boxW, frame);
44169
+ const charIdx2 = noise2 < density2 ? Math.min(particles.length - 1, Math.floor(density2 * particles.length)) : 0;
44170
+ buf += `\x1B[${boxTop + r};${boxLeft + boxW - 1}H${particles[charIdx2]}`;
44171
+ }
44172
+ const label = "INSTALLING";
44173
+ const labelCol = centerCol - Math.floor(label.length / 2);
44174
+ buf += `\x1B[${centerRow - 1};${labelCol}H\x1B[1;38;5;${yellow}m${label}`;
44175
+ const vLabel = `v${version}`;
44176
+ const vCol = centerCol - Math.floor(vLabel.length / 2);
44177
+ buf += `\x1B[${centerRow};${vCol}H\x1B[0;38;5;245m\x1B[48;5;${bgDark}m${vLabel}`;
44178
+ if (statusLine) {
44179
+ const sCol = centerCol - Math.floor(statusLine.length / 2);
44180
+ buf += `\x1B[${centerRow + 2};${Math.max(1, sCol)}H\x1B[38;5;240m\x1B[48;5;${bgDark}m${statusLine.slice(0, cols - 2)}`;
44181
+ }
44182
+ buf += `\x1B[0m`;
44183
+ process.stdout.write(buf);
44184
+ }
44185
+ function startInstallOverlay(version) {
44186
+ process.stdout.write("\x1B[?1049h\x1B[?25l");
44187
+ let frame = 0;
44188
+ let status = "";
44189
+ renderInstallFrame(version, frame, status);
44190
+ const timer = setInterval(() => {
44191
+ frame++;
44192
+ renderInstallFrame(version, frame, status);
44193
+ }, 80);
44194
+ return {
44195
+ setStatus(text) {
44196
+ status = text;
44197
+ },
44198
+ stop(finalText) {
44199
+ clearInterval(timer);
44200
+ status = finalText;
44201
+ renderInstallFrame(version, frame, status);
44202
+ }
44203
+ };
44204
+ }
44129
44205
  function startInlineSpinner(prefix) {
44130
44206
  let frame = 0;
44131
44207
  const nvActive = isNeovimActive();
@@ -44221,12 +44297,8 @@ async function handleUpdate(subcommand, ctx) {
44221
44297
  const doRebuild = menuResult.key === "rebuild" || menuResult.key === "full";
44222
44298
  const doPython = menuResult.key === "python" || menuResult.key === "full";
44223
44299
  const doCloudflared = menuResult.key === "full";
44224
- process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
44225
- process.stdout.write(`
44226
- ${c2.bold("Open Agents Update")}
44227
- ${c2.dim("\u2500".repeat(40))}
44228
-
44229
- `);
44300
+ const targetVersion = info?.latestVersion ?? currentVersion;
44301
+ const installOverlay = startInstallOverlay(targetVersion);
44230
44302
  let installError = "";
44231
44303
  const runInstall2 = (cmd) => new Promise((resolve32) => {
44232
44304
  const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
@@ -44237,24 +44309,22 @@ async function handleUpdate(subcommand, ctx) {
44237
44309
  child.stdout?.on("data", (chunk) => {
44238
44310
  const text = String(chunk);
44239
44311
  for (const line of text.split("\n")) {
44240
- if (line.trim()) {
44241
- process.stdout.write(` ${c2.dim("\u2502")} ${line.trim().slice(0, 70)}
44242
- `);
44243
- }
44312
+ if (line.trim())
44313
+ installOverlay.setStatus(line.trim().slice(0, 50));
44244
44314
  }
44245
44315
  });
44246
44316
  child.stderr?.on("data", (chunk) => {
44247
44317
  const text = String(chunk);
44248
44318
  for (const line of text.split("\n")) {
44249
44319
  if (line.trim() && !line.includes("npm warn")) {
44250
- process.stdout.write(` ${c2.dim("\u2502")} ${c2.yellow(line.trim().slice(0, 70))}
44251
- `);
44320
+ installOverlay.setStatus(line.trim().slice(0, 50));
44252
44321
  }
44253
44322
  }
44254
44323
  });
44255
44324
  });
44256
44325
  if (needsSudo) {
44257
- process.stdout.write("\x1B[?1049l");
44326
+ installOverlay.stop("Requesting permissions...");
44327
+ process.stdout.write("\x1B[?1049l\x1B[?25h");
44258
44328
  renderInfo("Global npm directory requires elevated permissions.");
44259
44329
  renderInfo("Enter your password if prompted...");
44260
44330
  safeWrite("\n");
@@ -44267,24 +44337,18 @@ async function handleUpdate(subcommand, ctx) {
44267
44337
  renderWarning("Could not acquire sudo credentials. Try: sudo npm i -g open-agents-ai");
44268
44338
  return;
44269
44339
  }
44270
- process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
44271
- process.stdout.write(`
44272
- ${c2.bold("Open Agents Update")}
44273
- ${c2.dim("\u2500".repeat(40))}
44274
-
44275
- `);
44340
+ const installOverlay2 = startInstallOverlay(targetVersion);
44341
+ Object.assign(installOverlay, installOverlay2);
44276
44342
  }
44277
44343
  const sudoPrefix = needsSudo ? "sudo " : "";
44278
44344
  let primaryUpdated = false;
44279
44345
  let depsUpdated = false;
44280
44346
  if (doPackage && info) {
44281
- const installSpinner = startInlineSpinner("Installing update");
44347
+ installOverlay.setStatus("Installing package...");
44282
44348
  const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
44283
44349
  let installOk = await runInstall2(installCmd);
44284
44350
  if (!installOk && /ENOTEMPTY|errno -39/i.test(installError)) {
44285
- installSpinner.stop("ENOTEMPTY \u2014 cleaning stale npm artifacts...");
44286
- process.stdout.write(` ${c2.dim("\u2502")} Removing stale temp directories and npm cache...
44287
- `);
44351
+ installOverlay.setStatus("Cleaning stale artifacts...");
44288
44352
  try {
44289
44353
  const prefix = await execA("npm prefix -g", { timeout: 5e3 });
44290
44354
  const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
@@ -44293,28 +44357,22 @@ async function handleUpdate(subcommand, ctx) {
44293
44357
  await execA(`${sudoPrefix}npm cache clean --force 2>/dev/null || true`, { timeout: 3e4 });
44294
44358
  } catch {
44295
44359
  }
44296
- process.stdout.write(` ${c2.dim("\u2502")} Retrying with --force...
44297
- `);
44298
- const retrySpinner = startInlineSpinner("Retrying install (force)");
44360
+ installOverlay.setStatus("Retrying install...");
44299
44361
  installError = "";
44300
44362
  installOk = await runInstall2(`${sudoPrefix}npm install -g open-agents-ai@latest --force --prefer-online`);
44301
- if (!installOk) {
44302
- retrySpinner.stop("Retry failed.");
44303
- } else {
44304
- retrySpinner.stop(`Update installed (v${info.latestVersion}).`);
44305
- }
44306
44363
  }
44307
44364
  if (!installOk) {
44308
- installSpinner.stop("Update install failed.");
44365
+ installOverlay.stop("Install failed");
44366
+ await new Promise((r) => setTimeout(r, 1500));
44367
+ process.stdout.write("\x1B[?1049l\x1B[?25h");
44309
44368
  renderWarning(`Try manually: ${sudoPrefix}npm i -g open-agents-ai`);
44310
- process.stdout.write("\x1B[?1049l");
44311
44369
  return;
44312
44370
  }
44313
- installSpinner.stop(`Update installed (v${info.latestVersion}).`);
44371
+ installOverlay.setStatus(`Package installed (v${info.latestVersion})`);
44314
44372
  primaryUpdated = true;
44315
44373
  }
44316
44374
  if (doDeps) {
44317
- const depsSpinner = startInlineSpinner("Updating subordinate dependencies");
44375
+ installOverlay.setStatus("Updating dependencies...");
44318
44376
  try {
44319
44377
  const prefix = await execA("npm prefix -g", { timeout: 5e3 });
44320
44378
  const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
@@ -44333,23 +44391,22 @@ async function handleUpdate(subcommand, ctx) {
44333
44391
  }
44334
44392
  } catch {
44335
44393
  }
44336
- depsSpinner.stop(depsUpdated ? "Dependencies updated." : "Dependencies checked.");
44394
+ installOverlay.setStatus(depsUpdated ? "Dependencies updated" : "Dependencies OK");
44337
44395
  }
44338
44396
  if (!primaryUpdated && !depsUpdated && !doRebuild && !doPython && !doCloudflared) {
44339
- renderInfo("No changes needed.");
44340
- safeWrite("\n");
44341
- await new Promise((r) => setTimeout(r, 1e3));
44342
- process.stdout.write("\x1B[?1049l");
44397
+ installOverlay.stop("No changes needed");
44398
+ await new Promise((r) => setTimeout(r, 1500));
44399
+ process.stdout.write("\x1B[?1049l\x1B[?25h");
44343
44400
  return;
44344
44401
  }
44345
44402
  if (doRebuild) {
44346
- const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
44347
- const rebuildOk = await new Promise((resolve32) => {
44403
+ installOverlay.setStatus("Rebuilding native modules...");
44404
+ await new Promise((resolve32) => {
44348
44405
  const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve32(true));
44349
44406
  child.stdout?.resume();
44350
44407
  child.stderr?.resume();
44351
44408
  });
44352
- rebuildSpinner.stop(rebuildOk ? "Native modules rebuilt." : "Native rebuild skipped.");
44409
+ installOverlay.setStatus("Native modules rebuilt");
44353
44410
  }
44354
44411
  const { existsSync: fsExists } = await import("node:fs");
44355
44412
  const { join: pathJoin } = await import("node:path");
@@ -44357,46 +44414,42 @@ async function handleUpdate(subcommand, ctx) {
44357
44414
  if (doPython) {
44358
44415
  let hasPython = hasCmd("python3") || hasCmd("python");
44359
44416
  if (!hasPython) {
44360
- const pyInstallSpinner = startInlineSpinner("Installing Python3");
44417
+ installOverlay.setStatus("Installing Python3...");
44361
44418
  try {
44362
44419
  ensurePython3();
44363
44420
  hasPython = hasCmd("python3") || hasCmd("python");
44364
- pyInstallSpinner.stop(hasPython ? "Python3 installed." : "Python3 install failed.");
44365
44421
  } catch {
44366
- pyInstallSpinner.stop("Python3 install failed.");
44367
44422
  }
44423
+ installOverlay.setStatus(hasPython ? "Python3 installed" : "Python3 unavailable");
44368
44424
  }
44369
44425
  if (hasPython && !checkPythonVenv()) {
44370
- const venvInstallSpinner = startInlineSpinner("Installing python3-venv");
44426
+ installOverlay.setStatus("Installing python3-venv...");
44371
44427
  try {
44372
44428
  ensurePythonVenv();
44373
- venvInstallSpinner.stop(checkPythonVenv() ? "python3-venv installed." : "python3-venv install failed.");
44374
44429
  } catch {
44375
- venvInstallSpinner.stop("python3-venv install failed.");
44376
44430
  }
44377
44431
  }
44378
44432
  const venvDir = pathJoin(getHome(), ".open-agents", "venv");
44379
44433
  const venvPip = pathJoin(venvDir, "bin", "pip");
44380
44434
  if (fsExists(venvPip)) {
44381
- const pySpinner = startInlineSpinner("Upgrading Python venv packages");
44382
- const pyOk = await new Promise((resolve32) => {
44435
+ installOverlay.setStatus("Upgrading Python packages...");
44436
+ await new Promise((resolve32) => {
44383
44437
  const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
44384
44438
  child.stdout?.resume();
44385
44439
  child.stderr?.resume();
44386
44440
  });
44387
- pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
44441
+ installOverlay.setStatus("Python packages updated");
44388
44442
  } else {
44389
- const pySpinner = startInlineSpinner("Setting up Python venv & deps");
44390
- await ensureVisionDeps((msg) => {
44391
- pySpinner.stop(msg);
44443
+ installOverlay.setStatus("Setting up Python venv...");
44444
+ await ensureVisionDeps(() => {
44392
44445
  }).catch(() => {
44393
44446
  });
44394
- pySpinner.stop("Python deps bootstrapped.");
44447
+ installOverlay.setStatus("Python deps bootstrapped");
44395
44448
  }
44396
44449
  }
44397
44450
  let hasCf = false;
44398
44451
  if (doCloudflared) {
44399
- const cfSpinner = startInlineSpinner("Checking cloudflared");
44452
+ installOverlay.setStatus("Checking cloudflared...");
44400
44453
  try {
44401
44454
  const { execSync: es } = await import("node:child_process");
44402
44455
  es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
@@ -44404,29 +44457,29 @@ async function handleUpdate(subcommand, ctx) {
44404
44457
  } catch {
44405
44458
  }
44406
44459
  if (!hasCf) {
44407
- cfSpinner.stop("Installing cloudflared...");
44408
- ensureCloudflaredBackground((msg) => renderInfo(msg));
44460
+ installOverlay.setStatus("Installing cloudflared...");
44461
+ ensureCloudflaredBackground(() => {
44462
+ });
44409
44463
  await new Promise((r) => setTimeout(r, 1e3));
44410
44464
  } else {
44411
- cfSpinner.stop("cloudflared ready.");
44465
+ installOverlay.setStatus("cloudflared ready");
44412
44466
  }
44413
44467
  ensureTranscribeCliBackground();
44414
44468
  }
44415
44469
  if (!primaryUpdated) {
44416
- safeWrite(`
44417
- ${c2.green("\u2714")} Done.
44418
- `);
44419
- await new Promise((r) => setTimeout(r, 1e3));
44420
- process.stdout.write("\x1B[?1049l");
44470
+ installOverlay.stop("Done");
44471
+ await new Promise((r) => setTimeout(r, 1500));
44472
+ process.stdout.write("\x1B[?1049l\x1B[?25h");
44421
44473
  return;
44422
44474
  }
44423
- const reloadSpinner = startInlineSpinner("Loading");
44475
+ installOverlay.setStatus("Reloading...");
44424
44476
  await new Promise((r) => setTimeout(r, 400));
44425
44477
  ctx.contextSave?.();
44426
44478
  const hadActiveTask = ctx.savePendingTaskState?.() ?? false;
44427
44479
  const resumeFlag = hadActiveTask ? "1" : "update-only";
44428
- reloadSpinner.stop("Reloading\u2026");
44429
- process.stdout.write("\x1B[?1049l");
44480
+ installOverlay.stop("Reloading\u2026");
44481
+ await new Promise((r) => setTimeout(r, 300));
44482
+ process.stdout.write("\x1B[?1049l\x1B[?25h");
44430
44483
  const { execPath, argv } = process;
44431
44484
  try {
44432
44485
  const { execFileSync } = await import("node:child_process");
@@ -56480,10 +56533,22 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
56480
56533
  headerBtnActive = command;
56481
56534
  (async () => {
56482
56535
  try {
56483
- await writeContentAsync(() => handleSlashCommand(command, commandCtxRef));
56536
+ const needsContentWrap = command === "/help" || command === "/cohere";
56537
+ if (needsContentWrap && statusBar.isActive)
56538
+ statusBar.beginContentWrite();
56539
+ await handleSlashCommand(command, commandCtxRef);
56540
+ if (needsContentWrap && statusBar.isActive)
56541
+ statusBar.endContentWrite();
56484
56542
  } catch {
56543
+ try {
56544
+ if (statusBar.isActive)
56545
+ statusBar.endContentWrite();
56546
+ } catch {
56547
+ }
56485
56548
  }
56486
56549
  headerBtnActive = null;
56550
+ if (statusBar.isActive)
56551
+ statusBar.handleResize();
56487
56552
  })();
56488
56553
  });
56489
56554
  rl.output = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.87",
3
+ "version": "0.138.89",
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",