Repository navigation
refactor(web,mobile): environment renderers take the resolved icon - #1
amanthanvi wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Sorry @amanthanvi, you've used your own review budget of 250,000 diff characters for the last 7 days.
You can request another review in 1 day and 11 hours by commenting @sourcery-ai review. Upgrade to get a review now.
Reviewer's GuideThis refactor widens environment rendering from legacy machine-kind strings to EnvironmentIcon values: the contracts resolver now preserves richer stored icons and canonicalizes plain kinds for stable references, while web and mobile renderers and all call sites consume the new value without changing the currently drawn glyphs. Sequence diagram for resolving and rendering environment iconssequenceDiagram
participant Caller
participant resolveEnvironmentIcon
participant EnvironmentIconCache
participant EnvironmentMachineIcon
participant EnvironmentMachineSymbol
Caller->>resolveEnvironmentIcon: resolveEnvironmentIcon(config)
alt stored richer icon
resolveEnvironmentIcon-->>Caller: stored EnvironmentIcon
else plain legacy kind or detected machine
resolveEnvironmentIcon->>EnvironmentIconCache: environmentIconForMachineKind(kind)
EnvironmentIconCache-->>resolveEnvironmentIcon: shared EnvironmentIcon reference
resolveEnvironmentIcon-->>Caller: canonical EnvironmentIcon
end
alt web
Caller->>EnvironmentMachineIcon: icon=resolvedIcon
EnvironmentMachineIcon->>EnvironmentMachineIcon: environmentMachineIcon(icon)
EnvironmentMachineIcon-->>Caller: current glyph or server fallback
else mobile
Caller->>EnvironmentMachineSymbol: icon=resolvedIcon
EnvironmentMachineSymbol->>EnvironmentMachineSymbol: isEnvironmentMachineKind(icon.name)
EnvironmentMachineSymbol-->>Caller: current symbol or server fallback
end
Flow diagram for legacy and richer environment icon handlingflowchart TD
A[Server config or descriptor] --> B[resolveEnvironmentIcon]
B --> C{Stored environmentIcon?}
C -->|Richer icon| D[Return stored EnvironmentIcon]
C -->|Plain legacy kind| E[environmentIconForMachineKind]
C -->|None| F[Detected machine or server]
F --> E
E --> G[Return shared canonical reference]
D --> H{Renderer supports icon name?}
G --> H
H -->|Yes| I[Draw existing glyph]
H -->|No| J[Draw generic server glyph]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
badc290 to
802e8ab
Compare
Thread transfer impact
This comment will update automatically after the next completed run. |
ac19c03 to
f3732fb
Compare
|
Pushed The comment on the icon memoization said rows are memoized so the resolver hands back the same object across renders and across settings snapshots. That is true for a plain machine kind and false for everything else. The cache is keyed by kind, so an emoji, monogram, or image icon is returned as the decoded value and gets a fresh object from every snapshot, which repaints that row. The comment now says which case the cache covers and which it does not, and why the gap is left open. Settings change on user action, not on a timer, so a content keyed cache would buy a repaint nobody is present to see, at the price of holding image bytes alive for as long as the cache does. Rebased onto |
f3732fb to
b1eaa0a
Compare
Rebased onto current mainRebased the whole stack onto main at
A clean textual replay does not prove the stack still holds together, so I went looking for the hazard that would hide behind one. Layer 2 renames Each layer is its own pull request, so I verified each one standing alone rather than only at the tip:
No review thread was open when I rebased, so the force push moved commits rather than answers. Line comments from earlier rounds now anchor to the old SHAs. |
|
@sourcery-ai review |
|
Sorry @amanthanvi, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 28 minutes by commenting |
b1eaa0a to
a25e1e6
Compare
Rebased onto current main, and the monogram counter lost its
|
| layer | typecheck | lint | tests | restyle |
|---|---|---|---|---|
| 01 contracts | 4 packages, 0 errors | 0 errors | 4 files, 245 tests | 1207 |
| 02 rename | 5 packages, 0 errors | 0 errors | 5 files, 276 tests | 1207 |
| 03 curated | 5 packages, 0 errors | 0 errors | 6 files, 285 tests | 1207 |
| 04 rich | 5 packages, 0 errors | 0 errors | 9 files, 296 tests | 1207 |
| 05 lucide | 5 packages, 0 errors | 0 errors | 10 files, 300 tests | 1207 |
| 06 image, mobile, detect | 5 packages, 0 errors | 0 errors | 12 files, 327 tests | 1207 |
The force push moved commits, so line comments from earlier rounds now anchor to the old SHAs.
|
@sourcery-ai review |
a25e1e6 to
446fd2e
Compare
Rebased onto current mainRebased the stack onto main at What main changed that this stack had to follow
That made one commit unnecessary. The layer 3 commit that deduplicates the icon submenu's lock row said it existed for the ceiling. It still removes a duplicated row, so it stays with a message that says only that. Conflicts
Review findingsSourcery reviewed the last push. One finding was real and is fixed on layer 6: the web dialog let Save run while an image was still encoding, which wrote the previous image and dropped the new pick. The other two have replies on the threads. One asks mobile to hide the emoji glyph from screen readers, but mobile glyphs have been labeled on main all along. The other asks to reject a photo whose dimensions the picker did not report, which is a trade-off the code already records. Layer 6 also drops an Per-layer verificationEach layer is its own pull request, so each was checked standing alone.
Layer 1 runs one test fewer than last time because main removed one of its own tests from The force push moved commits, so line comments from earlier rounds now anchor to the old SHAs. |
|
@sourcery-ai review |
446fd2e to
21f657c
Compare
Rebased onto current mainRebased the stack onto main at Main added four web lint errors in that range: Two changes follow main:
Each layer typechecks with 0 errors in every package it changes, lints with 0 errors, and passes its tests, from 4 files and 244 tests at layer 1 to 12 files and 327 tests at layer 6. The fix commits cited in earlier review replies have new SHAs, and those replies now point at them. |
21f657c to
93ec64f
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The web picker incorrectly marks colored named overrides as equivalent plain machine-kind selections.
Review effort: Balanced
Findings: 1
What changed in this PR
This stacked refactor widens environment rendering across contracts, web, and mobile to consume resolved EnvironmentIcon values while preserving legacy glyphs and stable references.
Changes:
- Replaces
resolveEnvironmentMachineKindwithresolveEnvironmentIcon. - Adds shared references for legacy machine icons.
- Updates web/mobile renderers, callers, projections, and tests.
| File | Description |
|---|---|
packages/contracts/src/server.ts |
Adds icon resolution and reference caching. |
packages/contracts/src/server.test.ts |
Tests icon resolution and identity. |
packages/client-runtime/src/state/presentation.ts |
Projects resolved environment icons. |
packages/client-runtime/src/state/presentation.test.ts |
Updates projection assertions. |
apps/web/src/routes/_chat.pull-requests.tsx |
Uses resolved icons in filters. |
apps/web/src/components/ThreadStatusIndicators.tsx |
Passes resolved remote icons. |
apps/web/src/components/Sidebar.tsx |
Widens sidebar icon values. |
apps/web/src/components/settings/SettingsScopeSentence.tsx |
Renders resolved scope icons. |
apps/web/src/components/settings/SettingInheritance.tsx |
Widens inheritance icon data. |
apps/web/src/components/settings/ScheduledTasksSettings.tsx |
Updates scheduled-task icons. |
apps/web/src/components/settings/ProviderSettingsPanel.tsx |
Updates provider environment icons. |
apps/web/src/components/settings/LoadBalancingSettings.tsx |
Passes resolved row icons. |
apps/web/src/components/settings/GitHubRoutingSettings.tsx |
Passes resolved routing icons. |
apps/web/src/components/settings/EnvironmentRow.tsx |
Accepts EnvironmentIcon. |
apps/web/src/components/settings/EnvironmentIconPicker.tsx |
Adapts picker to resolved icons. |
apps/web/src/components/settings/ConnectionsSettings.tsx |
Updates connection-row icons. |
apps/web/src/components/pullRequest/pullRequestProjectAssignment.logic.ts |
Widens assignment metadata. |
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx |
Renders resolved picker icons. |
apps/web/src/components/ProjectEnvironmentBadge.tsx |
Widens badge icon map. |
apps/web/src/components/LegacySidebar.tsx |
Updates legacy sidebar icons. |
apps/web/src/components/EnvironmentMachineIcon.tsx |
Accepts icons with server fallback. |
apps/web/src/components/CommandPalette.tsx |
Widens palette environment metadata. |
apps/web/src/components/CommandPalette.logic.test.ts |
Updates palette fixtures. |
apps/web/src/components/cloud/CloudEnvironmentConnectList.tsx |
Updates cloud connection icons. |
apps/web/src/components/ChatView.tsx |
Resolves environment option icons. |
apps/web/src/components/chat/DraftHeroHeadline.tsx |
Builds resolved icon maps. |
apps/web/src/components/BranchToolbarEnvironmentSelector.tsx |
Updates selector icons. |
apps/web/src/components/BranchToolbar.tsx |
Updates toolbar icons. |
apps/web/src/components/BranchToolbar.logic.ts |
Widens environment option type. |
apps/mobile/src/state/thread-list-environments.ts |
Projects and caches icons. |
apps/mobile/src/state/thread-list-environments.test.ts |
Updates projection assertions. |
apps/mobile/src/features/threads/thread-list-v2-items.tsx |
Widens thread-row icon props. |
apps/mobile/src/features/threads/NewTaskDraftScreen.tsx |
Updates draft environment icon. |
apps/mobile/src/features/threads/NewTaskContextPickerScreens.tsx |
Updates picker icons. |
apps/mobile/src/features/settings/SettingsScheduledTasksRouteScreen.tsx |
Updates task icons and menu symbols. |
apps/mobile/src/features/settings/SettingsClientStorageRouteScreen.tsx |
Widens cache-row icons. |
apps/mobile/src/features/settings/components/SettingsEnvironmentFilterHeader.tsx |
Resolves native menu symbols. |
apps/mobile/src/features/projects/AddProjectScreen.tsx |
Widens project environment options. |
apps/mobile/src/features/connection/ConnectionEnvironmentRow.tsx |
Updates connection icon rendering. |
apps/mobile/src/features/connection/CloudEnvironmentRows.tsx |
Widens cloud-row icons. |
apps/mobile/src/features/archive/ArchivedThreadsScreen.tsx |
Widens archived-group icons. |
apps/mobile/src/components/EnvironmentMachineSymbol.tsx |
Accepts icons with server fallback. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const resolvedKind = | ||
| resolved.kind === "icon" && isEnvironmentMachineKind(resolved.name) ? resolved.name : null; |
Rebased onto orchestrator V2Rebased the stack onto main at What the rebase had to adapt:
Layer 1 has one new fix. An inline PNG must now carry all eight signature bytes, since Macroscope found that the old prefix check let a seven-byte value through. Every layer passes typecheck, lint, format, and its own tests. At the top of the stack, I picked icons on web and in the iOS simulator against isolated dev state, and each client showed the other's pick. |
93ec64f to
194c982
Compare
194c982 to
26a1ce0
Compare
|
Sourcery has withdrawn its approval of this pull request. It auto-reviews a pull request 5 times, and this push is past that limit, so the approval no longer reflects code Sourcery has read. Comment |
Sourcery withdrew this approval because it has stopped reviewing this pull request.
`resolveEnvironmentMachineKind` collapsed the stored override to one of seven kinds, so every renderer saw a machine kind and nothing richer could reach a glyph. This is the mechanical widening that lets the next changes draw more than seven shapes, isolated so the churn is one review pass. The resolver becomes `resolveEnvironmentIcon` and returns the override itself. A plain pick of a legacy kind lands on one shared reference per kind from `environmentIconForMachineKind`, so memoized thread rows keep skipping across settings snapshots, and anything richer comes back as stored. `EnvironmentMachineIcon` and `EnvironmentMachineSymbol` take an `icon` prop and, for now, read its name back to the same seven glyphs, with a name this build cannot draw falling back to the generic server. The old name is deleted rather than aliased. `isEnvironmentMachineKind` stays exported, and a function still named "machine kind" returning an emoji variant invites passing one to the other, where it silently returns false. No behavior change. At this point the stored value can only be a legacy string lifted into the named variant, so every renderer still draws what it drew before. Field and prop names on the call sites stay as they are. Claude Fable 5.1 via Claude Code
The comment read as though the shared reference kept every environment row from repainting. It covers plain machine kinds only. An emoji, monogram, or image icon comes back as the decoded value, so those rows repaint once per settings change. Say that, and say why a content-keyed cache is not worth it.
Main now lists a machine in the T3 Connect section even when it is saved over another route, so T3 Connect can be added as a fallback. Those rows took their icon from the relay-saved map, which skips such machines, or from the relay descriptor alone, which carries no settings. So a machine with a picked emoji, monogram, or image showed its detected kind there and the picked icon in the saved list on the same screen. Web now looks up the config of every saved machine for the icon, and the mobile available row reads the machine's config the way the connected row already does. Found by an independent review of the rebased stack. Claude Opus 5.5 via Claude Code
26a1ce0 to
9becaed
Compare
Sourcery withdrew this approval because it has stopped reviewing this pull request.
|
Sourcery has withdrawn its approval of this pull request. It auto-reviews a pull request 5 times, and this push is past that limit, so the approval no longer reflects code Sourcery has read. Comment |
1 similar comment
|
Sourcery has withdrawn its approval of this pull request. It auto-reviews a pull request 5 times, and this push is past that limit, so the approval no longer reflects code Sourcery has read. Comment |
Sourcery withdrew this approval because it has stopped reviewing this pull request.
Rebased onto main
|

What changed
resolveEnvironmentMachineKindbecomesresolveEnvironmentIconand returns the stored override itself. A plain pick of a legacy kind lands on one shared reference per kind fromenvironmentIconForMachineKind, so memoized thread rows keep skipping across settings snapshots.EnvironmentMachineIcon(web) andEnvironmentMachineSymbol(mobile) take aniconprop and, for now, read its name back to the same seven glyphs; a name this build cannot draw falls back to the generic server.Orchestrator V2 moved per-environment glyph resolution into shared atoms (
packages/client-runtime/src/state/presentation.tsfor web,apps/mobile/src/state/thread-list-environments.tsfor mobile) and added call sites in scheduled tasks and the mobile settings filter. Those now carry the icon too. Native menu items take only a symbol name, so they go throughenvironmentMachineSymbolName, which falls back to the generic server for anything that is not a curated icon.The old name is deleted rather than aliased.
isEnvironmentMachineKindstays exported, and a function still named "machine kind" returning an emoji variant invites passing one to the other, where it silently returns false.Main now lists a machine in the T3 Connect section even when it is saved over another route, so T3 Connect can be added as a fallback. Those rows read the user's pick from that machine's own config, on web and mobile, so they match the saved list on the same screen.
Why
This is the mechanical widening that lets the next layers draw more than seven shapes. It is isolated so the churn across 42 files is one review pass. No behavior changes. At this point the stored value can only be a legacy string lifted into the named variant, so every renderer draws what it drew before. Field and prop names on the call sites stay as they are.
Stacked on pingdotgg#15511. Layer 2 of 6.
Opened on the fork because GitHub only accepts a base branch that lives in the base repository, and stacks cannot span a fork and its upstream. Layers 2 through 6 form a native stack on the fork, so merging one layer there rebases the rest. Each will be re-targeted to pingdotgg/t3code once its base merges. The entry point upstream is pingdotgg#15511.
Verification
server.test.tscovers the shared-reference guarantee and the fallback.CommandPalette.logic.test.ts,pullRequestProjectAssignment.logic.test.ts, andBranchToolbar.logic.test.tspass with the widened type.Claude Fable 5.1 via Claude Code
Summary by Sourcery
Pass resolved environment icons through web and mobile renderers while preserving current visuals and preparing support for richer icon types.
Enhancements:
Tests:
Chores: