Feat: Add composable Scene modifiers and Scene environment propagation - #70
Merged
Conversation
- Give Scene the SwiftUI protocol shape (associated Body, SceneBuilder
body) with Never as the primitive terminator
- Add the EnvironmentModifiedScene layer with Scene.environment(_:_:),
.palette(_:), and .appearance(_:) modifiers; SceneResolution unwinds
modifier chains outside-in into the frame environment (inner values
win) and returns the renderable core
- Resolve scenes in RenderLoop before the view-level root palette
override so scene values reach all views and out-of-tree surfaces;
identity paths stay byte-identical for unwrapped scenes
- Add ScenePhase with an environment key (active by default); phase
actions arrive with the application-actions work
- Fixes the documented WindowGroup { … }.palette(…) shape from issue #2
- Add the scene-level palette section to the theming guide - Extend the scene fixture with the issue-2 palette shape, composed modifiers, and an App body using scene modifiers
- Add overrides for the Scene protocol body contract, the scene environment modifiers, WindowGroup's primitive body, ScenePhase, and the scenePhase environment key - Regenerate the manifest with TUIkitAPICheck against fresh 6.0.3 macOS and Linux snapshots
wadetregaskis
added a commit
to wadetregaskis/TUIkit
that referenced
this pull request
Sep 2, 2026
205 upstream commits have landed since the fork point (6b22531, 2026-04-24) — all of them in a four-day burst, 2026-07-19 to 07-22, across pull requests phranck#44 to phranck#70. Reviewing that once is easy to start and impossible to finish without somewhere to put the answer, and the question comes back every time upstream moves again. So: Documentation/Upstream-review/ holds the record, and Tools/UpstreamReview/upstream-review.sh does the mechanical parts. The tool enumerates every upstream-only commit oldest-first in TOPOLOGICAL order, which is the load-bearing choice: it keeps a pull request's commits contiguous and ahead of the merge that landed them, so each commit can be read against the feature it belongs to. 169 of the 183 non-merge commits live inside a PR branch; judged alone, "extract a helper" is unjudgeable. Position is DERIVED from the ledger — reviewed means has a row — rather than tracked beside it. A cursor and a ledger can disagree, and then neither can be trusted. `verify` checks the four ways this can rot: - a row naming a commit upstream no longer has (force-push or rebase); - the same commit recorded twice; - a HOLE behind the current position — the reviewed set must be a contiguous prefix of the enumeration, or "where we are" means nothing; - a verdict outside the vocabulary. Each row carries a patch id as well as a hash, because a rebase preserves the former and destroys the latter: an orphaned row can then be re-anchored instead of re-reviewed. Verdicts are a closed set (adopt / adapt / inspired / have / n-a / reject / defer / queued / noise) so a typo cannot quietly invent a category, and the `ours` column carries our own commit hashes so the ledger reads in both directions. Bash 3.2 throughout — macOS ships 3.2, and Tools/validate-test-boundaries.sh already set that precedent. Co-Authored-By: Claude <[email protected]>
wadetregaskis
added a commit
to wadetregaskis/TUIkit
that referenced
this pull request
Sep 2, 2026
The tail — storage, view contracts, data flow, scenes — judged at branch granularity, since by this point each branch's character was clear from its first commit and per-commit detail would not have changed a verdict. PR phranck#65's serialised writes are already ours (NSLock plus a serial save queue). Its error reporting is not: we drop persistence failures on the floor, so a read-only config directory looks like a successful save. Deferred — real, small, unforced. PRs phranck#67, phranck#69 and phranck#70 are deferred as a batch and explicitly NOT as upstream-review work. They are all one thing — align the framework's shape with SwiftUI's — and CLAUDE.md requires that to be answered against the real SDK, which is how SwiftUI-compatibility.md was built. Reading what upstream happened to write is the wrong instrument. Some of it is already shipped here; DynamicProperty as a public protocol is not. The next step is an audit pass over the data-flow and view-modifier surfaces with these branches as one input among several, which is a piece of work rather than triage. Also fixes the ledger's row order: recording 8a73ec3 out of sequence made `verify` report a gap, which is the check doing its job. Final spread across 205 commits: 56 n-a, 37 noise, 35 have, 35 defer, 17 adapt, 16 reject, 5 queued, 4 inspired. Co-Authored-By: Claude <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #19. Fixes #2.
Summary
Scenegets SwiftUI's protocol shape (associatedtype Body: Scene,@SceneBuilder var body) withNeveras the primitive terminator;WindowGroupdeclares a primitive body andSceneBuildergainsbuildExpressionScene.environment(_:_:),.palette(_:),.appearance(_:)wrap scenes in an internalEnvironmentModifiedScene;SceneResolutionunwinds chains outside-in into the frame environment (inner values win) and hands the renderable core to the render loop — this layer is the documented extension point for the Enhancement: Implementation of an Application Menu System #5 command infrastructureRenderLoopapplies scene values before the view-level root palette override, so scene environment reaches all child views and out-of-tree surfaces (status bar, app header); identity paths stay byte-identical for unwrapped scenes via existential openingScenePhase(background < inactive < active) with ascenePhaseenvironment key defaulting to.active; phase-driven actions arrive with [P2-28] Add terminal accessibility, search, refresh, and application actions #33, multiwindow semantics deliberately not copiedWindowGroup { … }.palette(…)now compiles and changes rendered colors; covered by tests and the scene compile fixture (including anAppbody using scene modifiers)Test plan
./scripts/test-linux.shverify-compatibility-manifest.shpasses against the regenerated manifest