Skip to content

chore: delete 18k lines of code that nothing reaches - #26238

Merged
t3dotgg merged 1 commit into
mainfrom
t3/slop-cleanup-v2
Oct 28, 2026
Merged

t3dotgg merged 1 commit into
mainfrom
t3/slop-cleanup-v2

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Oct 28, 2026

Copy link
Copy Markdown
Member

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

  • Flag checks that can never fail. 26 capability flags are true on all 146 protocol-2 releases, and 2 were never true. 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.
  • API nobody calls. 11 WebSocket methods and 3 HTTP routes that no client calls today and no protocol-2 release ever called (all 142 tags checked).
  • Code only tests use. For example the in-memory copy of the SQL projection store (ProjectionStore.layerMemory), the whole unused ProviderRuntimeEventV2 union, the OpenCode CLI inventory, the sidebar PR snapshot code, and the old mobile connection store.
  • Dead code. Unreachable timeline branches and the checkpoint rollback chain, dead GitActionsControl modes, ThreadLifecycleService, the second adapter-registry builder, props nobody passes, writes to columns nothing reads, and exports only their own file uses.
  • DesktopBridge. Members marked optional "for older shells" are required now. The desktop window only loads its own bundled UI, and the preload defines every member.
  • Purge leftovers. Replay fixtures and recorder scenarios nothing reads, 55 acp-mock-agent flags no test sets, orphan native fixtures, and a fixture kit for a closed issue.
  • Mobile manual memos. 266 useMemo/useCallback calls 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.
  • Small stuff. Unreachable APNs remote-start code in the relay, two orphaned Expo 57 patches, unused deps and devDependency moves, unused marketing images, dead CSS, debug leftovers, and stale docs.

Review tip: hide whitespace. With whitespace hidden, the diff is +2,219 / -20,229.

Worth knowing

  • If the bounded thread snapshot ever returns a body that does not decode, the client now loads the thread over the socket instead of trying the full HTTP snapshot first. That fallback existed for servers without the bounded route; every protocol-2 server has it.
  • Old mobile file-cache folders from v0.0.28 and older are no longer migrated or cleaned up. Current readers already reject that data.
  • Found along the way, not changed here: on mobile, HardwareKeyboardCommandProvider can show a stale command list until the route changes, because the compiler already drops registrationVersion from that cache on main.

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:changed on the rebased commit: format, lint, knip, typecheck of 36 packages, and 5,167 tests in 375 files pass.
  • Each of the 12 slices passed its own checks and focused tests. An independent review read every added line and removed condition; its findings (a relay token-claim step, a config-loaded gate in settings sync, and the observability reference) are fixed here.
  • Rebasing found two semantic conflicts git did not flag. This branch inlined nextQueuedRun, which main had since changed to skip held runs (#17885); main's version and its call sites are kept. A new Codex test on main used 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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Oct 28, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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:

  • All code in this push has already been reviewed. Approvability was decided on eligibility alone.

No code changes detected at 2819196. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.3 KiB 1.3 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 21.6 KiB 21.6 KiB 0 B (0.0%) 24.4 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.1 KiB 5.0 KiB −6 B (−0.1%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.3 KiB 1.3 KiB −6 B (−0.5%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.9 KiB 21.9 KiB 0 B (0.0%) 24.4 KiB ✅
Claude Live turn messages 2 2 0 (0.0%) 8 ✅

Baseline: 3b2f958 · PR result: 2819196 · Source CI: success

Scenario and decoded snapshot size

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

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

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

@t3dotgg
t3dotgg force-pushed the t3/slop-cleanup-v2 branch 4 times, most recently from 96c615d to ed6e9d3 Compare October 28, 2026 02:15
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>
@t3dotgg
t3dotgg force-pushed the t3/slop-cleanup-v2 branch from ed6e9d3 to 2819196 Compare October 28, 2026 02:21
@t3dotgg
t3dotgg merged commit 67661cf into main Oct 28, 2026
33 checks passed
@t3dotgg
t3dotgg deleted the t3/slop-cleanup-v2 branch October 28, 2026 02:27
henrychu04 added a commit to henrychu04/t3code-coder that referenced this pull request Oct 28, 2026
Merge upstream/main 67661cf into coder-only (sync stage 4 of 4: pingdotgg#26238)
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Oct 28, 2026
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
aorwall added a commit to aorwall/t3code that referenced this pull request Oct 28, 2026
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>
aorwall added a commit to aorwall/t3code that referenced this pull request Oct 28, 2026
**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
vedprakash2302 added a commit to vedprakash2302/Cody that referenced this pull request Oct 28, 2026
- 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.
SketchPiece added a commit to SketchPiece/t3code that referenced this pull request Oct 28, 2026
…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>
xiaogwu pushed a commit to xiaogwu/t3code that referenced this pull request Oct 28, 2026
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 29, 2026
… 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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
… 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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
… 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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
… 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>
immakermatty added a commit to Lazurio/t3code that referenced this pull request Oct 30, 2026
… 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant