Skip to content

Model menu: a started chat's harness is fixed (no rail, no Add harness…) - #22226

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
leo/model-menu-harness-lock
Oct 20, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
leo/model-menu-harness-lock

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

In a chat that already has a message, the composer's model menu drew a harness rail holding only that chat's harness (plus the Starred tab), then offered "Add harness…" as its last row. The chat can't switch harness (it has been locked since 2026-10-13), so a rail of one icon followed by an offer to add another read as a broken switcher.

Now a started chat's harness is fixed, as in Claude Code:

  • Started chat (turnCount > 0 or any row): the full picker is search, that harness's models and More models. No harness rail, no Starred tab, no Add harness…. The compact menu (agent.modelMenu) gets no rail either; its More models opens the same rail-less picker. Row stars still toggle, since they don't need the rail and feed the New Tab's Starred tab.
  • New Tab and chats with no message: unchanged. The rail lists every installed harness, and Add harness… stays.
  • Debug Settings toggle "Allow switching harness in a started chat" (agent.harnessSwitchInStartedChat, default off). On, a started chat keeps the whole rail, never just its own harness, plus Add harness…, and a pick in another harness starts a new chat there through the existing chat.new path. It reaches the page live as the composer event's harnessSwitch, beside plainFooter and modelMenu. It's a Debug Settings tunable, not a cmux.json key, so the settings lists don't change.

Mechanism: ModelPicker takes harnessFixed; ComposerPickers passes its existing locked value, which the toggle now overrides. If acpmux hasn't listed the chat's own harness yet (first open after launch), the picker keeps the old full rail rather than show an empty menu.

Testing

Ran on Huge Blue (bun test, per file):

  • Red on the tests-only commit c75798d: 3 fail (the started-chat picker, the toggle-on rail, the started-chat compact menu).
  • Green on the head 15b21d3: test/model-picker-picks.test.tsx 22/22, test/model-menu-compact.test.tsx 19/19, test/signed-out-rail.test.tsx 4/4; model-picker-composition, model-picker-height, effort-picker-slider, gallery-coverage and gallery-manifest pass.
  • CMUX_BROWSER_TESTS=1 bun test test/agent-pane-harness-catalog.test.ts (Chromium) passes at 15b21d3. It opens Add harness… from a started chat, so it turns the started-chat harness switch on through window.cmuxAcpmuxComposer first, which tests the toggle end to end in the page.
  • bun run typecheck: no type errors in 1629 files. vp check (fmt + lint) is clean on the changed files.
  • test/ui-rules.test.ts fails the same way at the base ca13780 (+4 received); it isn't from this change.
  • A full bun test run in one process fails about 148 tests at the base from cross-file state; the only new failures at the head were the three new tests, which pass when run per file.
  • verify-local.py --affected: Swift syntax, test wiring, xcstrings and the other checks pass. localization fails with 35k parity errors in catalogs this PR doesn't touch (a base finding).

Observed / Not run

Not run: the Swift side (AgentPaneTunables.harnessSwitchInStartedChat, the composer event's harnessSwitch and the new AgentPaneHarnessSwitchTunableTests) is only syntax-parsed here. It follows the modelMenu wiring line for line. PRs into feat-cmux-next skip cmux-next swift test, and no native build ran on this Mac. I haven't checked the toggle in a tagged build.

Changelog

Changed: In a chat that has started, the model menu lists only that chat's harness's models, with no harness rail or Add harness….

Proof

Gallery fixtures agent-pane.model-picker started-chat (full picker) and started-chat-quick-menu (compact menu) let the Linux gallery advisory run capture both states. Screenshots will be added here from that run.

Checklist

  • Behavior changes have added or updated tests
  • Localization audited: no new user-facing strings (the Debug Settings label and help are English developer text, as for every tunable)

🤖 Generated with Claude Code

teamleaderleo and others added 5 commits October 19, 2026 16:57
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…switch

Once a chat has a message, the model menu lists its harness's models alone:
search, the models and More models, with no harness rail, Starred tab or
Add harness…, in both the full picker and the compact menu. New Tab and
chats with no message keep the whole rail. Debug Settings' "Allow switching
harness in a started chat" (agent.harnessSwitchInStartedChat, off) keeps
the rail and the switch in started chats.

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>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review bb48381: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr22226 -f ref=leo/model-menu-harness-lock -f platform=macos -f backend_mode=local

Unclear: web / react-apps-check (1) failed: no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check).

CI failed on bb4838140f (run 39347577279 attempt 1): 3 unknown.
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped.

Job Verdict Why
web / react-apps-check (1) unknown no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check)
web / react-apps-check (2) unknown no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check)
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Not re-run automatically: web / react-apps-check (1), web / react-apps-check (2), web / react-apps-check are not machine failures.

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.

red: web / Web status; base red: the same failure on the base dde0ebb; does not block
red: web / react-apps-check; base red: the same failure on the base dde0ebb; does not block
red: web / react-apps-check (1); base red: the same failure on the base dde0ebb; does not block
red: web / react-apps-check (2); base red: the same failure on the base dde0ebb; does not block

CI fast guards failed on bb4838140f (https://github.com/manaflow-ai/cmux/actions/runs/39347577279). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 3/5

[Medium impact] The PR changes two bounded user-facing workflows: agent model picking and Markdown reading settings.

The PR should not merge until the webview build and width-saving failures are fixed.

Findings

  1. P1 Reading Settings breaks the build ▶
  2. P1 Chosen widths are not saved ▶
  3. P2 Code scale changes nothing ▶
  4. P2 Loaded models stay hidden ▶

Summary

Started chats hide the harness rail and Add harness option. A Debug Settings toggle restores cross-harness picks.

  • Started chats see only models from their own harness.
  • Debug Settings can restore harness switching in started chats.
  • Markdown reading widths expand and code size follows body text.

Reviews (3) · Last reviewed commit: "chore(next): PR autofix at 15b21d38fb92" · Reviewed by Greptile

Comment on lines +303 to +304
const harnessFixed = props.harnessFixed === true && ownHarness.length > 0;
const harnesses = harnessFixed ? ownHarness : allHarnesses;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Loaded models stay hidden

If a started chat's picker opens before its harness is listed, the user can select Starred in the temporary rail. When the models arrive, harnessFixed hides the rail but leaves selectedHarness on STARRED. The picker then shows only favorites, possibly an empty list, instead of all models. The user must search or reopen it to recover.

Make starredView false whenever harnessFixed is true, and add a test where models arrive while Starred is selected.

teamleaderleo and others added 2 commits October 19, 2026 17:13
The Harnesses page browser test opens Add harness… from a started chat,
so it turns on the started-chat harness switch first, through the host's
composer entry point. Drop an assertion that could never fail, and reset
the composer settings after unmounting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lineHeight: { key: "markdown.font.lineHeight", default: 1.6, min: 1, max: 2.4, step: 0.05 },
paragraph: { key: "markdown.spacing.paragraph", default: 1, min: 0, max: 3, step: 0.1 },
codeSize: { key: "markdown.code.blockSize", default: 14, min: 8, max: 32, step: 1 },
codeScale: { key: "markdown.code.scale", default: 0.875, min: 0.6, max: 1.25, step: 0.025 },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Reading Settings breaks the build

Renaming codeSize to codeScale leaves ReadingSettings.tsx using values.codeSize, r.codeSize, and actions.set("codeSize", value). These references no longer type-check, so the webview build fails. Without typechecking, opening Reading Settings throws when Slider reads range.min from the missing range. Update the callers and tests together with this rename.

*/
export const MARKDOWN_READING = {
width: { key: "markdown.layout.width", default: 72, min: 40, max: 160, step: 2 },
width: { key: "markdown.layout.width", default: 72, min: 30, max: 1000, step: 1, bigStep: 10 },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Chosen widths are not saved

The width slider now offers 30 to 1000, but MarkdownViewerSettingsSchema still accepts only 40 to 160. Choosing 300 widens the page immediately because setPreference updates it before saving. The host then refuses the write through SettingsController.setSetting, so the chosen width disappears on reload. Update the native range alongside this range.

Comment on lines +394 to +395
if (typeof code.scale === "number" && Number.isFinite(code.scale))
put("--cmux-md-code-scale", String(numberIn(code.scale, MARKDOWN_READING.codeScale)));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Code scale changes nothing

Setting markdown.code.scale has no visible effect. The new size calculations exist only in MARKDOWN_STYLE_DEFAULTS, which is not applied to the page. styles.css still sets inline code to 0.88em and blocks to 14px, so the emitted --cmux-md-code-scale is unused. Update the actual stylesheet defaults to use the scale so this setting changes the rendered text.

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

teamleaderleo added a commit that referenced this pull request Oct 20, 2026
…ollow their changes (#22516)

* test(markdown): Cmd-A in the selection test is ControlOrMeta, so Linux CI selects all

Meta+A on the Linux runners' Chromium and WebKit is not ProseMirror's Select All (Mod is Ctrl
there), so the selection stayed empty. The other browser tests already press ControlOrMeta.

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

* test(changelog): the Updated card's text selection follows its headline layout

e98d3a1 made the top change the card's headline, bulleted the rest and spelled the
eyebrow 'Nightly · Oct 19' (the raw build moved to its tooltip). The test still dragged the
first bullet for the top change, read rows 1 and 2 of a two-row list, and looked for the build.

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

* test(status glyphs): a wait is the attention dot in both sets

3207401 and 301bd27 replaced the talk bubble with the attention dot for a wait (in
the warning color). The Codex set now draws the dot twice: the test tells the wait's from
done's by position and color, not shape, and the static sheet's 2x edge probes follow the disc.

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

* test(narrow layouts): give the file 300 s, as its seven pages take about 195 s

The default 120 s per-file limit in run-webviews-tests.sh killed it on the CI runner after
six of its seven tests; the runner's own header line raises the limit for this file.

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

* gallery: model-menu-starred opens before the first send; the markdown host keeps table widths

75bc940 (#22226) gave a started chat's model menu no harness rail and so no Starred tab;
the variant still showed a finished chat, and its play found no Starred option. It now shows a
new chat, where the rail and Starred stay.

452cce0 moved a file's table column widths from the page's storage to the host
(cmux.markdown.setTableWidths, back in the config as tableWidths). The gallery's markdown host
had neither, so a reload forgot the widths. It now keeps them in the tab's session storage.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Oct 20, 2026
…22513)

* fix(next): the Starred models gallery state is a new chat (base red)

#22226 fixed a started chat's harness, so its model menu has no rail and
no Starred tab. The composer gallery's model-menu-starred state still
drew a finished chat, so its play failed with no element for option
"Starred" and composer-type-scale went red at the base for every PR.

The state now opens a new chat, where the rail and its Starred tab live.

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

* test(markdown): table keys run as on the Mac, so Linux CI's Cmd-A reaches Select All

The third Cmd-A in a table should fall through to the editor's Select All
(tableKeyDown returns false once the whole table is selected). ProseMirror's
keymaps decide what Mod means from navigator.platform when they load: jsdom's
platform is "" and bun's is the host's, so on the Linux runners Mod was Ctrl,
Cmd-A matched nothing and the CellSelection stayed. The test has been red on
Linux since it landed (ade5a7d / 8ba372b) and passes on a Mac.

The page now says it is a Mac before ProseMirror loads (the editor only runs
in a Mac WebView), and the two ProseMirror value imports load after that.
No editor source changes.

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

* chore(webviews): vp check passes again (formatting; one stray bun-types reference)

`vp check` in webviews failed on formatting in five settings files from the
Chiefs-in-Settings and host-sections changes; `vp check --fix` reformats them
with no code change. Behind the formatting, the type check failed 10 times:
`/// <reference types="bun-types" />` in new-tab-list-motion-render.test.tsx
(0f60d16, #22397) pulled in bun's devserver ImportMeta.hot, whose
`on(event, () => void)` conflicts with Vite's typed `hot.on` in every dev
module. The tsconfig already loads bun's types; the line is removed.

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

* test(markdown): say the table keys' Mac override needs a process of its own

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

* test(next): New Tab first-frame test fits the Cards page's three cards (base red)

new-tab-warm-first-frame.test.ts expected a device chat on the first frame next to three
acpmux sessions. Since 9215b25 (Cards New Tab template, the new default) the default page
shows three chat cards, sessions first, so the device chat never had a slot and the 8 warm-open
tests failed in Chromium and WebKit. The test now lists two sessions and the device chat, so it
still proves a warm open paints the host's late device chats from the first frame.

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

* fix(next): the webviews check gate passes its text-focus and lint steps (base red)

`bun run check` in webviews stopped at check:text-focus on three Swift
text fields, and `vp check` (denyWarnings) failed on 7 lint warnings.

- WorkspaceTodoPageView / WorkspaceTodoRow: the TextFields get
  .focusEffectDisabled(); the done mark uses Palette.accent instead of
  Color.accentColor (check-system-blue owns that file on this PR).
- AddressBarView: text-focus-allow on the read-only bar's isSelectable;
  AddressField is a ChromeTextField, whose init sets focusRingType = .none.
- ChatDisplaySettings, NowPlayingPlayer, NewTabScreen, ThreadMinimap:
  line-level oxlint suppressions with reasons for the 7 warnings
  (controls already inside a <label>, a datalist option, role notes, and
  the minimap's every-commit layout effect). No behavior change.

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

* webviews: status-glyphs test expects the attention dot for a wait

3207401 and 301bd27 (Lawrence, 2026-10-20) replaced the talk
bubble with the attention dot for waiting, in the Codex-like set and in
the Static glyphs. The test still expected the bubble, so it went red on
every PR. The Codex test now expects the dot for waiting, tells it from
done by color, and the 2x edge probes follow the new disc.

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

* fix(next settings): the Density card's 3 lint warnings get line-level suppressions (base red)

The new Density card (bc4dce8) added two inputs inside a <label> and a
role="radio" tile; vp check denies warnings, so the check gate went red again.

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

* test(markdown): Cmd-A and kept column widths pass in the Linux browser lane (base red)

markdown-selection-drag: the context reports navigator.platform as MacIntel,
as the Mac WebView does. ProseMirror binds Mod (Select All is Mod-a) from the
platform when its keymaps load, so on Linux Mod was Ctrl and Cmd-A selected
nothing.

markdown-table-obsidian: the gallery's markdown host answers
cmux.markdown.setTableWidths and sends the saved value back as tableWidths in
the config, with the frame's localStorage standing in for the file's extended
attribute. Since 452cce0 the page keeps widths through the host; the mock
host had no such op, the write failed quietly and a reload lost the width.

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

* fix(next): the find pill has a reduced-transparency fallback (check-layers base red)

d3a9df0 gave the Liquid Glass find pill a backdrop-filter with no
prefers-reduced-transparency or data-reduce-transparency fallback in its own file,
so check-layers failed the webviews check gate.

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

* chore(next): PR autofix at 8e6179a

- schemas/defaults/cmux-next.json

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39416502321

* chore(next): PR autofix at 6b3bea6

- schemas/defaults/cmux-next.json

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39418461225

* chore(next): PR autofix at e4b0d16

- schemas/defaults/cmux-next.json

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39419009274

* test(agent pane): the Cards New Tab template's pills are deliberate

agent-pane-no-capsules has failed at the feat-cmux-next tip since
9215b25 (Cards New Tab template, u2851). That template is a pill
design on purpose, from the user's scrawl of Aside's New Tab page: a round
field, a round Search | Ask switch and a round selected Chats tab, all at
border-radius 999px. #22285 later scoped the field and switch rules to
[data-pill]. The test now lists those five Cards selectors as deliberate
capsules beside the composer chips. Every other template and control is
still held to small-radius rects.

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

* chore(next): PR autofix at 84b7643

- schemas/defaults/cmux-next.json

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39427646005

* test(markdown): the kept-width test reloads only after the host has the width

On #22513 the resize-width test failed once in CI chromium (Received 90):
the page sends cmux.markdown.setTableWidths after the drag and the gallery
host stores it a task later, so a reload can beat the write. The test now
waits for the stored width before it reloads, and fails loudly if it never
arrives. It passes 4/4 on big-red.

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

* test(next): whats-new text selection follows the Updated card headline layout (base red)

e98d3a1 made the first change the card headline and bullets only the rest, and the
eyebrow now reads "Nightly · Oct 19" with the build in its tooltip. The drag test selects the
headline, the double-click and wrap tests index the bullets from 0, and the eyebrow check
looks for the day.

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

* test(markdown): the selection test keeps the base ControlOrMeta fix alone

#22516 landed ControlOrMeta+a for this test. With this branch Mac platform
init script on top, Mod became Cmd while ControlOrMeta pressed Ctrl on Linux,
so Cmd-A selected nothing again. The base version passes 8/8 on big-red.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant