chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce - #17

Closed
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe
Closed

chore(upstream): hand off blocked sync through t3code@ba9c9ae81dce#17
maarco wants to merge 3 commits into
mainfrom
claude/sweet-sagan-nl5qpe

Conversation

@maarco

@maarcomaarco commented Aug 9, 2026

Copy link
Copy Markdown
Owner

⚠️ Read this first

This PR contains no source changes and must not be merged as-is. It carries a blocker writeup and a verified resume artifact, so the sync can continue without redoing work already done.

The scheduled sync has been failing since Aug 3 — issues #10, #11, #12, #13, #14, #15 are all the same blockage. main never advanced past the last successful merge (5192f777f), so every daily run re-plans the same growing delta from the same merge base. Eight days of drift accumulated: 140 upstream commits, 41 conflicted files, ~150 hunks.

fieldvalue
upstream sourceba9c9ae81dce4e554b4dd52abfd28d0c01b5c651
last upstream sha in main5192f777fe54c2a2a359f6c25ecf5fbde46d49b0
target based0c01668c0f87b10bf952f929c55c7a8ca818fdf
new upstream commits140
conflicted files41 (27 resolved, 14 need your call)

PR #9 (bot sync through e60821f0e0d8) is a strict subset of this delta and should be closed in favour of whatever lands from this work.

Why it's blocked

Upstream 0de95407 feat: sidebar v2 is now the default sidebar restructured the whole sidebar: old Sidebar.tsxLegacySidebar.tsx, SidebarV2.tsxSidebar.tsx, and the sidebarV2Enabled opt-in flipped to a legacySidebarEnabled opt-out.

Marcode's Sidebar.tsx is the unified workspace tree — a documented product contract and a manifest hotspot. Git therefore aligns Marcode's ~8,000-line sidebar against upstream's newly-promoted v2. Sidebar.tsx alone has ~5,100 lines inside conflict regions, including one hunk of 921 Marcode lines vs 2 upstream lines and another of 39 vs 527.

The settings contract now cleanly merges to carry bothlegacySidebarEnabled (upstream, default false) and unifiedWorkspaceSidebar (Marcode, default true) — two overlapping "which sidebar do I get" axes — while Marcode's useSidebarV2Enabled hook is gone. Deciding what those mean together is a product decision. Taking either side wholesale is forbidden by AGENTS.md and the runbook, and the runbook requires driving the real UI at 390px/820px before trusting a resolution here, which a headless container cannot do. So it stops rather than guessing.

14 files need your decisionSidebar.tsx (18 hunks), RightPanelTabs.tsx (12), ChatView.tsx (10), ProjectScriptsControl.tsx (9), ThreadTerminalDrawer.tsx (7), index.css (7), rightPanelStore.ts (6), ChatHeader.tsx (5), AppSidebarLayout.tsx (5), SidebarChrome.tsx (3), mobile-showcase-environment.ts (3), plus rightPanelStore.test.ts, useHandleNewThread.ts, SettingsPanels.tsx (1 each).

What's resolved and verified

48 files hand-resolved — the other 27 conflicted files plus 16 carrying silent fork-boundary breaks and the renumbered migrations.

  • vp run --filter @t3tools/contracts typecheck — clean
  • vp run --filter @t3tools/client-runtime typecheck — clean
  • vp run --filter t3 typecheck — clean
  • 5 focused server suites — 44 passed
  • client-runtime pagination + project grouping — 18 passed

No UI verification was performed. The web package cannot typecheck while the 14 files above still hold markers.

Silent fork-boundary breaks found (merged clean, NO conflict)

The dangerous class — each would have shipped a quietly broken Marcode:

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

Migration renumbering (correctness-critical)

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 + test label updated). Renumbering an applied id would re-run or skip it on existing installs.

Other decisions worth a look

  • http.ts — took upstream's HttpMiddleware.compression() refactor, kept Marcode's marcode://app origins (Marcode really registers that scheme, so CORS must carry it).
  • bootService.test.ts — upstream's headline fix this sync is KillMode=mixed + OOMPolicy=continue. Kept Marcode's identity test and added upstream's new OOM test. T3_BOOT_SERVICE_UNIT stays upstream-shaped.
  • threadSnapshotHttp.ts/threads.ts — both sides changed the same signature (Marcode's three-state found|missing|unavailable result vs upstream's pagination window). Combined, adapted upstream's loadOlderTurns call site and test harness; upstream's 18 pagination tests pass.
  • tooltip.tsx — upstream bumped z-50z-70 so tooltips overlay popovers/menus, but Marcode routes z through the inline floating-surface-z scale where a class is inert. Preserved the intent by adding portalOverlayTooltip: 13150. This touches Marcode's floating-surface z contract.
  • .env.example — took upstream's now-default production Connect config, renamed T3CODE_*MARCODE_* to match consumers.
  • FilePreviewPanel.tsx — modify/delete; Marcode's deletion stands (retired surface, no importers).
  • pnpm-lock.yaml regenerated via pnpm install. No coupled vendored subtree sync was needed.

Resuming

resolved-files.tar.gz holds the final content of all 48 hand-resolved files. Unpacking it over a freshly reproduced merge takes the conflict count from 41 down to exactly the 14 above.

This was verified end-to-end in a scratch worktree — the resulting tree is byte-identical to the state the typechecks and 62 passing tests ran against. (An earlier resolutions.patch on this branch did not apply: a HEAD-relative diff cannot target the unmerged index a conflicted merge leaves behind. Testing the recipe caught it; it has been replaced.)

Full recipe and writeup: docs/operations/upstream-sync-handoffs/ba9c9ae81dce/README.md

The scheduled sync has been failing since Aug 3 (issues #10-#15): `main` never
advanced past the last successful merge, so every run re-plans the same growing
delta. Eight days of drift accumulated - 140 upstream commits, 41 conflicted
files, ~150 hunks.
Resolved and verified 27 of the 41 conflicted files plus 16 more files carrying
silent fork-boundary breaks, then stopped. Upstream promoted sidebar v2 to the
default and deleted the v1/v2 split, which collides head-on with Marcode's
unified workspace tree; the settings contract now carries both
`legacySidebarEnabled` and `unifiedWorkspaceSidebar` as overlapping opt-out
axes. Reconciling them is a product decision, taking either side wholesale is
forbidden by AGENTS.md and the runbook, and the runbook requires driving the
real UI at 390px/820px before trusting any resolution there - which a headless
container cannot do.
This commit carries no source changes. It adds the blocker writeup and a
conflict-marker-free patch of every resolution already made and verified, so the
merge can be resumed without redoing that work.
Verified before stopping: contracts, client-runtime, and server typecheck clean;
44 focused server tests and 18 client-runtime pagination/grouping tests pass.
Highlights captured in the writeup: nine silent fork-boundary breaks that merged
without conflict (theme boot storage key, appearance font mirror, bundled-dev
env var, two desktop home-dir paths, `t3 pair` home lookup, migrate-dev-db
source db, boot-service unit name, and a mis-aligned projector hunk that would
have dropped two upstream fields), plus the migration renumbering needed because
Marcode owns id 33.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Aug 9, 2026
`vp check` flagged markdown table alignment in the handoff README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
The resolutions.patch this branch first carried did not apply. It was a
HEAD-relative diff, and `git apply --3way` cannot target the unmerged index a
conflicted merge leaves behind: every conflicted path failed with "does not
exist in index", and files new from upstream collided the other way with
"already exists in index". Testing the recipe caught it.
Replaced with the final content of all 48 hand-resolved files as a tarball plus
their path list. Verified end to end in a scratch worktree: reproduce the merge
(41 conflicts), unpack, drop the retired FilePreviewPanel and upstream's
pre-renumbering migration filenames, stage, and exactly the 14 web files needing
the sidebar decision remain. Every unpacked file is byte-identical to the tree
the typechecks and 62 passing tests were run against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HR4z1PYYsw3DHuWoqSWL46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@maarco@claude