fix(daemon): signal ready before SDK preload to unblock Java startup

The daemon previously awaited preloadSdks() before sending the ready
event, blocking the Java plugin's DaemonBridge startup for the full
Claude Agent SDK import duration (potentially seconds on slow disks).

Move the ready signal before preloadSdks(). The SDK is now loaded in
the background; acquireRuntime() already lazy-loads via ensureQueryFn()
with its own promise cache, so the first send simply waits for the
in-flight load instead of blocking daemon startup. Heartbeat and status
commands become available immediately.

Also emit a sdk_ready event when the background preload completes, so
the Java side can log the transition for diagnostics.
This commit is contained in:
hebulin
2026-08-25 11:10:23 +08:00
parent db9874a4be
commit fa2010cce6
+18 -8
View File
@@ -580,19 +580,29 @@ async function runDaemonMain() {
platform: process.platform,
});
// Pre-load SDK
await preloadSdks();
// Signal ready BEFORE pre-loading the SDK so the Java side can start sending
// heartbeats and status queries immediately. The SDK load is moved to
// background: acquireRuntime() already lazy-loads via ensureQueryFn() with
// its own caching, so the first send will simply wait for the in-flight load
// instead of blocking daemon startup. (#performance)
sendDaemonEvent('ready', {
pid: process.pid,
sdkPreloaded: false, // SDK is loading in the background
});
// Pre-load SDK in the background (non-blocking). Errors are logged but do
// not affect daemon readiness — a failed preload is retried lazily on the
// first send via ensureQueryFn().
preloadSdks().then(() => {
sendDaemonEvent('sdk_ready', { pid: process.pid });
}).catch((e) => {
_originalStderrWrite(`[daemon] Background SDK preload failed: ${e?.message || e}\n`, 'utf8');
});
// Best-effort cleanup of stale temp image files (>24h). Fire-and-forget so
// it doesn't block daemon readiness.
cleanupStaleTempImages().catch(() => {});
// Signal ready
sendDaemonEvent('ready', {
pid: process.pid,
sdkPreloaded,
});
// --- Listen for requests on stdin ---
const rl = createInterface({
input: process.stdin,