open-agents-ai 0.105.0 → 0.105.1

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 +150 -92
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -40187,13 +40187,6 @@ async function handleUpdate(subcommand, ctx) {
40187
40187
  }
40188
40188
  };
40189
40189
  }
40190
- process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
40191
- process.stdout.write(`
40192
- ${c2.bold("Open Agents Update")}
40193
- ${c2.dim("\u2500".repeat(40))}
40194
-
40195
- `);
40196
- const checkSpinner = startInlineSpinner(`Checking for updates ${c2.dim(`(current: v${currentVersion})`)}`);
40197
40190
  const info = await checkForUpdate(currentVersion, true);
40198
40191
  const { exec: exec4, execSync: es2 } = await import("node:child_process");
40199
40192
  let needsSudo = false;
@@ -40207,6 +40200,65 @@ async function handleUpdate(subcommand, ctx) {
40207
40200
  }
40208
40201
  } catch {
40209
40202
  }
40203
+ const items = [];
40204
+ const skipKeys = [];
40205
+ items.push({ key: "hdr_status", label: selectColors.dim(`\u2500\u2500\u2500 v${currentVersion} \u2500\u2500\u2500`), kind: "header" });
40206
+ skipKeys.push("hdr_status");
40207
+ if (info) {
40208
+ items.push({ key: "info_avail", label: `Update available: v${currentVersion} \u2192 ${c2.bold(c2.green("v" + info.latestVersion))}`, kind: "info" });
40209
+ } else {
40210
+ items.push({ key: "info_avail", label: c2.dim("Primary package is up to date"), kind: "info" });
40211
+ }
40212
+ skipKeys.push("info_avail");
40213
+ items.push({ key: "hdr_options", label: selectColors.dim("\u2500\u2500\u2500 Update Options \u2500\u2500\u2500"), kind: "header" });
40214
+ skipKeys.push("hdr_options");
40215
+ if (info) {
40216
+ items.push({ key: "quick", label: "Quick Update", detail: "Install latest package only (fast)", kind: "action" });
40217
+ }
40218
+ items.push({ key: "full", label: "Full Update", detail: "Package + dependencies + native modules + Python + cloudflared", kind: "action" });
40219
+ items.push({ key: "deps_only", label: "Dependencies Only", detail: "Update subordinate deps (nexus, viem, moondream, etc.)", kind: "action" });
40220
+ items.push({ key: "rebuild", label: "Rebuild Native Modules", detail: "Rebuild better-sqlite3, node-pty, etc.", kind: "action" });
40221
+ items.push({ key: "python", label: "Python Packages Only", detail: "Upgrade venv packages (moondream, tesseract, etc.)", kind: "action" });
40222
+ items.push({ key: "hdr_policy", label: selectColors.dim("\u2500\u2500\u2500 Policy \u2500\u2500\u2500"), kind: "header" });
40223
+ skipKeys.push("hdr_policy");
40224
+ items.push({ key: "policy_auto", label: "Auto-update mode", detail: "Install updates automatically after tasks", kind: "action" });
40225
+ items.push({ key: "policy_manual", label: "Manual-update mode", detail: "Only update when you run /update", kind: "action" });
40226
+ const menuResult = await tuiSelect({
40227
+ items,
40228
+ title: "Update Manager",
40229
+ rl: ctx.rl,
40230
+ skipKeys,
40231
+ availableRows: ctx.availableContentRows?.()
40232
+ });
40233
+ if (!menuResult.confirmed || !menuResult.key) {
40234
+ renderInfo("Update cancelled.");
40235
+ return;
40236
+ }
40237
+ if (menuResult.key === "policy_auto") {
40238
+ const settings = { updateMode: "auto" };
40239
+ saveProjectSettings(repoRoot, settings);
40240
+ saveGlobalSettings(settings);
40241
+ renderInfo("Update mode: auto \u2014 updates install automatically after task completion.");
40242
+ return;
40243
+ }
40244
+ if (menuResult.key === "policy_manual") {
40245
+ const settings = { updateMode: "manual" };
40246
+ saveProjectSettings(repoRoot, settings);
40247
+ saveGlobalSettings(settings);
40248
+ renderInfo("Update mode: manual \u2014 only installs when you run /update.");
40249
+ return;
40250
+ }
40251
+ const doPackage = menuResult.key === "quick" || menuResult.key === "full";
40252
+ const doDeps = menuResult.key === "deps_only" || menuResult.key === "full";
40253
+ const doRebuild = menuResult.key === "rebuild" || menuResult.key === "full";
40254
+ const doPython = menuResult.key === "python" || menuResult.key === "full";
40255
+ const doCloudflared = menuResult.key === "full";
40256
+ process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
40257
+ process.stdout.write(`
40258
+ ${c2.bold("Open Agents Update")}
40259
+ ${c2.dim("\u2500".repeat(40))}
40260
+
40261
+ `);
40210
40262
  let installError = "";
40211
40263
  const runInstall2 = (cmd) => new Promise((resolve32) => {
40212
40264
  const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
@@ -40219,7 +40271,6 @@ async function handleUpdate(subcommand, ctx) {
40219
40271
  if (needsSudo) {
40220
40272
  process.stdout.write("\x1B[?1049l");
40221
40273
  renderInfo("Global npm directory requires elevated permissions.");
40222
- renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
40223
40274
  safeWrite("\n");
40224
40275
  try {
40225
40276
  es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
@@ -40236,14 +40287,11 @@ async function handleUpdate(subcommand, ctx) {
40236
40287
  }
40237
40288
  const sudoPrefix = needsSudo ? "sudo " : "";
40238
40289
  let primaryUpdated = false;
40239
- if (!info) {
40240
- checkSpinner.stop(`Primary package up to date (v${currentVersion}).`);
40241
- } else {
40242
- checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
40290
+ let depsUpdated = false;
40291
+ if (doPackage && info) {
40243
40292
  const installSpinner = startInlineSpinner("Installing update");
40244
40293
  const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
40245
- let installOk = false;
40246
- installOk = await runInstall2(installCmd);
40294
+ let installOk = await runInstall2(installCmd);
40247
40295
  if (!installOk && /ENOTEMPTY|errno -39/i.test(installError)) {
40248
40296
  installSpinner.stop("Cleaning stale npm temp files...");
40249
40297
  try {
@@ -40264,10 +40312,6 @@ async function handleUpdate(subcommand, ctx) {
40264
40312
  }
40265
40313
  if (!installOk) {
40266
40314
  installSpinner.stop("Update install failed.");
40267
- const errPreview = installError.split("\n").filter((l) => l.trim()).slice(-3).join("\n ");
40268
- if (errPreview)
40269
- renderWarning(`Error:
40270
- ${errPreview}`);
40271
40315
  renderWarning(`Try manually: ${sudoPrefix}npm i -g open-agents-ai`);
40272
40316
  process.stdout.write("\x1B[?1049l");
40273
40317
  return;
@@ -40275,99 +40319,113 @@ async function handleUpdate(subcommand, ctx) {
40275
40319
  installSpinner.stop(`Update installed (v${info.latestVersion}).`);
40276
40320
  primaryUpdated = true;
40277
40321
  }
40278
- const depsSpinner = startInlineSpinner("Checking subordinate dependencies");
40279
- let depsUpdated = false;
40280
- try {
40281
- const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
40282
- const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
40283
- const { existsSync: fe, readFileSync: rf } = await import("node:fs");
40284
- const { join: pj } = await import("node:path");
40285
- const pkgPath = pj(globalModules, "open-agents-ai", "package.json");
40286
- if (fe(pkgPath)) {
40287
- const pkg = JSON.parse(rf(pkgPath, "utf8"));
40288
- const allDeps = { ...pkg.dependencies || {}, ...pkg.optionalDependencies || {} };
40289
- const depNames = Object.keys(allDeps);
40290
- if (depNames.length > 0) {
40291
- const updateCmd = `${sudoPrefix}npm update --prefer-online --prefix "${pj(globalModules, "open-agents-ai")}" 2>/dev/null || true`;
40292
- const updateOk = await runInstall2(updateCmd);
40293
- if (updateOk)
40294
- depsUpdated = true;
40322
+ if (doDeps) {
40323
+ const depsSpinner = startInlineSpinner("Updating subordinate dependencies");
40324
+ try {
40325
+ const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
40326
+ const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
40327
+ const { existsSync: fe, readFileSync: rf } = await import("node:fs");
40328
+ const { join: pj } = await import("node:path");
40329
+ const pkgPath = pj(globalModules, "open-agents-ai", "package.json");
40330
+ if (fe(pkgPath)) {
40331
+ const pkg = JSON.parse(rf(pkgPath, "utf8"));
40332
+ const allDeps = { ...pkg.dependencies || {}, ...pkg.optionalDependencies || {} };
40333
+ if (Object.keys(allDeps).length > 0) {
40334
+ const updateCmd = `${sudoPrefix}npm update --prefer-online --prefix "${pj(globalModules, "open-agents-ai")}" 2>/dev/null || true`;
40335
+ const updateOk = await runInstall2(updateCmd);
40336
+ if (updateOk)
40337
+ depsUpdated = true;
40338
+ }
40295
40339
  }
40340
+ } catch {
40296
40341
  }
40297
- } catch {
40342
+ depsSpinner.stop(depsUpdated ? "Dependencies updated." : "Dependencies checked.");
40298
40343
  }
40299
- depsSpinner.stop(depsUpdated ? "Dependencies updated to latest." : "Dependencies checked.");
40300
- if (!primaryUpdated && !depsUpdated) {
40301
- renderInfo("Everything is up to date \u2014 no changes needed.");
40344
+ if (!primaryUpdated && !depsUpdated && !doRebuild && !doPython && !doCloudflared) {
40345
+ renderInfo("No changes needed.");
40302
40346
  safeWrite("\n");
40303
40347
  await new Promise((r) => setTimeout(r, 1e3));
40304
40348
  process.stdout.write("\x1B[?1049l");
40305
40349
  return;
40306
40350
  }
40307
- const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
40308
- const rebuildOk = await new Promise((resolve32) => {
40309
- const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve32(true));
40310
- child.stdout?.resume();
40311
- child.stderr?.resume();
40312
- });
40313
- rebuildSpinner.stop(rebuildOk ? "Native modules rebuilt." : "Native rebuild skipped.");
40351
+ if (doRebuild) {
40352
+ const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
40353
+ const rebuildOk = await new Promise((resolve32) => {
40354
+ const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve32(true));
40355
+ child.stdout?.resume();
40356
+ child.stderr?.resume();
40357
+ });
40358
+ rebuildSpinner.stop(rebuildOk ? "Native modules rebuilt." : "Native rebuild skipped.");
40359
+ }
40314
40360
  const { existsSync: fsExists } = await import("node:fs");
40315
40361
  const { join: pathJoin } = await import("node:path");
40316
40362
  const { homedir: getHome } = await import("node:os");
40317
- let hasPython = hasCmd("python3") || hasCmd("python");
40318
- if (!hasPython) {
40319
- const pyInstallSpinner = startInlineSpinner("Installing Python3");
40320
- try {
40321
- ensurePython3();
40322
- hasPython = hasCmd("python3") || hasCmd("python");
40323
- pyInstallSpinner.stop(hasPython ? "Python3 installed." : "Python3 install failed.");
40324
- } catch {
40325
- pyInstallSpinner.stop("Python3 install failed.");
40363
+ if (doPython) {
40364
+ let hasPython = hasCmd("python3") || hasCmd("python");
40365
+ if (!hasPython) {
40366
+ const pyInstallSpinner = startInlineSpinner("Installing Python3");
40367
+ try {
40368
+ ensurePython3();
40369
+ hasPython = hasCmd("python3") || hasCmd("python");
40370
+ pyInstallSpinner.stop(hasPython ? "Python3 installed." : "Python3 install failed.");
40371
+ } catch {
40372
+ pyInstallSpinner.stop("Python3 install failed.");
40373
+ }
40374
+ }
40375
+ if (hasPython && !checkPythonVenv()) {
40376
+ const venvInstallSpinner = startInlineSpinner("Installing python3-venv");
40377
+ try {
40378
+ ensurePythonVenv();
40379
+ venvInstallSpinner.stop(checkPythonVenv() ? "python3-venv installed." : "python3-venv install failed.");
40380
+ } catch {
40381
+ venvInstallSpinner.stop("python3-venv install failed.");
40382
+ }
40383
+ }
40384
+ const venvDir = pathJoin(getHome(), ".open-agents", "venv");
40385
+ const venvPip = pathJoin(venvDir, "bin", "pip");
40386
+ if (fsExists(venvPip)) {
40387
+ const pySpinner = startInlineSpinner("Upgrading Python venv packages");
40388
+ const pyOk = await new Promise((resolve32) => {
40389
+ const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
40390
+ child.stdout?.resume();
40391
+ child.stderr?.resume();
40392
+ });
40393
+ pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
40394
+ } else {
40395
+ const pySpinner = startInlineSpinner("Setting up Python venv & deps");
40396
+ await ensureVisionDeps((msg) => {
40397
+ pySpinner.stop(msg);
40398
+ }).catch(() => {
40399
+ });
40400
+ pySpinner.stop("Python deps bootstrapped.");
40326
40401
  }
40327
40402
  }
40328
- if (hasPython && !checkPythonVenv()) {
40329
- const venvInstallSpinner = startInlineSpinner("Installing python3-venv");
40403
+ let hasCf = false;
40404
+ if (doCloudflared) {
40405
+ const cfSpinner = startInlineSpinner("Checking cloudflared");
40330
40406
  try {
40331
- ensurePythonVenv();
40332
- venvInstallSpinner.stop(checkPythonVenv() ? "python3-venv installed." : "python3-venv install failed.");
40407
+ const { execSync: es } = await import("node:child_process");
40408
+ es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
40409
+ hasCf = true;
40333
40410
  } catch {
40334
- venvInstallSpinner.stop("python3-venv install failed.");
40335
40411
  }
40412
+ if (!hasCf) {
40413
+ cfSpinner.stop("Installing cloudflared...");
40414
+ ensureCloudflaredBackground((msg) => renderInfo(msg));
40415
+ await new Promise((r) => setTimeout(r, 1e3));
40416
+ } else {
40417
+ cfSpinner.stop("cloudflared ready.");
40418
+ }
40419
+ ensureTranscribeCliBackground();
40336
40420
  }
40337
- const venvDir = pathJoin(getHome(), ".open-agents", "venv");
40338
- const venvPip = pathJoin(venvDir, "bin", "pip");
40339
- if (fsExists(venvPip)) {
40340
- const pySpinner = startInlineSpinner("Upgrading Python venv packages");
40341
- const pyOk = await new Promise((resolve32) => {
40342
- const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
40343
- child.stdout?.resume();
40344
- child.stderr?.resume();
40345
- });
40346
- pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
40347
- } else {
40348
- const pySpinner = startInlineSpinner("Setting up Python venv & deps");
40349
- await ensureVisionDeps((msg) => {
40350
- pySpinner.stop(msg);
40351
- }).catch(() => {
40352
- });
40353
- pySpinner.stop("Python deps bootstrapped.");
40354
- }
40355
- const cfSpinner = startInlineSpinner("Checking cloudflared");
40356
- let hasCf = false;
40357
- try {
40358
- const { execSync: es } = await import("node:child_process");
40359
- es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
40360
- hasCf = true;
40361
- } catch {
40362
- }
40363
- if (!hasCf) {
40364
- cfSpinner.stop("Installing cloudflared...");
40365
- ensureCloudflaredBackground((msg) => renderInfo(msg));
40421
+ if (!primaryUpdated) {
40422
+ safeWrite(`
40423
+ ${c2.green("\u2714")} Done.
40424
+ `);
40366
40425
  await new Promise((r) => setTimeout(r, 1e3));
40367
- } else {
40368
- cfSpinner.stop("cloudflared ready.");
40426
+ process.stdout.write("\x1B[?1049l");
40427
+ return;
40369
40428
  }
40370
- ensureTranscribeCliBackground();
40371
40429
  const reloadSpinner = startInlineSpinner("Loading");
40372
40430
  await new Promise((r) => setTimeout(r, 400));
40373
40431
  ctx.contextSave?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.105.0",
3
+ "version": "0.105.1",
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",