Detached engine lifecycle: adopt-safe restart, fleet-aware self-shutdown, Quit command, and UI toggle (#1594) - #1603
Merged
jeonghun-jj-lee merged 10 commits intoSep 28, 2026
Conversation
added 8 commits
September 27, 2026 21:28
…d path (#1595) On any adopted window (every reload after the first cold-spawn), the extension now creates a ServerManager via the new `seed()` static method, which sets the manager into the running/daemonized state with the adopted engine's port and PID. Changes: - ServerManager.seed(opts, { port, pid }) — creates a manager representing an already-running engine. stop() kills by PID, start() cold-spawns fresh. - Extracted wireReadyState() — shared ready-wiring (SSE connect, keepalive, stray sweep, chat-open, provider signal) used by both cold-spawn onReady and adopted-path inline boot. Chat-open fires only on first-ready. - Adopted path seeds serverManager with the same options a cold-spawn uses, so amicode.restartServer kills the adopted engine and respawns correctly. - Hash computation (binaryHash, configHash) moved before the adopt/cold-spawn split so the seeded manager's afterHealthy writes a valid handshake. - detach() path in deactivate is unchanged — no kill-on-deactivate.
Extension → App engine-state push: - pushEngineState(on|booting|off) broadcasts to all live app panels - Wired at every lifecycle transition: onReady → on, keepalive gone → off, restart → booting then on, stop → off, start fail → off - pushFleetRole() broadcasts fleet topology (client/server/standalone) - Both fire on app-ready (persistent) so new panels get current state Bridge allowlist: - Added amicode.stopServer to BRIDGE_ALLOWED_COMMANDS (companion to the existing amicode.restartServer) App-side engine toggle component: - engine-toggle.ts: pure parsers + command sender (no DOM deps, testable) - engine-toggle.tsx: SolidJS component in the status popover body - Green dot / yellow pulsing dot / gray dot for on/booting/off - Clicking on → stops engine, clicking off → restarts engine - Locked (non-interactive, cursor-not-allowed) while booting - Hidden on fleet-client windows (fleet-role message) - Defaults to 'booting' before first push (safe cold-boot state) Tests: - Extension: pushEngineState posts correct message shape (5 tests) - Extension: BRIDGE_ALLOWED_COMMANDS includes amicode.stopServer - App: parseEngineStateMessage/parseFleetRoleMessage parsers (11 tests) - App: sendEngineCommand sends correct bridge commands
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
added 2 commits
September 27, 2026 22:50
- Rename engine-toggle.ts → engine-toggle-utils.ts to avoid TS5056 collision with engine-toggle.tsx (both produce engine-toggle.d.ts) - Drop .ts/.tsx extensions from imports (tsgo TS5097) - Widen closeWindow type to PromiseLike<void> (vscode.commands.executeCommand returns Thenable, not Promise — TS2322 on CI's stricter tsc) - Update manifest hashes for the renamed/changed files
…1229) Fix 1: session.ts getUsage — guard Decimal.mul against non-numeric cost fields (e.g. {} from malformed costInfo) with safeNum helper. Fix 2: system.ts — add Muse Glimmer model detection and {{MODEL_NAME}} substitution in PROMPT_META for both Muse Spark and Muse Glimmer. Add provider-ID-based Kimi matching for kimi-for-coding/moonshotai/moonshotai-cn. Fix 3: request.ts — add x-parent-session-id header to opencode provider branch (was only in the non-opencode branch). Fix 4: registry.ts — change webSearchEnabled from exact providerID match to prefix match (startsWith) so opencode-go and similar variants work. Fix 5: provider.ts — narrow Bedrock DeepSeek prefix from 'deepseek' to 'deepseek.r1' so native model IDs like deepseek.v3.2 are not erroneously prefixed with us. while cross-region profiles like deepseek.r1-v1:0 still get the prefix. Fix 6: compaction.ts — serialize conversation as text ([User]:, [Assistant]:, [Assistant tool call]:, [Tool result]:, [Attached ...]) into buildPrompt's context array and send as a single user message instead of separate model messages + user prompt. Plugin context appended after </conversation> tags. Handles file attachments in user messages.
jeonghun-jj-lee
marked this pull request as ready for review
September 28, 2026 03:31
jeonghun-jj-lee
merged commit Sep 28, 2026
2484f96
into
feature/free-tier-fleet
11 of 12 checks passed
jeonghun-jj-lee
deleted the
amico/issue-1594-detached-engine-lifecycle
branch
September 28, 2026 03:33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements #1594 and its four sub-issues as one integration branch:
ServerManageron the adopted path so Stop/Restart work on every window/keepaliveself-shutdown — fleet-aware idle predicate (grace × turns × subscribers × role-exempt)Amicode: Quitcommand — stop engine + close window in one action, with in-flight warningChanges
S1 — Adopt-safe lifecycle (
874213bc)ServerManager.seed()static method: creates a manager in running-daemonized state from the handshake's PID/portwireReadyState()function extracted from cold-spawn and adopted paths (chat-open guarded to first-ready)ServerManager, so Stop/Restart work identically on every windowS2 — /keepalive self-shutdown (
ec8eabe0)POST /keepaliveroute (authenticated, reads graceSeconds from body)AMICO_ENGINE_ROLE_EXEMPT=1env flag for fleet server/hub rolesS3 — Quit command (
82b698ea)amicode.quitcommand with stop-then-close ordering (stop before window teardown, otherwise detach lets the engine survive)S4 — Engine toggle (
c21fa602)engine-statepush (on/booting/off) at every lifecycle transitionamicode.stopServeradded to bridge allowlistTest Results
297 test files passed, 5017 tests green, 0 failures (60 skipped = pre-existing fleet e2e + slow tests).
2 test files skipped are pre-existing fleet_peer_e2e.test.ts (SSH forwarding infra, unrelated).
Closes
Closes #1595, closes #1596, closes #1597, closes #1598.
Part of #1594.