open-agents-ai 0.187.216 → 0.187.218

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 +175 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -291721,11 +291721,9 @@ function tuiSelect(opts) {
291721
291721
  const first2 = findSelectable(0, 1);
291722
291722
  cursor = first2 >= 0 ? first2 : 0;
291723
291723
  }
291724
- const reservedTopBottom = 0;
291725
291724
  const hasCrumbs = opts.breadcrumbs && opts.breadcrumbs.length > 0;
291726
- const selectChrome = (hasCrumbs ? 11 : 10) + 1;
291727
- const contentArea = opts.availableRows ? opts.availableRows + reservedTopBottom : termRows();
291728
- let maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
291725
+ const selectChrome = (hasCrumbs ? 9 : 8) + 1;
291726
+ let maxVisible = opts.maxVisible ?? Math.max(3, termRows() - selectChrome);
291729
291727
  let scrollOffset = 0;
291730
291728
  let lastRenderedLines = 0;
291731
291729
  return new Promise((resolve39) => {
@@ -293277,6 +293275,7 @@ __export(setup_exports, {
293277
293275
  pullModelWithAutoUpdate: () => pullModelWithAutoUpdate,
293278
293276
  recommendModel: () => recommendModel,
293279
293277
  renderScoreBar: () => renderScoreBar,
293278
+ runElevatedCommand: () => runElevatedCommand,
293280
293279
  runSetupWizard: () => runSetupWizard,
293281
293280
  updateOllama: () => updateOllama
293282
293281
  });
@@ -293564,15 +293563,24 @@ function ensureZstd() {
293564
293563
  process.stdout.write(`
293565
293564
  ${c3.cyan("●")} Installing zstd (required by ollama install.sh)...
293566
293565
  `);
293567
- const candidates = [
293568
- `pkexec sh -c "${installCmd}"`,
293569
- `sudo ${installCmd}`,
293570
- installCmd
293571
- // bare (works if already root)
293572
- ];
293573
- for (const cmd of candidates) {
293566
+ const hasDisplay = !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
293567
+ const askpassHelper = detectAskpassHelper() ?? writeAskpassHelper();
293568
+ const askpassEnv = askpassHelper ? { ...process.env, SUDO_ASKPASS: askpassHelper, DEBIAN_FRONTEND: "noninteractive" } : { ...process.env, DEBIAN_FRONTEND: "noninteractive" };
293569
+ const candidates = [];
293570
+ if (hasCmd("pkexec") && hasDisplay) {
293571
+ candidates.push({ cmd: `pkexec sh -c ${shellEscape(installCmd)}`, env: process.env });
293572
+ }
293573
+ if (askpassHelper) {
293574
+ candidates.push({ cmd: `sudo -A ${installCmd}`, env: askpassEnv });
293575
+ }
293576
+ candidates.push({ cmd: installCmd, env: process.env });
293577
+ for (const cand of candidates) {
293574
293578
  try {
293575
- execSync48(cmd, { stdio: "inherit", timeout: 18e4 });
293579
+ execSync48(cand.cmd, {
293580
+ stdio: ["ignore", "inherit", "pipe"],
293581
+ env: cand.env,
293582
+ timeout: 18e4
293583
+ });
293576
293584
  if (hasCmd("zstd")) {
293577
293585
  process.stdout.write(` ${c3.green("✔")} zstd installed.
293578
293586
  `);
@@ -293585,17 +293593,159 @@ function ensureZstd() {
293585
293593
  `);
293586
293594
  return false;
293587
293595
  }
293596
+ function detectAskpassHelper() {
293597
+ const linuxHelpers = [
293598
+ "/usr/lib/ssh/ssh-askpass",
293599
+ // openssh-askpass
293600
+ "/usr/lib/openssh/ssh-askpass",
293601
+ "/usr/libexec/openssh/ssh-askpass",
293602
+ "/usr/bin/ksshaskpass",
293603
+ // KDE
293604
+ "/usr/bin/lxqt-openssh-askpass"
293605
+ ];
293606
+ if (process.platform === "linux") {
293607
+ for (const path5 of linuxHelpers) {
293608
+ try {
293609
+ if (existsSync59(path5)) return path5;
293610
+ } catch {
293611
+ }
293612
+ }
293613
+ for (const name10 of ["ssh-askpass", "ksshaskpass", "x11-ssh-askpass"]) {
293614
+ if (hasCmd(name10)) {
293615
+ try {
293616
+ const p2 = execSync48(`command -v ${name10}`, { encoding: "utf8" }).trim();
293617
+ if (p2) return p2;
293618
+ } catch {
293619
+ }
293620
+ }
293621
+ }
293622
+ }
293623
+ return null;
293624
+ }
293625
+ function writeAskpassHelper() {
293626
+ const tmpDir = join76(homedir26(), ".open-agents");
293627
+ try {
293628
+ mkdirSync33(tmpDir, { recursive: true });
293629
+ } catch {
293630
+ }
293631
+ const helperPath = join76(tmpDir, "askpass-helper.sh");
293632
+ let body = "";
293633
+ if (process.platform === "darwin") {
293634
+ body = `#!/bin/sh
293635
+ osascript -e 'Tell application "System Events" to display dialog "Open Agents needs admin access to update Ollama.\\n\\nPassword:" with title "Open Agents" with hidden answer default answer "" buttons {"Cancel","OK"} default button "OK"' -e 'text returned of result' 2>/dev/null
293636
+ `;
293637
+ } else if (process.platform === "linux") {
293638
+ const hasZenity = hasCmd("zenity");
293639
+ const hasKdialog = hasCmd("kdialog");
293640
+ const hasYad = hasCmd("yad");
293641
+ if (!hasZenity && !hasKdialog && !hasYad) return null;
293642
+ const lines = ["#!/bin/sh", 'TITLE="Open Agents"', 'TEXT="Open Agents needs admin access to update Ollama. Enter your password:"'];
293643
+ if (hasZenity) {
293644
+ lines.push('zenity --password --title="$TITLE" --text="$TEXT" 2>/dev/null && exit 0');
293645
+ }
293646
+ if (hasKdialog) {
293647
+ lines.push('kdialog --title "$TITLE" --password "$TEXT" 2>/dev/null && exit 0');
293648
+ }
293649
+ if (hasYad) {
293650
+ lines.push('yad --title="$TITLE" --text="$TEXT" --entry --hide-text 2>/dev/null && exit 0');
293651
+ }
293652
+ lines.push("exit 1");
293653
+ body = lines.join("\n") + "\n";
293654
+ } else {
293655
+ return null;
293656
+ }
293657
+ try {
293658
+ writeFileSync30(helperPath, body, { mode: 448 });
293659
+ execSync48(`chmod 700 "${helperPath}"`, { stdio: "ignore" });
293660
+ return helperPath;
293661
+ } catch {
293662
+ return null;
293663
+ }
293664
+ }
293665
+ function buildElevatedInstall() {
293666
+ const installCmd = "curl -fsSL https://ollama.com/install.sh | sh";
293667
+ const baseEnv = { ...process.env };
293668
+ if (process.platform === "linux" && hasCmd("pkexec") && (process.env.DISPLAY || process.env.WAYLAND_DISPLAY)) {
293669
+ return {
293670
+ cmd: `pkexec sh -c ${shellEscape(installCmd)}`,
293671
+ env: baseEnv,
293672
+ mode: "pkexec"
293673
+ };
293674
+ }
293675
+ const nativeAskpass = detectAskpassHelper();
293676
+ const writtenHelper = nativeAskpass ?? writeAskpassHelper();
293677
+ if (writtenHelper) {
293678
+ return {
293679
+ cmd: installCmd,
293680
+ // unchanged — install.sh's internal sudo calls will use ASKPASS
293681
+ env: { ...baseEnv, SUDO_ASKPASS: writtenHelper, DEBIAN_FRONTEND: "noninteractive" },
293682
+ mode: "askpass"
293683
+ };
293684
+ }
293685
+ return {
293686
+ cmd: installCmd,
293687
+ env: baseEnv,
293688
+ mode: "fallback"
293689
+ };
293690
+ }
293691
+ function shellEscape(s2) {
293692
+ return `'${s2.replace(/'/g, `'\\''`)}'`;
293693
+ }
293694
+ function runElevatedCommand(command, opts = {}) {
293695
+ const timeout2 = opts.timeoutMs ?? 6e4;
293696
+ const hasDisplay = !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
293697
+ const askpassHelper = detectAskpassHelper() ?? writeAskpassHelper();
293698
+ const askpassEnv = askpassHelper ? { ...process.env, SUDO_ASKPASS: askpassHelper } : process.env;
293699
+ const candidates = [];
293700
+ if (hasCmd("pkexec") && hasDisplay) {
293701
+ candidates.push({ cmd: `pkexec sh -c ${shellEscape(command)}`, env: process.env });
293702
+ }
293703
+ if (askpassHelper) {
293704
+ candidates.push({ cmd: `sudo -A sh -c ${shellEscape(command)}`, env: askpassEnv });
293705
+ }
293706
+ candidates.push({ cmd: command, env: process.env });
293707
+ let lastErr = null;
293708
+ for (const cand of candidates) {
293709
+ try {
293710
+ execSync48(cand.cmd, {
293711
+ stdio: ["ignore", "pipe", "pipe"],
293712
+ // never inherit TUI stdin
293713
+ env: cand.env,
293714
+ timeout: timeout2
293715
+ });
293716
+ return;
293717
+ } catch (err) {
293718
+ lastErr = err;
293719
+ }
293720
+ }
293721
+ if (!opts.swallowErrors && lastErr) {
293722
+ throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
293723
+ }
293724
+ }
293588
293725
  function runOllamaInstallScript() {
293589
293726
  const zstdReady = ensureZstd();
293590
293727
  if (!zstdReady) {
293591
293728
  process.stdout.write(` ${c3.yellow("⚠")} Proceeding without zstd — install may fail if the script requires it.
293592
293729
  `);
293593
293730
  }
293594
- const cmd = "curl -fsSL https://ollama.com/install.sh | sh";
293731
+ const elevated = buildElevatedInstall();
293732
+ if (elevated.mode === "pkexec") {
293733
+ process.stdout.write(` ${c3.cyan("●")} Elevation: pkexec (graphical PolicyKit prompt)
293734
+ `);
293735
+ } else if (elevated.mode === "askpass") {
293736
+ process.stdout.write(` ${c3.cyan("●")} Elevation: SUDO_ASKPASS (GUI password modal)
293737
+ `);
293738
+ } else {
293739
+ process.stdout.write(` ${c3.yellow("⚠")} No GUI password helper available — install may stall waiting for sudo.
293740
+ `);
293741
+ process.stdout.write(` ${c3.yellow("⚠")} Install one of: pkexec / zenity / kdialog / yad / ssh-askpass
293742
+ `);
293743
+ }
293595
293744
  const runOnce = () => {
293596
- execSync48(cmd, {
293597
- stdio: ["inherit", "inherit", "pipe"],
293598
- timeout: 3e5
293745
+ execSync48(elevated.cmd, {
293746
+ stdio: ["ignore", "inherit", "pipe"],
293747
+ env: elevated.env,
293748
+ timeout: 6e5
293599
293749
  });
293600
293750
  };
293601
293751
  try {
@@ -304975,10 +305125,13 @@ async function handleParallel(arg, ctx3) {
304975
305125
  const overrideContent = `[Service]
304976
305126
  Environment="OLLAMA_NUM_PARALLEL=${n2}"
304977
305127
  `;
304978
- execSync57(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
304979
- execSync57(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
304980
- execSync57("sudo systemctl daemon-reload", { stdio: "pipe" });
304981
- execSync57("sudo systemctl restart ollama.service", { stdio: "pipe" });
305128
+ const { runElevatedCommand: runElev } = await Promise.resolve().then(() => (init_setup(), setup_exports));
305129
+ runElev(`mkdir -p ${overrideDir}`, { timeoutMs: 3e4 });
305130
+ const escapedContent = overrideContent.replace(/'/g, `'\\''`);
305131
+ runElev(`bash -c 'cat > ${overrideFile} <<EOF
305132
+ ${escapedContent}EOF'`, { timeoutMs: 3e4 });
305133
+ runElev("systemctl daemon-reload", { timeoutMs: 3e4 });
305134
+ runElev("systemctl restart ollama.service", { timeoutMs: 3e4 });
304982
305135
  let ready = false;
304983
305136
  for (let i2 = 0; i2 < 30 && !ready; i2++) {
304984
305137
  await new Promise((r2) => setTimeout(r2, 500));
@@ -305410,8 +305563,8 @@ async function handleUpdate(subcommand, ctx3) {
305410
305563
  if (doUpdateOllama()) {
305411
305564
  renderInfo("Ollama updated successfully.");
305412
305565
  try {
305413
- const { execSync: es } = await import("node:child_process");
305414
- es("sudo systemctl restart ollama 2>/dev/null || true", { timeout: 1e4, stdio: "pipe" });
305566
+ const { runElevatedCommand: runElevatedCommand2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
305567
+ runElevatedCommand2("systemctl restart ollama", { timeoutMs: 1e4, swallowErrors: true });
305415
305568
  } catch {
305416
305569
  }
305417
305570
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.216",
3
+ "version": "0.187.218",
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",