arisa 2.2.0 → 2.2.3

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.2.0",
3
+ "version": "2.2.3",
4
4
  "description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
5
5
  "preferGlobal": true,
6
6
  "bin": {
@@ -150,7 +150,7 @@ async function runClaude(message: string, chatId: string): Promise<string> {
150
150
  stdin: "pipe",
151
151
  stdout: "pipe",
152
152
  stderr: "pipe",
153
- env: { ...process.env, CI: "1" },
153
+ env: { ...process.env },
154
154
  });
155
155
  proc.stdin.end();
156
156
 
@@ -143,13 +143,13 @@ export async function runSetup(): Promise<boolean> {
143
143
  // ─── Phase 2: CLI Installation (first run, interactive) ─────────
144
144
 
145
145
  if (isFirstRun && process.stdin.isTTY) {
146
- await setupClis(inq);
146
+ await setupClis(inq, vars);
147
147
  }
148
148
 
149
149
  return true;
150
150
  }
151
151
 
152
- async function setupClis(inq: typeof import("@inquirer/prompts") | null) {
152
+ async function setupClis(inq: typeof import("@inquirer/prompts") | null, vars: Record<string, string>) {
153
153
  let claudeInstalled = isAgentCliInstalled("claude");
154
154
  let codexInstalled = isAgentCliInstalled("codex");
155
155
 
@@ -202,7 +202,7 @@ async function setupClis(inq: typeof import("@inquirer/prompts") | null) {
202
202
  }
203
203
  if (doLogin) {
204
204
  console.log();
205
- await runInteractiveLogin("claude");
205
+ await runInteractiveLogin("claude", vars);
206
206
  }
207
207
  }
208
208
 
@@ -216,7 +216,7 @@ async function setupClis(inq: typeof import("@inquirer/prompts") | null) {
216
216
  }
217
217
  if (doLogin) {
218
218
  console.log();
219
- await runInteractiveLogin("codex");
219
+ await runInteractiveLogin("codex", vars);
220
220
  }
221
221
  }
222
222
 
@@ -244,7 +244,7 @@ async function installCli(cli: AgentCliName): Promise<boolean> {
244
244
  }
245
245
  }
246
246
 
247
- async function runInteractiveLogin(cli: AgentCliName): Promise<boolean> {
247
+ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, string>): Promise<boolean> {
248
248
  const args = cli === "claude"
249
249
  ? ["setup-token"]
250
250
  : ["login", "--device-auth"];
@@ -252,6 +252,43 @@ async function runInteractiveLogin(cli: AgentCliName): Promise<boolean> {
252
252
  console.log(`Starting ${cli} login...`);
253
253
 
254
254
  try {
255
+ // For claude: capture stdout to extract OAuth token while still showing output
256
+ if (cli === "claude") {
257
+ const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args), {
258
+ stdin: "inherit",
259
+ stdout: "pipe",
260
+ stderr: "inherit",
261
+ });
262
+
263
+ let output = "";
264
+ const reader = (proc.stdout as ReadableStream<Uint8Array>).getReader();
265
+ const decoder = new TextDecoder();
266
+ while (true) {
267
+ const { done, value } = await reader.read();
268
+ if (done) break;
269
+ const chunk = decoder.decode(value, { stream: true });
270
+ process.stdout.write(chunk);
271
+ output += chunk;
272
+ }
273
+
274
+ const exitCode = await proc.exited;
275
+ if (exitCode === 0) {
276
+ // Extract token (sk-ant-oat01-...) and save to .env
277
+ const tokenMatch = output.match(/(sk-ant-\S+)/);
278
+ if (tokenMatch) {
279
+ vars.CLAUDE_CODE_OAUTH_TOKEN = tokenMatch[1];
280
+ saveEnv(vars);
281
+ console.log(" ✓ claude token saved to .env");
282
+ }
283
+ console.log(` ✓ claude login successful`);
284
+ return true;
285
+ } else {
286
+ console.log(` ✗ claude login failed (exit ${exitCode})`);
287
+ return false;
288
+ }
289
+ }
290
+
291
+ // For codex and others: inherit all stdio
255
292
  const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args), {
256
293
  stdin: "inherit",
257
294
  stdout: "inherit",
@@ -54,10 +54,14 @@ export function isAgentCliInstalled(cli: AgentCliName): boolean {
54
54
  return resolveAgentCliPath(cli) !== null;
55
55
  }
56
56
 
57
+ const INK_SHIM = join(dirname(new URL(import.meta.url).pathname), "ink-shim.js");
58
+
57
59
  export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]): string[] {
58
60
  const cliPath = resolveAgentCliPath(cli);
59
61
  if (!cliPath) {
60
62
  throw new Error(`${cli} CLI not found`);
61
63
  }
62
- return ["bun", "--bun", cliPath, ...args];
64
+ // Preload shim that patches process.stdin.setRawMode to prevent Ink crash
65
+ // when running without a TTY (systemd, su -c, etc.)
66
+ return ["bun", "--preload", INK_SHIM, cliPath, ...args];
63
67
  }
@@ -39,6 +39,11 @@ function loadEnvFile(): Record<string, string> {
39
39
 
40
40
  const envFile = loadEnvFile();
41
41
 
42
+ // Inject .env vars into process.env so child processes inherit them
43
+ for (const [key, value] of Object.entries(envFile)) {
44
+ if (!process.env[key]) process.env[key] = value;
45
+ }
46
+
42
47
  function env(key: string): string | undefined {
43
48
  return process.env[key] || envFile[key];
44
49
  }
@@ -0,0 +1,5 @@
1
+ // Shim for running CLI tools that use Ink without a TTY.
2
+ // Prevents "Raw mode is not supported" crash by providing a no-op setRawMode.
3
+ if (process.stdin && !process.stdin.setRawMode) {
4
+ process.stdin.setRawMode = () => process.stdin;
5
+ }