Skip to content

chore(upstream): sync marcode through 2daff8c2 - #63

Draft
maarco wants to merge 105 commits into
mainfrom
claude/gracious-bohr-60kaon
Draft

chore(upstream): sync marcode through 2daff8c2#63
maarco wants to merge 105 commits into
mainfrom
claude/gracious-bohr-60kaon

Conversation

@maarco

@maarco maarco commented Aug 30, 2026

Copy link
Copy Markdown
Owner

What Changed

Merges pingdotgg/t3code@2daff8c25adf701fddd062ae93b94cc57d420ec2 into main — 102 upstream commits since the last sync base f035a0f4. One two-parent merge commit (586dcfb2), plus two follow-up CI fixes. No rebase, no force push.

Headline upstream content: Expo SDK 57, turn file attachments (PDF/ZIP up to 50MB), thread↔pull-request linking, OpenCode child approvals and model catalogs, the macOS service PATH fix, and the Uniwind semantic-theme refactor for mobile.

34 paths conflicted. Every one was resolved by hand, combining both intents — no whole-file ours/theirs, no reset/restore/stash/clean.

Silent fork-boundary breaks caught (no conflict — these are the dangerous ones)

Break Why it would have broken Marcode Fix
New oxlint rule test hardcoded t3code/no-mobile-uniwind-theme-escape-hatches Marcode's plugin meta name is marcode; the rule id would not resolve Retargeted at marcode/, rule registered at error in vite.config.ts
Three oxlint-disable-next-line t3code/… comments Suppress nothing against a plugin named marcode, so lint would fail Retargeted at marcode/
New t3 theme CLI read T3CODE_HOME Every other Marcode CLI command reads MARCODE_HOME; this one command would have silently targeted the default install Switched to MARCODE_HOME, test renamed with it
New connection/clientMetadata.ts hardcoded "T3 Code Desktop" / "T3 Code Web" Merged cleanly and would have relabelled every connected client in the connections list Both labels sourced from branding's APP_BASE_NAME; upstream's test now asserts the Marcode label
androidAdaptiveForeground auto-merged to upstream's white T3 wordmark on all three channels Invisible on Marcode's white release background, and wrong branding on dev/nightly Re-authored android-icon-foreground.svg with the black Marcode glyph in the adaptive safe zone; regenerated the 432×432 transparent PNG
(found by CI, 9eff59df) Migrations.test.ts pins the registry tail with slice(-10) The two renumbered migrations pushed ProjectWorkspaceLayout (id 33) out of the window — the pin firing exactly as designed Widened to slice(-12) and added both entries, keeping id 33 as the anchor
(found by CI, 4bfa609a) New useEnvironmentThemeSync.test.ts seeds localStorage with "t3code:theme" Marcode renamed the selected-theme key to "marcode:theme" (useTheme.ts STORAGE_KEY). No theme resolved, so the hook fell back to dark and all four light-appearance assertions failed Seeded "marcode:theme", matching the literal useTheme.test.ts already uses

The last two were not caught by the pre-push audit and were found by CI. After fixing the second, every "t3code:*" literal this merge introduces was swept against the keys Marcode actually renamed; the only other one, "t3code:default-theme-applied:v2:", is entirely new upstream with no Marcode counterpart, so it correctly stays upstream-shaped.

Conflict decisions

Server

  • cloud/bootService.ts — took upstream's PATH export in the launchd plist (fix(server): keep provider CLIs available in the macOS service pingdotgg/t3code#8173, keeps provider CLIs on the macOS service) and kept Marcode's MARCODE_HOME key. resolveLauncherBaseDir reads MARCODE_HOME and exits without it, so the plist must match the systemd unit.
  • cloud/bootService.test.ts — kept both tests (Marcode's MARCODE_HOME pin, upstream's installer-PATH assertion), retargeting the Marcode one at the new macRenderOptions fixture.
  • persistence/Migrations.ts — upstream's two new migrations renumbered to the next free Marcode ids: 042 → 043 ProjectionThreadLinkedPullRequest, 043 → 044 ProjectionThreadsUnsettledAt. Marcode's ProjectWorkspaceLayout holds 033, so every shared migration sits one id higher; renumbering an applied id would re-run or skip it on existing installs. Both the migration's own test and the registry pin were retargeted.
  • ServerEnvironment{,.test}.ts, contracts/environment.ts — both capability flags kept (threadPullRequestLinking + workspaceLayoutMutations).
  • server.test.ts — both imports kept.

Web

  • connection/platform.ts — took upstream's clientPresentationMetadata refactor (feat(analytics): report connected client platforms pingdotgg/t3code#8481: device type, OS, browser family, hosted deployment).
  • sidebar/SidebarChrome.tsx — kept Marcode's bare drag strip. Upstream's only change was fix(web): add back button to project settings pingdotgg/t3code#8168's project-settings Back button inside SidebarUtilityMenu, which Marcode moved to FloatingPillNav — whose "Back to Workspace" entry already covers every off-thread route, so the defect does not exist on this surface.
  • ChatView.tsx — took upstream's useThreadActions destructuring (its consumers merged in cleanly) without the duplicate handleNewThread Marcode moved down; kept the one-prop ChatHeader; kept Marcode's composer insets and applied fix(web): four composer spacing defects pingdotgg/t3code#8090's shoulder-tab reduction at both breakpoints so sm:pb-10 does not shadow it.
  • ChatMarkdown.tsx — took upstream's editorPreferences/editorLabels/remoteOpen/entities imports; dropped useRightPanelStore and the now-dead useActiveEnvironmentId. File links still open in the floating editor.
  • ThreadTerminalDrawer.tsx — kept Marcode's xterm implementation. fix(web): make terminal links appear clickable only when clickable pingdotgg/t3code#7488's fix lands through the shared terminal-links producer, which Marcode already routes on via match.kind.
  • settings/KeybindingsSettings.tsx — took upstream's extracted WarningTooltipIcon / BrowserKeybindingNotice, restoring Marcode's copy inside them.
  • chat/OpenInPicker.tsx — took upstream's editorLabelForPlatform refactor (it subsumes Marcode's Finder/Explorer/Files ternary), kept Marcode's filled FolderOpenFilled glyph.
  • hooks/useHandleNewThread.ts — kept Marcode's workspace placement registration, took upstream's fix(clients): honor project default models in new threads pingdotgg/t3code#6011 project-default model resolution.
  • composerDraftStore.ts — kept the marcode: key, took the version bump to 9 (persisted draft shape changed with attachments).
  • providerUpdateDismissal.ts — followed upstream's un-export, kept the Marcode key.
  • files/FilePreviewPanel.tsx — kept Marcode's deletion. fix(web): render nested markdown images correctly pingdotgg/t3code#8501's nested-image fix still lands in ChatMarkdown, which Marcode uses for chat.

Mobile

  • app.config.ts — kept MARCODE_IOS_PERSONAL_TEAM, took upstream's new runtimeVersionPolicy, adopted Fix Android adaptive launcher icon pingdotgg/t3code#4332's adaptive-icon fix with Marcode branding (see table above). Backgrounds are white on every channel, which preserves the rendered icon exactly — the old full-bleed white foreground already hid the per-channel tints.
  • package.json — took fix(mobile): reduce dev-client reload and Metro startup cost pingdotgg/t3code#8694's dev-client startup fix (no --clear, new dev:client:reset), kept the marcode-* schemes.
  • CompactBrandTitle.tsx + HomeHeader.tsx — adopted upstream's Uniwind semantic classes (required: useThemeColor.ts was deleted upstream and the new escape-hatch rule is an error), kept MarcodeMark and the conditional stage pill.
  • lib/authClientMetadata.ts — kept the Marcode label, took upstream's tablet/phone device-type detection.

Tooling and docsbuild-desktop-artifact.test.ts kept all imports from both sides plus Marcode's provisioning-profile fixture alongside upstream's sign assertion; AGENTS.md kept Marcode's sections and ported the one rule upstream added that they did not already cover; docs/README.md kept the unified-workspace entry and added OpenCode; pnpm-lock.yaml was regenerated with pnpm, not hand-resolved.

Removals pinned with tests

Upstream deleted two tests that were the only thing holding a Marcode removal in place. Both were replaced so the next sync conflicts loudly instead of silently reverting:

Coupled subtrees

pnpm-workspace.yaml moved, so the effect-version-subtree coupling was checked: the effect catalog entry is unchanged at 4.0.0-beta.103, so .repos/effect-smol needs no sync. infra/relay/package.json did not move, so the alchemy coupling is not triggered.

Why

The daily scheduled sync hit a conflicted delta and filed #62 rather than pushing a branch. This is the hand resolution that unblocks it.

Hotspots are treated as mandatory-review paths, not keep-Marcode paths: every upstream correctness, security, and operational fix above survives even where it landed in a customized file.

UI Changes

Not captured — this container has no display, so the web and mobile surfaces were not driven. Verification below is tests, typecheck, format, and lint only. Before taking this out of draft, the runbook's runtime verification is still owed: apps/web/**, apps/mobile/** and assets/** all changed, so the affected surfaces need a real pass at 390px and 820px, plus vp run icons:check for the regenerated Android adaptive foreground.

The one visual change worth a specific look is the Android adaptive launcher icon on dev, nightly, and production — the rendered result should be unchanged (black Marcode glyph on white), now without Android double-masking the silhouette.

Verification

  • Full apps/web suite — 297 files, 3263 tests, all pass locally via the package's own test script (vp run --filter ./apps/web test), matching CI's total exactly. Note: vp test run apps/web is not equivalent — it bypasses the package's vitest project config and six files fail to load on wasm/icon assets.
  • Full apps/server/src/persistence — 21 files, 35 tests, all pass.
  • Focused testsoxlint-plugin-marcode uniwind rule, bootService, cli/theme, ServerEnvironment, serviceLauncher, migrations 042/043 + the registry pin, mobileBranding, threadSidebarWidth, clientMetadata, contracts/environment, Sidebar.logic, composerDraftStore, editorLabels, terminal-links, branding, ChatMarkdown.workspace-images, ComposerTasksBadge, ComposerStashBadge, build-desktop-artifact, upstream-sync-workflow.
  • Typecheckapps/web, apps/server, apps/mobile, apps/desktop, packages/contracts all exit 0.
  • Formatvp fmt --check clean across all 568 changed source files.
  • Lintvp lint exits 0 across apps/*/src, packages, oxlint-plugin-marcode, scripts. Only pre-existing no-native-title-tooltip warnings (the documented Marcode seam kept at warn).

Known environment artifact: 4 tests in apps/server/src/cli/theme.test.ts fail in the authoring container and pass in CI (confirmed green there). They map 1:1 to the file's four chmodSync(…, 0o555 / 0o000) sites; that container runs as uid 0, and root can write into a 0555 directory, so those rollback paths structurally cannot trigger. Verified by probe, not assumed.

Checklist

  • This PR is small and focused — no, and deliberately so: it is one upstream merge commit, which is the unit the sync policy defines. Splitting it would fabricate history.
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — not possible in this container; owed before undraft, see above
  • I included a video for animation/interaction changes — as above

Closes #62.

t3dotgg and others added 30 commits August 24, 2026 12:42
Co-authored-by: mweinbach <maxweinbach5@gmail.com>
…gg#7140)

Co-authored-by: Dara Adedeji <daraaded@amazon.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge and others added 24 commits August 28, 2026 17:53
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
PRs pingdotgg#8437 and pingdotgg#8236 crossed: one made stashShortcutLabel a required
ComposerStashMenu prop, the other added a test case without it, so
main fails web typecheck.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Brings in 102 upstream commits since f035a0f (Expo SDK 57, turn file
attachments, thread<->pull-request linking, OpenCode child approvals, the
macOS service PATH fix, and the Uniwind semantic-theme refactor).

34 paths conflicted. Each was resolved by hand, combining both intents:

Server
- cloud/bootService.ts: took upstream's PATH export in the launchd plist
  (pingdotgg#8173, keeps provider CLIs on the macOS service) and kept Marcode's
  MARCODE_HOME key. The launcher's resolveLauncherBaseDir reads MARCODE_HOME
  and exits without it, so the plist must match the systemd unit.
- cloud/bootService.test.ts: kept both tests -- Marcode's MARCODE_HOME pin and
  upstream's new installer-PATH assertion -- retargeting the Marcode one at
  the new macRenderOptions fixture.
- persistence/Migrations.ts: upstream's two new migrations were renumbered to
  the next free Marcode ids (042 -> 043 ProjectionThreadLinkedPullRequest,
  043 -> 044 ProjectionThreadsUnsettledAt). Marcode's ProjectWorkspaceLayout
  holds 033, so every shared migration sits one id higher; renumbering an
  applied id would re-run or skip it on existing installs. The migration's
  own test was retargeted at ids 42/43.
- environment/ServerEnvironment{,.test}.ts, contracts/environment.ts: both
  capability flags kept (threadPullRequestLinking + workspaceLayoutMutations).
- server.test.ts: both imports kept.
- cli/theme.ts + theme.test.ts: the new theme CLI read T3CODE_HOME while every
  other Marcode CLI command reads MARCODE_HOME, so `t3 theme` would have
  silently targeted the default install. Switched to MARCODE_HOME.

Web
- connection/platform.ts: took upstream's clientPresentationMetadata refactor
  (pingdotgg#8481 device type, OS, browser family, hosted deployment). Its new
  clientMetadata.ts merged cleanly but hardcoded "T3 Code Desktop"/"T3 Code
  Web"; both labels now come from branding's APP_BASE_NAME, and upstream's
  test asserts the Marcode label so a future sync fails loudly.
- components/sidebar/SidebarChrome.tsx: kept Marcode's bare drag strip.
  Upstream's only change here was pingdotgg#8168's project-settings Back button inside
  SidebarUtilityMenu, which Marcode moved to FloatingPillNav -- whose "Back to
  Workspace" entry already covers every off-thread route.
- components/ChatView.tsx: took upstream's useThreadActions destructuring
  (its consumers merged in cleanly) without the duplicate handleNewThread
  Marcode moved down; kept Marcode's one-prop ChatHeader; kept Marcode's
  composer insets and applied pingdotgg#8090's shoulder-tab reduction at both
  breakpoints so sm:pb-10 does not shadow it.
- components/ChatMarkdown.tsx: took upstream's editorPreferences, editorLabels,
  remoteOpen and entities imports; dropped useRightPanelStore and the now-dead
  useActiveEnvironmentId. File links still open in the floating editor.
- components/ThreadTerminalDrawer.tsx: kept Marcode's xterm implementation.
  pingdotgg#7488's fix lands through the shared terminal-links producer, which Marcode
  already routes on via match.kind, so no isTerminalUrl import is needed.
- components/settings/KeybindingsSettings.tsx: took upstream's extracted
  WarningTooltipIcon and BrowserKeybindingNotice, restoring Marcode's copy.
- components/chat/OpenInPicker.tsx: took upstream's editorLabelForPlatform
  refactor (which subsumes Marcode's Finder/Explorer/Files ternary) and kept
  Marcode's filled FolderOpenFilled glyph.
- hooks/useHandleNewThread.ts: kept Marcode's workspace placement registration
  and took upstream's pingdotgg#6011 project-default model resolution.
- composerDraftStore.ts: kept the marcode: storage key, took the version bump
  to 9 (the persisted draft shape changed with file attachments).
- providerUpdateDismissal.ts: followed upstream's un-export, kept the key.
- components/Sidebar.tsx: both imports kept.
- components/files/FilePreviewPanel.tsx: kept Marcode's deletion. pingdotgg#8501's
  nested-image fix still lands in ChatMarkdown, which Marcode uses for chat.
- components/threadSidebarWidth.test.ts: upstream deleted this file as a
  trivial layout test, but its "keeps the brand out of the sidebar header"
  case is the only assertion pinning a Marcode removal upstream still ships.
  Kept, and retargeted off the constant upstream un-exported.

Mobile
- app.config.ts: kept MARCODE_IOS_PERSONAL_TEAM and took upstream's new
  runtimeVersionPolicy. Adopted pingdotgg#4332's adaptive-icon fix (a universal export
  already carries a rounded-square silhouette, so Android double-masked it)
  with a Marcode-branded foreground: android-icon-foreground.svg now carries
  the black Marcode glyph in the adaptive safe zone, and the background is
  white on every channel. That preserves the rendered icon exactly -- the old
  full-bleed white foreground already hid the per-channel tints.
- package.json: took pingdotgg#8694's dev-client startup fix (no --clear, new
  dev:client:reset) and kept the marcode-* schemes.
- components/CompactBrandTitle.tsx + features/home/HomeHeader.tsx: adopted
  upstream's Uniwind semantic classes (required -- the new
  no-mobile-uniwind-theme-escape-hatches rule is an error and useThemeColor
  was deleted) and kept MarcodeMark plus the conditional stage pill.
- components/T3Wordmark.tsx: kept Marcode's deletion, and replaced the
  upstream test deleted in pingdotgg#8397 with a focused pin asserting both lockups
  render MarcodeMark and that T3Wordmark stays out of the tree.
- lib/authClientMetadata.ts: kept the Marcode label, took upstream's
  tablet/phone device-type detection.

Tooling and docs
- oxlint-plugin-marcode: upstream's new no-mobile-uniwind-theme-escape-hatches
  rule landed in the renamed directory; its test hardcoded t3code/ rule ids,
  which do not resolve against a plugin named marcode. Retargeted at marcode/
  and registered the rule at error in vite.config.ts, keeping the documented
  warn seam on no-native-title-tooltip.
- Three oxlint-disable-next-line comments arrived with a t3code/ prefix and
  would not have suppressed anything; retargeted at marcode/.
- scripts/build-desktop-artifact.test.ts: kept all imports from both sides and
  Marcode's provisioning-profile fixture alongside upstream's sign assertion.
- AGENTS.md: kept Marcode's sections and ported the one rule upstream added
  that they did not already cover.
- docs/README.md: kept the unified-workspace entry, added OpenCode.
- pnpm-lock.yaml: regenerated with pnpm, not hand-resolved.

pnpm-workspace.yaml moved, but the effect catalog entry is unchanged at
4.0.0-beta.103, so the effect-smol subtree needs no sync. infra/relay did not
move, so the alchemy coupling is not triggered.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 30, 2026
…rations

The sync renumbered upstream's 042/043 to Marcode's free ids 043/044.
Migrations.test.ts pins the tail of the registry with slice(-10), so the two
appended entries pushed ProjectWorkspaceLayout (id 33) out of the window and
the pin failed -- which is exactly what it exists to do.

Widened to slice(-12) and added both entries, keeping id 33 as the anchor the
assertion is built around.
@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.4 KiB 13.3 KiB −118 B (−0.9%) 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 6.9 KiB +1 B (+0.0%) 7.3 KiB
Codex Live turn WebSocket wire 6.5 KiB 6.4 KiB −119 B (−1.8%) 7.8 KiB
Codex Live turn WebSocket decoded 55.0 KiB 55.6 KiB +558 B (+1.0%) 66.4 KiB
Codex Live turn messages 16 10 −6 (−37.5%) 21
Claude Total thread wire 13.4 KiB 13.3 KiB −103 B (−0.7%) 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 6.9 KiB +8 B (+0.1%) 7.3 KiB
Claude Live turn WebSocket wire 6.6 KiB 6.4 KiB −111 B (−1.7%) 7.8 KiB
Claude Live turn WebSocket decoded 55.8 KiB 56.4 KiB +620 B (+1.1%) 66.4 KiB
Claude Live turn messages 16 11 −5 (−31.3%) 21

Baseline: 133f3f7 · PR result: 4bfa609 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Upstream's new useEnvironmentThemeSync test seeds localStorage with
"t3code:theme", but Marcode renamed the selected-theme key to "marcode:theme"
(useTheme.ts STORAGE_KEY; useTheme.test.ts already uses the same literal).

Seeding the upstream key resolved no stored theme, so the hook fell back to the
default dark appearance and all four light-appearance assertions failed. The
merge produced no conflict here because the file is new upstream.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

upstream sync blocked: pingdotgg/t3code@2daff8c25adf