arisa 2.3.26 → 2.3.27

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 CHANGED
@@ -416,14 +416,15 @@ function arisaUserExists() {
416
416
  }
417
417
 
418
418
  function isArisaUserProvisioned() {
419
- return arisaUserExists() && existsSync("/home/arisa/.bun/bin/bun");
419
+ return arisaUserExists();
420
420
  }
421
421
 
422
422
  function step(ok, msg) {
423
423
  process.stdout.write(` ${ok ? "\u2713" : "\u2717"} ${msg}\n`);
424
424
  }
425
425
 
426
- const ARISA_BUN_ENV = 'export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/arisa/.bun/bin:$PATH';
426
+ const ROOT_BUN_INSTALL = process.env.BUN_INSTALL || join(homeDir, ".bun");
427
+ const ARISA_BUN_ENV = `export BUN_INSTALL=${ROOT_BUN_INSTALL} && export PATH=${ROOT_BUN_INSTALL}/bin:$PATH`;
427
428
 
428
429
  function provisionArisaUser() {
429
430
  process.stdout.write("Creating user 'arisa' for Claude/Codex CLI execution...\n");
@@ -445,21 +446,20 @@ function provisionArisaUser() {
445
446
  step(false, `Sudo setup skipped: ${e.message || e}`);
446
447
  }
447
448
 
448
- // 3. Install bun for arisa (curl lightweight, no bun child process)
449
- process.stdout.write(" Installing bun for arisa (this may take a minute)...\n");
450
- const bunInstall = spawnSync("su", ["-", "arisa", "-c", "curl -fsSL https://bun.sh/install | bash"], {
451
- stdio: "inherit",
452
- timeout: 180_000,
453
- });
454
- if (bunInstall.status !== 0) {
455
- step(false, "Failed to install bun");
456
- process.exit(1);
457
- }
458
- step(true, "Bun installed for arisa");
449
+ // 3. Give arisa access to root's bun (no separate install needed)
450
+ grantBunAccess();
451
+ step(true, "Access to root's bun granted");
459
452
 
460
453
  process.stdout.write(" Done. Core will run as arisa; Claude/Codex calls are direct.\n\n");
461
454
  }
462
455
 
456
+ function grantBunAccess() {
457
+ // Allow arisa to traverse into /root (execute only, not read)
458
+ spawnSync("chmod", ["o+x", homeDir], { stdio: "ignore" });
459
+ // Allow arisa to read+execute root's bun and globally installed CLIs
460
+ spawnSync("chmod", ["-R", "o+rX", ROOT_BUN_INSTALL], { stdio: "ignore" });
461
+ }
462
+
463
463
  // Provision arisa user if running as root and not yet done
464
464
  if (isRoot() && !isArisaUserProvisioned()) {
465
465
  provisionArisaUser();
@@ -468,6 +468,8 @@ if (isRoot() && !isArisaUserProvisioned()) {
468
468
  // When root + arisa exists: route all runtime data through arisa's home
469
469
  // so Core (running as arisa) and Daemon (root) share the same data dir.
470
470
  if (isRoot() && arisaUserExists()) {
471
+ // Ensure arisa can access root's bun on every startup
472
+ grantBunAccess();
471
473
  const arisaDataDir = "/home/arisa/.arisa";
472
474
  const rootDataDir = join("/root", ".arisa");
473
475
 
@@ -538,7 +540,7 @@ switch (command) {
538
540
  // preserves parent env (ARISA_DATA_DIR, tokens, API keys).
539
541
  let child;
540
542
  if (isRoot() && arisaUserExists()) {
541
- const bunEnv = "export HOME=/home/arisa && export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/arisa/.bun/bin:$PATH";
543
+ const bunEnv = `export HOME=/home/arisa && ${ARISA_BUN_ENV}`;
542
544
  const cmd = `${bunEnv} && cd ${pkgRoot} && exec bun --watch ${daemonEntry}`;
543
545
  child = spawnSync("su", ["arisa", "-s", "/bin/bash", "-c", cmd], {
544
546
  stdio: "inherit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arisa",
3
- "version": "2.3.26",
3
+ "version": "2.3.27",
4
4
  "description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
5
5
  "keywords": [
6
6
  "tinyclaw",
@@ -52,4 +52,4 @@
52
52
  "@types/bun": "latest",
53
53
  "@types/crypto-js": "^4.2.2"
54
54
  }
55
- }
55
+ }
@@ -19,7 +19,6 @@ const CLI_PACKAGES: Record<AgentCliName, string> = {
19
19
  codex: "@openai/codex",
20
20
  };
21
21
 
22
- const ARISA_BUN_ENV = 'export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/arisa/.bun/bin:$PATH';
23
22
  const INSTALL_TIMEOUT = 120_000; // 2min
24
23
 
25
24
  type NotifyFn = (text: string) => Promise<void>;
@@ -34,10 +33,8 @@ async function installCli(cli: AgentCliName): Promise<boolean> {
34
33
  log.info(`Auto-install: installing ${cli} (${pkg})...`);
35
34
 
36
35
  try {
37
- // When running as root, install into arisa user's bun (consistent with setup.ts)
38
- const cmd = isRunningAsRoot()
39
- ? ["su", "-", "arisa", "-c", `${ARISA_BUN_ENV} && bun add -g ${pkg}`]
40
- : ["bun", "add", "-g", pkg];
36
+ // Install into root's bun (arisa has read+execute access)
37
+ const cmd = ["bun", "add", "-g", pkg];
41
38
 
42
39
  const proc = Bun.spawn(cmd, {
43
40
  stdout: "pipe",
@@ -131,7 +131,8 @@ export function startCore() {
131
131
  // (encryption keys, DB, PID files, etc.) before Core reads them.
132
132
  spawnSync("chown", ["-R", "arisa:arisa", config.arisaDir], { stdio: "ignore" });
133
133
 
134
- const bunEnv = "export HOME=/home/arisa && export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/arisa/.bun/bin:$PATH";
134
+ const bunInstall = process.env.BUN_INSTALL || "/root/.bun";
135
+ const bunEnv = `export HOME=/home/arisa && export BUN_INSTALL=${bunInstall} && export PATH=${bunInstall}/bin:$PATH`;
135
136
  const inner = `${bunEnv} && cd ${config.projectDir} && exec bun --watch ${coreEntry}`;
136
137
  cmd = ["su", "arisa", "-s", "/bin/bash", "-c", inner];
137
138
  log.info(`Starting Core as arisa: bun --watch ${coreEntry}`);
@@ -230,9 +230,8 @@ async function setupClis(inq: typeof import("@inquirer/prompts") | null, vars: R
230
230
 
231
231
  async function installCli(cli: AgentCliName): Promise<boolean> {
232
232
  try {
233
- const cmd = isRunningAsRoot()
234
- ? ["su", "-", "arisa", "-c", `export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/arisa/.bun/bin:$PATH && bun add -g ${CLI_PACKAGES[cli]}`]
235
- : ["bun", "add", "-g", CLI_PACKAGES[cli]];
233
+ // Install into root's bun (arisa has read+execute access)
234
+ const cmd = ["bun", "add", "-g", CLI_PACKAGES[cli]];
236
235
  const proc = Bun.spawn(cmd, {
237
236
  stdout: "inherit",
238
237
  stderr: "inherit",
@@ -10,9 +10,11 @@ import { delimiter, dirname, join } from "path";
10
10
 
11
11
  export type AgentCliName = "claude" | "codex";
12
12
 
13
- const ARISA_USER_BUN = "/home/arisa/.bun/bin";
14
13
  const ARISA_HOME = "/home/arisa";
15
- const ARISA_BUN_ENV = `export HOME=${ARISA_HOME} && export BUN_INSTALL=${ARISA_HOME}/.bun && export PATH=${ARISA_USER_BUN}:$PATH`;
14
+ // Use root's bun arisa user has traverse+read access via chmod o+x /root, o+rX /root/.bun
15
+ const ROOT_BUN_INSTALL = process.env.BUN_INSTALL || "/root/.bun";
16
+ const ROOT_BUN_BIN = `${ROOT_BUN_INSTALL}/bin`;
17
+ const ARISA_BUN_ENV = `export HOME=${ARISA_HOME} && export BUN_INSTALL=${ROOT_BUN_INSTALL} && export PATH=${ROOT_BUN_BIN}:$PATH`;
16
18
 
17
19
  export function isRunningAsRoot(): boolean {
18
20
  return process.getuid?.() === 0;
@@ -43,7 +45,7 @@ function candidatePaths(cli: AgentCliName): string[] {
43
45
  // When root, CLIs are installed under arisa user's bun
44
46
  return unique([
45
47
  cliOverrideEnvVar(cli),
46
- join(ARISA_USER_BUN, cli),
48
+ join(ROOT_BUN_BIN, cli),
47
49
  ]);
48
50
  }
49
51
 
@@ -98,7 +100,7 @@ export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]
98
100
  if (isRunningAsRoot()) {
99
101
  // Run as arisa user — Claude CLI refuses to run as root.
100
102
  // This path is used by Daemon fallback calls; Core runs as arisa directly.
101
- const cliPath = resolveAgentCliPath(cli) || join(ARISA_USER_BUN, cli);
103
+ const cliPath = resolveAgentCliPath(cli) || join(ROOT_BUN_BIN, cli);
102
104
  const inner = ["bun", "--bun", INK_SHIM, cliPath, ...args].map(shellEscape).join(" ");
103
105
  // su without "-" preserves parent env (tokens, keys); explicit HOME/PATH for arisa
104
106
  return ["su", "arisa", "-s", "/bin/bash", "-c", `${ARISA_BUN_ENV} && ${buildEnvExports()}${inner}`];