Repository navigation
chore: delete 18k lines of code that nothing reaches - #26238
Conversation
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — This cleanup removes APIs, compatibility paths, and unused code across clients and servers. The investigation did not establish the full behavioral reach of the removals or complete the assessment of default changes and diagnostic suppressions. Notes:
No code changes detected at You can add or adjust custom eligibility rules. Learn more. |
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. |
96c615d to
ed6e9d3
Compare
Two slop audits found code nothing reaches. This removes the parts that need no product decision: dead exports and files, code only its own tests keep alive, client checks on capability flags every protocol-2 server has always sent as true, legacy paths for peers that cannot connect, unused RPCs, orphan fixtures, deps and assets, and manual memos the React Compiler already handles in mobile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ed6e9d3 to
2819196
Compare
Merge upstream/main 67661cf into coder-only (sync stage 4 of 4: pingdotgg#26238)
Upstream removed encodeScanCache (pingdotgg#26238); the archived usage test now writes the saved usage file with makeScanCacheWriter, as upstream's own tests do. Claude Opus 5.5 in Claude Code
Upstream pingdotgg#26238 stopped checking `projectCloneTracking`, so adding a project by URL now calls `startProjectClone`, which Moatless does not dispatch. The palette action was already filtered, but `openCommandPalette({ open: "add-project" })` and the pull request list's empty-state button still opened the flow. The gaps entry now records that Moatless folds `context` itself (soaplabs/moatless#1326). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
**The open decision is resolved on the backend.** Upstream pingdotgg#26238 (67661cf, "delete 18k lines of code that nothing reaches") replaced most client capability checks with `serverConfig !== null`. Three capabilities Moatless did not advertise now run unconditionally: - `inlineMessageContext`: context chips are sent only as a separate `context` field, which Moatless's `message.dispatch` dropped. **Merge soaplabs/moatless#1326 first.** It folds `context` into the turn text in the client's old legacy form and advertises the capability. Without it, attached chips are silently dropped. - `projectCloneTracking`: add-by-URL calls `startProjectClone`/`projectClones`, which Moatless does not dispatch. Moatless already lists `projectManagement` unsupported. Commit 1030d44 now also drops `openCommandPalette({ open: "add-project" })` in `commandPaletteBus.ts` and hides the pull request list's empty-state Add project button, so no entry point reaches the clone flow. The `projectClones` subscription still fails quietly to an empty list (recorded in moatless `docs/deferred-changes.md`). - `attachmentUploads`: no inline fallback is left for a deployment without `SESSION_JWT_SECRET`. The Helm chart and docker-compose both set it. The fork's checks were kept wherever a conflict landed on them. The deleted ones were not restored, because that means re-growing code upstream removed across many files. The backend handles them instead; what is left is in `docs/fork/gaps.md` → "Upstream stopped reading the capabilities Moatless leaves absent". ## Conflict notes - 112 files were touched by both sides. The tracker entry in `docs/fork/upstream-merge-log.md` has the decisions. - **Restored:** `preview.navigate`. Upstream deleted it as unreached; the fork's framed preview calls it and Moatless serves it. It is restored in `contracts`, `client-runtime` and the `apps/server` stub. New inventory entries `preview-navigate-fork-method` and `primary-environment-context`. The fork keeps `environments/primary/context.ts`. - **`/login`:** upstream deleted `AuthSurfaceShell`, so the page uses `StandalonePage`. - **Lint rule rename:** upstream renamed `t3code/react-effect-budget` to `t3code/no-unreasoned-state-sync`, which now reports every effect. Fork disables were renamed in 14 files. - **Sidebar and navigation:** fork filters use `delegatedUnderParent` alongside the fork's listing of Moatless child tasks. - **`agentContextBudget.json`:** `mcpToolListJsonBytes` is +108. That is the fork's `ProjectScript.port` showing up in two MCP tool schemas; new entry `agent-context-budget`. - **File counts:** 1736 files landed vs 1724 in the upstream range. The 15 extra are fork files this merge edited. The 3 missing are `cli/pair.ts`, `pair.test.ts` and `primary/context.ts`, all kept as the fork has them. The fork delta is 763 files, up from 758. ## Usable as-is - F6 / sidebar keyboard navigation, the multi-project sidebar filter, the background-work line. - Add-provider ordering, model labels, the queued-message sender, stopped runs no longer shown as errors. - PR bot approvals, markdown frontmatter rendering, Steer during compaction. ## Unsupported in Moatless / needs implementation - **Linked environments (peer links):** `peerLinks.list/link/unlink/answerRequest`, capabilities `peerLinks`, `mcpModeLimitHeader`, `linkFence`, environment chips and the cross-machine @ picker (4005759, 8b14660). The new methods declare `UnsupportedMethodError`. The Labs row and its search item are gated by `serverBehaviorSettings`. - **Triage:** `server.prepareTriage`, capability `triage` (7e884b2). Declares `UnsupportedMethodError`. - **Dev-server stop:** `preview.stopLocalServer`, capability `localServerStop`, `ThreadServersPanel` (a27ec88). Declares `UnsupportedMethodError`. - **Snooze presets:** the `snoozePresets` server setting (93a9e07). Gated by `serverBehaviorSettings`. - **MCP:** the `delegate_task` / `clientRequestId` tools and the `T3-Mode-Limit` header. - **Capability collapse:** the three items at the top; `docs/fork/gaps.md` has the updated entry. ## Backend behavior to consider reproducing in Moatless Recorded in `docs/fork/gaps.md` → "Runtime fixes upstream made to its own server". - **Security:** the GitHub token is sent only to its own host (80b7b0f); Antigravity paths are contained to the workspace (8251578). - **Agent questions and runs:** - Pending agent questions survive a restart (867112c). - A hung delegated-stop effect is time-bounded (36d4d71). - A child delivery no longer reopens a completed or settled parent run (d033768, 32bf48f). - Handoff recovery (07242ab). - **Providers:** - Claude fixes (531cee6, fe867b8, bc8d02f, 8d94203). - Codex retry and recovery (740de0e, b88da91). - OpenCode runtime mode (b5af460). - ACP index reuse (3b2f958). - Compact MCP schemas (bc81367). - **Git:** - Parallel worktree creation no longer collides on the `.git/config` lock (3b22620). - Forgejo glob hang (a846084). - Renumbered PRs re-link (3a87681). - **Runtime and terminal:** cgroup delegation (4b00290); terminal grid sync on attach (49a9e80). ## Verification `verify.mjs` full parallel pass: every check except `test` is green. - **Still failing, unchanged from 2026-10-27:** `t3` `RepositoryIdentityResolver`, `GitVcsDriver`, `CodexChatGptAuth`, `CodexManagedRuntime` (the sandbox's `/tmp` gap) and `provider-opencode` `OpenCodeServerLedger`. - **Caused by this merge and fixed:** `AgentContextBudget`, `threadShell` and `features.test`. - **Not re-run:** after those fixes, the fixed files and `@t3tools/client-runtime` were re-run green. `@t3tools/web` as a whole was not re-run; it was 454/455 before the fix. ## After merging Upstream's new `agent-context-budget.yml` workflow arrives enabled. Disable it with `gh workflow disable agent-context-budget.yml --repo soaplabs/t3code`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/804df90b-12bf-469c-9caa-2a616e14b3ca
- Side chat context: codyProviderText now runs where upstream builds userText, before the provider thread loads, so the handoff budget measures the real text (adapted to upstream's ProviderTurnStartService reshuffle). - Side chat approvals: rebuilt on upstream's timeline approval rows (pingdotgg#26255); the side chat panel passes its requests to MessagesTimeline and its composer drops the removed approval panel. New guard: apps/web/src/cody/sideChatApprovals.test.ts. - Side chats: threadContextRecord comes from @t3tools/shared (moved by pingdotgg#26202); the panel drops activeTurnInProgress and the composer drops isConnecting, both removed upstream. - Removed Cody's archived shell stream filter and optional onRollbackCheckpoint prop; upstream deleted subscribeArchivedShell and the timeline checkpoint rollback (pingdotgg#26238). - ws.ts: kept Cody's client feature flag on upstream's slimmer layerWsRpc signature. - Navigation thread list: upstream's isShownUnderParent check plus Cody's side chat filter. - Command palette: upstream's always-on linked pull requests item plus Cody's side chat items. - Connections: Cody's WSL tailnet pairing link kept, with upstream's moved pairing token helpers. - Desktop: startup recovery window (pingdotgg#25903) says Cody and points at Cody's releases; Cody's auto-install listener starts alongside it; Windows work-account sign-in installed next to upstream's clipboard permission prompt. - agentContextBudget.json re-measured with Cody's final-answer block (+371 bytes). - Fork tests: DesktopClerk bridge test expects the new open-url listener; the wrap-up fold test uses timelineTurnFoldRunIdsByEntryId; mocks follow removed getProjectThread and layerWsRpc arguments; lint directive renamed to no-unreasoned-state-sync. - personal-fork skill: sync notes for these changes.
…upstream's composer and module cleanup Upstream deleted the background policy stream as unreached (pingdotgg#26238); Helm Mobile's Mac remote reads it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the bubble Root decision 0210, plan DEV-6676 (row 25). With T3CODE_LAZURIO_BUDDY=1 the web client is Buddy's surface: a header with Mattyčus, the conversation's days in a pane where the window has room and a date line above each day's first message, and no thread list, new thread, fork, rollback or thread details card. `/` opens Buddy's one thread through the thread route, and a message sent during a turn steers it; queueing is the explicit alternative. In Buddy's bubble the surface speaks the frame's side of lazurio.buddy.* v1, written from the protocol's description: it says it is ready, keeps the last valid page context from its parent on the host's exact origin, and asks for its window's size from its header and on Escape, which asks for the panel unless a dialog, menu or list is open in the surface or something inside stopped the key (the editor marks every Escape as handled). A day in the pane turns off following the end first, as the timeline's minimap does, so the jump stays. In the bubble the surface wears the host page's appearance through T3's own appearance preference; where T3 cannot wear it (storage blocked, or a saved single-appearance theme), the document wears T3's standard palette in the host's appearance (request of 2026-10-25). The server holds the same for every client and agent. Decorators where it builds the orchestrator and the checkpoint store refuse forks, rollbacks, other threads and deleting Buddy's thread, and take no checkpoints in Buddy's project, which is the managed Folder's (T3CODE_LAZURIO_FOLDER=<Folder>/.agents/buddy) and else ~/Lazurio/.agents/buddy. A thread.create with Buddy's thread id passes only while Buddy's thread route makes the thread (MakingBuddysThread), so a client cannot spend the route's fixed command on a thread of its own. A startup phase before recovery turns off continuing threads after an update, the agent browser, and Codex and Claude, once, recorded in <state>/lazurio/buddy-surface.json so that later choices stay. `GET /api/lazurio/buddy/days` lists the conversation's days for the pane. The day lines and the day jump check Buddy mode once per timeline, for the timeline's own Environment, and the rows read it from the timeline's shared state, so no other Environment's timeline does that work or takes a jump. On v0.1.3 two web seams are rebuilt and one server refusal is added. - Upstream installs the chat route's shortcuts once at app start (pingdotgg#25366 removed ChatRouteGlobalShortcuts), so Buddy's condition joins their `when` in shortcuts/chatRouteCommands.ts: `isBuddySurfaceNow()` reads the primary server config from the app's atom registry when a key is pressed. Without it Shift+Mod+N on Buddy's surface would try a new thread that the server then refuses. - The timeline no longer takes onManualNavigation (pingdotgg#25463); the day jump is called below the timeline's own navigateTimeline and passes it, and the day line sits beside upstream's AudioPreviewUnmountContext (pingdotgg#21363). - Upstream's guest share of a thread (pingdotgg#24104) is refused in Buddy's T3 Code: thread.guest-share.open, .redeem and thread.guest-message.submit fail in the command guard, because Buddy's conversation belongs to a Personalspace, which is never shared (root decision 0091); closing a share stays possible. The root renders no GuestShareDialogHost on Buddy's surface. A test drives a guest share of Buddy's thread through the server's orchestrator. Settings and Usage are modals over the thread now (pingdotgg#24847); the prompt-link draft stays off Buddy's surface inside the rewritten ChatRouteLayout, and the first-run gate stays off on NEW's slimmer root. The guards are Effect.fn decorators (effectFnOpportunity), the two effects of BuddySurface.tsx carry justified react-effect-budget suppressions, and the file headers are cut to the four-line comment limit. Any other thread of Buddy's Environment, opened by a link or a typed address, leads to Buddy's thread as `/` does: the chat layout shows BuddySurfaceIndex, which asks the server for Buddy's thread and replaces the address, so that thread never renders under Buddy's presentation. A thread of another Environment stays T3's, and ChatView and the thread details ask about the thread's own Environment. A browser test opens such an address directly. On v0.1.4: the root keeps upstream's local-Environment switch beside the Buddy surface check (pingdotgg#26207); the timeline finds upstream's unmatched pending approvals (pingdotgg#26255) after the day lines and adds the day keys to upstream's list data next to its new footer. ThreadDetailsPanel no longer exports its props type (pingdotgg#26238), so Buddy's panel takes ComponentProps of it, and the effect suppressions use the renamed lint rule t3code/no-unreasoned-state-sync (pingdotgg#26161). The host appearance, which row 28's commit carried on v0.1.3, comes back to this row: T3 no longer re-applies its theme from useTheme's effect (pingdotgg#25007, pingdotgg#25461), so the stand-in follows every application of T3's saved theme through subscribeRenderedAppearance, and the theme tests apply T3's stored appearance as app start does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T3CODE_RELEASE_REPOSITORY (owner/name) selects whose GitHub Releases the release index, `t3 update`, the boot service, remote self-update and the install scripts use; unset, the Lazurio distribution installs and updates from Lazurio/t3code. A server run by the service launcher checks its own channel there at startup and every six hours (never when unmanaged, on preview builds, or with T3CODE_UPDATE_CHECK_ENABLED=false) and advertises a strictly newer release as `availableServerUpdate`. The index picks the highest version per channel, not the first one published. Once the launcher has committed this server's version, the server points the user's `t3` link at its own runtime, so the CLI and the server stay on one version after an in-app Update. On v0.1.3 the server, CLI and boot-service seams are unchanged (launcher protocol 3). Upstream removed the composer's "Server update available" notice (pingdotgg#25401) and now offers updates from the update button at the bottom of the sidebar and Settings -> Environments. The advertised release therefore moves onto that button: collectServerUpdateTargets takes a server's advertised release as its target (it is strictly newer by construction, so the version-core comparison, which ignores a fork's prerelease suffix, is skipped), and useUpdateEverything no longer holds such a target until it is on npm, because the release lives in the server's own channel. The composer keeps only the running/failed notice; its Retry targets the advertised version. The install scripts are rebuilt on upstream's new lookup (pingdotgg#22907): stable reads github.com/<repo>/releases/latest, the other trains page the API up to ten pages, and each answer is filtered by the runtime's train rule instead of upstream's narrow vX.Y.Z pattern, which rejects X.Y.Z-lazurio.N. install-scripts.test.ts now serves releases/latest (with its Accept header) and two API pages, and checks which URLs each train reads. Overlay comments are cut to the new four-line limit. On v0.1.4: upstream removed thread continuation after a server update (pingdotgg#26238), so the five web seams that passed it along keep only the overlay's targetVersion from the release channel. The launcher protocol stays 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Launchpad's "+ Nový modul" opens Chat with #lazurio-prompt=<id>&lazurio-org=<login> in the fragment. main.tsx takes it off the address before the router reads it; once the primary environment is live, the text and project folder come from this origin's /.lazurio/prompts/<id>, and a new thread opens in that project (in a managed Environment, its Lazurio Folder project) with the text in the composer, never sent. Upstream's /new?prompt= links carry the text in the address, so the overlay keeps its own. The tab keeps only the id and the login across the pairing reload, never the text; it is taken once and expires after two minutes. On v0.1.3 the router, history and provider-auth delivery moved from main.tsx into startAppServices() in appInit.tsx (pingdotgg#25004), so the capture now runs on the line before `const router = startAppServices()`, still before any router exists; it now also runs before provider-auth delivery, which acts only on its own fragment. ChatRouteLayout was rewritten for Settings and Usage as modals over the thread (pingdotgg#24847); <LazurioPromptDraft /> is its first child and stays mounted while a modal is open. The component's one effect carries a justified react-effect-budget suppression and its comments are cut to four lines. It imports prefersCzech from row 9's threadTabs.ts and reads lazurioFolder from row 15's server config, so this row alone does not typecheck. On v0.1.4: upstream deleted lib/projectPaths.ts (pingdotgg#26238); the draft reads findProjectByPath and inferProjectTitleFromPath from @t3tools/client-runtime/state/projects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the bubble Root decision 0210, plan DEV-6676 (row 25). With T3CODE_LAZURIO_BUDDY=1 the web client is Buddy's surface: a header with Mattyčus, the conversation's days in a pane where the window has room and a date line above each day's first message, and no thread list, new thread, fork, rollback or thread details card. `/` opens Buddy's one thread through the thread route, and a message sent during a turn steers it; queueing is the explicit alternative. In Buddy's bubble the surface speaks the frame's side of lazurio.buddy.* v1, written from the protocol's description: it says it is ready, keeps the last valid page context from its parent on the host's exact origin, and asks for its window's size from its header and on Escape, which asks for the panel unless a dialog, menu or list is open in the surface or something inside stopped the key (the editor marks every Escape as handled). A day in the pane turns off following the end first, as the timeline's minimap does, so the jump stays. In the bubble the surface wears the host page's appearance through T3's own appearance preference; where T3 cannot wear it (storage blocked, or a saved single-appearance theme), the document wears T3's standard palette in the host's appearance (request of 2026-10-25). The server holds the same for every client and agent. Decorators where it builds the orchestrator and the checkpoint store refuse forks, rollbacks, other threads and deleting Buddy's thread, and take no checkpoints in Buddy's project, which is the managed Folder's (T3CODE_LAZURIO_FOLDER=<Folder>/.agents/buddy) and else ~/Lazurio/.agents/buddy. A thread.create with Buddy's thread id passes only while Buddy's thread route makes the thread (MakingBuddysThread), so a client cannot spend the route's fixed command on a thread of its own. A startup phase before recovery turns off continuing threads after an update, the agent browser, and Codex and Claude, once, recorded in <state>/lazurio/buddy-surface.json so that later choices stay. `GET /api/lazurio/buddy/days` lists the conversation's days for the pane. The day lines and the day jump check Buddy mode once per timeline, for the timeline's own Environment, and the rows read it from the timeline's shared state, so no other Environment's timeline does that work or takes a jump. On v0.1.3 two web seams are rebuilt and one server refusal is added. - Upstream installs the chat route's shortcuts once at app start (pingdotgg#25366 removed ChatRouteGlobalShortcuts), so Buddy's condition joins their `when` in shortcuts/chatRouteCommands.ts: `isBuddySurfaceNow()` reads the primary server config from the app's atom registry when a key is pressed. Without it Shift+Mod+N on Buddy's surface would try a new thread that the server then refuses. - The timeline no longer takes onManualNavigation (pingdotgg#25463); the day jump is called below the timeline's own navigateTimeline and passes it, and the day line sits beside upstream's AudioPreviewUnmountContext (pingdotgg#21363). - Upstream's guest share of a thread (pingdotgg#24104) is refused in Buddy's T3 Code: thread.guest-share.open, .redeem and thread.guest-message.submit fail in the command guard, because Buddy's conversation belongs to a Personalspace, which is never shared (root decision 0091); closing a share stays possible. The root renders no GuestShareDialogHost on Buddy's surface. A test drives a guest share of Buddy's thread through the server's orchestrator. Settings and Usage are modals over the thread now (pingdotgg#24847); the prompt-link draft stays off Buddy's surface inside the rewritten ChatRouteLayout, and the first-run gate stays off on NEW's slimmer root. The guards are Effect.fn decorators (effectFnOpportunity), the two effects of BuddySurface.tsx carry justified react-effect-budget suppressions, and the file headers are cut to the four-line comment limit. Any other thread of Buddy's Environment, opened by a link or a typed address, leads to Buddy's thread as `/` does: the chat layout shows BuddySurfaceIndex, which asks the server for Buddy's thread and replaces the address, so that thread never renders under Buddy's presentation. A thread of another Environment stays T3's, and ChatView and the thread details ask about the thread's own Environment. A browser test opens such an address directly. On v0.1.4: the root keeps upstream's local-Environment switch beside the Buddy surface check (pingdotgg#26207); the timeline finds upstream's unmatched pending approvals (pingdotgg#26255) after the day lines and adds the day keys to upstream's list data next to its new footer. ThreadDetailsPanel no longer exports its props type (pingdotgg#26238), so Buddy's panel takes ComponentProps of it, and the effect suppressions use the renamed lint rule t3code/no-unreasoned-state-sync (pingdotgg#26161). The host appearance, which row 28's commit carried on v0.1.3, comes back to this row: T3 no longer re-applies its theme from useTheme's effect (pingdotgg#25007, pingdotgg#25461), so the stand-in follows every application of T3's saved theme through subscribeRenderedAppearance, and the theme tests apply T3's stored appearance as app start does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T3CODE_RELEASE_REPOSITORY (owner/name) selects whose GitHub Releases the release index, `t3 update`, the boot service, remote self-update and the install scripts use; unset, the Lazurio distribution installs and updates from Lazurio/t3code. A server run by the service launcher checks its own channel there at startup and every six hours (never when unmanaged, on preview builds, or with T3CODE_UPDATE_CHECK_ENABLED=false) and advertises a strictly newer release as `availableServerUpdate`. The index picks the highest version per channel, not the first one published. Once the launcher has committed this server's version, the server points the user's `t3` link at its own runtime, so the CLI and the server stay on one version after an in-app Update. On v0.1.3 the server, CLI and boot-service seams are unchanged (launcher protocol 3). Upstream removed the composer's "Server update available" notice (pingdotgg#25401) and now offers updates from the update button at the bottom of the sidebar and Settings -> Environments. The advertised release therefore moves onto that button: collectServerUpdateTargets takes a server's advertised release as its target (it is strictly newer by construction, so the version-core comparison, which ignores a fork's prerelease suffix, is skipped), and useUpdateEverything no longer holds such a target until it is on npm, because the release lives in the server's own channel. The composer keeps only the running/failed notice; its Retry targets the advertised version. The install scripts are rebuilt on upstream's new lookup (pingdotgg#22907): stable reads github.com/<repo>/releases/latest, the other trains page the API up to ten pages, and each answer is filtered by the runtime's train rule instead of upstream's narrow vX.Y.Z pattern, which rejects X.Y.Z-lazurio.N. install-scripts.test.ts now serves releases/latest (with its Accept header) and two API pages, and checks which URLs each train reads. Overlay comments are cut to the new four-line limit. On v0.1.4: upstream removed thread continuation after a server update (pingdotgg#26238), so the five web seams that passed it along keep only the overlay's targetVersion from the release channel. The launcher protocol stays 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Launchpad's "+ Nový modul" opens Chat with #lazurio-prompt=<id>&lazurio-org=<login> in the fragment. main.tsx takes it off the address before the router reads it; once the primary environment is live, the text and project folder come from this origin's /.lazurio/prompts/<id>, and a new thread opens in that project (in a managed Environment, its Lazurio Folder project) with the text in the composer, never sent. Upstream's /new?prompt= links carry the text in the address, so the overlay keeps its own. The tab keeps only the id and the login across the pairing reload, never the text; it is taken once and expires after two minutes. On v0.1.3 the router, history and provider-auth delivery moved from main.tsx into startAppServices() in appInit.tsx (pingdotgg#25004), so the capture now runs on the line before `const router = startAppServices()`, still before any router exists; it now also runs before provider-auth delivery, which acts only on its own fragment. ChatRouteLayout was rewritten for Settings and Usage as modals over the thread (pingdotgg#24847); <LazurioPromptDraft /> is its first child and stays mounted while a modal is open. The component's one effect carries a justified react-effect-budget suppression and its comments are cut to four lines. It imports prefersCzech from row 9's threadTabs.ts and reads lazurioFolder from row 15's server config, so this row alone does not typecheck. On v0.1.4: upstream deleted lib/projectPaths.ts (pingdotgg#26238); the draft reads findProjectByPath and inferProjectTitleFromPath from @t3tools/client-runtime/state/projects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the bubble Root decision 0210, plan DEV-6676 (row 25). With T3CODE_LAZURIO_BUDDY=1 the web client is Buddy's surface: a header with Mattyčus, the conversation's days in a pane where the window has room and a date line above each day's first message, and no thread list, new thread, fork, rollback or thread details card. `/` opens Buddy's one thread through the thread route, and a message sent during a turn steers it; queueing is the explicit alternative. In Buddy's bubble the surface speaks the frame's side of lazurio.buddy.* v1, written from the protocol's description: it says it is ready, keeps the last valid page context from its parent on the host's exact origin, and asks for its window's size from its header and on Escape, which asks for the panel unless a dialog, menu or list is open in the surface or something inside stopped the key (the editor marks every Escape as handled). A day in the pane turns off following the end first, as the timeline's minimap does, so the jump stays. In the bubble the surface wears the host page's appearance through T3's own appearance preference; where T3 cannot wear it (storage blocked, or a saved single-appearance theme), the document wears T3's standard palette in the host's appearance (request of 2026-10-25). The server holds the same for every client and agent. Decorators where it builds the orchestrator and the checkpoint store refuse forks, rollbacks, other threads and deleting Buddy's thread, and take no checkpoints in Buddy's project, which is the managed Folder's (T3CODE_LAZURIO_FOLDER=<Folder>/.agents/buddy) and else ~/Lazurio/.agents/buddy. A thread.create with Buddy's thread id passes only while Buddy's thread route makes the thread (MakingBuddysThread), so a client cannot spend the route's fixed command on a thread of its own. A startup phase before recovery turns off continuing threads after an update, the agent browser, and Codex and Claude, once, recorded in <state>/lazurio/buddy-surface.json so that later choices stay. `GET /api/lazurio/buddy/days` lists the conversation's days for the pane. The day lines and the day jump check Buddy mode once per timeline, for the timeline's own Environment, and the rows read it from the timeline's shared state, so no other Environment's timeline does that work or takes a jump. On v0.1.3 two web seams are rebuilt and one server refusal is added. - Upstream installs the chat route's shortcuts once at app start (pingdotgg#25366 removed ChatRouteGlobalShortcuts), so Buddy's condition joins their `when` in shortcuts/chatRouteCommands.ts: `isBuddySurfaceNow()` reads the primary server config from the app's atom registry when a key is pressed. Without it Shift+Mod+N on Buddy's surface would try a new thread that the server then refuses. - The timeline no longer takes onManualNavigation (pingdotgg#25463); the day jump is called below the timeline's own navigateTimeline and passes it, and the day line sits beside upstream's AudioPreviewUnmountContext (pingdotgg#21363). - Upstream's guest share of a thread (pingdotgg#24104) is refused in Buddy's T3 Code: thread.guest-share.open, .redeem and thread.guest-message.submit fail in the command guard, because Buddy's conversation belongs to a Personalspace, which is never shared (root decision 0091); closing a share stays possible. The root renders no GuestShareDialogHost on Buddy's surface. A test drives a guest share of Buddy's thread through the server's orchestrator. Settings and Usage are modals over the thread now (pingdotgg#24847); the prompt-link draft stays off Buddy's surface inside the rewritten ChatRouteLayout, and the first-run gate stays off on NEW's slimmer root. The guards are Effect.fn decorators (effectFnOpportunity), the two effects of BuddySurface.tsx carry justified react-effect-budget suppressions, and the file headers are cut to the four-line comment limit. Any other thread of Buddy's Environment, opened by a link or a typed address, leads to Buddy's thread as `/` does: the chat layout shows BuddySurfaceIndex, which asks the server for Buddy's thread and replaces the address, so that thread never renders under Buddy's presentation. A thread of another Environment stays T3's, and ChatView and the thread details ask about the thread's own Environment. A browser test opens such an address directly. On v0.1.4: the root keeps upstream's local-Environment switch beside the Buddy surface check (pingdotgg#26207); the timeline finds upstream's unmatched pending approvals (pingdotgg#26255) after the day lines and adds the day keys to upstream's list data next to its new footer. ThreadDetailsPanel no longer exports its props type (pingdotgg#26238), so Buddy's panel takes ComponentProps of it, and the effect suppressions use the renamed lint rule t3code/no-unreasoned-state-sync (pingdotgg#26161). The host appearance, which row 28's commit carried on v0.1.3, comes back to this row: T3 no longer re-applies its theme from useTheme's effect (pingdotgg#25007, pingdotgg#25461), so the stand-in follows every application of T3's saved theme through subscribeRenderedAppearance, and the theme tests apply T3's stored appearance as app start does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T3CODE_RELEASE_REPOSITORY (owner/name) selects whose GitHub Releases the release index, `t3 update`, the boot service, remote self-update and the install scripts use; unset, the Lazurio distribution installs and updates from Lazurio/t3code. A server run by the service launcher checks its own channel there at startup and every six hours (never when unmanaged, on preview builds, or with T3CODE_UPDATE_CHECK_ENABLED=false) and advertises a strictly newer release as `availableServerUpdate`. The index picks the highest version per channel, not the first one published. Once the launcher has committed this server's version, the server points the user's `t3` link at its own runtime, so the CLI and the server stay on one version after an in-app Update. On v0.1.3 the server, CLI and boot-service seams are unchanged (launcher protocol 3). Upstream removed the composer's "Server update available" notice (pingdotgg#25401) and now offers updates from the update button at the bottom of the sidebar and Settings -> Environments. The advertised release therefore moves onto that button: collectServerUpdateTargets takes a server's advertised release as its target (it is strictly newer by construction, so the version-core comparison, which ignores a fork's prerelease suffix, is skipped), and useUpdateEverything no longer holds such a target until it is on npm, because the release lives in the server's own channel. The composer keeps only the running/failed notice; its Retry targets the advertised version. The install scripts are rebuilt on upstream's new lookup (pingdotgg#22907): stable reads github.com/<repo>/releases/latest, the other trains page the API up to ten pages, and each answer is filtered by the runtime's train rule instead of upstream's narrow vX.Y.Z pattern, which rejects X.Y.Z-lazurio.N. install-scripts.test.ts now serves releases/latest (with its Accept header) and two API pages, and checks which URLs each train reads. Overlay comments are cut to the new four-line limit. On v0.1.4 the client no longer asks a server to continue its threads (continueRunningThreads is gone from the web, pingdotgg#26238): a server prepares the continuation itself on every graceful stop. The five web seams that passed the request along keep only the overlay's targetVersion. The update dialog shows one row per machine (pingdotgg#26210); a server whose target differs from the version in its header shows its own targetVersion (servers offer their channels' releases, stable or preview), and the dialog promises that threads may continue only to a server with the threadRestartContinuation capability from 0.0.46-0 (SHUTDOWN_CONTINUATION_SINCE in updateEverything.logic.ts), since older releases continued only on the client's request. watchAvailableServerUpdate gets FetchHttpClient.layer inside ServerEnvironment's make, so CLI commands that build the layer need no HTTP client of their own. That provision shadowed the test layer's HTTP client, so the guard of ServerEnvironment.test.ts now stubs FetchHttpClient.Fetch, lets the forked check run and expects no request from a web or desktop server; forcing managed: true makes it fail. releaseIndex.test's cases count the requests the same way, with a managed stable server as the case that does ask, so dropping the unmanaged early return fails them too. Upstream's own installer test (install.test.ts, pingdotgg#22490) now names pingdotgg/t3code in T3CODE_RELEASE_REPOSITORY, because its fixture serves upstream's repository; without it the installer asks for Lazurio/t3code and exits. The v0.1.3 line missed this because the fork CI ran only its fixed gate and changed tests, and install.test.ts was neither. The launcher protocol stays 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Launchpad's "+ Nový modul" opens Chat with #lazurio-prompt=<id>&lazurio-org=<login> in the fragment. main.tsx takes it off the address before the router reads it; once the primary environment is live, the text and project folder come from this origin's /.lazurio/prompts/<id>, and a new thread opens in that project (in a managed Environment, its Lazurio Folder project) with the text in the composer, never sent. Upstream's /new?prompt= links carry the text in the address, so the overlay keeps its own. The tab keeps only the id and the login across the pairing reload, never the text; it is taken once and expires after two minutes. On v0.1.3 the router, history and provider-auth delivery moved from main.tsx into startAppServices() in appInit.tsx (pingdotgg#25004), so the capture now runs on the line before `const router = startAppServices()`, still before any router exists; it now also runs before provider-auth delivery, which acts only on its own fragment. ChatRouteLayout was rewritten for Settings and Usage as modals over the thread (pingdotgg#24847); <LazurioPromptDraft /> is its first child and stays mounted while a modal is open. The component's one effect carries a justified react-effect-budget suppression and its comments are cut to four lines. It imports prefersCzech from row 9's threadTabs.ts and reads lazurioFolder from row 15's server config, so this row alone does not typecheck. On v0.1.4: upstream deleted lib/projectPaths.ts (pingdotgg#26238); the draft reads findProjectByPath and inferProjectTitleFromPath from @t3tools/client-runtime/state/projects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Root decision 0200, point 4: in the standard look the web client takes the design system's colours, type and radii from the --lz-* tokens the Environment's shell declares (LazurioPlatform F36). One file, apps/web/src/lazurio/theme.css, imported right after index.css in main.tsx; without the shell nothing matches. On v0.1.3 the row applies cleanly. main.tsx now imports the Inter font before index.css, and the theme import still follows index.css directly. index.css (pingdotgg#25323, pingdotgg#25251, pingdotgg#24865 and others) removed no token the file maps; it added guest and diff-icon tokens, which stay T3's. The default "New design" (pingdotgg#24865) maps none of these tokens in light mode; its dark-mode surfaces stay T3's, to be checked on canary for Environment themes with a dark variant. On v0.1.4: upstream removed the unused --update-surface token (pingdotgg#26238), so the mapping is gone; pingdotgg#25778 made the new design the only one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the bubble Root decision 0210, plan DEV-6676 (row 25). With T3CODE_LAZURIO_BUDDY=1 the web client is Buddy's surface: a header with Mattyčus, the conversation's days in a pane where the window has room and a date line above each day's first message, and no thread list, new thread, fork, rollback or thread details card. `/` opens Buddy's one thread through the thread route, and a message sent during a turn steers it; queueing is the explicit alternative. In Buddy's bubble the surface speaks the frame's side of lazurio.buddy.* v1, written from the protocol's description: it says it is ready, keeps the last valid page context from its parent on the host's exact origin, and asks for its window's size from its header and on Escape, which asks for the panel unless a dialog, menu or list is open in the surface or something inside stopped the key (the editor marks every Escape as handled). A day in the pane turns off following the end first, as the timeline's minimap does, so the jump stays. In the bubble the surface wears the host page's appearance through T3's own appearance preference; where T3 cannot wear it (storage blocked, or a saved single-appearance theme), the document wears T3's standard palette in the host's appearance (request of 2026-10-25). The server holds the same for every client and agent. Decorators where it builds the orchestrator and the checkpoint store refuse forks, rollbacks, other threads and deleting Buddy's thread, and take no checkpoints in Buddy's project, which is the managed Folder's (T3CODE_LAZURIO_FOLDER=<Folder>/.agents/buddy) and else ~/Lazurio/.agents/buddy. A thread.create with Buddy's thread id passes only while Buddy's thread route makes the thread (MakingBuddysThread), so a client cannot spend the route's fixed command on a thread of its own. A startup phase before recovery turns off continuing threads after an update, the agent browser, and Codex and Claude, once, recorded in <state>/lazurio/buddy-surface.json so that later choices stay. `GET /api/lazurio/buddy/days` lists the conversation's days for the pane. The day lines and the day jump check Buddy mode once per timeline, for the timeline's own Environment, and the rows read it from the timeline's shared state, so no other Environment's timeline does that work or takes a jump. On v0.1.3 two web seams are rebuilt and one server refusal is added. - Upstream installs the chat route's shortcuts once at app start (pingdotgg#25366 removed ChatRouteGlobalShortcuts), so Buddy's condition joins their `when` in shortcuts/chatRouteCommands.ts: `isBuddySurfaceNow()` reads the primary server config from the app's atom registry when a key is pressed. Without it Shift+Mod+N on Buddy's surface would try a new thread that the server then refuses. - The timeline no longer takes onManualNavigation (pingdotgg#25463); the day jump is called below the timeline's own navigateTimeline and passes it, and the day line sits beside upstream's AudioPreviewUnmountContext (pingdotgg#21363). - Upstream's guest share of a thread (pingdotgg#24104) is refused in Buddy's T3 Code: thread.guest-share.open, .redeem and thread.guest-message.submit fail in the command guard, because Buddy's conversation belongs to a Personalspace, which is never shared (root decision 0091); closing a share stays possible. The root renders no GuestShareDialogHost on Buddy's surface. A test drives a guest share of Buddy's thread through the server's orchestrator. Settings and Usage are modals over the thread now (pingdotgg#24847); the prompt-link draft stays off Buddy's surface inside the rewritten ChatRouteLayout, and the first-run gate stays off on NEW's slimmer root. The guards are Effect.fn decorators (effectFnOpportunity), the two effects of BuddySurface.tsx carry justified react-effect-budget suppressions, and the file headers are cut to the four-line comment limit. Any other thread of Buddy's Environment, opened by a link or a typed address, leads to Buddy's thread as `/` does: the chat layout shows BuddySurfaceIndex, which asks the server for Buddy's thread and replaces the address, so that thread never renders under Buddy's presentation. A thread of another Environment stays T3's, and ChatView and the thread details ask about the thread's own Environment. A browser test opens such an address directly. On v0.1.4: the root keeps upstream's local-Environment switch beside the Buddy surface check (pingdotgg#26207); the timeline finds upstream's unmatched pending approvals (pingdotgg#26255) after the day lines and adds the day keys to upstream's list data next to its new footer. ThreadDetailsPanel no longer exports its props type (pingdotgg#26238), so Buddy's panel takes ComponentProps of it, and the effect suppressions use the renamed lint rule t3code/no-unreasoned-state-sync (pingdotgg#26161). The host appearance, which row 28's commit carried on v0.1.3, comes back to this row: T3 no longer re-applies its theme from useTheme's effect (pingdotgg#25007, pingdotgg#25461), so the stand-in follows every application of T3's saved theme through subscribeRenderedAppearance, and the theme tests apply T3's stored appearance as app start does. Upstream's linked Environments (pingdotgg#16655, pingdotgg#16684, pingdotgg#17129) let a peer read and send into this server's threads; a Personalspace is never shared (0091), so withoutLinkedEnvironments reads linkedEnvironmentsEnabled as false in Buddy's T3 Code whatever is stored, which turns off every upstream gate that reads it (peer-link OAuth, a linked client's /mcp, outbound links, link requests, remote tasks). Every settings write through it also stores the switch off, the startup's Buddy defaults included, so a value stored before Buddy is read as off and the next settings write stores it off; `t3 environment link`, which builds its own settings (cli/environment.ts), takes the same guard, so a command run without T3CODE_LAZURIO_BUDDY reads what Buddy's server stored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the bubble Root decision 0210, plan DEV-6676 (row 25). With T3CODE_LAZURIO_BUDDY=1 the web client is Buddy's surface: a header with Mattyčus, the conversation's days in a pane where the window has room and a date line above each day's first message, and no thread list, new thread, fork, rollback or thread details card. `/` opens Buddy's one thread through the thread route, and a message sent during a turn steers it; queueing is the explicit alternative. In Buddy's bubble the surface speaks the frame's side of lazurio.buddy.* v1, written from the protocol's description: it says it is ready, keeps the last valid page context from its parent on the host's exact origin, and asks for its window's size from its header and on Escape, which asks for the panel unless a dialog, menu or list is open in the surface or something inside stopped the key (the editor marks every Escape as handled). A day in the pane turns off following the end first, as the timeline's minimap does, so the jump stays. In the bubble the surface wears the host page's appearance through T3's own appearance preference; where T3 cannot wear it (storage blocked, or a saved single-appearance theme), the document wears T3's standard palette in the host's appearance (request of 2026-10-25). The server holds the same for every client and agent. Decorators where it builds the orchestrator and the checkpoint store refuse forks, rollbacks, other threads and deleting Buddy's thread, and take no checkpoints in Buddy's project, which is the managed Folder's (T3CODE_LAZURIO_FOLDER=<Folder>/.agents/buddy) and else ~/Lazurio/.agents/buddy. A thread.create with Buddy's thread id passes only while Buddy's thread route makes the thread (MakingBuddysThread), so a client cannot spend the route's fixed command on a thread of its own. A startup phase before recovery turns off continuing threads after an update, the agent browser, and Codex and Claude, once, recorded in <state>/lazurio/buddy-surface.json so that later choices stay. `GET /api/lazurio/buddy/days` lists the conversation's days for the pane. The day lines and the day jump check Buddy mode once per timeline, for the timeline's own Environment, and the rows read it from the timeline's shared state, so no other Environment's timeline does that work or takes a jump. On v0.1.3 two web seams are rebuilt and one server refusal is added. - Upstream installs the chat route's shortcuts once at app start (pingdotgg#25366 removed ChatRouteGlobalShortcuts), so Buddy's condition joins their `when` in shortcuts/chatRouteCommands.ts: `isBuddySurfaceNow()` reads the primary server config from the app's atom registry when a key is pressed. Without it Shift+Mod+N on Buddy's surface would try a new thread that the server then refuses. - The timeline no longer takes onManualNavigation (pingdotgg#25463); the day jump is called below the timeline's own navigateTimeline and passes it, and the day line sits beside upstream's AudioPreviewUnmountContext (pingdotgg#21363). - Upstream's guest share of a thread (pingdotgg#24104) is refused in Buddy's T3 Code: thread.guest-share.open, .redeem and thread.guest-message.submit fail in the command guard, because Buddy's conversation belongs to a Personalspace, which is never shared (root decision 0091); closing a share stays possible. The root renders no GuestShareDialogHost on Buddy's surface. A test drives a guest share of Buddy's thread through the server's orchestrator. Settings and Usage are modals over the thread now (pingdotgg#24847); the prompt-link draft stays off Buddy's surface inside the rewritten ChatRouteLayout, and the first-run gate stays off on NEW's slimmer root. The guards are Effect.fn decorators (effectFnOpportunity), the two effects of BuddySurface.tsx carry justified react-effect-budget suppressions, and the file headers are cut to the four-line comment limit. Any other thread of Buddy's Environment, opened by a link or a typed address, leads to Buddy's thread as `/` does: the chat layout shows BuddySurfaceIndex, which asks the server for Buddy's thread and replaces the address, so that thread never renders under Buddy's presentation. A thread of another Environment stays T3's, and ChatView and the thread details ask about the thread's own Environment. A browser test opens such an address directly. On v0.1.4: the root keeps upstream's local-Environment switch beside the Buddy surface check (pingdotgg#26207); the timeline finds upstream's unmatched pending approvals (pingdotgg#26255) after the day lines and adds the day keys to upstream's list data next to its new footer. ThreadDetailsPanel no longer exports its props type (pingdotgg#26238), so Buddy's panel takes ComponentProps of it, and the effect suppressions use the renamed lint rule t3code/no-unreasoned-state-sync (pingdotgg#26161). The host appearance, which row 28's commit carried on v0.1.3, comes back to this row: T3 no longer re-applies its theme from useTheme's effect (pingdotgg#25007, pingdotgg#25461), so the stand-in follows every application of T3's saved theme through subscribeRenderedAppearance, and the theme tests apply T3's stored appearance as app start does. Upstream's linked Environments (pingdotgg#16655, pingdotgg#16684, pingdotgg#17129) let a peer read and send into this server's threads; a Personalspace is never shared (0091), so withoutLinkedEnvironments reads linkedEnvironmentsEnabled as false in Buddy's T3 Code whatever is stored, which turns off every upstream gate that reads it (peer-link OAuth, a linked client's /mcp, outbound links, link requests, remote tasks). Every settings write through it also stores the switch off, the startup's Buddy defaults included, so a value stored before Buddy is read as off and the next settings write stores it off; `t3 environment link`, which builds its own settings (cli/environment.ts), takes the same guard, so a command run without T3CODE_LAZURIO_BUDDY reads what Buddy's server stored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Another slop audit. A lot of this repo is code that nothing can reach: dead exports, code that only its own tests keep alive, client checks on capability flags that every protocol-2 server has always sent as
true, legacy paths for peers that can no longer connect, and fixtures the October test purge (#22557) left behind.This PR deletes the parts that need no product decision. Users see no change. About 18k lines net go, across 878 files, and 61 files are gone. It replaces #23984, which fell 581 commits behind; every item was proven again on current
main.What goes
trueon all 146 protocol-2 releases, and 2 were nevertrue. The server still sends every flag, because older app-store mobile builds read them. Where a check also waited for the server config, an explicit config check stays. With the checks go the legacy "context as text" send path, single-link PR mode, the client-side command-context fallback, the full-snapshot fallback, and per-update thread continuation.ProjectionStore.layerMemory), the whole unusedProviderRuntimeEventV2union, the OpenCode CLI inventory, the sidebar PR snapshot code, and the old mobile connection store.GitActionsControlmodes,ThreadLifecycleService, the second adapter-registry builder, props nobody passes, writes to columns nothing reads, and exports only their own file uses.acp-mock-agentflags no test sets, orphan native fixtures, and a fixture kit for a closed issue.useMemo/useCallbackcalls in files the React Compiler already compiles. Each removal was checked against the compiled output, so the value still comes from the compiler cache with the same deps. 168 stay, because removing them would change caching or identity.Review tip: hide whitespace. With whitespace hidden, the diff is +2,219 / -20,229.
Worth knowing
HardwareKeyboardCommandProvidercan show a stale command list until the route changes, because the compiler already dropsregistrationVersionfrom that cache onmain.Not in this PR (product calls or refactors): LegacySidebar, legacy Plan mode, OpenCode 1.x, the V1 importer, the 5 flags missing from early previews, package scripts maintainers run by hand, and merging logic web and mobile both carry.
Verification
vp run check:changedon the rebased commit: format, lint, knip, typecheck of 36 packages, and 5,167 tests in 375 files pass.nextQueuedRun, whichmainhad since changed to skip held runs (#17885);main's version and its call sites are kept. A new Codex test onmainused a testkit helper this branch moved; it now uses the shared one.Created with Claude Opus 5.5 in Claude Code, inside T3 Code. GPT-6.1 Sol in Codex started several slices before a provider outage; Claude Opus 5.5 finished them.
🤖 Generated with Claude Code