view shell live code: a patch carries new Swift files
Leo (2026-11-04): "Couldn't we architect stuff to make everything more amenable to hot swappage? Bridge better api better thin the layer nicer / Idk how well we can pre prepare stored properties/function signatures/deal with files"
This is the "new files" piece of that: a new Swift file no longer forces a rebuild of the view shell. In the 8,315-PR sample, 41% of the PRs that needed a rebuild added a file.
What changes
-
Prototypes/ViewShell/inject.sh: besides the files named, the patch now links two kinds of file:- every Swift file of the module that the running Debug build never compiled (it has no object in
ViewShell.build): a new file; - every file newer than that build's executable.
It prints
also X.swift (new since the build | changed since the build)for each one. So a new view in a new file, used from an edited file, links inside the patch. Each repeat patch holds all of the new code, so callers never keep an earlier patch's copy of the new file.main.swiftandLiveCode.swiftstill refuse. With no Debug build at.build/debug(orCMUX_VIEW_SHELL_BUILD), the patch holds only the files named, as before, and the script says so. - every Swift file of the module that the running Debug build never compiled (it has no object in
-
scripts/cmux-next/live_apply.py(try-pr's classifier): an added Swift file no longer counts as a rebuild. An addedmain.swiftor@mainis the exception and counts asnew entry point. New types in existing files keep their rebuild reason. -
scripts/measure/live-code-shell.sh: a new step 3 writesLiveCodeProbeDot.swift, hasBadge.swiftuse it, and injects naming onlyBadge.swift. The stored-property step becomes step 4.result.jsongainsnew_file_editandnew_file_edit_to_pixels_s. -
Docs: the view shell README ("Live code") and
docs/cmux-next/hot-reload.md.
Verification
python3 -m unittest scripts/cmux-next/tests/test_live_apply.py: 12 tests pass, including the new-file test and the@mainone.- On a fleet Mac,
scripts/measure/live-code-shell.shwas run at this head and at its base (4546c99a, which has the #35850 pointer fix but the oldinject.sh). Both ran on the same machine. Rendered badge widths at 2×:
| step | base | this PR |
|---|---|---|
| 0, the build | 135 px | 135 px |
| 1, padding 24, red | 199 px | 199 px |
| 2, padding 40 | 263 px | 263 px |
3, a new file LiveCodeProbeDot.swift used by Badge.swift; only Badge.swift named | refused: dlopen … symbol not found … LiveCodeProbeDot… | also LiveCodeProbeDot.swift (new since the build), 283 px with the dot, 1.26 s from edit to pixels |
4, a new @State | refused | refused by the layout check |
- A file counts as new when the Debug build has no object for it (
ViewShell.build/<name>.swift.o). An earlier version read SwiftPM'ssourceslist, but that list quotes a path with a space, which made every file look new.
Part of manaflow-ai/cmuxterm-hq#7066.
🤖 Generated with Claude Code
Agent session: agent session