arisa 2.3.53 → 2.3.54

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/bin/arisa.js +40 -6
  2. package/package.json +1 -1
package/bin/arisa.js CHANGED
@@ -501,7 +501,8 @@ if (isRoot() && arisaUserExists()) {
501
501
 
502
502
  // Pre-flight: install missing CLIs while still root (before su arisa).
503
503
  // arisa user has read+execute but NOT write access to root's bun dir.
504
- function preflightInstallClis() {
504
+ // Interactive when TTY — asks which CLIs to install.
505
+ async function preflightInstallClis() {
505
506
  const clis = {
506
507
  claude: "@anthropic-ai/claude-code",
507
508
  codex: "@openai/codex",
@@ -517,16 +518,49 @@ function preflightInstallClis() {
517
518
 
518
519
  if (missing.length === 0) return;
519
520
 
520
- process.stdout.write(`[preflight] Installing missing CLIs as root: ${missing.map((m) => m.name).join(", ")}\n`);
521
- for (const { name, pkg } of missing) {
521
+ // Show status
522
+ process.stdout.write("\nCLI Status:\n");
523
+ for (const name of Object.keys(clis)) {
524
+ const installed = existsSync(join(bunBinDir, name));
525
+ const label = name === "claude" ? "Claude" : "Codex";
526
+ process.stdout.write(` ${installed ? "\u2713" : "\u2717"} ${label}${installed ? "" : " \u2014 not installed"}\n`);
527
+ }
528
+
529
+ let toInstall = missing;
530
+
531
+ if (process.stdin.isTTY) {
532
+ const rl = require("node:readline");
533
+ const ask = (q) =>
534
+ new Promise((resolve) => {
535
+ const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
536
+ iface.question(q, (a) => { iface.close(); resolve(a.trim()); });
537
+ });
538
+
539
+ toInstall = [];
540
+ for (const cli of missing) {
541
+ const label = cli.name === "claude" ? "Claude" : "Codex";
542
+ const answer = await ask(`Install ${label} (${cli.pkg})? (Y/n): `);
543
+ if (answer.toLowerCase() !== "n") {
544
+ toInstall.push(cli);
545
+ }
546
+ }
547
+ }
548
+
549
+ if (toInstall.length === 0) {
550
+ process.stdout.write(" Skipping CLI installation.\n");
551
+ return;
552
+ }
553
+
554
+ for (const { name, pkg } of toInstall) {
555
+ process.stdout.write(`\nInstalling ${name}...\n`);
522
556
  const result = spawnSync("bun", ["add", "-g", pkg], {
523
557
  stdio: "inherit",
524
558
  timeout: 180000,
525
559
  });
526
560
  if (result.status === 0) {
527
- process.stdout.write(`[preflight] ${name} installed\n`);
561
+ process.stdout.write(` \u2713 ${name} installed\n`);
528
562
  } else {
529
- process.stdout.write(`[preflight] ${name} install failed\n`);
563
+ process.stdout.write(` \u2717 ${name} install failed\n`);
530
564
  }
531
565
  }
532
566
 
@@ -535,7 +569,7 @@ function preflightInstallClis() {
535
569
  }
536
570
 
537
571
  if (isRoot() && arisaUserExists()) {
538
- preflightInstallClis();
572
+ await preflightInstallClis();
539
573
  }
540
574
 
541
575
  // Then fall through to normal daemon startup
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arisa",
3
- "version": "2.3.53",
3
+ "version": "2.3.54",
4
4
  "description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
5
5
  "keywords": [
6
6
  "tinyclaw",