Skip to content

feat(cmux-next): Labs flags, one registry for opt-in looks and behaviors (hq#1980, no bead) - #20452

Closed
teamleaderleo wants to merge 39 commits into
feat-cmux-nextfrom
op-next-call-keys/labs
Closed

teamleaderleo wants to merge 39 commits into
feat-cmux-nextfrom
op-next-call-keys/labs

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Labs (hq#1980): new looks and behaviors ship behind a flag that a person turns on, not in the defaults. This builds on the existing labs.previewFeatures and keeps it as the only mechanism. Its users (#20429's Now Playing card) keep reading snapshot.previewFeatures.

  • Registry: each row of schemas/settings/source/labs.json is a LabsFlag with owner, created, expires (about 14 days), cohort (off / nightly-next / default) and a one-line intent (its help). gen-settings-sources.py checks the fields and generates the Swift LabsFlag enum and webviews/src/experiments/labs.generated.ts. It prints warning: labs.<name> ... expired for any flag past its expiry, including under --check; the warning never fails the run.
  • Defaults: every flag defaults off. nightly-next flags are on in nightly and dev builds only. Promoting a flag to default is a one-line PR, and that PR is the design call.
  • Where flags show up: Settings > Experimental > Labs (a toggle with the intent line), the palette's settings scope, Help > Feature Flags (now bound, opens that list), cmux.json, MDM, and the agent policy.
  • New Tab page, team builds only: one quiet line, "Labs" (or "Labs (N on)"), on the page's column edges and type scale, collapsed by default and remembered per viewer. Open, it lists each flag as a 28px row: name, one-line intent (truncated before the badge), a "New" or "Expires soon" hint, and a switch; recently toggled first, else newest. Right-click a row for Turn On/Off and All Labs…. "All Labs…" opens Settings > Labs. A toggle is newTab.setLab, saved through the schema. Release and RC builds show nothing. Variant A of three, picked by cg-design-judge (feat(cmux-next): Labs flags, one registry for opt-in looks and behaviors (hq#1980, no bead) #20452 (comment)).
  • Palette: "Labs…" (Help > Feature Flags is now Help > Labs…; "feature flags" stays a search keyword) opens Settings > Labs.
  • One helper per side:
    • Swift: snapshot.lab(.name).
    • Web: useLabsFlag("name") / labsFlag("name"), which read data-labs on <html>. Every PageWebView page gets that attribute, kept current. labsTeamBuild() reads data-labs-team.
  • Docs: skills/cmux-architecture/references/labs-flags.md explains how to put a change behind Labs.

Testing

  • Swift

    • LabsFlagTests: the cohort and file decide a flag, a bad value is off with a diagnostic, and every flag is a toggle with its fields.
    • NewTabLabsTests: a page toggle is saved in cmux.json, and a name that is not a flag writes nothing; All Labs… runs help.featureFlags.
    • Red: the fleet run-swift-testing-suites.sh at the red commits fails (no member 'lab'; the New Tab red is a compile red, since its API did not exist yet).
    • Green: fleet run-swift-testing-suites.sh on the merged head 18a0888: 288 suites passed, 0 failed (the step exits 1 only because AcpmuxBundleReplacedTests skips without a published same-tree cmux-tui for that SHA).
    • Settings export on the merged head: no diff (exportIsFresh passes).
  • Web: bun test test/new-tab-labs.test.tsx was red at e59433f (no section) and is green now. src/experiments/labs.test.ts passes.

  • Checks:

    • gen-settings-sources.py --check, gen-strings.mjs --check agentPane, ui-rules, and scoped vp check pass.
    • In bun run check, every step before the final whole-repo vp check passes. That last lint was killed on big-red (143); CI react-apps-check covers it.
    • crash ratchet, concurrency, system-blue and the scoped god-file check pass. App size is at the cap (113801).
  • Review (subagent): the agent pane's own web view (agent.pageHost off, the default) never got data-labs; fixed with AgentPaneLabs. The generator now rejects a key that is not labs.<name>. Known limit: a page's first moments can carry the flag list from when its web view was made; useLabsFlag follows the live value.

  • Localization: the two new New Tab strings are in all 21 locales. Flag intents show in English on the New Tab page (team builds only); Settings shows them localized.

  • Redesign (variant A): test/new-tab-labs.test.tsx was red first (3a5f675, 3a48dc6) and is green: collapsed by default as "Labs" / "Labs (N on)", rows with intent and switch, New / Expires soon hints, recently toggled first with a storage fallback, remembered open state, row menu. agent-pane-no-capsules, theme-colors, subtle-elevation and ui-rules pass locally. Release compile BUILD SUCCEEDED on d69557f.

Changelog

Added: Labs: opt-in flags for new looks and behaviors, listed in Settings > Experimental > Labs, the palette ("Labs…") and, in nightly and dev builds, a quick-toggle line on the New Tab page

Proof

Real cmux NEXT DEV builds from the fleet (--builder mac), on capture slots; host chip masked. Base: the New Tab page and palette before this PR. Head: this branch. The switch knob in these stills is white; since then it takes the page's theme color (theme-colors/subtle-elevation rules), otherwise unchanged.

Light Dark
Before: New Tab
After: Labs collapsed
After: Labs open
After: row right-click menu
Before: palette "Labs"
After: palette "Labs…"

Open, close, reopen, then turn the flag on and off (head, light):

labs toggle

Full quality: labs-real-toggle-after.mp4

🤖 Generated with Claude Code

teamleaderleo and others added 10 commits October 13, 2026 21:50
…on on/off

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ors (hq#1980)

schemas/settings/source/labs.json is the flag registry: each labs.<name>
row carries owner, created, expires, cohort (off / nightly-next / default)
and its one-line intent (help). gen-settings-sources.py checks the fields,
generates the Swift LabsFlag enum and webviews/src/experiments/
labs.generated.ts, and warns (never fails) for a flag past its expiry.

- Swift reads a flag with snapshot.lab(.name): cmux.json's value, else
  the cohort for this build (nightly-next: nightly and dev builds).
  previewFeatures is the first flag; snapshot.previewFeatures now reads it.
- Pages get the on flags as data-labs on <html> (LabsState, updated by
  the settings controller); web reads labsFlag / useLabsFlag.
- Flags are agent-settable from the registry, show in Settings >
  Experimental > Labs, flip from the palette's settings scope, and
  Help > Feature Flags opens them.
- skills/cmux-architecture/references/labs-flags.md: how to add,
  promote (one-line cohort PR = the design call), extend or delete one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (red)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1980)

In nightly and dev builds the New Tab page lists every Labs flag with its
one-line intent and a toggle, so the team tries prototypes where they start
work; All Labs... opens Settings > Labs. A toggle is newTab.setLab, saved as
labs.<flag> through the schema like the style switch's template (one
AgentPaneNewTabSetting callback for both). Pages see a team build as
data-labs-team on <html>; labsTeamBuild() reads it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CmuxNextApp sees two JSONValue types (Settings and Daemon).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 7de02dc6-fd5e-4116-b3c1-50842c1fb916

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…call-keys/labs

# Conflicts:
#	Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/NewTabStyleSwitchTests.swift
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-eyccd created for this PR by the cmux coordinator.

Review of #20452: with agent.pageHost off (the default) the agent pane and
its New Tab page make their own WKWebView, so data-labs and data-labs-team
never reached them and the New Tab Labs section never showed. AgentPaneLabs
adds them at document start with the theme bootstrap and follows LabsState.
Also: the Labs tests await each save (#20423's fix for the yield wait), the
generator rejects a flag key that is not labs.<name> or has no default
without a traceback, and labsFlag() says when to use the hook instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@blacksmith-sh

This comment has been minimized.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

all web/size checks green

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Not verified: macOS jobs did not run: compile and app tests were skipped on b9b8a8897d; ci-status is green without them.

CI passes on b9b8a8897d (run 38663518174 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

CI fast guards passes on b9b8a8897d (https://github.com/manaflow-ai/cmux/actions/runs/38663518174). This covers only the fast guards, not CI: CI's result is the ci-status check, and the CI failure attribution comment names any failing test.

teamleaderleo and others added 2 commits October 13, 2026 23:20
gallery-coverage asks every component for an entry: the New Tab page gets a
labs variant (data-labs-team set), and the section follows data-labs-team
through useLabsTeamBuild so it shows when the attribute does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- vp fmt webviews/src/agent-session/acpmux/modelPickerLayout.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/38521627926
@cursor

cursor Bot commented Oct 14, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Gallery

Review in feed

203 states changed: gallery.visual-media-board/all-previews, agent-pane.artifact-panel/markdown, agent-pane.transcript/long-code, agent-pane.edited-files/fourteen-files, pages.settings/appearance-group-9, ... · 9 new states · 51 broken states · 107 play checks failed

Diff page and renders (the run's gallery-pr artifact)

State Before · after
gallery.visual-media-board/all-previews (Apple System Colors, chromium)
agent-pane.artifact-panel/markdown (Apple System Colors, webkit)
agent-pane.transcript/long-code (Apple System Colors Light, webkit)
agent-pane.edited-files/fourteen-files (Apple System Colors, webkit)
pages.settings/appearance-group-9 (Apple System Colors, chromium)
pages.settings/invalid-search-template (Apple System Colors Light, webkit)

197 more on the diff page.

Live preview (follows this branch; start it with scripts/gallery-live.sh up <branch> from an hq checkout):

  • gallery.visual-media-board/all-previews: /wt/op-next-call-keys-labs/?entry=gallery.visual-media-board#/gallery.visual-media-board/all-previews
  • agent-pane.artifact-panel/markdown: /wt/op-next-call-keys-labs/?entry=agent-pane.artifact-panel#/agent-pane.artifact-panel/markdown
  • agent-pane.transcript/long-code: /wt/op-next-call-keys-labs/?entry=agent-pane.transcript#/agent-pane.transcript/long-code
  • agent-pane.edited-files/fourteen-files: /wt/op-next-call-keys-labs/?entry=agent-pane.edited-files#/agent-pane.edited-files/fourteen-files
  • pages.settings/appearance-group-9: /wt/op-next-call-keys-labs/?entry=pages.settings#/pages.settings/appearance-group-9
  • pages.settings/invalid-search-template: /wt/op-next-call-keys-labs/?entry=pages.settings#/pages.settings/invalid-search-template
  • 125 more on the diff page

Play checks failed (0 px anchor movement, 0 layout shift, no frame over 33 ms unless the entry gives a reason):

  • gallery.visual-media-board/all-previews (Apple System Colors, chromium): step 1 click button "Pause previews": layout shift 0.0002 (limit 0) · step 2 click button "Play previews": layout shift 0.0002 (limit 0) · play: waitFor did not hold within 5000 ms
  • agent-pane.artifact-panel/markdown (Apple System Colors, webkit): play: no element for button "Open preview"
  • agent-pane.artifact-panel/html (Apple System Colors Light, chromium): play: no element for button "Open preview"
  • agent-pane.artifact-panel/html (Apple System Colors Light, chromium): play: no element for button "Open preview"
  • agent-pane.dictation/hide (Apple System Colors, webkit): play: no element for menuitem "Hide Dictation Button"
  • agent-pane.dictation/hide (Apple System Colors, chromium): play: no element for menuitem "Hide Dictation Button"
  • 596 more on the diff page

707 nondeterministic states differed from a second render of the same head (a clock or fixture leak) and are not counted as changes.

6554 unchanged · base 31d2b02 · head 60bdd67

teamleaderleo and others added 3 commits October 14, 2026 00:35
…call-keys/labs

# Conflicts:
#	webviews/src/agent-session/acpmux/newtab/NewTabScreen.gallery.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the DEV build it drew as a raised button; it now uses the All Chats
link's style.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@blacksmith-sh

This comment has been minimized.

@teamleaderleo teamleaderleo added the show-leo Waiting for Leo to see captures before merge label Oct 14, 2026
Fleet export-action-surfaces.sh at ad062d5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo and others added 2 commits October 14, 2026 17:25
…eed no MutationObserver outside a browser

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 15, 2026 00:26 — with GitHub Actions Inactive
@cursor

cursor Bot commented Oct 15, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 15, 2026 00:54 — with GitHub Actions Inactive
… white

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 15, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 15, 2026 00:58 — with GitHub Actions Inactive
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Superseded: opt-ins live in Debug settings, per Lawrence.

This branch was previously deployed

2 inactive (1 outdated) deployments
cmux-tui-merge-tree — b9b8a889 Deployed Oct 15, 2026 by teamleaderleo via publish the merge tree #1140
artifacts — 035edbf1 Deployed Oct 14, 2026 by teamleaderleo via publish tree-addressed cmux-tui #15260
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

show-leo Waiting for Leo to see captures before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant