arisa 2.3.37 → 2.3.39
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/setup.ts +58 -14
- package/src/shared/ai-cli.ts +3 -3
package/package.json
CHANGED
package/src/daemon/setup.ts
CHANGED
|
@@ -268,12 +268,18 @@ async function checkCliAuth(inq: typeof import("@inquirer/prompts") | null, vars
|
|
|
268
268
|
|
|
269
269
|
/**
|
|
270
270
|
* Quick probe: is this CLI authenticated?
|
|
271
|
-
* Claude: `claude auth status`
|
|
272
|
-
* Codex:
|
|
271
|
+
* Claude: check CLAUDE_CODE_OAUTH_TOKEN env/.env, or `claude auth status`
|
|
272
|
+
* Codex: no simple auth check, assume OK if installed
|
|
273
273
|
*/
|
|
274
274
|
async function isCliAuthenticated(cli: AgentCliName): Promise<boolean> {
|
|
275
275
|
try {
|
|
276
276
|
if (cli === "claude") {
|
|
277
|
+
// setup-token auth: token lives in env var (not .credentials.json)
|
|
278
|
+
if (process.env.CLAUDE_CODE_OAUTH_TOKEN?.startsWith("sk-ant-")) {
|
|
279
|
+
console.log(`[setup] claude auth via CLAUDE_CODE_OAUTH_TOKEN env var`);
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
// Native CLI auth: check `claude auth status`
|
|
277
283
|
const cmd = buildBunWrappedAgentCliCommand("claude", ["auth", "status"], { skipPreload: true });
|
|
278
284
|
const proc = Bun.spawn(cmd, { stdout: "pipe", stderr: "pipe" });
|
|
279
285
|
const stdout = await new Response(proc.stdout).text();
|
|
@@ -314,8 +320,56 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
|
|
|
314
320
|
console.log(`Starting ${cli} login...`);
|
|
315
321
|
|
|
316
322
|
try {
|
|
317
|
-
|
|
318
|
-
|
|
323
|
+
if (cli === "claude") {
|
|
324
|
+
// `claude setup-token` generates a long-lived (1 year) OAuth token for
|
|
325
|
+
// headless/CI environments. It prints the token to stdout but does NOT
|
|
326
|
+
// write .credentials.json. We must capture it and save to .env.
|
|
327
|
+
const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args, { skipPreload: true }), {
|
|
328
|
+
stdin: "inherit",
|
|
329
|
+
stdout: "pipe",
|
|
330
|
+
stderr: "inherit",
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
let output = "";
|
|
334
|
+
const reader = (proc.stdout as ReadableStream<Uint8Array>).getReader();
|
|
335
|
+
const decoder = new TextDecoder();
|
|
336
|
+
while (true) {
|
|
337
|
+
const { done, value } = await reader.read();
|
|
338
|
+
if (done) break;
|
|
339
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
340
|
+
process.stdout.write(chunk);
|
|
341
|
+
output += chunk;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const exitCode = await proc.exited;
|
|
345
|
+
if (exitCode !== 0) {
|
|
346
|
+
console.log(` ✗ claude login failed (exit ${exitCode})`);
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Extract token from output (format: sk-ant-oat01-...)
|
|
351
|
+
// The CLI wraps long tokens across multiple lines — collect until blank line, strip whitespace.
|
|
352
|
+
const tokenStartIdx = output.indexOf("sk-ant-oat01-");
|
|
353
|
+
const tokenArea = tokenStartIdx >= 0
|
|
354
|
+
? output.substring(tokenStartIdx, output.indexOf("\n\n", tokenStartIdx) >>> 0 || tokenStartIdx + 200)
|
|
355
|
+
: "";
|
|
356
|
+
const tokenMatch = tokenArea ? tokenArea.replace(/\s+/g, "").match(/(sk-ant-oat01-[A-Za-z0-9_-]+)/) : null;
|
|
357
|
+
if (tokenMatch) {
|
|
358
|
+
const token = tokenMatch[1];
|
|
359
|
+
console.log(` [token] ${token.slice(0, 20)}...${token.slice(-6)} (${token.length} chars)`);
|
|
360
|
+
vars.CLAUDE_CODE_OAUTH_TOKEN = token;
|
|
361
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN = token;
|
|
362
|
+
saveEnv(vars);
|
|
363
|
+
console.log(" ✓ token saved to .env");
|
|
364
|
+
} else {
|
|
365
|
+
console.log(" ⚠ could not extract token from output — set CLAUDE_CODE_OAUTH_TOKEN manually in ~/.arisa/.env");
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
console.log(` ✓ claude login successful`);
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// For codex and others: inherit all stdio
|
|
319
373
|
const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args, { skipPreload: true }), {
|
|
320
374
|
stdin: "inherit",
|
|
321
375
|
stdout: "inherit",
|
|
@@ -325,16 +379,6 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
|
|
|
325
379
|
|
|
326
380
|
if (exitCode === 0) {
|
|
327
381
|
console.log(` ✓ ${cli} login successful`);
|
|
328
|
-
|
|
329
|
-
// Clean up stale CLAUDE_CODE_OAUTH_TOKEN from .env if present —
|
|
330
|
-
// it overrides the CLI's own credential store and breaks token refresh.
|
|
331
|
-
if (cli === "claude" && vars.CLAUDE_CODE_OAUTH_TOKEN) {
|
|
332
|
-
delete vars.CLAUDE_CODE_OAUTH_TOKEN;
|
|
333
|
-
delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
334
|
-
saveEnv(vars);
|
|
335
|
-
console.log(" ✓ removed stale CLAUDE_CODE_OAUTH_TOKEN from .env (CLI manages auth internally)");
|
|
336
|
-
}
|
|
337
|
-
|
|
338
382
|
return true;
|
|
339
383
|
} else {
|
|
340
384
|
console.log(` ✗ ${cli} login failed (exit ${exitCode})`);
|
package/src/shared/ai-cli.ts
CHANGED
|
@@ -81,10 +81,10 @@ export function isAgentCliInstalled(cli: AgentCliName): boolean {
|
|
|
81
81
|
const INK_SHIM = join(dirname(new URL(import.meta.url).pathname), "ink-shim.js");
|
|
82
82
|
|
|
83
83
|
// Env vars that must survive the su - login shell reset.
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
// Injecting a stale accessToken via env var breaks refresh.
|
|
84
|
+
// CLAUDE_CODE_OAUTH_TOKEN is a long-lived (1 year) token from `claude setup-token`
|
|
85
|
+
// — the headless auth method. It must be passed through to the CLI.
|
|
87
86
|
const PASSTHROUGH_VARS = [
|
|
87
|
+
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
88
88
|
"ANTHROPIC_API_KEY",
|
|
89
89
|
"OPENAI_API_KEY",
|
|
90
90
|
];
|