arisa 2.3.14 → 2.3.15
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 +37 -71
package/package.json
CHANGED
package/src/daemon/setup.ts
CHANGED
|
@@ -255,81 +255,52 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
|
|
|
255
255
|
console.log(`Starting ${cli} login...`);
|
|
256
256
|
|
|
257
257
|
try {
|
|
258
|
-
// For claude:
|
|
258
|
+
// For claude: run setup-token with full stdio, then read token from credentials or prompt
|
|
259
259
|
if (cli === "claude") {
|
|
260
|
+
// Run with inherited stdio — user interacts directly, no output capture
|
|
260
261
|
const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args), {
|
|
261
262
|
stdin: "inherit",
|
|
262
|
-
stdout: "
|
|
263
|
+
stdout: "inherit",
|
|
263
264
|
stderr: "inherit",
|
|
264
265
|
});
|
|
265
266
|
|
|
266
|
-
let output = "";
|
|
267
|
-
const reader = (proc.stdout as ReadableStream<Uint8Array>).getReader();
|
|
268
|
-
const decoder = new TextDecoder();
|
|
269
|
-
while (true) {
|
|
270
|
-
const { done, value } = await reader.read();
|
|
271
|
-
if (done) break;
|
|
272
|
-
const chunk = decoder.decode(value, { stream: true });
|
|
273
|
-
process.stdout.write(chunk);
|
|
274
|
-
output += chunk;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
267
|
const exitCode = await proc.exited;
|
|
278
|
-
if (exitCode
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
for (let i = 0; i < s.length; i++) {
|
|
283
|
-
if (s.charCodeAt(i) === 0x1b) {
|
|
284
|
-
i++;
|
|
285
|
-
if (i >= s.length) break;
|
|
286
|
-
if (s[i] === "[") {
|
|
287
|
-
// CSI: ESC [ <params 0x20-0x3F>* <final 0x40-0x7E>
|
|
288
|
-
i++;
|
|
289
|
-
while (i < s.length && s.charCodeAt(i) < 0x40) i++;
|
|
290
|
-
// i now on final byte, loop will i++
|
|
291
|
-
} else if (s[i] === "]") {
|
|
292
|
-
// OSC: ESC ] ... BEL(0x07) or ST(ESC \)
|
|
293
|
-
i++;
|
|
294
|
-
while (i < s.length && s.charCodeAt(i) !== 0x07 && s[i] !== "\x1b") i++;
|
|
295
|
-
} else if (s[i] === "(" || s[i] === ")" || s[i] === "#") {
|
|
296
|
-
i++; // skip designator byte
|
|
297
|
-
}
|
|
298
|
-
// else: 2-byte Fe sequence, already skipped
|
|
299
|
-
} else if (s.charCodeAt(i) < 0x20 && s[i] !== "\n" && s[i] !== "\r") {
|
|
300
|
-
// skip control chars
|
|
301
|
-
} else {
|
|
302
|
-
out += s[i];
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return out;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const clean = stripAnsi(output);
|
|
309
|
-
const startIdx = clean.indexOf("sk-ant-");
|
|
310
|
-
let token = "";
|
|
268
|
+
if (exitCode !== 0) {
|
|
269
|
+
console.log(` ✗ claude login failed (exit ${exitCode})`);
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
311
272
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
273
|
+
// Try to read token from Claude's credentials file
|
|
274
|
+
const claudeDir = isRunningAsRoot() ? "/home/arisa/.claude" : join(process.env.HOME || "~", ".claude");
|
|
275
|
+
const credsPath = join(claudeDir, ".credentials.json");
|
|
276
|
+
let token = "";
|
|
277
|
+
|
|
278
|
+
if (existsSync(credsPath)) {
|
|
279
|
+
try {
|
|
280
|
+
const creds = JSON.parse(readFileSync(credsPath, "utf8"));
|
|
281
|
+
token = creds?.claudeAiOauth?.accessToken || "";
|
|
282
|
+
if (token) console.log(` ✓ token read from ${credsPath}`);
|
|
283
|
+
} catch {}
|
|
284
|
+
}
|
|
316
285
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
286
|
+
// If no credentials file, ask user to paste the token
|
|
287
|
+
if (!token) {
|
|
288
|
+
console.log("\n The token was displayed above. Please paste it here:");
|
|
289
|
+
const pasted = await readLine(" CLAUDE_CODE_OAUTH_TOKEN: ");
|
|
290
|
+
token = pasted.replace(/\s+/g, "").trim();
|
|
291
|
+
}
|
|
320
292
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
293
|
+
if (token && token.startsWith("sk-ant-")) {
|
|
294
|
+
console.log(` [token] ${token.slice(0, 20)}...${token.slice(-6)} (${token.length} chars)`);
|
|
295
|
+
vars.CLAUDE_CODE_OAUTH_TOKEN = token;
|
|
296
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN = token;
|
|
297
|
+
saveEnv(vars);
|
|
298
|
+
console.log(" ✓ claude token saved to .env");
|
|
327
299
|
|
|
328
|
-
|
|
329
|
-
|
|
300
|
+
// Also write credentials file for arisa user if it doesn't exist
|
|
301
|
+
if (!existsSync(credsPath)) {
|
|
330
302
|
try {
|
|
331
303
|
if (!existsSync(claudeDir)) mkdirSync(claudeDir, { recursive: true });
|
|
332
|
-
const credsPath = join(claudeDir, ".credentials.json");
|
|
333
304
|
const creds = {
|
|
334
305
|
claudeAiOauth: {
|
|
335
306
|
accessToken: token,
|
|
@@ -345,18 +316,13 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
|
|
|
345
316
|
} catch (e) {
|
|
346
317
|
console.log(` ⚠ could not write credentials file: ${e}`);
|
|
347
318
|
}
|
|
348
|
-
} else {
|
|
349
|
-
console.log(` ⚠ token extraction failed (indexOf=${startIdx}, len=${token.length})`);
|
|
350
|
-
if (startIdx >= 0) {
|
|
351
|
-
console.log(` [clean] ${clean.substring(startIdx, startIdx + 150).replace(/\n/g, "\\n")}`);
|
|
352
|
-
}
|
|
353
319
|
}
|
|
354
|
-
console.log(` ✓ claude login successful`);
|
|
355
|
-
return true;
|
|
356
320
|
} else {
|
|
357
|
-
console.log(
|
|
358
|
-
return false;
|
|
321
|
+
console.log(" ⚠ no valid token provided");
|
|
359
322
|
}
|
|
323
|
+
|
|
324
|
+
console.log(` ✓ claude login successful`);
|
|
325
|
+
return true;
|
|
360
326
|
}
|
|
361
327
|
|
|
362
328
|
// For codex and others: inherit all stdio
|