Skip to content

chore(sync): merge pingdotgg/t3code main and new adopted heads - #361

Merged
Yarden-zamir merged 96 commits into
mainfrom
fork-sync/2026-10-26-0308
Oct 26, 2026
Merged

Yarden-zamir merged 96 commits into
mainfrom
fork-sync/2026-10-26-0308

Conversation

@Yarden-zamir

@Yarden-zamir Yarden-zamir commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Cause

Fork Sync run 40262460560 stopped on merge conflicts in 16 files.

Conflicts and resolution

18 hunks in 15 files:

  • appInit.tsx: the fork theme fonts, plus upstream's new startAgentOpenedPreviews.
  • CommandPalette.tsx: the fork guard (find does nothing in a terminal thread), plus upstream's thread key check.
  • ThreadNotificationCoordinator.tsx, ServerBrowser.ts: imports from both sides. ServerBrowser.test.ts: both tests.
  • StorageSettings.tsx: the fork reclamation summary with upstream's nowMs.
  • client-runtime/state/terminal.ts: the fork resumable attachStream, inside upstream's new atoms object.
  • projectScriptEditor.tsx: upstream now remounts the form per request and starts each field from request.initial. The fork fields (global, preview overlay, run in background, global shortcut) do the same.
  • ProjectSetupScriptRunner.ts: upstream's simpler stripTerminalControl, still exported for the fork terminal provider.
  • DesktopBrowserHost.ts: upstream's dropRelay(tab), then the fork presentation replay.
  • Mobile:
    • CloudAuthProvider.tsx: took upstream's cloud account service. It attaches once and has no unmount teardown. So the fork mounted-bridge counter, which kept the Android assistant panel from ending the app's session, is no longer needed.
    • ThreadFeed.tsx: upstream's render-time jump to a message, plus the fork message link target and its note.
    • ThreadDetailScreen.tsx, ThreadTerminalRouteScreen.tsx, ConnectionsNewRouteScreen.tsx: the fork imports with upstream's.
  • pnpm-lock.yaml: rebuilt with lockfile.py. The added integrity lines equal upstream's. Upstream also dropped 12 packages that fork dependencies still use, so they stay at their old integrity.

Adopted upstream pull requests

Each new head is a rebase onto newer upstream with lint and API fixes. Compared with git range-diff, they bring no new behavior. They are merged with merge commits, and mergedHead follows:

Pull request New head
pingdotgg#16653 /mcp narrows a client's modes 56f88be
pingdotgg#16654 t3_thread_launch takes clientRequestId 8a5f64e
pingdotgg#16655 link to another environment 25835af
pingdotgg#16684 agents use linked environments through any T3 tool 7c2dfcb
pingdotgg#16695 work a linked environment starts stays within its link 47ede02
pingdotgg#16698 linked environments in Connections ab3252d
pingdotgg#16719 delegate_task to a linked environment 8674123
  • The fork kept its own side where it adapts the adopted code: machine-map links, fork test files, and the tool text from earlier syncs.
  • Adopted files that the fork does not change take the new head's version, with its fixes (decodeEffect, asSome, dropped unused parameters, readOnly reads).
  • Migration rule: the heads renumber their migrations to 070_PeerLinks and 071_PeerLinkFence. Fork main still registers neither.
  • The heads' test additions are left out where the fork keeps the same tests in its own *.fork.test.ts files, or where upstream deleted the test.

Fork fixes

  • Fork right panel (useThreadRightPanel.tsx): it still passed three inputs that upstream's useAgentOpenedPreviews dropped. It also repeated two effects that upstream moved into followPreviewSessions. Both are removed, as upstream did in ChatView.

  • useRelativeTimeTick was removed upstream: ForkChangelogDialog and LinkedEnvironmentsSettings now use useNowMinute.

  • New lint and Effect rules in fork code:

    • succeedSome/succeedNone, orElseSucceed and forEach.
    • Unused imports and variables are gone. DocumentText is provided in the fork test layers that now need it.
    • Array index keys:
      • The machine map process table now has a real key.
      • Lists with no identity keep their index key, with a stated reason: slot layout rows, chart segments, and change lists that never reorder.
  • Upstream's new file preview browser test (AttachmentFilePreview.browser.test.tsx, 130 tests):

    • It failed in Fork CI: 7 tests ran past their 15-second limit or the 1-second vi.waitFor default.
    • Upstream runs it on 8-vCPU Blacksmith runners: 96 seconds for this file, 107 seconds for the whole web suite. Fork CI uses the standard 4-vCPU ubuntu-24.04 runner, which took about 6 minutes for the suite.
    • Pure upstream fails the same way on the VPS. The fork does not change the preview code.
    • Fork runs now skip this one file through apps/web/src/forkExcludedUpstreamTests.ts, as the server list already does for its tests. The entry names its reason and when to remove it. docs/fork/operations.md says so.
    • Owner decision: a larger runner for Fork CI's Test Web job would bring these tests back.

Upstream changes in fork areas

83 files changed on both sides. A review of the behavior changes found the right panel fix above. Checked and fine:

  • Mobile terminal threads: they still start, attach and redirect with upstream's session store, including pending launches and read-only terminals.
  • Mobile message links, read-aloud and outbox: still wired.
  • Assistant panel: it keeps the app's cloud session.
  • Browser capture: the fork capture sits next to upstream's new hidden-tab painting. Both take counted surface activity.
  • Fork settings panels: the fork slots and additions are intact.
  • Working section on by default: fork code follows the new default.

Checks

  • checks.py: typecheck, migration check, adopted pull request check, format and lint on all fork files pass.
  • fork_tests.py: 176 fork test files pass locally (117 root and 59 web).
  • Server: the touched server tests pass (80 tests). The other apps/server fork test files are left to Fork CI.

Fork repair skill changes

  • lockfile.py accepts a rebuild that keeps packages upstream dropped, when fork dependencies still use them. It names how many stay. Tested in test_scripts.py.
  • SKILL.md: compare a new adopted head with git range-diff, and take the head's version of adopted files that the fork does not change.

flamboh and others added 30 commits October 25, 2026 18:10
…ers (pingdotgg#25011)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ects (pingdotgg#25070)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…een effects (pingdotgg#25071)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…buses and mirrors (pingdotgg#25073)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…tView effects (pingdotgg#25006)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…nd grows back (pingdotgg#25076)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… service (pingdotgg#25150)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ons nobody uses (pingdotgg#25152)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…session

For devices opened elsewhere (a device pool, cloud, or remote host), install
the cached dev client for this checkout's fingerprint through the caller's
agent-device session, from the caller's workspace (agent-device scopes
session ownership to it). It never builds; without a shared build it names
the next step. --abi picks the Android build, --metro opens it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generated android/ios projects and the Expo config's extra section (env-
specific values a dev client reads from Metro) changed the hash per machine,
so a Linux VM never found a Mac's build in the shared cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge and others added 26 commits October 25, 2026 19:53
A link's agents run as the receiving environment's user, so at full access
the fence only ever stopped T3's own tools, never what the agent could do.
It also kept a host from driving machines it fully trusts: answering a
pending question or steering a thread the user started there, updating a
project, or running the project's setup script in a worktree it launched.

The stamp now records the access the link was paired with, and only a link
below full access is fenced. Its work still carries linkOrigin, so clients
keep showing where it came from. Stamps from before access was recorded stay
fenced.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delegate_task takes target.environmentId (and optionally target.projectId).
The child then runs as an ordinary thread in the linked environment,
launched through the link with a key derived from the caller's
clientRequestId, in the project there with this thread's repository unless
one is named.

The parent here records the task with delegated_task.remote.request: its
node, subagent row and turn item, with remoteChild instead of a local child
thread. RemoteDelegation follows the thread there and completes the task
with delegated_task.remote.complete, which reuses the parent half of a local
finalize, so the parent wakes as it would for a local child. Open remote
tasks are followed again at startup. A revoked or expired link fails the
task with that reason; any other error backs off, up to five minutes.

task_status and mode=wait answer from the row, task_cancel interrupts the
thread there and completes the task as cancelled, and restart recovery no
longer treats a remote task as abandoned provider work.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Read failed-run activity and prefer that run's error over an earlier assistant
reply. Keep successful replies unchanged and retrieve long errors in full
without taking diagnostics from a later run.

Add failed-run, pagination, run-isolation and successful-recovery regressions
for the existing review on pingdotgg#16719.

Implemented with GPT-6.1-Sol through Codex in T3 Code on behalf of Lenoridev.
When the task's run on the linked environment ended, the follower completed
the task with that run's reply, even while the thread there still waited on
its own subagents, background tasks or a completion delivery that would wake
it for the real answer. A local task waits for that work and takes its
result from the run that answered after it.

t3_thread_wait takes an optional untilDelegatedWorkSettled. With it, the wait
also blocks until delegatedTaskProgress reports result_available for the
thread, waking on task, provider-thread and run updates, and reports that
result run as resultRun. The follower passes it and reads the result from
resultRun. Both fields are optional: an older peer ignores the input and
answers as before, and the follower then falls back to the launched run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…there

Stop on a parent skipped a remote task that already had its result, so
follow-up work on its thread in the linked environment (a message sent
there with t3_thread_send, or a run that started after the result) kept
running. A local child is stopped on every Stop, result or not, and
cancelling a finished remote task already stops its thread there.

Stop now records the owed stop with an internal
delegated_task.remote.stop command: it sets remoteChild.stoppedThere to
false and counts the stop, leaving the status, result and completion
delivery alone. The follower, restarted from the live event tail or by
the startup scan, sends that stop under a key per count and records it
as "stopped"; a "ran-out" report never clears it. One follower runs per
task, and a request while it runs makes it look once more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es keep the cause

delegate_task with environmentId launched in the linked project's checkout even when
isolation "worktree" was asked for. A worktree there would branch from a commit this
checkout has and the other may not, so the call is refused before launching, pointing
at t3_thread_launch with a worktree workspaceStrategy.

Recording the task or its cancellation no longer builds the caller's message from the
dispatch error; the cause goes to the log and the caller gets a fixed message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delegate_task to a linked environment launches an ordinary thread there,
marked delegatedFrom, so a client connected to both machines listed it in
the sidebar as well as in the parent's lineage panel. Its approvals and
questions also never reached the parent here.

Lists now treat such a thread as a subagent when the client also lists
the thread that delegated it: the web sidebar and its project ordering,
mobile's thread lists, and notifications leave it out. A parent here is
flagged, and shows the "subagent needs input" banner, when the task or
one of its own subagents there asks. A task whose parent the client
cannot list (that machine switched off, or the parent gone) stays listed
on its own, so its work is never out of reach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RemoteDelegation.start resumes every open remote task at once, and each
follower read its parent's whole subagent list to find one task, then held
it across a wait of up to ten minutes. A parent with 1,441 tasks (35 MB of
payload) and 122 open ones made every restart decode ~170k records and hold
8 GB, so the server ran out of heap seconds after starting and crash-looped.

getThreadRecords now takes a subagentIds filter. Followers, and task_status
waits that re-read on every parent subagent.updated, read just their task.
Against a copy of the affected database the startup fan-out drops from 8.2 GB
retained over 21.6 s to 8 MB over 61 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mes (pingdotgg#25260)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@Yarden-zamir
Yarden-zamir merged commit 1c46a3b into main Oct 26, 2026
19 checks passed
@Yarden-zamir
Yarden-zamir deleted the fork-sync/2026-10-26-0308 branch October 26, 2026 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants