arisa 2.3.9 → 2.3.11

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arisa",
3
- "version": "2.3.9",
3
+ "version": "2.3.11",
4
4
  "description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
5
5
  "preferGlobal": true,
6
6
  "bin": {
@@ -108,12 +108,20 @@ export async function probeCliAuth(): Promise<void> {
108
108
  if (!isAgentCliInstalled(cli)) continue;
109
109
 
110
110
  log.info(`Auth probe: testing ${cli}...`);
111
+ if (cli === "claude") {
112
+ const hasToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
113
+ const tokenPreview = hasToken ? `${process.env.CLAUDE_CODE_OAUTH_TOKEN!.slice(0, 15)}...` : "NOT SET";
114
+ log.info(`Auth probe: CLAUDE_CODE_OAUTH_TOKEN=${tokenPreview}`);
115
+ }
111
116
  try {
112
117
  const args = cli === "claude"
113
118
  ? ["-p", "say ok", "--model", "haiku", "--dangerously-skip-permissions"]
114
119
  : ["exec", "--dangerously-bypass-approvals-and-sandbox", "echo ok"];
115
120
 
116
- const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args), {
121
+ const cmd = buildBunWrappedAgentCliCommand(cli, args);
122
+ log.info(`Auth probe cmd: ${cmd.map(c => c.length > 80 ? c.slice(0, 80) + "..." : c).join(" ")}`);
123
+
124
+ const proc = Bun.spawn(cmd, {
117
125
  stdout: "pipe",
118
126
  stderr: "pipe",
119
127
  env: { ...process.env },
@@ -276,34 +276,58 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
276
276
 
277
277
  const exitCode = await proc.exited;
278
278
  if (exitCode === 0) {
279
- // Find token in raw output don't rely on ANSI stripping or line parsing.
280
- // Just locate "sk-ant-" and the end boundary, then keep only token chars.
281
- const startIdx = output.indexOf("sk-ant-");
279
+ // Step 1: Strip ANSI escape sequences FIRST (their params contain digits/letters)
280
+ const clean = output
281
+ .replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "") // CSI: ESC [ params final
282
+ .replace(/\x1b\][^\x07]*\x07/g, "") // OSC: ESC ] ... BEL
283
+ .replace(/\x1b[^[\]]/g, "") // Other ESC sequences (ESC + one char)
284
+ .replace(/[\x00-\x09\x0b-\x0c\x0e-\x1f]/g, ""); // Control chars (keep \n \r)
285
+
286
+ // Step 2: Find boundaries in clean text
287
+ const startIdx = clean.indexOf("sk-ant-");
282
288
  let token = "";
283
289
 
284
290
  if (startIdx >= 0) {
285
- // End boundary: look for known text after the token
286
- let endIdx = output.indexOf("Store this token", startIdx);
287
- if (endIdx < 0) endIdx = output.indexOf("Use this token", startIdx);
288
- if (endIdx < 0) endIdx = startIdx + 300;
291
+ let endIdx = clean.indexOf("Store", startIdx);
292
+ if (endIdx < 0) endIdx = clean.indexOf("Use this", startIdx);
293
+ if (endIdx < 0) endIdx = startIdx + 200;
289
294
 
290
- const tokenArea = output.substring(startIdx, endIdx);
291
- // Strip EVERYTHING except token-valid chars: A-Z a-z 0-9 _ -
295
+ const tokenArea = clean.substring(startIdx, endIdx);
296
+ // Step 3: Strip whitespace and any remaining non-token chars
292
297
  token = tokenArea.replace(/[^A-Za-z0-9_-]/g, "");
293
298
  }
294
299
 
295
- if (token && token.startsWith("sk-ant-") && token.length > 50) {
300
+ if (token && token.startsWith("sk-ant-") && token.length > 50 && token.length < 150) {
296
301
  console.log(` [token] ${token.slice(0, 20)}...${token.slice(-6)} (${token.length} chars)`);
297
302
  vars.CLAUDE_CODE_OAUTH_TOKEN = token;
303
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = token;
298
304
  saveEnv(vars);
299
305
  console.log(" ✓ claude token saved to .env");
306
+
307
+ // Also write credentials file for arisa user (belt + suspenders)
308
+ const claudeDir = isRunningAsRoot() ? "/home/arisa/.claude" : join(process.env.HOME || "~", ".claude");
309
+ try {
310
+ if (!existsSync(claudeDir)) mkdirSync(claudeDir, { recursive: true });
311
+ const credsPath = join(claudeDir, ".credentials.json");
312
+ const creds = {
313
+ claudeAiOauth: {
314
+ accessToken: token,
315
+ expiresAt: Date.now() + 365 * 24 * 60 * 60 * 1000,
316
+ scopes: ["user:inference", "user:profile"],
317
+ },
318
+ };
319
+ writeFileSync(credsPath, JSON.stringify(creds, null, 2) + "\n");
320
+ if (isRunningAsRoot()) {
321
+ Bun.spawnSync(["chown", "-R", "arisa:arisa", claudeDir]);
322
+ }
323
+ console.log(` ✓ credentials written to ${credsPath}`);
324
+ } catch (e) {
325
+ console.log(` ⚠ could not write credentials file: ${e}`);
326
+ }
300
327
  } else {
301
328
  console.log(` ⚠ token extraction failed (indexOf=${startIdx}, len=${token.length})`);
302
- // Dump raw bytes around expected position for debugging
303
329
  if (startIdx >= 0) {
304
- const raw = output.substring(startIdx, startIdx + 200);
305
- const hex = [...raw].map(c => c.charCodeAt(0).toString(16).padStart(2, "0")).join(" ");
306
- console.log(` [hex] ${hex.slice(0, 300)}`);
330
+ console.log(` [clean] ${clean.substring(startIdx, startIdx + 150).replace(/\n/g, "\\n")}`);
307
331
  }
308
332
  }
309
333
  console.log(` ✓ claude login successful`);