get_ai_agents_status used to probe all six agent CLIs (claude_code,
codex, opencode, pi, gemini, kiro) sequentially during cold start. For
each agent missing from PATH it would fall through to three login-shell
spawns (`<shell> -lc 'command -v <agent>'`), each evaluating the user's
full zsh init. On a machine with no agents installed this added ~5 s to
cold start.
The result is not on the first-paint render path. It feeds the status
bar AI badge, the AI tab in settings, and the AI agents onboarding
prompt — all of which are gated behind aiFeaturesEnabled and the
onboarding flow, so they happily render nothing while the probe is
pending.
Three additive changes:
* useAiAgentsStatus now takes an `enabled` option. When false (AI
features off, or running in a detached note window) the probe never
fires. App.tsx passes `aiFeaturesEnabled && !noteWindowParams`.
* When enabled, the invoke call is deferred via requestIdleCallback
(with setTimeout(0) fallback because WKWebView lacks the API) so it
lands after first paint instead of during it.
* Rust get_ai_agents_status is now async and fans the six check_cli()
calls out under tokio::task::spawn_blocking + tokio::join!. Per-agent
check_cli() signatures stay sync, so run_agent_stream callers are
unaffected and the per-agent unit tests need no changes.
Cold-start measurements on this machine (no agents on PATH, dev mode):
Baseline (main, AI on): cascade settles at t+15.5 s
Patched, AI features off: t+5.0 s
Patched, AI features on: t+6.0 s,
AI status arrives ~1.6 s after first
paint, fully off the critical path.
Fixes: https://github.com/refactoringhq/tolaria/issues/726
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>