Skip to content

ccmux v0.2.1

Choose a tag to compare

@github-actions github-actions released this 29 Jul 11:22

model from transcript (source of truth), not the statusline whitelist — a new Claude family (Fable/Mythos) is never shown as a blank model again

fix: session model is read from the transcript (source of truth), not scraped from the statusline against a family whitelist — so a new Claude family (Fable, Mythos, …) is never shown as a blank model again

  • ccmux list reported model: null for sessions on any family the pane scraper hadn't been taught.
    The model was matched with a (Opus|Sonnet|Haiku) regex against the rendered statusline — a
    whitelist that silently dropped Fable 5 (and would drop the next family too), and that depended on
    the user's arbitrary custom statusline and reflected the start-time model, not the current one.
  • The model now comes from the transcript's message.model (Claude) / turn_context.model (Codex) —
    the source of truth, always fresh, format-independent. <synthetic> turns are skipped and only real
    assistant turns are trusted (image-gen model ids live in tool payloads). Display formatting is a pure
    transform (prettyModel: claude-fable-5 → "Fable 5"), never a lookup table, so a future family
    renders with zero code change; anything off-shape falls back to the raw stripped id.
  • The pane scraper keeps only genuinely-live signals (working/idle, best-effort context); its old
    double-duty "model → booted" gate is replaced by a statusline-independent ready marker. The
    managed-list and external-discover paths now share one model source and one formatter.

fix: shipped bundle is truly self-contained — stub react-devtools-core at build time so a cache-cleared / offline machine no longer dies on start with ENOENT; + guard test against future hoisted externals

  • Fix the shipped bundle silently depending on the global bun cache / npm at startup. ink imports an
    optional DEV-only React DevTools client (react-devtools-core) via a HOISTED static import, so it
    loaded on every launch — and built with --external it resolved that import at runtime against
    ~/.bun/install/cache (or an npm auto-install). A machine whose cache was cleared, or that had no
    network, died on start with ENOENT ... react-devtools-core — the daemon (and every session it
    supervises) down. The "self-contained" bundle was never actually self-contained. The build now
    compiles an inert stub in its place (Bun.build() API + a resolve plugin instead of the
    bun build --external spawn), so the single-file bundle carries no external import and starts
    offline / with an empty cache. The bundling moved to scripts/bundle.ts (one build path shared by
    stage / CI / release), the misleading "never reached in prod" comment and the obsolete "build only
    outside the project tree" caveat are gone, and a guard test builds via that same path and asserts
    the bundle starts under a wiped cache + dead registry — so this can never silently regress.