arisa 2.3.28 → 2.3.29
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/package.json +1 -1
- package/src/daemon/agent-cli.ts +1 -1
- package/src/daemon/setup.ts +53 -22
- package/src/shared/ai-cli.ts +2 -2
package/package.json
CHANGED
package/src/daemon/agent-cli.ts
CHANGED
|
@@ -110,7 +110,7 @@ export async function runWithCliFallback(prompt: string, timeoutMs: number): Pro
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
const reason = result.exitCode === 0
|
|
113
|
-
?
|
|
113
|
+
? `empty output${result.stderr ? ` (stderr: ${summarizeError(result.stderr)})` : ""}`
|
|
114
114
|
: `exit=${result.exitCode}: ${summarizeError(result.stderr || result.output)}`;
|
|
115
115
|
failures.push(`${getAgentCliLabel(cli)} ${reason}`);
|
|
116
116
|
} catch (error) {
|
package/src/daemon/setup.ts
CHANGED
|
@@ -246,6 +246,32 @@ async function installCli(cli: AgentCliName): Promise<boolean> {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
/**
|
|
250
|
+
* Read the OAuth token from Claude CLI's credentials file.
|
|
251
|
+
* Claude CLI stores credentials at ~/.claude/.credentials.json after login.
|
|
252
|
+
*/
|
|
253
|
+
function readClaudeCredentialsToken(): string | null {
|
|
254
|
+
const candidateDirs = [
|
|
255
|
+
isRunningAsRoot() ? "/home/arisa/.claude" : null,
|
|
256
|
+
join(process.env.HOME || "~", ".claude"),
|
|
257
|
+
].filter(Boolean) as string[];
|
|
258
|
+
|
|
259
|
+
for (const dir of candidateDirs) {
|
|
260
|
+
const credsPath = join(dir, ".credentials.json");
|
|
261
|
+
if (!existsSync(credsPath)) continue;
|
|
262
|
+
try {
|
|
263
|
+
const raw = JSON.parse(readFileSync(credsPath, "utf8"));
|
|
264
|
+
const token = raw?.claudeAiOauth?.accessToken;
|
|
265
|
+
if (typeof token === "string" && token.startsWith("sk-ant-") && token.length > 50) {
|
|
266
|
+
return token;
|
|
267
|
+
}
|
|
268
|
+
} catch {
|
|
269
|
+
// Malformed file, skip
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
249
275
|
async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, string>): Promise<boolean> {
|
|
250
276
|
const args = cli === "claude"
|
|
251
277
|
? ["setup-token"]
|
|
@@ -317,6 +343,14 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
|
|
|
317
343
|
token = tokenArea.replace(/[^A-Za-z0-9_-]/g, "");
|
|
318
344
|
}
|
|
319
345
|
|
|
346
|
+
// Fallback: if stdout scraping missed the token, read from Claude CLI's credentials file
|
|
347
|
+
if (!token || !token.startsWith("sk-ant-") || token.length <= 50 || token.length >= 150) {
|
|
348
|
+
token = readClaudeCredentialsToken() || "";
|
|
349
|
+
if (token) {
|
|
350
|
+
console.log(` ✓ token read from credentials file`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
320
354
|
if (token && token.startsWith("sk-ant-") && token.length > 50 && token.length < 150) {
|
|
321
355
|
console.log(` [token] ${token.slice(0, 20)}...${token.slice(-6)} (${token.length} chars)`);
|
|
322
356
|
vars.CLAUDE_CODE_OAUTH_TOKEN = token;
|
|
@@ -324,31 +358,28 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
|
|
|
324
358
|
saveEnv(vars);
|
|
325
359
|
console.log(" ✓ claude token saved to .env");
|
|
326
360
|
|
|
327
|
-
// Also write credentials file for arisa user
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
Bun.spawnSync(["chown", "-R", "arisa:arisa",
|
|
361
|
+
// Also write credentials file for arisa user when running as root
|
|
362
|
+
if (isRunningAsRoot()) {
|
|
363
|
+
const arisaClaudeDir = "/home/arisa/.claude";
|
|
364
|
+
try {
|
|
365
|
+
if (!existsSync(arisaClaudeDir)) mkdirSync(arisaClaudeDir, { recursive: true });
|
|
366
|
+
const credsPath = join(arisaClaudeDir, ".credentials.json");
|
|
367
|
+
const creds = {
|
|
368
|
+
claudeAiOauth: {
|
|
369
|
+
accessToken: token,
|
|
370
|
+
expiresAt: Date.now() + 365 * 24 * 60 * 60 * 1000,
|
|
371
|
+
scopes: ["user:inference", "user:profile"],
|
|
372
|
+
},
|
|
373
|
+
};
|
|
374
|
+
writeFileSync(credsPath, JSON.stringify(creds, null, 2) + "\n");
|
|
375
|
+
Bun.spawnSync(["chown", "-R", "arisa:arisa", arisaClaudeDir]);
|
|
376
|
+
console.log(` ✓ credentials written to ${credsPath}`);
|
|
377
|
+
} catch (e) {
|
|
378
|
+
console.log(` ⚠ could not write credentials file: ${e}`);
|
|
342
379
|
}
|
|
343
|
-
console.log(` ✓ credentials written to ${credsPath}`);
|
|
344
|
-
} catch (e) {
|
|
345
|
-
console.log(` ⚠ could not write credentials file: ${e}`);
|
|
346
380
|
}
|
|
347
381
|
} else {
|
|
348
|
-
console.log(` ⚠ token
|
|
349
|
-
if (startIdx >= 0) {
|
|
350
|
-
console.log(` [clean] ${clean.substring(startIdx, startIdx + 150).replace(/\n/g, "\\n")}`);
|
|
351
|
-
}
|
|
382
|
+
console.log(` ⚠ token not captured (Claude CLI stored credentials internally)`);
|
|
352
383
|
}
|
|
353
384
|
console.log(` ✓ claude login successful`);
|
|
354
385
|
return true;
|
package/src/shared/ai-cli.ts
CHANGED
|
@@ -101,7 +101,7 @@ export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]
|
|
|
101
101
|
// Run as arisa user — Claude CLI refuses to run as root.
|
|
102
102
|
// This path is used by Daemon fallback calls; Core runs as arisa directly.
|
|
103
103
|
const cliPath = resolveAgentCliPath(cli) || join(ROOT_BUN_BIN, cli);
|
|
104
|
-
const inner = ["bun", "--bun", INK_SHIM, cliPath, ...args].map(shellEscape).join(" ");
|
|
104
|
+
const inner = ["bun", "--bun", "--preload", INK_SHIM, cliPath, ...args].map(shellEscape).join(" ");
|
|
105
105
|
// su without "-" preserves parent env (tokens, keys); explicit HOME/PATH for arisa
|
|
106
106
|
return ["su", "arisa", "-s", "/bin/bash", "-c", `${ARISA_BUN_ENV} && ${buildEnvExports()}${inner}`];
|
|
107
107
|
}
|
|
@@ -112,5 +112,5 @@ export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]
|
|
|
112
112
|
}
|
|
113
113
|
// Preload shim that patches process.stdin.setRawMode to prevent Ink crash
|
|
114
114
|
// when running without a TTY (systemd, su -c, etc.)
|
|
115
|
-
return ["bun", "--bun", INK_SHIM, cliPath, ...args];
|
|
115
|
+
return ["bun", "--bun", "--preload", INK_SHIM, cliPath, ...args];
|
|
116
116
|
}
|