arisa 2.3.17 → 2.3.19
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 +12 -3
- package/package.json +1 -1
- package/scripts/dump-commands.ts +26 -0
- package/src/core/media.ts +1 -1
- package/src/core/processor.ts +6 -8
- package/src/daemon/auto-install.ts +9 -3
- package/src/shared/ai-cli.ts +2 -2
package/bin/arisa.js
CHANGED
|
@@ -428,7 +428,7 @@ const ARISA_BUN_ENV = 'export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/
|
|
|
428
428
|
function provisionArisaUser() {
|
|
429
429
|
process.stdout.write("Creating user 'arisa' for Claude/Codex CLI execution...\n");
|
|
430
430
|
|
|
431
|
-
// 1. Create user
|
|
431
|
+
// 1. Create user with sudo access
|
|
432
432
|
const useradd = spawnSync("useradd", ["-m", "-s", "/bin/bash", "arisa"], { stdio: "pipe" });
|
|
433
433
|
if (useradd.status !== 0) {
|
|
434
434
|
step(false, `Failed to create user: ${(useradd.stderr || "").toString().trim()}`);
|
|
@@ -436,7 +436,16 @@ function provisionArisaUser() {
|
|
|
436
436
|
}
|
|
437
437
|
step(true, "User arisa created");
|
|
438
438
|
|
|
439
|
-
// 2.
|
|
439
|
+
// 2. Grant passwordless sudo (needed for full tool execution in Claude/Codex)
|
|
440
|
+
try {
|
|
441
|
+
writeFileSync("/etc/sudoers.d/arisa", "arisa ALL=(ALL) NOPASSWD: ALL\n", { mode: 0o440 });
|
|
442
|
+
step(true, "Passwordless sudo granted");
|
|
443
|
+
} catch (e) {
|
|
444
|
+
// Not fatal — sudo may not be installed in minimal containers
|
|
445
|
+
step(false, `Sudo setup skipped: ${e.message || e}`);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// 3. Install bun for arisa (curl — lightweight, no bun child process)
|
|
440
449
|
process.stdout.write(" Installing bun for arisa (this may take a minute)...\n");
|
|
441
450
|
const bunInstall = spawnSync("su", ["-", "arisa", "-c", "curl -fsSL https://bun.sh/install | bash"], {
|
|
442
451
|
stdio: "inherit",
|
|
@@ -448,7 +457,7 @@ function provisionArisaUser() {
|
|
|
448
457
|
}
|
|
449
458
|
step(true, "Bun installed for arisa");
|
|
450
459
|
|
|
451
|
-
//
|
|
460
|
+
// 4. Write ink-shim for non-TTY execution (prevents Ink setRawMode crash)
|
|
452
461
|
const shimPath = "/home/arisa/.arisa-ink-shim.js";
|
|
453
462
|
writeFileSync(shimPath, 'if(process.stdin&&!process.stdin.isTTY){process.stdin.setRawMode=()=>process.stdin;process.stdin.isTTY=true;}\n');
|
|
454
463
|
spawnSync("chown", ["arisa:arisa", shimPath], { stdio: "ignore" });
|
package/package.json
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Diagnostic: prints the exact su/bun commands that Arisa would execute,
|
|
4
|
+
* ready to copy-paste into a terminal.
|
|
5
|
+
*/
|
|
6
|
+
import { buildBunWrappedAgentCliCommand } from "../src/shared/ai-cli";
|
|
7
|
+
|
|
8
|
+
function printable(cmd: string[]): string {
|
|
9
|
+
if (cmd[0] === "su") {
|
|
10
|
+
// cmd = ["su", "arisa", "-s", "/bin/bash", "-c", "<bash script>"]
|
|
11
|
+
// Wrap the -c argument in double quotes — safe because shellEscape only uses single quotes
|
|
12
|
+
return `${cmd.slice(0, 5).join(" ")} "${cmd[5]}"`;
|
|
13
|
+
}
|
|
14
|
+
// Non-root: just join, quoting args with spaces
|
|
15
|
+
return cmd.map(c => /[\s']/.test(c) ? `"${c}"` : c).join(" ");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const probeArgs = ["-p", "say ok", "--model", "haiku", "--output-format", "text", "--dangerously-skip-permissions"];
|
|
19
|
+
const processorArgs = ["--dangerously-skip-permissions", "--output-format", "text", "--model", "claude-sonnet-4-20250514", "-p", "hello test"];
|
|
20
|
+
|
|
21
|
+
console.log("=== AUTH PROBE (daemon/auto-install.ts) ===\n");
|
|
22
|
+
console.log(printable(buildBunWrappedAgentCliCommand("claude", probeArgs)));
|
|
23
|
+
|
|
24
|
+
console.log("\n\n=== MESSAGE PROCESSOR (core/processor.ts) ===\n");
|
|
25
|
+
console.log(printable(buildBunWrappedAgentCliCommand("claude", processorArgs)));
|
|
26
|
+
console.log();
|
package/src/core/media.ts
CHANGED
|
@@ -60,7 +60,7 @@ export async function transcribeAudio(base64: string, filename: string): Promise
|
|
|
60
60
|
const file = Bun.file(tempPath);
|
|
61
61
|
const transcription = await client.audio.transcriptions.create({
|
|
62
62
|
file: file,
|
|
63
|
-
model: "
|
|
63
|
+
model: "gpt-4o-mini-transcribe",
|
|
64
64
|
});
|
|
65
65
|
log.info(`Transcribed audio: "${transcription.text.substring(0, 80)}..."`);
|
|
66
66
|
return transcription.text;
|
package/src/core/processor.ts
CHANGED
|
@@ -142,10 +142,11 @@ async function runClaude(message: string, chatId: string): Promise<string> {
|
|
|
142
142
|
log.info(
|
|
143
143
|
`Claude send | promptChars: ${prompt.length} | preview: ${previewPrompt(prompt)}`
|
|
144
144
|
);
|
|
145
|
-
|
|
145
|
+
const spawnCmd = buildBunWrappedAgentCliCommand("claude", args);
|
|
146
|
+
log.info(`Claude spawn cmd (${spawnCmd.length} parts):\n${spawnCmd.map((c, i) => ` [${i}] ${c}`).join("\n")}`);
|
|
146
147
|
log.debug(`Claude prompt >>>>\n${prompt}\n<<<<`);
|
|
147
148
|
|
|
148
|
-
const proc = Bun.spawn(
|
|
149
|
+
const proc = Bun.spawn(spawnCmd, {
|
|
149
150
|
cwd: config.projectDir,
|
|
150
151
|
stdin: "pipe",
|
|
151
152
|
stdout: "pipe",
|
|
@@ -212,14 +213,11 @@ export async function processWithCodex(message: string): Promise<string> {
|
|
|
212
213
|
log.info(
|
|
213
214
|
`Codex send | promptChars: ${message.length} | preview: ${previewPrompt(message)}`
|
|
214
215
|
);
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
? "exec resume --last --dangerously-bypass-approvals-and-sandbox <prompt>"
|
|
218
|
-
: `exec --dangerously-bypass-approvals-and-sandbox -C ${config.projectDir} <prompt>`}`
|
|
219
|
-
);
|
|
216
|
+
const spawnCmd = buildBunWrappedAgentCliCommand("codex", args);
|
|
217
|
+
log.info(`Codex spawn cmd (${spawnCmd.length} parts):\n${spawnCmd.map((c, i) => ` [${i}] ${c}`).join("\n")}`);
|
|
220
218
|
log.debug(`Codex prompt >>>>\n${message}\n<<<<`);
|
|
221
219
|
|
|
222
|
-
const proc = Bun.spawn(
|
|
220
|
+
const proc = Bun.spawn(spawnCmd, {
|
|
223
221
|
cwd: config.projectDir,
|
|
224
222
|
stdout: "pipe",
|
|
225
223
|
stderr: "pipe",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { createLogger } from "../shared/logger";
|
|
13
|
-
import { isAgentCliInstalled, buildBunWrappedAgentCliCommand, type AgentCliName } from "../shared/ai-cli";
|
|
13
|
+
import { isAgentCliInstalled, isRunningAsRoot, buildBunWrappedAgentCliCommand, type AgentCliName } from "../shared/ai-cli";
|
|
14
14
|
|
|
15
15
|
const log = createLogger("daemon");
|
|
16
16
|
|
|
@@ -19,6 +19,7 @@ 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';
|
|
22
23
|
const INSTALL_TIMEOUT = 120_000; // 2min
|
|
23
24
|
|
|
24
25
|
type NotifyFn = (text: string) => Promise<void>;
|
|
@@ -33,7 +34,12 @@ async function installCli(cli: AgentCliName): Promise<boolean> {
|
|
|
33
34
|
log.info(`Auto-install: installing ${cli} (${pkg})...`);
|
|
34
35
|
|
|
35
36
|
try {
|
|
36
|
-
|
|
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];
|
|
41
|
+
|
|
42
|
+
const proc = Bun.spawn(cmd, {
|
|
37
43
|
stdout: "pipe",
|
|
38
44
|
stderr: "pipe",
|
|
39
45
|
env: { ...process.env },
|
|
@@ -119,7 +125,7 @@ export async function probeCliAuth(): Promise<void> {
|
|
|
119
125
|
: ["exec", "--dangerously-bypass-approvals-and-sandbox", "echo ok"];
|
|
120
126
|
|
|
121
127
|
const cmd = buildBunWrappedAgentCliCommand(cli, args);
|
|
122
|
-
log.info(`Auth probe cmd
|
|
128
|
+
log.info(`Auth probe cmd (${cmd.length} parts):\n${cmd.map((c, i) => ` [${i}] ${c}`).join("\n")}`);
|
|
123
129
|
|
|
124
130
|
const proc = Bun.spawn(cmd, {
|
|
125
131
|
stdout: "pipe",
|
package/src/shared/ai-cli.ts
CHANGED
|
@@ -100,7 +100,7 @@ export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]
|
|
|
100
100
|
// Run as arisa user — Claude CLI refuses to run as root
|
|
101
101
|
const cliPath = resolveAgentCliPath(cli) || join(ARISA_USER_BUN, cli);
|
|
102
102
|
const shimPath = existsSync(ARISA_INK_SHIM) ? ARISA_INK_SHIM : INK_SHIM;
|
|
103
|
-
const inner = ["bun", "--bun",
|
|
103
|
+
const inner = ["bun", "--bun", shimPath, cliPath, ...args].map(shellEscape).join(" ");
|
|
104
104
|
// su without "-" preserves parent env (tokens, keys); explicit HOME/PATH for arisa
|
|
105
105
|
return ["su", "arisa", "-s", "/bin/bash", "-c", `${ARISA_BUN_ENV} && ${buildEnvExports()}${inner}`];
|
|
106
106
|
}
|
|
@@ -111,5 +111,5 @@ export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]
|
|
|
111
111
|
}
|
|
112
112
|
// Preload shim that patches process.stdin.setRawMode to prevent Ink crash
|
|
113
113
|
// when running without a TTY (systemd, su -c, etc.)
|
|
114
|
-
return ["bun", "--bun",
|
|
114
|
+
return ["bun", "--bun", INK_SHIM, cliPath, ...args];
|
|
115
115
|
}
|