[CMUX Next] Chief pet: floating pet, notices, quick reply and Settings (whole stack)

Merged
TE
17d ago
+5213-94

Summary

This PR lands the whole Chief pet stack. It targets feat-cmux-next and contains #21728 (floating panel), #21732 (notice deck) and #21736 (quick reply), plus the review fixes listed below. Merging it lands all four, and those three close as included. This section covers the settings part; the stacked PRs describe the rest and carry their side-by-sides.

The settings part: It adds two settings in a Chief Pet card under Settings > Agents (section home) and removes the chiefPet.enabled Debug Settings toggle.

  • Show Chief Pet (home.chiefPetEnabled), off by default. Help text: "A small Chief floats over every app and shows agent events above it. Drag it anywhere; click it to message the Chief or reply to a session."
  • Character (home.chiefPetMascot): one of the Chief Dock's nine pixel mascots, the ones Codex generated (orb, orb-spark, orb-hood, machine, machine-cyan, machine-blue, moon, moon-blue, fox). It defaults to orb, as the dock does. An unknown id falls back to Orb and reports a diagnostic.

How the settings behave:

  • The palette's settings rows pick both up through the schema. cmux settings set home.chiefPetEnabled true and cmux settings set home.chiefPetMascot fox change them from the CLI.
  • Agents may set both (agentSettableTable), since they change looks only.
  • The pet follows both live. Turning it off hides the pet, the notices and the reply box. Changing the character redraws the pet where it is.
  • They're wired next to the other follow(settings) services in AppDelegate. Showcase captures never start the pet.

The generated settings exports (schemas/settings/settings-schema.json, schemas/defaults/cmux-next.json, docs/mdm/*) and the Settings page string bundle are regenerated by the PR autofix job, which needs a Mac swift test. They aren't hand-edited here.

Review fixes (correctness review subagent)

  • Reply safety: a typed reply goes into a terminal only while that notice is still its tab's unread notification. This is the same guard a notify --reply banner uses.
  • Notices read elsewhere: a notice read on another client, on the phone, by closing its tab or by a daemon restart now leaves the pet. The pet reconciles against the unread count.
  • Reply menu:
    • Two notices with the same title stay two menu items.
    • The chosen session survives refreshes. If it goes away, the box falls back to the Chief, never to another session.
    • ⌘Return opens the target. Other ⌘ keys stop at the box instead of acting on the cmux window behind it.
  • Clicks and opening:
    • Notice capsules now receive the press, so a click opens the tab.
    • An agent chat opens its own tab instead of a second copy in the floating chat.
  • Deck edge case: a finished turn that arrives behind three waiting notices no longer animates or schedules a timer for a notice that isn't shown.
  • Module and file rules:
    • CmuxNextFloating no longer imports CmuxNextDaemon; the App maps the notification.
    • The notification service makes the pet, so AppServices.swift, AppDelegate.swift and CmuxConfigSnapshot.swift don't grow.
    • The standard constant was renamed to initial for the lint.

Reference

The character choices against the Codex-generated avatars (chief-pet-refs/codex-generated), both at 720 × 720. Each choice is drawn at the pet's 88 × 80 pt box at @2x:

characters

Testing

ChiefPetSettingTests (CmuxNextSettingsTests) covers:

  • off by default, with the row's default matching the parser's, in the Home section, as a toggle;
  • cmux.json turning the pet on;
  • a value that isn't a bool staying off, with a diagnostic;
  • agents being allowed to set it;
  • the character defaulting to Orb, accepting a mascot id, and rejecting an unknown one with a diagnostic;
  • the character row's choices matching the mascot ids.

In ChiefPetTests:

  • everySettingIdIsAMascot pins the module's ids to the same list.
  • controllerShowsThePetOnlyWhileItIsOn drives the observed switch: no panel while off; turning it on shows the pet; a click opens the reply box; turning it off hides both; turning it on again reuses the same panel.

What ran:

  • The cmux-next fast tier passed on aba0ee4. It built CmuxNextFloating and every test target, including the new test files.
  • The cmux-next swift test job is skipped on PRs, so the new tests compiled but have not been executed. They run after merge. They were not run locally either (Linux host).
  • lint-ios-package-conventions.sh is clean on this stack's files.
  • check-no-godfiles.sh shows no growth.
  • CmuxNextApp shrinks by about 140 source lines.

Known red checks:

  • defaults-snapshot: the generated settings exports (settings-schema.json, docs/mdm, defaults snapshot) need a Mac swift test to regenerate. The PR autofix doesn't regenerate them; the base autofix bot does after merge. The two new defaults (home.chiefPetEnabled false, home.chiefPetMascot "orb") still need a defaults owner's approval.
  • build / release-compile fails on every current feat-cmux-next PR.
  • cmux-next checks fails only on the Chief first-turn token-cost check, which also fails on base.

Localization: 13 new strings in CmuxNextSettings/Localizable.xcstrings, all with 20 locales: the group, the toggle and its help, "Character", and the nine mascot names. Chief stays untranslated.

Changelog

Added: A floating Chief pet (Settings > Home > Show Chief Pet) that shows agent events over any app and lets you message the Chief or reply to a session without switching to cmux, with a choice of nine pixel characters

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Adds the Chief pet to Settings > Agents: a pixel mascot floating over every app that shows agent notices above it and offers a quick reply. Replaces the Debug Settings toggle with home.chiefPetEnabled (off by default, user-only) and home.chiefPetMascot (nine mascots, Orb by default, agent-settable); the pet follows both settings live.

  • Notices, their bubble, and the reply box live in the new CmuxNextFloating target; the notification service feeds the pet only events that would alert on this Mac, and a notice read elsewhere leaves the pet.
  • A typed reply enters a terminal only while the notice is still that tab's unread notification, and only for an agent's or notify --reply notice; other terminal notices open their tab, and a session that leaves drops the text instead of sending it to the Chief. ⌘Return opens the target and the chosen session survives refreshes.
  • The pet, notices, and reply box stay out of screen shares; unknown mascot ids fall back to Orb with a diagnostic.
  • The bubble and reply field draw their title from the type scale.
  • Generated settings exports for MDM and the defaults snapshot are regenerated after each base merge, and the CI target graph lists the new floating surfaces.
  • Home's Keyboard Shortcuts link now opens in the background instead of on the main thread.