arisa 2.3.53 → 2.3.55
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.
- package/bin/arisa.js +50 -6
- package/package.json +1 -1
- package/src/daemon/setup.ts +7 -4
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
|
-
|
|
504
|
+
// Uses @inquirer/prompts checkbox when available (same UI as setup.ts).
|
|
505
|
+
async function preflightInstallClis() {
|
|
505
506
|
const clis = {
|
|
506
507
|
claude: "@anthropic-ai/claude-code",
|
|
507
508
|
codex: "@openai/codex",
|
|
@@ -517,16 +518,59 @@ function preflightInstallClis() {
|
|
|
517
518
|
|
|
518
519
|
if (missing.length === 0) return;
|
|
519
520
|
|
|
520
|
-
|
|
521
|
-
|
|
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
|
+
// Try @inquirer/prompts for the same checkbox UI as setup.ts
|
|
533
|
+
let inq = null;
|
|
534
|
+
try { inq = await import("@inquirer/prompts"); } catch {}
|
|
535
|
+
|
|
536
|
+
if (inq) {
|
|
537
|
+
const selected = await inq.checkbox({
|
|
538
|
+
message: "Install missing CLIs? (space to select, enter to confirm)",
|
|
539
|
+
choices: missing.map((cli) => ({
|
|
540
|
+
name: `${cli.name === "claude" ? "Claude" : "Codex"} (${cli.pkg})`,
|
|
541
|
+
value: cli,
|
|
542
|
+
checked: true,
|
|
543
|
+
})),
|
|
544
|
+
});
|
|
545
|
+
toInstall = selected;
|
|
546
|
+
} else {
|
|
547
|
+
// Fallback: simple Y/n
|
|
548
|
+
const rl = require("node:readline");
|
|
549
|
+
const ask = (q) =>
|
|
550
|
+
new Promise((resolve) => {
|
|
551
|
+
const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
|
|
552
|
+
iface.question(q, (a) => { iface.close(); resolve(a.trim()); });
|
|
553
|
+
});
|
|
554
|
+
const answer = await ask("\nInstall missing CLIs? (Y/n): ");
|
|
555
|
+
if (answer.toLowerCase() === "n") toInstall = [];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (toInstall.length === 0) {
|
|
560
|
+
process.stdout.write(" Skipping CLI installation.\n");
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
for (const { name, pkg } of toInstall) {
|
|
565
|
+
process.stdout.write(`\nInstalling ${name}...\n`);
|
|
522
566
|
const result = spawnSync("bun", ["add", "-g", pkg], {
|
|
523
567
|
stdio: "inherit",
|
|
524
568
|
timeout: 180000,
|
|
525
569
|
});
|
|
526
570
|
if (result.status === 0) {
|
|
527
|
-
process.stdout.write(`
|
|
571
|
+
process.stdout.write(` \u2713 ${name} installed\n`);
|
|
528
572
|
} else {
|
|
529
|
-
process.stdout.write(`
|
|
573
|
+
process.stdout.write(` \u2717 ${name} install failed\n`);
|
|
530
574
|
}
|
|
531
575
|
}
|
|
532
576
|
|
|
@@ -535,7 +579,7 @@ function preflightInstallClis() {
|
|
|
535
579
|
}
|
|
536
580
|
|
|
537
581
|
if (isRoot() && arisaUserExists()) {
|
|
538
|
-
preflightInstallClis();
|
|
582
|
+
await preflightInstallClis();
|
|
539
583
|
}
|
|
540
584
|
|
|
541
585
|
// Then fall through to normal daemon startup
|
package/package.json
CHANGED
package/src/daemon/setup.ts
CHANGED
|
@@ -140,20 +140,23 @@ export async function runSetup(): Promise<boolean> {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// ─── Phase 2: CLI Installation ──────────────────────────────────
|
|
143
|
+
// When running as root, bin/arisa.js pre-flight already handled CLI
|
|
144
|
+
// installation with the interactive checkbox before switching to arisa.
|
|
145
|
+
// This phase is only needed for direct (non-root) runs.
|
|
143
146
|
|
|
144
147
|
if (process.stdin.isTTY) {
|
|
145
148
|
let claudeInstalled = isAgentCliInstalled("claude");
|
|
146
149
|
let codexInstalled = isAgentCliInstalled("codex");
|
|
147
150
|
|
|
148
|
-
console.log("\nCLI Status:");
|
|
149
|
-
console.log(` ${claudeInstalled ? "✓" : "✗"} Claude${claudeInstalled ? "" : " — not installed"}`);
|
|
150
|
-
console.log(` ${codexInstalled ? "✓" : "✗"} Codex${codexInstalled ? "" : " — not installed"}`);
|
|
151
|
-
|
|
152
151
|
const missing: AgentCliName[] = [];
|
|
153
152
|
if (!claudeInstalled) missing.push("claude");
|
|
154
153
|
if (!codexInstalled) missing.push("codex");
|
|
155
154
|
|
|
156
155
|
if (missing.length > 0) {
|
|
156
|
+
console.log("\nCLI Status:");
|
|
157
|
+
console.log(` ${claudeInstalled ? "✓" : "✗"} Claude${claudeInstalled ? "" : " — not installed"}`);
|
|
158
|
+
console.log(` ${codexInstalled ? "✓" : "✗"} Codex${codexInstalled ? "" : " — not installed"}`);
|
|
159
|
+
|
|
157
160
|
let toInstall: AgentCliName[] = [];
|
|
158
161
|
|
|
159
162
|
if (inq) {
|