chore(upstream): sync marcode through 761d4bac - #73
Merged
Conversation
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>
) Append terminal history incrementally and materialize text for snapshots and coalesced disk writes. Clear evicted line references without changing retained output. Continues [pingdotgg#9357](pingdotgg#9357). The original contribution and author credit are preserved. The current line limit and wire format stay unchanged. A strict byte limit remains separate work. Created with GPT-6 Astra (preview) in Codex. Co-authored-by: will <will@moondiner.com>
Keep bounded, byte-counted terminal chunks and append only unread output. Use UTF-16 cursors so compaction preserves live terminal replies. Reset on lifecycle changes or a real retained-data gap. Keep the existing wire protocol, native buffer interface, and client retention limit. Native streaming and strict server replay byte bounds remain separate. Continue the client helpers from pingdotgg#9027 at source head 9391da2. 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>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Stop post-construction terminal snapshots, canvas paint, and cursor timers while a drawer or right panel is hidden. Keep parsing output and answering VT queries, then render current state once on reveal. Cover delayed WASM initialization, selection behavior, zero-size mounts, and reveal with real-core headless tests. Keep the existing startup background fill. Continue the zero-size guard from source commit eb5b681 in the terminal streaming contribution. 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.1 <noreply@anthropic.com>
…dotgg#9713) Accept file-backed image drafts and v4 outbox records while keeping current inline image creation and v3 outbox writes. Retain image files during previews, uploads, and legacy inline reads. Preserve image MIME types and stop canceled sends after asynchronous reads. The later file-backed writers remain held until new native runtime fingerprints contain these readers and the storage guards. Continue Wout Stiens' mobile draft work with separate reader-only corrections. The original contribution remains unchanged. 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>
Read only the selected thread's events when resuming its detail stream. Measure bounded row counts and serialized payload bytes before replay, using the existing aggregate index and a captured authoritative head. Keep snapshot resets for oversized or invalid cursors. Reset recreated threads when a snapshot exists, and keep bounded replay for deleted threads whose snapshot is absent. Shell replay and the detail-event filter are unchanged. Created with GPT-6 Astra (preview) in Codex.
…g#9651) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Reuse ordered timeline entries and raw rows for safe streaming text updates. Keep full derivation for structural, metadata, activity, and control changes. Preserve immutable attachment-preview objects when their current URLs are unchanged. Cover URL renewal/removal, completion, grouping, pagination, and earlier-row immutability. Continue extoci's ordered timeline projection work with separate integration and attachment corrections. The original contribution remains unchanged. Created with GPT-6 Astra (preview) in Codex. Co-Authored-By: extoci <hi@extoci.lol>
Give HTTP sends and response-body reads ten seconds each. Keep the existing typed transport errors, delivery records, and queue policy. Abort stalled requests and let the next signed job run. JWT retrieval is outside these deadlines. Do not add retries for an uncertain response result. Created with GPT-6 Astra (preview) in Codex.
…rt (pingdotgg#5362) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…gdotgg#9965) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
705 upstream commits, 116 conflicted paths. Conflict decisions, grouped: Retired surfaces (Marcode product contracts kept) - Right-panel file/files surfaces stay deleted: FileBrowserPanel, FilePreviewPanel and their exclusive deps (FileBreadcrumbs, filePath, useFileSaveCoordinator, fileTreePathReconciliation). Upstream's new openFile/openAttachment store actions, file-surface tabs, copy-path menu item and FilePreviewPanel branch in ChatView go with them. filePreviewMode.ts is restored: ChatMarkdown's retained task-checkbox tests need setMarkdownTaskChecked. - ChatHeader keeps Marcode's title-only header plus the pill-nav ThreadActionsCluster. Upstream's whole delta there is the title action menu, project favicon/icon and new-thread-in-project machinery this fork deliberately does not mount. - SidebarChrome stays the bare Electron drag strip; the pinning test in threadSidebarWidth.test.ts caught the merge reintroducing SidebarBrand. Upstream refactors adopted, Marcode behaviour re-applied on top - terminalOutput.ts: took upstream's chunked output model and ported Marcode's ANSI escape-boundary trimming onto both cut points (reset and append). - fileSaveCoordinator: took upstream's confirmedRevision tracking; cancel() now zeroes both counters and a cancel token stops an in-flight write from confirming a discarded revision (upstream's guard made the old cancel leak a second persist). - PullRequestCandidatePicker, SidebarUpdateReleaseNotes, PullRequestListFilters, ComposerSurface, updatesTestHarness, writeFakeCli: upstream extractions taken, with Marcode's tooltip/type-scale/transparency intents re-applied at the new shared producer. - rightPanelStore drops the dead updatePullRequestTabStatus; RightPanelTabs gains upstream's browser-profile submenu, tab scroll buttons and PR status seeds while keeping Marcode's surface-overflow menu and shelf geometry. Migrations - Upstream's 042-047 renumbered to Marcode's 043-048; ProjectWorkspaceLayout keeps 033 and the shared migrations stay one id higher, as the registry comment requires. Migration tests renumbered with them. Fork-boundary breaks that merged cleanly and produced no conflict - vite.config.ts lint overrides addressed the plugin as `t3code/`; Marcode's plugin is `marcode`. Same for seven oxlint-disable directives and two rule tests. The per-file effect-runtime debt map moved from the rule source into the config, merging both baselines. - `t3 theme` and `t3 app` read T3CODE_HOME; this CLI's base-dir variable is MARCODE_HOME everywhere else. - updatesTestHarness exported T3CODE_HOME/T3CODE_DESKTOP_MOCK_* to the desktop update tests; DesktopRemoteUpdates and AnalyticsService tests set T3CODE_* names their sources no longer read. - bootService's service-stopped message and six test assertions named t3code.service; Marcode's unit is marcode.service. - AgentSessionScanner matched `/.t3/worktrees/`; Marcode's home is `.marcode`. - clientMetadata, mobile authClientMetadata and ~100 user-visible strings across server CLI, desktop activation, onboarding, settings and user docs said "T3 Code"/"T3 Connect". - ExpandedImagePreview and theme tests used the `t3code:` scheme and `t3code:theme` key; Marcode uses `marcode:`/`marcode:theme`. - scripts/package.json lost the `yaml` dependency the upstream-sync tooling parses the manifest with. - ci.yml: ripgrep stays its own "Install workspace search dependency" step so the pin in upstream-sync-workflow.test.ts keeps matching. Terminal divergence - ThreadTerminalDrawer stays on xterm (kept for its search). Upstream's move to their Ghostty surface required re-porting by hand: the wrapped-link range helpers upstream deleted from terminal-links.ts are restored, the drawer reads the new chunked output, openTerminalLinkInPreview drops the removed args, and writeTerminalOutputUpdate moved to the Ghostty surface that owns it. The divergence is now commented where it lives. Verification: full-workspace typecheck clean; vp lint reports zero errors; vp fmt --check clean over all 1805 changed files; focused tests green across contracts, shared, client-runtime state, web stores/files/sidebar/connection, server boot service/CLI/migrations/environment, oxlint plugin and sync tooling. Two failures reproduce identically on origin/main in this container and are not from the merge: packages/shared Net.test.ts port allocation, and ThreadTerminalDrawer.test.ts failing to resolve @aliimam/icons under an --ignore-scripts install. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MXHnM9VTENCo5sjeucMArL
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. |
Four CI jobs failed on the merge commit. Each cause and its fix: Check (knip) — upstream added a knip dead-code/dependency gate in this sync, so it ran against Marcode's tree for the first time. Dropped dependencies the fork genuinely no longer imports (`@types/react`, `react`, and `@effect/atom-react` from `packages/client-runtime`; `@radix-ui/react-popover` from `apps/web`) and regenerated the lockfile. Added a scoped `apps/web` ignore block, marked as a fork seam, for the Marcode-owned modules knip reports as unused because the fork mounts them from surfaces upstream does not have. Also reformatted `packages/client-runtime/src/operations/projectWorkspace.ts`, which the merge left untouched but the oxfmt bump in this sync reformats. Test — `apps/desktop/src/preview/BrowserSession.test.ts` asserted on `persist:t3code-preview-`. This is a silent fork-boundary break: upstream rewrote the test, it merged without a conflict, and the production prefix in `BrowserSession.ts` is Marcode's `persist:marcode-preview-`. Fixture updated to match the source of truth. Test Server 1 — same class of break in `apps/server/src/terminal/Manager.test.ts`, which seeded `T3CODE_SECRET` to prove secret stripping. `Manager.ts` strips on the `MARCODE_` prefix, so the upstream fixture silently stopped exercising the behavior it names. Renamed to `MARCODE_SECRET`. Test Server 2 — `apps/server/src/persistence/Migrations.test.ts` pins the tail of the migration registry, and this sync added six upstream migrations, sliding Marcode's id-33 anchor out of the `slice(-10)` window. Widened to `slice(-16)` so id 33 stays inside the assertion: it is the anchor the one-id offset is measured from, and a window that no longer covers it stops pinning the offset. `apps/server/src/terminal/Manager.test.ts` still fails locally on "preserves non-notFound cwd stat failures" because this container runs as root and a chmod 000 directory does not block uid 0. That assertion is unrelated to the renamed fixture and passes in CI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MXHnM9VTENCo5sjeucMArL
…e directory
`Test Server 1` failed on four cases in the new upstream file
`apps/server/src/cli/app.test.ts`. The fixtures start a fake desktop app under
`<root>/.t3` and then invoke `t3 app` with no base directory, but Marcode
resolves that default to `~/.marcode` (`resolveBaseDir` in os-jank.ts, renamed
from upstream's `~/.t3`). The fake desktop listened on a socket the CLI never
dialed, so the failure read as a broken CLI rather than a stale fixture.
Nothing pinned that default, which is why the file merged clean. `os-jank.test.ts`
now pins `resolveBaseDir` for both the undefined and blank inputs, so a future
sync that reintroduces `~/.t3` fails at the resolver instead of in a fixture.
Auditing the rest of the merged tree for `~/.t3` turned up a second break in
new upstream code, this one invisible to CI. `DesktopWslEnvironment` writes the
WSL node-pty prebuild marker as `marcode-wsl-node-pty.json`, but upstream's new
`node_pty_payload_present()` guard scans for `t3code-wsl-node-pty.json`. The
guard exists to stop a runtime whose pty.node went missing from staying
cache-ready forever; against a marker nothing writes it inverts, reporting every
cached WSL runtime as missing its native payload and reinstalling it on every
launch. The test suite agreed with the guard because its fixture staged the same
pre-rename name, so both sides were self-consistently wrong and green.
The marker is now one exported constant used by the build script, the probe, the
install guard, and the fixture, with a test asserting all three scripts carry it
and none carry the old name. The WSL runtime parent moves from
`$HOME/.t3/wsl-runtime` to `$HOME/.marcode/wsl-runtime` through the same kind of
constant; this staging path is new in this sync and has never shipped, so no
installed runtime needs migrating.
Left as-is: the `.t3code-wsl-runtime-{ready,selected}` dotfiles inside a staged
runtime. They are internal, written and read by the same script, and not the
user-visible identity the `~/.t3` rename was about.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MXHnM9VTENCo5sjeucMArL
…vice The `Check` job typechecks with the Effect diagnostics plugin enabled, which rejects a `node:path` import where an Effect API exists (`effect(nodeBuiltinImport)`). That plugin does not run in a plain local `vp run typecheck`, so the import passed here and failed in CI. The new assertions already run inside `it.effect`, so they take `Path.Path` from the layer they were provided instead. `node:os` stays: `homedir()` is what the resolver itself reads and the rule flags only builtins with an Effect equivalent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MXHnM9VTENCo5sjeucMArL
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
Merges
pingdotgg/t3code@761d4bac(705 upstream commits sincef035a0f4) intomainas one two-parent merge commit. 116 paths conflicted and were resolved by hand.Retired surfaces — Marcode product contracts kept
file/filessurfaces stay deleted:FileBrowserPanel,FilePreviewPaneland their exclusive dependencies. Upstream's newopenFile/openAttachmentstore actions, file-surface tabs, copy-path menu item and theFilePreviewPanelbranch inChatViewgo with them.filePreviewMode.tsis restored — ChatMarkdown's retained task-checkbox tests needsetMarkdownTaskChecked.ChatHeaderkeeps Marcode's title-only header plus the pill-navThreadActionsCluster. Upstream's entire delta there is the title action menu, project favicon/icon and new-thread-in-project machinery this fork deliberately does not mount.SidebarChromestays the bare Electron drag strip. The pinning test inthreadSidebarWidth.test.tscaught the merge reintroducingSidebarBrand— exactly what it exists for.Upstream refactors adopted, Marcode behaviour re-applied on top
terminalOutput.ts— took upstream's chunked output model and ported Marcode's ANSI escape-boundary trimming onto both cut points (reset and append), so a trim still never lands inside a CSI/OSC/bare-ESC sequence.fileSaveCoordinator— took upstream'sconfirmedRevisiontracking. Combining it with Marcode'scancel()exposed a real bug: upstream's new entry guard compareslatestRevisionwithconfirmedRevision, so a write in flight when the buffer was discarded confirmed a stale revision and let the discarded buffer persist a second time.cancel()now zeroes both counters and a cancel token stops the in-flight write from confirming.PullRequestCandidatePicker,SidebarUpdateReleaseNotes,PullRequestListFilters,ComposerSurface,updatesTestHarness,writeFakeCli— upstream's extractions taken, with Marcode's tooltip, type-scale and glass-transparency intents re-applied at the new shared producer rather than kept as a divergent copy.rightPanelStoredrops the deadupdatePullRequestTabStatus;RightPanelTabsgains upstream's browser-profile submenu, tab scroll buttons and PR status seeds while keeping Marcode's surface-overflow menu and shelf geometry.Migrations
Upstream's
042–047renumbered to Marcode's043–048.ProjectWorkspaceLayoutkeeps033and every shared migration stays one id higher, as the registry comment requires — renumbering an applied id would re-run or skip it on existing installs. Migration tests renumbered with them.Fork-boundary breaks that merged cleanly and produced no conflict
These are the dangerous ones; each was found by grepping the merged tree and by typecheck:
vite.config.tslint overrides addressed the plugin ast3code/; sevenoxlint-disabledirectives and two rule tests did the samemarcode/; the per-file effect-runtime debt map moved from the rule source into the config, merging both baselinest3 themeandt3 appreadT3CODE_HOMEMARCODE_HOME, the base-dir variable everywhere else in this CLIupdatesTestHarnessexportedT3CODE_HOME/T3CODE_DESKTOP_MOCK_*;DesktopRemoteUpdatesandAnalyticsServicetests setT3CODE_*names their sources no longer readMARCODE_*bootService's service-stopped message and six test assertions namedt3code.servicemarcode.service, via theBOOT_SERVICE_UNIT_FILEconstantAgentSessionScannermatched/.t3/worktrees//.marcode/worktrees/clientMetadata, mobileauthClientMetadataand user docsExpandedImagePreviewand theme tests usedt3code:/t3code:thememarcode:/marcode:themescripts/package.jsonlost theyamldependency the upstream-sync tooling parses the manifest withci.ymlfolded ripgrep into an upstream step, silently breaking the pin inupstream-sync-workflow.test.tsInstall workspace search dependencystepCompatibility identifiers left upstream-shaped on purpose:
T3_BOOT_SERVICE_UNIT,T3_SERVICE_LAUNCHER_CONTEXT,@t3tools/*, thet3CLI/package name,com.t3tools.t3code.service,T3CODE_DESKTOP_REUSE_RESOURCE_MONITOR, and thet3code:storage keys Marcode never migrated.Terminal divergence
ThreadTerminalDrawerstays on xterm — kept for its search, which upstream's Ghostty surface has no equivalent for. Upstream's migration meant re-porting by hand: the wrapped-link range helpers upstream deleted fromterminal-links.tsare restored, the drawer reads the new chunked output,openTerminalLinkInPreviewdrops the removed args, andwriteTerminalOutputUpdatemoved to the Ghostty surface that owns it. The divergence is now commented where it lives, perAGENTS.md.Why
The scheduled sync could not land this delta on its own — 116 conflicted paths means the workflow files a blocked issue and pushes nothing. This is the hand resolution that unblocks it, and after it merges the next scheduled run sees a new merge base and returns to
clean-mergeon its own.UI Changes
No screenshots: this container has no display and the sync makes no new Marcode-authored UI. The user-visible deltas are upstream's own (welcome wizard, browser-profile submenu, PR list filters, panel animations) plus the Marcode surfaces this merge preserves rather than changes. Worth one
test-t3-apppass on a machine with a browser before this comes out of draft — see below.Checklist
Verification run
vp run -r typecheck: clean (15 packages).vp lintoverapps packages scripts oxlint-plugin-marcode infra: 0 errors (warnings are pre-existing react-compiler/tooltip categories).vp fmt --checkover all 1805 changed files: clean.Two failures reproduce identically on
origin/mainin this container and are not from the merge — verified in a disposable detached worktree atorigin/main:packages/shared/src/Net.test.ts→findAvailablePort returns preferred when it is free: the container's port allocation. NeitherNet.tsnor its test is touched by this merge.apps/web/src/components/ThreadTerminalDrawer.test.ts→Failed to resolve entry for package "@aliimam/icons": the published package'smain/modulepoint at files only its build produces, so an--ignore-scriptsinstall cannot resolve it. Fails the same way onmainwith vite-plus 0.2.2.A third,
Manager.test.ts > preserves non-notFound cwd stat failures, fails only here: the container runs as root and achmod 000directory does not block uid 0. It passes in CI.Follow-up commits: CI, and three more silent breaks
The merge commit went red on four required jobs. Every cause was a fork-boundary
break of the same class as the table above — an upstream fixture or gate that
merged without a conflict and then did not describe Marcode.
Check@types/react,react,@effect/atom-reactfrom client-runtime;@radix-ui/react-popoverfrom web) and added a scopedapps/webignore, marked as a seam, for Marcode-owned modules knip cannot see mounted. Also reformattedprojectWorkspace.ts, untouched by the merge but reformatted by this sync's oxfmt bumpTestBrowserSession.test.tsassertedpersist:t3code-preview-persist:marcode-preview-, matchingPREVIEW_PARTITION_PREFIXTest Server 1Manager.test.tsseededT3CODE_SECRETto prove secret stripping;Manager.tsstrips on theMARCODE_prefix, so the fixture had stopped exercising the behaviour it namesMARCODE_SECRETTest Server 2slice(-10)windowslice(-16), keeping id 33 inside — it is the anchor the one-id offset is measured fromTest Server 1(2nd round)apps/server/src/cli/app.test.ts, new in this sync, starts a fake desktop under<root>/.t3and then invokest3 appwith no base directory. Marcode resolves that default to~/.marcode, so the fake desktop listened on a socket the CLI never dialedos-jank.test.tsnow pinsresolveBaseDirfor undefined and blank input, so a future sync that reintroduces~/.t3fails at the resolver instead of in a fixtureWSL node-pty marker — a break CI could not have caught
Auditing the tree for
~/.t3after that last failure turned up a genuineruntime bug in new upstream code.
DesktopWslEnvironmentwrites the WSL node-ptyprebuild marker as
marcode-wsl-node-pty.json, but upstream's newnode_pty_payload_present()guard scans fort3code-wsl-node-pty.json.That guard exists to stop a runtime whose
pty.nodewent missing from stayingcache-ready forever. Pointed at a marker nothing writes, it inverts: every cached
WSL runtime reads as missing its native payload and is reinstalled on every
launch. The test suite agreed with the guard because its fixture staged the same
pre-rename name — both sides were self-consistently wrong, and green.
The marker is now one exported constant shared by the build script, the probe,
the install guard and the fixture, with a test asserting all three scripts carry
it and none carry the old name.
This also resolves the WSL question this description previously left open:
$HOME/.t3/wsl-runtimebecomes$HOME/.marcode/wsl-runtime, through the samekind of constant. That staging path is new in this sync and has never shipped, so
no installed runtime needs migrating. The
.t3code-wsl-runtime-{ready,selected}dotfiles inside a staged runtime are left alone: internal, written and read by
the same script, and not the user-visible identity the
~/.t3rename was about.Left for a decision
ChatView.cursor-hygiene-webhook.ymlis a new upstream workflow keyed onCURSOR_T3CODE_WEBHOOK_*repo secrets. It skips cleanly when they are absent.effectcatalog version did not move (4.0.0-beta.103) andinfra/relay'salchemydep is unchanged, so neither coupling in.github/upstream-sync.ymlis triggered..repos/effect-smolsits atbeta.102, a skew that predates this merge.Still worth doing before this leaves draft
CI is green on
cfa4587a—Check,Test,Mobile Native Static AnalysisandRelease Smokeall pass. Not yet done, and not doable from this container:test-t3-apppass on a machine with a browser, per the sync runbook's UI-hotspot rule;test-t3-mobilepass — the PR carries the📱 Native Changelabel.🤖 Generated with Claude Code
https://claude.ai/code/session_01MXHnM9VTENCo5sjeucMArL
Generated by Claude Code