arisa 2.3.30 → 2.3.32

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.30",
3
+ "version": "2.3.32",
4
4
  "description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
5
5
  "keywords": [
6
6
  "tinyclaw",
@@ -131,7 +131,7 @@ async function runClaudeSetupToken(): Promise<void> {
131
131
 
132
132
  let proc: ReturnType<typeof Bun.spawn>;
133
133
  try {
134
- proc = Bun.spawn(buildBunWrappedAgentCliCommand("claude", ["setup-token"]), {
134
+ proc = Bun.spawn(buildBunWrappedAgentCliCommand("claude", ["setup-token"], { skipPreload: true }), {
135
135
  cwd: config.projectDir,
136
136
  stdin: "pipe",
137
137
  stdout: "pipe",
@@ -106,7 +106,7 @@ async function runCodexDeviceAuth(): Promise<void> {
106
106
 
107
107
  let proc: ReturnType<typeof Bun.spawn>;
108
108
  try {
109
- proc = Bun.spawn(buildBunWrappedAgentCliCommand("codex", ["login", "--device-auth"]), {
109
+ proc = Bun.spawn(buildBunWrappedAgentCliCommand("codex", ["login", "--device-auth"], { skipPreload: true }), {
110
110
  cwd: config.projectDir,
111
111
  stdin: "inherit",
112
112
  stdout: "pipe",
@@ -256,6 +256,8 @@ log.info(`Daemon push server listening on ${config.daemonSocket}`);
256
256
  // --- Load Core in-process (single bun process, no child spawn) ---
257
257
  log.info("Loading Core...");
258
258
  await import("../core/index.ts");
259
+ const { setCoreState } = await import("./lifecycle");
260
+ setCoreState("up");
259
261
  log.info("Core loaded");
260
262
 
261
263
  // --- Auto-install missing CLIs (delayed to avoid peak memory) ---
@@ -61,6 +61,10 @@ export function getCoreState(): CoreState {
61
61
  return coreState;
62
62
  }
63
63
 
64
+ export function setCoreState(state: CoreState) {
65
+ coreState = state;
66
+ }
67
+
64
68
  export function getCoreError(): string | null {
65
69
  return lastError;
66
70
  }
@@ -282,7 +282,7 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
282
282
  try {
283
283
  // For claude: capture stdout to extract OAuth token while still showing output
284
284
  if (cli === "claude") {
285
- const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args), {
285
+ const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args, { skipPreload: true }), {
286
286
  stdin: "inherit",
287
287
  stdout: "pipe",
288
288
  stderr: "inherit",
@@ -390,7 +390,7 @@ async function runInteractiveLogin(cli: AgentCliName, vars: Record<string, strin
390
390
  }
391
391
 
392
392
  // For codex and others: inherit all stdio
393
- const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args), {
393
+ const proc = Bun.spawn(buildBunWrappedAgentCliCommand(cli, args, { skipPreload: true }), {
394
394
  stdin: "inherit",
395
395
  stdout: "inherit",
396
396
  stderr: "inherit",
@@ -5,7 +5,7 @@
5
5
  * Claude CLI's non-root requirement.
6
6
  */
7
7
 
8
- import { existsSync } from "fs";
8
+ import { existsSync, openSync, readSync, closeSync } from "fs";
9
9
  import { delimiter, dirname, join } from "path";
10
10
 
11
11
  export type AgentCliName = "claude" | "codex";
@@ -96,21 +96,61 @@ function buildEnvExports(): string {
96
96
  return exports.length > 0 ? exports.join(" && ") + " && " : "";
97
97
  }
98
98
 
99
- export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]): string[] {
99
+ export interface AgentCliOptions {
100
+ /** Skip the ink-shim preload (useful for interactive login flows). Default: false */
101
+ skipPreload?: boolean;
102
+ }
103
+
104
+ /**
105
+ * Detect native executables (Mach-O, ELF) by reading magic bytes.
106
+ * Claude Code CLI v2+ ships as a native binary, not a JS script.
107
+ */
108
+ function isNativeBinary(filePath: string): boolean {
109
+ try {
110
+ const fd = openSync(filePath, "r");
111
+ const buf = Buffer.alloc(4);
112
+ readSync(fd, buf, 0, 4, 0);
113
+ closeSync(fd);
114
+ const magic = buf.readUInt32BE(0);
115
+ return (
116
+ magic === 0xCFFAEDFE || // Mach-O 64-bit LE (macOS arm64/x86_64)
117
+ magic === 0xCEFAEDFE || // Mach-O 32-bit LE
118
+ magic === 0xFEEDFACF || // Mach-O 64-bit BE
119
+ magic === 0xFEEDFACE || // Mach-O 32-bit BE
120
+ magic === 0xCAFEBABE || // Mach-O Universal
121
+ magic === 0x7F454C46 // ELF (Linux)
122
+ );
123
+ } catch {
124
+ return false;
125
+ }
126
+ }
127
+
128
+ export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[], options?: AgentCliOptions): string[] {
129
+ const cliPath = isRunningAsRoot()
130
+ ? (resolveAgentCliPath(cli) || join(ROOT_BUN_BIN, cli))
131
+ : resolveAgentCliPath(cli);
132
+
133
+ if (!cliPath) {
134
+ throw new Error(`${cli} CLI not found`);
135
+ }
136
+
137
+ // Native binaries (Mach-O, ELF) must be executed directly — bun can't parse them as JS
138
+ const native = isNativeBinary(cliPath);
139
+
100
140
  if (isRunningAsRoot()) {
101
141
  // Run as arisa user — Claude CLI refuses to run as root.
102
- // This path is used by Daemon fallback calls; Core runs as arisa directly.
103
- const cliPath = resolveAgentCliPath(cli) || join(ROOT_BUN_BIN, cli);
104
- const inner = ["bun", "--bun", "--preload", INK_SHIM, cliPath, ...args].map(shellEscape).join(" ");
142
+ const inner = native
143
+ ? [cliPath, ...args].map(shellEscape).join(" ")
144
+ : ["bun", "--bun", ...(!options?.skipPreload ? ["--preload", INK_SHIM] : []), cliPath, ...args].map(shellEscape).join(" ");
105
145
  // su without "-" preserves parent env (tokens, keys); explicit HOME/PATH for arisa
106
146
  return ["su", "arisa", "-s", "/bin/bash", "-c", `${ARISA_BUN_ENV} && ${buildEnvExports()}${inner}`];
107
147
  }
108
148
 
109
- const cliPath = resolveAgentCliPath(cli);
110
- if (!cliPath) {
111
- throw new Error(`${cli} CLI not found`);
149
+ if (native) {
150
+ return [cliPath, ...args];
112
151
  }
113
- // Preload shim that patches process.stdin.setRawMode to prevent Ink crash
114
- // when running without a TTY (systemd, su -c, etc.)
115
- return ["bun", "--bun", "--preload", INK_SHIM, cliPath, ...args];
152
+
153
+ // JS/Node scripts: wrap with bun for performance + optional ink-shim preload
154
+ const preloadArgs = !options?.skipPreload ? ["--preload", INK_SHIM] : [];
155
+ return ["bun", "--bun", ...preloadArgs, cliPath, ...args];
116
156
  }