Skip to content

chore(upstream): sync marcode through ba9c9ae81dce, port workspace tree onto the new sidebar - #18

Merged
maarco merged 143 commits into
mainfrom
integrate/upstream-ba9c9ae81dce
Aug 9, 2026
Merged

chore(upstream): sync marcode through ba9c9ae81dce, port workspace tree onto the new sidebar#18
maarco merged 143 commits into
mainfrom
integrate/upstream-ba9c9ae81dce

Conversation

@maarco

@maarco maarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Merges pingdotgg/t3code@ba9c9ae81dce — 140 upstream commits, 41 conflicted files, all resolved by hand.

The scheduled sync had been failing since Aug 3 (#10, #11, #12, #13, #14, #15 are all the same blockage): main never advanced past the last merge, so every daily run re-planned the same growing delta. This clears it. Supersedes #9 and #17.

field value
upstream source ba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
previous upstream sha in main 5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
merge base / target d0c01668c0f87b10bf952f929c55c7a8ca818fdf
upstream commits 140
conflicted files 41

The sidebar

Upstream promoted sidebar v2 to the default and deleted the v1/v2 split (0de95407), colliding head-on with Marcode's unified workspace tree. Rather than keep the tree welded into their file, it now lives in a Marcode-owned component:

  • unified-workspace/SidebarProjectWorkspaceSection.tsx — the whole tree, taking four stable props (which project, which thread is active, is this mobile) and sourcing thread actions, scripts and keybindings from hooks rather than accepting handlers threaded out of Sidebar.tsx's internals.
  • Sidebar.tsx — one import and one mount point, both marked ── Marcode fork seam ──, with a test pinning that they stay there and stay small.

That's the difference between the next upstream sidebar rewrite conflicting on two small hunks versus 5,100 lines.

The tree renders above upstream's thread sections, so their pinning, drafts and drag-to-reorder keep working untouched, and the workspace gets its attached files/folders, URL shortcuts, commands and live terminals/browser tabs with the Add-item menu for attaching code.

Flags collapse to upstream's legacySidebarEnabled; the Marcode-only sidebarV2Enabled is gone. Marcode still renders no sidebar on settings routes — FloatingPillNav owns brand/settings, so upstream's in-sidebar SettingsSidebarNav would duplicate them.

Silent fork-boundary breaks caught

Each of these merged without a conflict and would have shipped a quietly broken Marcode:

  1. Theme boot read the wrong key — upstream's new inline boot script reads localStorage["t3code:theme"]; Marcode renamed it to "marcode:theme". Every page load would have flashed the wrong theme before React mounted.
  2. appearanceFonts.ts didn't mirror Marcode's fonts — it documents its stacks as mirroring index.css and shows the resolved family to users in Settings → Appearance; upstream's are system fonts, Marcode's are Inter/JetBrains.
  3. --share bundled-dev speedup was inert — dev-runner sets T3CODE_BUNDLED_DEV, Marcode's vite config reads MARCODE_BUNDLED_DEV.
  4. DesktopEarlyElectronStartup.ts (new) read T3CODE_HOME while every Marcode writer sets MARCODE_HOME.
  5. DesktopStatePaths.ts (new) defaulted to ~/.t3 instead of ~/.marcode, feeding both early startup and DesktopEnvironment.
  6. t3 pair read T3CODE_HOME — the documented pairing-token recovery command.
  7. migrate-dev-db (new) imported the pre-rename resolveWorktreeT3Home and defaulted its source db to ~/.t3/userdata/state.sqlite, which doesn't exist here.
  8. New boot-service test hardcoded t3code.service; Marcode's unit is marcode.service.
  9. projector.ts hunks were mis-aligned — upstream's new defaultThreadEnvMode/faviconPath were aligned against Marcode's different project.workspace-layout-applied handler, so either side alone would have silently dropped them.
  10. DesktopLinuxUrlHandler.test.ts (new) asserted the Linux URL handler claims x-scheme-handler/t3code; the runtime correctly registers marcode.

Migration renumbering

Marcode owns id 33 = ProjectWorkspaceLayout, so shared migrations sit one higher. Upstream's new 36–40 collided with Marcode's 36 and were shifted to 37–41 (files git mvd, registry, pin test and migration test updated). Renumbering an already-applied id would re-run or skip it on existing installs.

Other decisions

  • Right panel — drops plan (upstream folded plans into the transcript), keeps Marcode's removal of file/files, adopts upstream's agents surface. Storage version 10. Both removals are now pinned by tests so a future sync fails loudly instead of silently restoring a second editing surface.
  • Usage page — upstream links /usage from their sidebar footer, which Marcode keeps empty. Wired into FloatingPillNav, or the whole feature would be unreachable.
  • Terminal — kept Marcode's xterm renderer, which carries terminal search that upstream's Ghostty surface lacks. Ported upstream's terminal theme tokens and Appearance font settings onto it; the Ghostty font preview got its own theme builder (terminal/ghostty/theme.ts) so a Ghostty consumer no longer imports from the xterm drawer. This divergence is a standing cost — see the note in AGENTS.md.
  • ProjectScriptsControl — kept Marcode's (it carries the handle/placement API the workspace tree drives). Upstream's extraction landed independently as projectScriptEditor.tsx for their new project settings page.
  • index.css — Marcode's palette with upstream's new semantic tokens folded in; followed their data-sidebar-versiondata-app-sidebar rename and their move of the font tokens into a runtime-overridable @theme block.
  • Chat header — upstream added a thread action menu on the title. Marcode's header shows only the title (the pill nav owns thread actions, and the sidebar row menu already provides them), so that machinery is deliberately not mounted; their pure resolveRenameCommit helper is kept with its tests.

Merge-friendliness guidance

AGENTS.md (= CLAUDE.md) gains "Write every change so the next upstream merge is cheap": add files rather than rewriting theirs, minimize coupling to their internals rather than just line count, mark the seam, take their refactors even when keeping your behavior, pin removals with tests, watch for the breaks that produce no conflict, and own the divergences you keep deliberately.

Verification

All four required checks green on e0c11584: Check, Test, Mobile Native Static Analysis, Release Smoke.

  • Full workspace typecheck clean (15 packages)
  • Per-package test runs: desktop 58, mobile 100, relay 27, oxlint 4, server 219, scripts 20, plus 484 focused web/client-runtime/contracts tests
  • vp fmt --check and vp lint clean on every changed file
  • No force push, reset, restore, stash, clean, or wholesale ours/theirs resolution

Five tests fail locally but pass in CI, all confirmed environmental and none in files this merge touches: four assert on chmod-denied access and this container runs as uid 0 (which bypasses chmod 000/400), and Net.test.ts needs an IPv6 loopback this container does not have (::1 returns EAFNOSUPPORT).

Not verified: no live browser pass — this ran headless, so the sidebar has not been seen running at 390px/820px.

t3dotgg and others added 30 commits August 1, 2026 22:42
…erver running (pingdotgg#5217)

Co-authored-by: Claude <noreply@anthropic.com>
…#2916)

Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…5327)

Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
…gdotgg#5073)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…om terminals (pingdotgg#5075)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…derer OOM crashes (pingdotgg#5148)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ingdotgg#5103)

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>
…oice (pingdotgg#5360)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
t3dotgg and others added 22 commits August 8, 2026 03:59
…nts (pingdotgg#5684)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nder (pingdotgg#5697)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#5745)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… never ran (pingdotgg#5710)

Co-authored-by: t3-turbo-simulation <simulation@t3turbo.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…otgg#5768)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…tgg#5772)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ep (pingdotgg#5776)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…data (pingdotgg#5773)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…g#5777)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…server (pingdotgg#5788)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Eight days of upstream drift (140 commits, 41 conflicted files). The scheduled
sync had been failing since Aug 3 (issues #10-#15) because main never advanced
past the last merge, so every run re-planned the same growing delta.

Sidebar: upstream promoted sidebar v2 to the default and deleted the v1/v2
split, colliding with Marcode's unified workspace tree. Rather than keep the
tree welded into their file, it moved to a Marcode-owned component
(unified-workspace/SidebarProjectWorkspaceSection) that takes four stable props
and sources everything else from hooks. Sidebar.tsx now carries an import plus
one mount point, so the next upstream rewrite conflicts on a seam instead of
5,100 lines. The tree renders above their thread sections, so their pinning,
drafts and drag-order keep working, and attach file/folder, URL shortcuts and
commands are reachable from the Add-item menu.

Flags collapse to upstream's legacySidebarEnabled; the Marcode-only
sidebarV2Enabled is gone.

Silent fork-boundary breaks fixed (all merged clean, no conflict): theme boot
read "t3code:theme" while Marcode renamed it "marcode:theme"; appearanceFonts
did not mirror Marcode's Inter/JetBrains stacks; the --share bundled-dev
speedup read the wrong env var; two new desktop files defaulted to ~/.t3;
t3 pair and migrate-dev-db looked in the wrong home; a new boot-service test
hardcoded t3code.service; and mis-aligned projector hunks would have dropped
upstream's defaultThreadEnvMode/faviconPath.

Migrations 36-40 renumbered to 37-41: Marcode owns id 33, so shared migrations
sit one higher. Renumbering an applied id would re-run or skip it.

Right panel drops "plan" (upstream folded plans into the transcript) and keeps
Marcode's removal of file/files, adds upstream's agents surface. Both removals
are now pinned by tests. Usage page wired into FloatingPillNav, which would
otherwise be unreachable since Marcode keeps the sidebar footer empty.

Kept Marcode's xterm terminal (it carries terminal search, which upstream's
Ghostty surface lacks) and ported upstream's terminal theme tokens and font
settings onto it; the Ghostty font preview gets its own theme builder.

AGENTS.md/CLAUDE.md gains a section on writing changes so the next sync is
cheap: add files rather than rewriting theirs, minimize coupling to their
internals, mark the seam, take their refactors, pin removals with tests, and
sweep for the breaks that produce no conflict.

Verified: contracts, client-runtime, server, desktop and web typecheck clean;
484 focused tests pass; fmt and lint clean on every changed file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
claude added 2 commits August 9, 2026 07:42
…idebar seam

CI found what my focused local verification missed: I typechecked only the
packages the merge touched, so `scripts` and `apps/mobile` went unchecked.

- scripts/dev-runner.test.ts: a new upstream test block passed `t3Home`;
  Marcode's CreateDevRunnerEnvInput field is `marcodeHome`.
- apps/mobile/src/lib/repositoryGroups.test.ts: upstream deleted the module
  and every consumer when they reworked the new-task flow. The modify/delete
  left Marcode's test behind importing a file that no longer exists, so the
  test file goes with it.
- apps/mobile new-task-project-selection.test.ts: project fixture predates
  Marcode's workspaceLayoutVersion/workspaceLayout contract fields.

Also adds a test pinning the unified-workspace fork seam. An upstream sidebar
rewrite that drops the mount merges perfectly cleanly and silently removes the
workspace tree from the product — the exact break a conflict never reports.
The test asserts the import, the mount, the flag gate, the seam marker, and
that the seam stays under five lines; verified it fails when the mount is
removed.

Full workspace typecheck is now clean (15 packages). The one remaining local
test failure, packages/shared Net.test.ts "findAvailablePort returns preferred
when it is free", is environmental and pre-existing: Net.ts and Net.test.ts are
byte-identical to pre-merge, and isPortAvailableOnLoopback requires binding
both 127.0.0.1 and ::1, while this container has no IPv6 loopback at all
(binding ::1 returns EAFNOSUPPORT, which the code does not treat as
"available" the way it does EADDRNOTAVAIL).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Round two of what CI caught. All three are the same fork-boundary shape: a
test asserting upstream's identity or numbering against Marcode's runtime.

- DesktopLinuxUrlHandler.test.ts (new upstream file): asserted the Linux URL
  handler registers x-scheme-handler/t3code. The handler takes its scheme from
  ElectronProtocol.getDesktopScheme(), which is `marcode` here, so the runtime
  was right and the assertion was wrong. The desktop-entry FILENAME still comes
  from the fixture's linuxWmClass, which is why only the mime half mismatched.
- Migrations.test.ts: Marcode's own pin on the registry tail, doing exactly
  what its comment promises ("a sync that adds a migration fails here
  loudly"). Extended to cover the renumbered 37-41.
- 041_ProjectionProjectFaviconPath.test.ts (new upstream file): ran migrations
  to 39/40 under upstream's numbering; Marcode's ids sit one higher.

Remaining local failures are all environmental and confirmed unrelated: four
tests that assert on chmod-denied access (server keybindings/router/terminal,
scripts release-manifest) cannot fail in this container because it runs as
uid 0, which bypasses chmod 000/400 entirely — verified directly. Plus
packages/shared Net.test.ts, where isPortAvailableOnLoopback requires binding
both 127.0.0.1 and ::1 and this container has no IPv6 loopback (::1 returns
EAFNOSUPPORT). None of those files are touched by this merge.

Verified per package rather than relying on `vp run test`, which only picks up
5 of the 14 test-bearing packages locally: desktop 58 passed, mobile 100
passed, relay 27 passed, oxlint plugin 4 passed, server 219 passed (3 root
chmod), scripts 20 passed (1 root chmod).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@maarco
maarco marked this pull request as ready for review August 9, 2026 08:52
@maarco
maarco merged commit df91c6c into main Aug 9, 2026
14 checks passed
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.