arisa 2.3.25 → 2.3.26

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/bin/arisa.js CHANGED
@@ -533,12 +533,23 @@ switch (command) {
533
533
  if (isDefaultInvocation) {
534
534
  printForegroundNotice();
535
535
  }
536
- // Run daemon in-process avoids an extra bun child (~150MB saved)
537
- await import(daemonEntry);
538
- break;
536
+ // Single bun process: daemon + core in-process with --watch.
537
+ // When root, run as arisa (Claude CLI refuses root). su without "-"
538
+ // preserves parent env (ARISA_DATA_DIR, tokens, API keys).
539
+ let child;
540
+ if (isRoot() && arisaUserExists()) {
541
+ const bunEnv = "export HOME=/home/arisa && export BUN_INSTALL=/home/arisa/.bun && export PATH=/home/arisa/.bun/bin:$PATH";
542
+ const cmd = `${bunEnv} && cd ${pkgRoot} && exec bun --watch ${daemonEntry}`;
543
+ child = spawnSync("su", ["arisa", "-s", "/bin/bash", "-c", cmd], {
544
+ stdio: "inherit",
545
+ env: process.env,
546
+ });
547
+ } else {
548
+ child = runWithBun(["--watch", daemonEntry, ...rest]);
549
+ }
550
+ process.exit(child.status === null ? 1 : child.status);
539
551
  }
540
552
  case "core": {
541
- // Run core in-process
542
553
  await import(coreEntry);
543
554
  break;
544
555
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arisa",
3
- "version": "2.3.25",
3
+ "version": "2.3.26",
4
4
  "description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
5
5
  "keywords": [
6
6
  "tinyclaw",
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * @module daemon/index
3
- * @role Entry point for the Daemon process.
3
+ * @role Single-process entry point: Daemon + Core in one bun runtime.
4
4
  * @responsibilities
5
5
  * - Run interactive setup if config is missing
6
6
  * - Start the Telegram channel adapter
7
- * - Spawn Core process with --watch
8
- * - Run HTTP server on :7778 for Core → Daemon pushes (scheduler)
7
+ * - Load Core in-process (HTTP server, Claude CLI, scheduler)
8
+ * - Run HTTP server for Core → Daemon pushes (scheduler)
9
9
  * - Route incoming messages to Core via bridge
10
10
  * - Route Core responses back to channel
11
- * @dependencies All daemon/* modules, shared/*
12
- * @effects Network (Telegram, HTTP servers), spawns Core process
11
+ * @dependencies All daemon/* modules, core/*, shared/*
12
+ * @effects Network (Telegram, HTTP servers), spawns Claude CLI
13
13
  */
14
14
 
15
15
  // Log version at startup
@@ -32,8 +32,7 @@ const { createLogger } = await import("../shared/logger");
32
32
  const { serveWithRetry, claimProcess, releaseProcess, cleanupSocket } = await import("../shared/ports");
33
33
  const { TelegramChannel } = await import("./channels/telegram");
34
34
  const { sendToCore } = await import("./bridge");
35
- const { startCore, stopCore, setLifecycleNotify, waitForCoreReady } = await import("./lifecycle");
36
- const { setAutoFixNotify } = await import("./autofix");
35
+ // lifecycle/autofix removed Core runs in-process, --watch handles restarts
37
36
  const { maybeStartCodexDeviceAuth, setCodexLoginNotify } = await import("./codex-login");
38
37
  const { maybeStartClaudeSetupToken, maybeFeedClaudeCode, setClaudeLoginNotify, isClaudeLoginPending } = await import("./claude-login");
39
38
  const { autoInstallMissingClis, setAutoInstallNotify, setAuthProbeCallback } = await import("./auto-install");
@@ -95,8 +94,6 @@ const sendToAllChats = async (text: string) => {
95
94
  }
96
95
  };
97
96
 
98
- setLifecycleNotify(sendToAllChats);
99
- setAutoFixNotify(sendToAllChats);
100
97
  setAutoInstallNotify(sendToAllChats);
101
98
  setAuthProbeCallback((cli, errorText) => {
102
99
  if (cli === "claude") {
@@ -256,11 +253,13 @@ const pushServer = await serveWithRetry({
256
253
 
257
254
  log.info(`Daemon push server listening on ${config.daemonSocket}`);
258
255
 
259
- // --- Start Core process ---
260
- startCore();
256
+ // --- Load Core in-process (single bun process, no child spawn) ---
257
+ log.info("Loading Core...");
258
+ await import("../core/index.ts");
259
+ log.info("Core loaded");
261
260
 
262
- // --- Auto-install missing CLIs (after Core is up to avoid OOM on low-RAM VPS) ---
263
- waitForCoreReady(30_000).then(() => void autoInstallMissingClis());
261
+ // --- Auto-install missing CLIs (delayed to avoid peak memory) ---
262
+ setTimeout(() => void autoInstallMissingClis(), 5000);
264
263
 
265
264
  // --- Connect Telegram (with retry for 409 conflict from stale polling sessions) ---
266
265
  (async function connectTelegram(maxRetries = 5) {
@@ -284,8 +283,7 @@ waitForCoreReady(30_000).then(() => void autoInstallMissingClis());
284
283
 
285
284
  // --- Graceful shutdown ---
286
285
  function shutdown() {
287
- log.info("Shutting down Daemon...");
288
- stopCore();
286
+ log.info("Shutting down...");
289
287
  cleanupSocket(config.daemonSocket);
290
288
  cleanupSocket(config.coreSocket);
291
289
  releaseProcess("daemon");