chore(upstream): sync marcode through fff33f9e - #71
Merged
Conversation
Co-authored-by: Julius Marminge <julius0216@outlook.com>
…gg#8694) Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: Ahmed Besic <ahmed-besic@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Julius Marminge <julius0216@outlook.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>
…text (pingdotgg#8804) 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: Julius Marminge <julius@mac.lan>
…gg#8734) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Julius Marminge <jmarminge@gmail.com>
…gg#9366) Co-authored-by: Claude Code <noreply@anthropic.com>
…lly (pingdotgg#9355) Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Code <noreply@anthropic.com>
…ngdotgg#9122) Co-authored-by: Lars Nieuwenhuis <35393046+lnieuwenhuis@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ingdotgg#9348) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…gdotgg#9123) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…pingdotgg#9202) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…old as legacy (pingdotgg#9397) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Integrates 337 upstream commits (f035a0f..fff33f9) by hand. 79 conflicts resolved combining upstream correctness/features with Marcode's product divergences. Key decisions: Branding / compatibility (kept Marcode identity, kept upstream-shaped compat ids): - README/docs/AGENTS: Marcode branding; added Google Antigravity provider. - cli/service.ts, bootService.ts: "Marcode service", systemd unit "marcode.service", plist exports MARCODE_HOME (not T3CODE_HOME) + took upstream's new PATH key; kept BOOT_SERVICE_UNIT_ENV="T3_BOOT_SERVICE_UNIT" and launchd label com.t3tools.t3code.service (compat). - Storage keys marcode:*, mobile schemes marcode-*, desktop scheme marcode:, browser partition marcode-preview-*, settingsSearch "Marcode Connect". Persistence hotspot: - Migrations: Marcode owns id 33 (ProjectWorkspaceLayout); upstream 042-047 renumbered +1 to 043-048 (files, registry, tests, registry-pin test). Server orchestration (unified-workspace seam): - projector/ProjectionPipeline: kept Marcode workspace-layout handling AND folded in upstream's new project fields (autoPull, projectIcon). - decider/commandInvariants: kept Marcode workspace-layout invariants + upstream imports. - WorkspaceFileSystem: kept Marcode resolveMutationTarget + upstream resolveReadTarget. Web (floating editor / unified workspace / retired file surfaces): - rightPanelStore/RightPanelTabs/ChatView/ChatMarkdown/_chat.pull-requests: kept Marcode's retirement of right-panel file surfaces + floating-editor opening; adopted upstream's ComposerSurface, PR status seeds, browser profiles. - AppSidebarLayout/SidebarChrome/ChatHeader: kept Marcode FloatingPillNav shell. - ThreadTerminalDrawer: kept Marcode xterm terminal (upstream switched to Ghostty). - oxlint no-manual-effect-runtime: adopted upstream's config-driven maxOccurrences, ported Marcode's baseline into vite.config.ts (fixed t3code/ -> marcode/ namespace). Silent-break fixes (clean merges that would have broken on Marcode identity): - updatesTestHarness.ts: T3CODE_* env keys -> MARCODE_*. - clientMetadata.ts / service.ts: "T3 Code" labels -> "Marcode". - vite.config.ts oxlint override namespace t3code/ -> marcode/. - bootService.test.ts systemd unit t3code.service -> marcode.service. Verified: typecheck clean for web, server, contracts, client-runtime, desktop; focused tests pass (bootService, migrations, orchestration, settlement, settings). pnpm-lock.yaml regenerated with pnpm; effect-smol subtree unchanged (effect version stable at 4.0.0-beta.103). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
Base advanced to 200e149 (chat ambient effects, #66) after this integration branched. Only pnpm-lock.yaml conflicted; regenerated with pnpm. ChatView, ChatHeader, index.css and popover auto-merged cleanly with the upstream sync. Verified: apps/web typecheck clean; ambient-effects tests and the sync's web tests pass (51 tests). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 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.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
The Check job failed on `vp check`. Two causes, both from this merge:
- Formatting: packages/client-runtime/src/operations/projectWorkspace.ts
reformatted with `vp fmt` (cosmetic arrow-wrapper collapse, no behavior change).
- Unused lint directives (reportUnusedDisableDirectives is an error):
- Three oxlint-disable comments arrived from upstream naming `t3code/...`
rules. Marcode's plugin is `meta.name: "marcode"`, so those ids do not
exist here and the directives were no-ops. Renamed to `marcode/...`,
matching the plugin and the rule ids already used in vite.config.ts.
- Three eslint-disable directives (ThreadTerminalDrawer, UnifiedWorkspaceRow,
floating-code-pill) stopped reporting under upstream's oxlint bump
(1.68 -> 1.79 via vite-plus 0.3.0) and are removed; the explanatory
comments that documented the intent are kept.
Verified: `vp check` reports 0 errors; typecheck clean for web, desktop,
server and client-runtime; formatting clean on every edited file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
… home Two silent fork-boundary breaks from the upstream merge, both of which merged without a conflict and only surfaced in CI. `scripts/package.json` auto-merged to upstream's dependency list, which drops Marcode's `yaml` dependency. The scripts workspace still imports it, so `Test` failed with `Cannot find package 'yaml'`. Restored the dependency and regenerated the lockfile. `apps/server/src/cli/app.test.ts` arrives whole from upstream with the new `t3 app` desktop-control command. Its fixtures hardcode `~/.t3` as the home the CLI falls back to when neither `--base-dir` nor `T3CODE_HOME` is set, but Marcode's `resolveBaseDir` defaults to `~/.marcode`. The fake desktop therefore bound a socket derived from a different state directory than the one the CLI dialed, and four tests failed with `connect ENOENT`. The fixtures now derive the directory from a named constant with a seam comment. `T3CODE_HOME`, the `t3code-` socket prefix, and the `t3` package name are compatibility identifiers and stay upstream-shaped. `os-jank.test.ts` now pins `resolveBaseDir`'s default so a future sync that reverts the directory name fails loudly instead of silently re-pointing every default-home caller. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
None of these produced a merge conflict. Upstream added new files and new call sites that name identifiers this fork renamed, so the merge took them cleanly and they only surface as a CI failure or, worse, as wrong runtime behavior. `T3Wordmark` -> `MarcodeMark`. Marcode renamed upstream's wordmark component on web and mobile. The merge re-added `apps/web/src/components/T3Wordmark.tsx` as a new file and pointed the web timeline's `t3-code` tool-server icon at it, while the matching mobile import in `thread-work-log.tsx` had no file to resolve -- that was the `Check` job's typecheck failure. Both surfaces now render `MarcodeMark` and the re-added component is removed. The `t3-code` server name is an upstream-shaped compatibility identifier and is untouched; only the icon beside it is brand identity. `scripts/brand-mark-ownership.test.ts` pins the removal, since a rename is otherwise invisible to the next merge. `T3CODE_HOME` -> `MARCODE_HOME` in the new `t3 app` and `t3 theme` commands. Marcode's base-dir variable is `MARCODE_HOME` in `config.ts`, `pair`, `triage` and the installed systemd unit; `triage.ts` already carries a seam comment saying so. Upstream's own comment in `theme.ts` states the intent -- "same precedence as the rest of the CLI" -- which on this fork selects `MARCODE_HOME`. Left as it stands, a provisioning script exporting `MARCODE_HOME` would have these two commands silently target the default install. `T3CODE_DISABLE_AUTO_UPDATE` -> `MARCODE_DISABLE_AUTO_UPDATE` in `DesktopRemoteUpdates.test.ts`. `DesktopConfig` reads the `MARCODE_` name and `DesktopUpdates` reports it, so the new upstream test seeded an ignored variable and asserted the upstream message. This was a real failing test, not a fixture detail. `t3code:theme` -> `marcode:theme` in `useEnvironmentThemeSync.test.ts`. `useTheme` stores the selected theme under `marcode:theme`, so the upstream seed set nothing and the setup had silently stopped covering "a theme is already stored". Sibling keys (`t3code:themes:v1`, `t3code:theme-appearance-mode`, ...) are persisted-state compatibility identifiers and stay upstream-shaped. Verified: `vp check` 0 errors; `vpr typecheck` clean across all 15 packages (this was red before); 247 focused tests pass across the changed surfaces. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
Both surfaced by reproducing the CI `Test` job locally (`vp run --filter '!t3' --filter '!@t3tools/monorepo' test`). Neither conflicted. `BrowserSession.test.ts` asserted upstream's `persist:t3code-preview-` partition prefix. `BrowserSession.ts` builds `persist:marcode-preview-`, so the three assertions pinned a string this fork does not produce. Browser partitions are per-profile Electron session keys; the assertions now pin the prefix Marcode actually ships. The `oxlint-plugin-marcode` rule tests for `no-mobile-uniwind-theme-escape-hatches` and `no-manual-effect-runtime-in-tests` built their oxlint fixture configs against plugin `t3code`. The plugin declares `name: "marcode"` in `index.ts` and every sibling rule test already uses `marcode/`, so oxlint rejected the fixture config outright -- "Plugin 't3code' not found" -- failing all 26 cases in those two files. This is the same namespace break already repaired in `vite.config.ts`; these two files were missed because the failure is a fixture parse error rather than a type or lint error. Verified: `vp check` 0 errors; desktop 707/707; oxlint-plugin-marcode 72/72. Two remaining local failures are container artifacts, not regressions, and both files are byte-identical to `main`: `update-release-package-versions.test.ts` and four `cli/theme.test.ts` cases assert on `chmod`-injected failures that a root container ignores, and `Net.test.ts` needs an IPv6 loopback this container does not have (`::1` bind returns EAFNOSUPPORT, so `isPortAvailableOnLoopback` can never succeed here). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
…breaks The CI `Test` job covers 13 packages; the local filter I had been reproducing it with resolved only five, and `apps/web` was not among them. Running the web suite directly surfaced three failures. `fileSaveCoordinator` is the real one, and it is a behavior conflict rather than a naming slip. Upstream added a `confirmedRevision` counter and changed `persistLatest`'s entry guard from `latestRevision === 0` to `latestRevision === confirmedRevision`. That zero is Marcode's `cancel()` sentinel -- the documented contract on `cancel()` names the old guard by hand -- so discarding a buffer mid-write no longer stopped the completing write from rescheduling, and the discarded contents were persisted a second time. Worse, and not covered by any existing test: the completing write recorded `confirmedRevision = 1` against a revision `cancel()` had zeroed, so the *next* edit -- whose revision climbs back to 1 -- compared equal to that stale confirmation and was silently never persisted. Discard, then keep typing, is an ordinary floating-editor sequence, so that was real data loss. Both intents are kept: upstream's already-confirmed dedup stays, and the zero sentinel is checked separately; a write that confirms after a discard no longer records a confirmation; and `cancel()` resets both counters so they cannot drift apart. A regression test covers the discard-then-edit sequence, which failed against the merged code and passes now. The other two are naming breaks that merged without a conflict: `clientMetadata.test.ts` asserted the label "T3 Code Desktop" while `clientPresentationMetadata` reports "Marcode Desktop", and `clientPersistenceStorage.test.ts` seeded `t3code:client-settings:v1`, a key this fork never writes, so the assertion below it had stopped covering the stored-settings path. That seed now reads `CLIENT_SETTINGS_STORAGE_KEY` off the module so it cannot drift again. Verified: apps/web 3795/3795 (316 files); `vp check` 0 errors; web typecheck clean. The server suite's 7 remaining local failures are all `chmod`-injection tests that a root container defeats (`keybindings`, `server`, `terminal/Manager`, and four `cli/theme` cases); every one of those files is byte-identical to `main`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
Hand-resolved merge of 337 upstream commits
pingdotgg/t3codef035a0f4..fff33f9einto Marcode. 79 conflicts resolved by combining upstream correctness/features with Marcode's product divergences (not whole-file ours/theirs).pnpm-lock.yamlregenerated with pnpm.Branding / compatibility — kept Marcode identity, kept upstream-shaped compat ids:
cli/service.ts,cloud/bootService.ts: "Marcode service", systemd unitmarcode.service, launchd plist exportsMARCODE_HOMEand took upstream's newPATHkey. KeptBOOT_SERVICE_UNIT_ENV="T3_BOOT_SERVICE_UNIT"and launchd labelcom.t3tools.t3code.service(compat).marcode:*storage keys,marcode-*mobile schemes,marcode:desktop scheme,marcode-preview-*browser partitions, "Marcode Connect".Persistence (hotspot) — Marcode owns migration id
033(ProjectWorkspaceLayout), so upstream's new migrations042-047were renumbered +1 to043-048(files, registry, tests, and the registry-pin test).Server orchestration (unified-workspace seam) — kept Marcode's workspace-layout handling and folded in upstream's new project fields (
autoPull,projectIcon);WorkspaceFileSystemkeeps Marcode'sresolveMutationTarget+ upstream's newresolveReadTarget.Web — kept Marcode's retired right-panel file surfaces + floating-editor file opening (
rightPanelStore,RightPanelTabs,ChatView,ChatMarkdown,_chat.pull-requests) while adopting upstream'sComposerSurface, PR-status seeds, and browser-profile launcher. Kept the FloatingPillNav shell (AppSidebarLayout,SidebarChrome,ChatHeader) and the xterm terminal (ThreadTerminalDrawer; upstream switched to Ghostty). Adopted upstream's config-driven oxlintmaxOccurrencesand ported Marcode's baseline intovite.config.ts.fileSaveCoordinatoris the one break in this sync that is a behavior conflict, not a naming slip, and it is the thing most worth a careful look.Upstream added a
confirmedRevisioncounter and changedpersistLatest's entry guard fromlatestRevision === 0tolatestRevision === confirmedRevision. That zero is Marcode'scancel()sentinel — the doc comment oncancel()names the old guard by hand — so:confirmedRevision = 1against a revisioncancel()had zeroed, so the next edit — whose revision climbs back to 1 — compared equal to that stale confirmation and was silently never persisted. Discard, then keep typing, is an ordinary floating-editor sequence, so this was real data loss.Both intents are kept: upstream's already-confirmed dedup stays, the zero sentinel is checked separately, a write confirming after a discard no longer records a confirmation, and
cancel()resets both counters so they cannot drift apart. A regression test covers discard-then-edit; it fails against the merged code and passes now.Silent fork-boundary breaks
None of these produced a merge conflict — upstream added new files and new call sites naming identifiers this fork renamed, so the merge took them cleanly. Most surfaced only as CI failures; several would not have surfaced at all.
updatesTestHarness.tsusedT3CODE_*env keysMARCODE_*configclientMetadata.ts/service.tslabelled "T3 Code"vite.config.tsoxlint namespacet3code/bootService.test.tsunitt3code.servicescripts/package.jsonlost Marcode'syamlTestred —Cannot find package 'yaml', plusTS2307inCheckcli/app.test.tsfixtures assume~/.t3Test Server 1red — fake desktop bound a socket the CLI never dialedT3Wordmarkre-added on web, dangling on mobileChecktypecheck red; web timeline rendered upstream's T3 lettermarkt3 app/t3 themereadT3CODE_HOMEMARCODE_HOMEsilently ignored; both commands target the default installDesktopRemoteUpdates.test.tsseededT3CODE_DISABLE_AUTO_UPDATEMARCODE_nameBrowserSession.test.tsassertedpersist:t3code-preview-persist:marcode-preview-oxlint-plugin-marcoderule tests targeted plugint3codeclientMetadata.test.tsasserted "T3 Code Desktop"clientPersistenceStorage.test.tsseededt3code:client-settings:v1useEnvironmentThemeSync.test.tsseededt3code:themefileSaveCoordinatorguard changeThree further invariants worth a second look:
MarcodeMarkon web and mobile. The merge re-addedapps/web/src/components/T3Wordmark.tsxas a new file and pointed thet3-codetool-server icon at it. Both surfaces now renderMarcodeMark; the re-added component is deleted. Thet3-codeserver name is an upstream-shaped compat identifier and is untouched — only the icon is brand identity.MARCODE_HOMEinconfig.ts,pair,triageand the installed systemd unit, andtriage.tsalready carried a seam comment saying upstream readsT3CODE_HOMEhere. Upstream's own comment in the newtheme.tsstates the intent — "same precedence as the rest of the CLI" — which on this fork selectsMARCODE_HOME. (An earlier revision of this description wrongly listedT3CODE_HOMEamong the kept compat identifiers.)name: "marcode". Two upstream rule-test files built fixture configs against plugint3code, which oxlint rejects at parse time rather than as a type or lint error — which is why they survived the earliervite.config.tsnamespace fix.Deliberately left upstream-shaped. A sweep of every production (non-test) file this merge touched found "T3 Code" in the new
cli/app.tsandcli/theme.tsuser-visible error messages. That is not a break: Marcode's ownpair.tsandtriage.tsonmainuse "T3 Code" in user-facing CLI prose, andapps/mobile/app.config.tspairsappName: "T3 Code"withscheme: "marcode"exactly asmaindoes. The CLI surface is deliberately upstream-shaped, consistent witht3being a kept compat identifier, so none of it was changed.mainis the oracle per surface — the fixes above are surface-specific, not a blanket rename.Removals and renames are now pinned by tests, since they are otherwise invisible to the next merge:
scripts/brand-mark-ownership.test.ts(no wordmark component or reference on web/mobile/desktop),os-jank.test.ts(default base dir is~/.marcode), the correctedBrowserSession.test.tsprefix assertions, theCLIENT_SETTINGS_STORAGE_KEYseed read off the module rather than a literal, and the existingbootService.test.tsplist assertion.Coupled subtrees:
pnpm-workspace.yamlbumped clerk/tailwind/vite-plus buteffectstayed at4.0.0-beta.103, so the vendoredeffect-smolsubtree is unchanged.Why
Daily upstream sync. Brings upstream correctness, security, protocol, dependency, and feature work (Antigravity provider, server-side thread settlement, PR labels/status seeds, browser profiles, media previews, composer refactor) into the maintained fork while preserving Marcode's intentional product divergences.
Closes the tracking block in #70 (
t3code@57a66608, included in this range).UI Changes
Not captured in this automated sync. Web/mobile/desktop UI hotspots changed and should get runtime verification (
test-t3-app/test-t3-mobile, 390px + 820px) before this leaves draft. Two changes are user-visible: the brand mark on both web and mobile timelines, and the editor discard/save behavior above.Checklist
vp check0 errors;vpr typecheckclean across all 15 packageschmodcontainer artifactsa1edd0e7—Check,Test,Mobile Native Static Analysis,Release Smoke, plus all threeTest Servershards,Rust, andclaude-review(run 33786720079)Left draft deliberately. CI is green and the branch is mergeable, but this automated sync does not mark PRs ready or merge them. The two unchecked boxes are the remaining human steps.
🤖 Generated with Claude Code
https://claude.ai/code/session_016jdCVqZCzYw2dSFVgnqvob
Generated by Claude Code