magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
# Controller agent guide

## Where to look

| Task | Location |
| --- | --- |
| Loop and app state | `app/mod.rs` |
| Event application contract | `drain.rs` (`DrainResult`, `DrainOutcome`) |
| Terminal capture and flush fence | `input_bridge.rs` |
| Redraw intent, cursor timers, scroll coalescing | `pacing.rs` |
| Typed actions and display effects | `app/actions.rs`, `app/reducer.rs`, `app/display_reducer.rs` |
| Startup readiness and initial prompt | `app/startup.rs` |
| Prompt/slash/steering submission and run lifecycle | `app/submit.rs`, `app/workers.rs` |
| Settings workflows | `app/modals.rs`, `app/auth.rs`, `app/theme.rs`, `app/catalog.rs` |
| Compaction, rewind, export | `app/compaction.rs`, `app/rewind.rs`, `app/export.rs` |
| Global fast-mode persistence | `app/fast_mode_persistence.rs` |
| Settings writes and saved-state refresh | `app/settings_persistence.rs` |
| Session picker listing and pruning workers | `app/session_maintenance.rs` |
| Idle Cargo-update restart capture | `app/updates.rs`; shared updater and four-hour check owner: `../../updates.rs` |

## Local conventions

- Drain at most 128 events or 2ms per pass. Preserve `DrainResult` as the handoff from event application to app effects.
- Preserve input-to-paint barriers and redraw decisions when draining backlog; input feedback must not wait behind another unbounded drain.
- Normal loop joins poll `is_finished()` first. Shutdown uses explicit bounded join policies; do not turn cleanup into an indefinite wait.
- Reconcile worker outcomes and matching completion identities before replacing the active worker; queued completion markers can outlive a worker.
- Settings persistence and session maintenance each own one worker and poll its join result. Keep the result until reconciled; event delivery must not be the sole record of completion.
- Footer branch refresh owns a completion mailbox and polls its result even when the shared wake queue is full or disconnected. Keep its worker until finished, then allow the next refresh.
- Session switching retains at most one 1024-event snapshot. Drain it before the live channel under the same 128-event/2ms budget; never send retained events back into the UI channel.
- Session-switch results must match the pending request and session generation. Rewind, export, and model-selection results also validate their captured session context.
- Separate critical startup readiness from decorative loads. A queued initial prompt needs both the painted-frame barrier and input flush fence before launch.
- Keep action/context values data-only; apply display commands in the display reducer and durable work through the owning runtime APIs.
- Fast-mode persistence is global: match request ids, retain delivery/join failures, clean up workers, and block retries after restart-required failure. Update memory only after successful persistence confirmation.
- Settings persistence keeps prior selections visible until saving succeeds. Preserve scope checks, model-selection exclusion, and restart-required failures: a refresh error can follow a successful disk write.
- Session maintenance applies results only to the captured session generation and never reopens a closed picker. Keep pruning separate from active prompts/session switches, and preserve its report if the following listing fails.
- Modal scope changes retain global/project separation and refresh derived disabled settings. Keep status/error text bounded and sanitized.
- Update checks own at most one timeout-bounded worker and retain results outside the event queue. `/update` returns an idle restart request; never run Cargo inside the terminal loop or retain a session lease in restart data.