Skip to content

chore(upstream): sync marcode through c163d502 - #72

Closed
maarco wants to merge 470 commits into
mainfrom
claude/gracious-bohr-bst6me
Closed

chore(upstream): sync marcode through c163d502#72
maarco wants to merge 470 commits into
mainfrom
claude/gracious-bohr-bst6me

Conversation

@maarco

@maarco maarco commented Sep 4, 2026

Copy link
Copy Markdown
Owner

What Changed

Merges pingdotgg/t3code@c163d502dd32b993c03d8c20a5fae55b159bd8dc into main as a normal two-parent merge commit: 466 upstream commits, 89 conflicted paths.

Every conflict was resolved by hand, combining both intents. No path was taken wholesale from one side except where one side contributed nothing.

CI is green on 38d51a48Check, Test, Mobile Native Static Analysis and Release Smoke all pass, plus Test Server 1/2/3, Rust, claude-review and the native fingerprint checks. Mergeable, no conflicts. Left as a draft deliberately: runtime verification is still outstanding (see below) and the three carry-forwards want a maintainer decision.

Conflict decisions

Fork identity and service lifecycle

  • bootService: kept Marcode's marcode.service unit and the plist's MARCODE_HOME key — resolveLauncherBaseDir reads it and exits without it. Took upstream's new PATH export and --allow-downgrade flow. The service-stopped hint now interpolates BOOT_SERVICE_UNIT_FILE rather than hardcoding upstream's unit name.
  • cli/service, cli/connect: kept Marcode branding, took upstream's installedVersion reporting and serviceReconcileFlags.
  • RuntimeInstructions: took upstream's shared runtime_info producer and moved Marcode's product name into it, so Codex, Claude, Cursor and Antigravity all report the fork correctly. Its test now asserts Marcode and rejects "T3 Code".

Persistence — Marcode owns migration id 33, so upstream's 042047 were renumbered to 043048 on the way in. Migrations.test.ts pins the full renumbered tail.

Orchestration

  • projector: git aligned upstream's project.meta-updated body against Marcode's project.workspace-layout-applied case. Split them apart and landed upstream's autoPull/projectIcon fields where they belong.
  • commandInvariants: took upstream's removal of the now-unused requireNonNegativeInteger; kept Marcode's workspace-layout block.
  • ServerEnvironment: capability set is the union of both sides.
  • WorkspaceFileSystem: kept Marcode's mutation-target canonicalization, took upstream's absolute-path read resolution.

Web

  • rightPanelStore / RightPanelTabs: kept Marcode's retirement of the file/files surfaces; took upstream's live pull-request tab icon, browser profile submenu, and tab scroll arrows alongside Marcode's surface-overflow menu.
  • ChatMarkdown: adopted upstream's panelPath prop rename and media fallback; file opens still land in the floating editor.
  • ChatView: took upstream's composer shell extraction, panel animations, agent-browser close confirmation and paste-to-focus; kept Marcode's pill-nav portal, ambient effects and right-panel terminal reconcile.
  • index.css: Marcode's dark palette is a strict superset of upstream's block.

Mobile / desktop / marketing — kept MarcodeMark, marcode-* dev-client schemes, MARCODE_IOS_PERSONAL_TEAM, and the black-on-white adaptive icon; took upstream's runtime version policy, dev-client reset script and tablet/phone detection. Followed upstream's uniwind migration for the mobile stage pill (their new lint rule bans the useThemeColor escape hatch it used). Marketing took upstream's responsive hero pipeline, with Marcode's branded mark moved into src/assets so the Astro <Image> pipeline serves it.

Breaks that merged cleanly and produced no conflict

The dangerous ones — each would have shipped silently. Ten found before pushing:

Break Fix
vite.config.ts lint overrides named the t3code plugin; Marcode's is marcode renamed (same for 5 oxlint-disable directives)
t3 app and t3 theme read T3CODE_HOME Marcode's base-dir variable is MARCODE_HOME
updatesTestHarness exported T3CODE_* env names renamed to the vars the desktop reads
app.test.ts rebuilt the default base dir as .t3 Marcode's is .marcode; the fake desktop listened on a socket the CLI never dialed
ProviderCommandReactor.test.ts hardcoded t3code/<hex> no longer placeholder-shaped under WORKTREE_BRANCH_PREFIX = "marcode"; now derived from the constant
BrowserSession/BrowserImport tests pinned persist:t3code-preview- renamed
DesktopRemoteUpdates.test.ts asserted T3CODE_DISABLE_AUTO_UPDATE renamed
32 newly introduced user-visible strings named "T3 Code" rebranded (comments and legacy install paths left upstream-shaped)
upstream's stale-write fix changed persistLatest's entry guard silently broke Marcode's cancel() invariant — cancel() now bumps a generation counter so an in-flight write cannot confirm a discarded buffer
vite-plus 0.2.2 → 0.3.0 resolves entries strictly exposed a broken main in @aliimam/icons (Marcode-only dep); patched like the repo's other dependency fixes

What CI caught that local verification did not

Four further rounds, all the same class. Recorded because the pattern is the lesson: scoped local checks cannot catch a break in a file the merge never touched.

Round Red check Cause
1 Check the vite-plus bump brings oxfmt 0.64, which reformats projectWorkspace.ts — a file this merge never touched, so a changed-files-only fmt --check could not see it
2 Test Server 1/2/3, Test migration tests select by number (toMigrationInclusive), which the renumbering missed; the ClearAutomaticProjectModelDefaults suite lives inside 016_CanonicalizeModelSelections.test.ts, so the file rename never reached its title or bounds either
3 Test Server 3 telemetry opt-out was not being exercised: AnalyticsService reads MARCODE_TELEMETRY_ENABLED and defaults it to true, but upstream's new disabled-path test set T3CODE_TELEMETRY_ENABLED. Telemetry stayed on and the test saw a real PostHog batch request go out. The one live behavior gap in this set, not a stale string
4 Test clientPersistenceStorage seeded t3code:client-settings:v1 (module reads marcode:, as the file's three other cases already do); useEnvironmentThemeSync seeded t3code:theme (useTheme reads marcode:theme), so the stored theme was never found

Only marcode:theme and marcode:client-settings:v1 are Marcode-renamed storage keys. The other theme keys (t3code:themes:v1, :theme-follow-system, :theme-appearance-mode, :theme-halves:v1) stay upstream-shaped and agree between index.html and themePalette.ts, so they were left alone.

Coverage kept where upstream deleted it

  • threadSettled.test.ts: upstream deleted it wholesale when settling moved server-side, taking the only coverage of hasQueuedTurnStart with it. Trimmed to that surviving suite instead of deleting.
  • threadSidebarWidth.test.ts, mobileBranding.test.ts and Marcode's terminal-selection tests kept.
  • rightPanelStore.test.ts now also pins the absence of openAttachment.

Coupled subtrees

effect stayed at 4.0.0-beta.103 and infra/relay/package.json did not move, so neither vendored subtree needed a sync:repos.

Why

Scheduled daily upstream sync. The delta was large enough to conflict, so this is the hand-resolved integration the runbook calls for in place of the bot's clean-merge branch.

Needs a maintainer decision

Four things, none blocking CI:

  1. ChatHeader — Marcode portals thread actions into FloatingPillNav, so upstream's header title action menu, inline rename, project favicon and project icon stay unmounted. This preserves the fork seam an earlier sync recorded, but it is now a larger upstream feature to keep declining.
  2. ThreadTerminalDrawer — Marcode keeps its xterm surface, so upstream's Ghostty rewrite of this file is not taken. Re-ported by hand each sync by design; flagging that the divergence keeps growing.
  3. Attachment previews — upstream previews browser-openable attachments in a right-panel file surface. Marcode retired that surface and has no attachment preview host, so these now fall through to the download path. Marked with a fork seam comment.
  4. Possible duplicate workaround for @aliimam/iconsapps/web/vite.config.ts already carries a Marcode resolve.alias pointing the package at its ESM build, for exactly the broken-main problem the new patches/@aliimam__icons@1.1.3.patch also fixes. The patch was needed for the failure hit here, but one of the two is probably redundant and worth collapsing rather than maintaining both.

UI Changes

No screenshots. This sync introduces no Marcode-authored UI, and the scheduled run had no browser available. Web and mobile runtime verification per the sync runbook is still outstandingtest-t3-app and test-t3-mobile should be driven before this leaves draft, since the merge touched ChatView, RightPanelTabs, ChatMarkdown, the composer shell and the mobile brand lockup.

Verification

  • Typecheck (clean): contracts, shared, t3 (server), client-runtime, web, desktop, mobile, scripts, marketing, oxlint-plugin-marcode
  • Lint: 0 errors across apps packages scripts oxlint-plugin-marcode
  • vp check: exit 0 (0 errors; the 695 warnings are pre-existing)
  • Tests: full apps/server (3,769 passing), full apps/web (3,905 passing), plus client-runtime, contracts, shared, desktop, mobile, oxlint plugin and scripts

Failures seen only in the scheduled runner's container, each verified as environmental and confirmed absent from CI:

  • chmod-based permission assertions (cli/theme.test.ts, keybindings, terminal/Manager, server.test.ts, update-release-package-versions) — the container runs as root, which ignores 0o000/0o400/0o555. Verified directly by writing into a 0555 directory as root.
  • browser-secret-native.test.mjs needs libsecret-1-dev, absent there; this PR adds that install step to CI (upstream's, merged alongside Marcode's ripgrep step).
  • Ghostty ?inline wasm imports (core.test.ts, runtimeAbi.test.ts) — fail only in that container; CI's Test job reports neither, on files this merge did not change.
  • .github/scripts/thread-transfer-report.test.cjs is a node:test file the vitest runner does not collect; passes under node --test (6/6).

Thread transfer impact stays within every enforced ceiling (see the bot comment).

Checklist

  • This PR is small and focused — no: it is a 466-commit upstream sync, reviewable by the per-hotspot decisions above
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — runtime verification still outstanding, see above
  • I included a video for animation/interaction changes — n/a

🤖 Generated with Claude Code

https://claude.ai/code/session_01JurM2fqYGVdQXriLvYuQ49

flamboh and others added 30 commits September 1, 2026 23:53
…9146)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
…dotgg#9075)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
…9166)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
t3dotgg and others added 20 commits September 4, 2026 06:23
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Defer the draft walk and JSON serialization until the storage write flushes.
Preserve hydration, migrations, attachment verification, and final flushes.

Continues the web portion of [pingdotgg#9049](pingdotgg#9049).
The mobile storage migration remains separate.

Created with GPT-6 Astra (preview) in Codex.

Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
466 upstream commits, 89 conflicted paths. Every conflict was resolved by
combining both intents; no path was taken wholesale from one side except
where one side had nothing to contribute.

Conflict decisions
------------------

Fork identity and service lifecycle
- bootService: kept Marcode's `marcode.service` unit and the plist's
  MARCODE_HOME key (the launcher's resolveLauncherBaseDir reads it and exits
  without it); took upstream's new PATH export and --allow-downgrade flow.
  The service-stopped hint now interpolates BOOT_SERVICE_UNIT_FILE instead of
  hardcoding upstream's unit name.
- cli/service, cli/connect: kept Marcode branding, took upstream's
  installedVersion reporting and serviceReconcileFlags.
- RuntimeInstructions: took upstream's shared runtime_info producer and moved
  Marcode's product name into it, so Codex, Claude, Cursor and Antigravity all
  report the fork correctly. Its test now asserts Marcode and rejects "T3 Code".

Persistence
- Migrations: Marcode owns id 33, so upstream's 042-047 were renumbered to
  043-048 on the way in. Migrations.test.ts pins the full renumbered tail.

Orchestration
- projector: git aligned upstream's project.meta-updated body against
  Marcode's project.workspace-layout-applied case. Split them apart and landed
  upstream's autoPull/projectIcon fields where they belong.
- commandInvariants: took upstream's removal of the now-unused
  requireNonNegativeInteger; kept Marcode's workspace-layout block.
- ServerEnvironment: capability set is the union of both sides.
- WorkspaceFileSystem: kept Marcode's mutation-target canonicalization and took
  upstream's absolute-path read resolution.

Web
- rightPanelStore and RightPanelTabs: kept Marcode's retirement of the
  file/files surfaces (the floating editor owns file editing) and took
  upstream's live pull-request tab icon, browser profile submenu and tab
  scroll arrows alongside Marcode's surface-overflow menu.
- ChatMarkdown: adopted upstream's panelPath prop rename and media fallback;
  file opens still land in the floating editor.
- ChatView: took upstream's composer shell extraction, panel animations,
  agent-browser close confirmation and paste-to-focus; kept Marcode's
  pill-nav portal, ambient effects and right-panel terminal reconcile.
- ChatHeader: kept Marcode's portaled action cluster; upstream's header title
  action menu stays unmounted, as the existing fork seam records.
- ThreadTerminalDrawer: Marcode keeps its xterm surface, so upstream's Ghostty
  rewrite of this file is not taken. This divergence is re-ported by hand each
  sync by design.
- index.css: Marcode's dark palette is a strict superset of upstream's block.

Mobile, desktop, marketing
- Kept MarcodeMark, marcode-* dev-client schemes, MARCODE_IOS_PERSONAL_TEAM and
  the black-on-white adaptive icon; took upstream's runtime version policy,
  dev-client reset script and tablet/phone client detection.
- Followed upstream's uniwind migration for the mobile stage pill, since their
  new lint rule bans the useThemeColor escape hatch it used.
- Marketing: took upstream's responsive hero image pipeline and moved Marcode's
  branded mark into src/assets so the Astro <Image> pipeline serves it.

Breaks that merged cleanly and produced no conflict
---------------------------------------------------
- vite.config.ts: upstream's new lint overrides named the t3code plugin;
  Marcode's is marcode. Same for five oxlint-disable directives.
- Upstream's new CLI commands (t3 app, t3 theme) read T3CODE_HOME; Marcode's
  base-dir variable is MARCODE_HOME everywhere else in the CLI.
- updatesTestHarness exported T3CODE_* env names the desktop never reads.
- app.test.ts rebuilt the CLI's default base dir as `.t3`; Marcode's is
  `.marcode`, so the fake desktop listened on a socket the CLI never dialed.
- ProviderCommandReactor.test.ts hardcoded a `t3code/<hex>` placeholder branch,
  which stopped being placeholder-shaped once WORKTREE_BRANCH_PREFIX became
  `marcode`. It now derives the prefix from the constant.
- BrowserSession/BrowserImport tests pinned `persist:t3code-preview-`.
- DesktopRemoteUpdates.test.ts asserted T3CODE_DISABLE_AUTO_UPDATE.
- RuntimeInstructions.test.ts and clientMetadata asserted upstream's product
  name; 32 newly introduced user-visible strings were rebranded.
- fileSaveCoordinator: upstream's stale-write fix changed persistLatest's entry
  guard, silently breaking Marcode's cancel() invariant. cancel() now bumps a
  generation counter so an in-flight write cannot confirm a discarded buffer.
- vite-plus 0.2.2 -> 0.3.0 resolves package entries strictly, exposing a broken
  `main` in @aliimam/icons (a Marcode-only dependency). Patched like the repo's
  other dependency fixes.

Coverage kept
-------------
- threadSettled.test.ts: upstream deleted it wholesale when settling moved
  server-side, taking the only coverage of hasQueuedTurnStart with it. Trimmed
  to that surviving suite instead.
- threadSidebarWidth.test.ts, mobileBranding.test.ts and Marcode's terminal
  selection tests were kept where upstream deleted them.
- rightPanelStore.test.ts now also pins the absence of openAttachment.

Coupled subtrees
----------------
effect stayed at 4.0.0-beta.103 and infra/relay/package.json did not move, so
neither vendored subtree needed a sync.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JurM2fqYGVdQXriLvYuQ49
@github-actions github-actions Bot added size:XXL 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Sep 4, 2026
The upstream merge bumps vite-plus 0.2.2 -> 0.3.0, which brings oxfmt
0.64.0. The newer formatter collapses this single-argument Effect.map
call differently, so a file the merge never touched started failing
`vp check`. Formatting only, no behavior change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JurM2fqYGVdQXriLvYuQ49
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.4 KiB 13.5 KiB +87 B (+0.6%) 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 7.0 KiB +136 B (+1.9%) 7.3 KiB
Codex Live turn WebSocket wire 6.5 KiB 6.5 KiB −49 B (−0.7%) 7.8 KiB
Codex Live turn WebSocket decoded 55.0 KiB 57.0 KiB +1.9 KiB (+3.5%) 66.4 KiB
Codex Live turn messages 16 8 −8 (−50.0%) 21
Claude Total thread wire 13.4 KiB 13.5 KiB +87 B (+0.6%) 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 7.0 KiB +139 B (+2.0%) 7.3 KiB
Claude Live turn WebSocket wire 6.5 KiB 6.5 KiB −52 B (−0.8%) 7.8 KiB
Claude Live turn WebSocket decoded 55.8 KiB 57.8 KiB +2.0 KiB (+3.5%) 66.4 KiB
Claude Live turn messages 16 8 −8 (−50.0%) 21

Baseline: 200e149 · PR result: 38d51a4 · Source CI: success

Scenario and decoded snapshot size

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

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

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

Four more breaks the merge introduced without a conflict, all caught by CI.

Migration ids are pinned numerically. Renumbering upstream's 042-047 onto
Marcode's free ids renamed the files and the layer() titles, but their
tests select migrations through `runMigrations({ toMigrationInclusive })`,
which still carried upstream's numbers. The ClearAutomaticProjectModelDefaults
suite lives inside 016_CanonicalizeModelSelections.test.ts, so the file
rename never reached its title or bounds either.

Telemetry opt-out was not being exercised. AnalyticsService reads
MARCODE_TELEMETRY_ENABLED and defaults it to true; upstream's new
disabled-path test set T3CODE_TELEMETRY_ENABLED, which the service ignores.
Telemetry stayed on and the test saw a real PostHog batch request. This is
the one break here that was a live behavior gap rather than a stale string.

Three suites still asserted product strings this sync rebranded:
pullRequestDiffHttp, DesktopAppUpdate, and ClaudeAdapter's runtime_info.

Verified with the full apps/server suite (3769 passing) plus the
client-runtime tests. The 7 remaining local failures are all chmod-based
permission assertions that cannot fail under this container's root user
and pass on CI's non-root runner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JurM2fqYGVdQXriLvYuQ49
Two more upstream tests seeded browser storage under upstream's key names,
so the modules under test never saw the fixture:

- clientPersistenceStorage's new diff-layout case wrote
  "t3code:client-settings:v1"; the module reads "marcode:client-settings:v1",
  which the file's three other cases already use.
- useEnvironmentThemeSync seeded "t3code:theme"; useTheme reads
  "marcode:theme", so the stored theme was never found and appearance
  stayed dark.

Only these two keys are Marcode-renamed. The rest of the theme keys
(t3code:themes:v1, :theme-follow-system, :theme-appearance-mode,
:theme-halves:v1) stay upstream-shaped and agree between index.html and
themePalette.ts, so they are left alone.

Verified with the full apps/web suite: 3905 passing. The two remaining
local failures are the Ghostty wasm `?inline` imports, which fail only in
this container -- CI's Test job reports neither.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JurM2fqYGVdQXriLvYuQ49
@maarco

maarco commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

Superseded by merged PR #74.

@maarco maarco closed this Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.