Skip to content

feat(home): add Home, an agent that manages threads across your machines - #16

Merged
amartya18 merged 4 commits into
mainfrom
t3code/home-agent-main
Nov 6, 2026
Merged

amartya18 merged 4 commits into
mainfrom
t3code/home-agent-main

Conversation

@amartya18

@amartya18 amartya18 commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Why

You want Theo's Home agent (pingdotgg#15975) running on this fork's main, which is now upstream v0.1.7 plus the fork's own commits. That PR is based on Oct 5. The earlier port (#15) targets v0.1.6, dropped three features, and has bugs that keep Home from reaching other machines reliably.

Home is one agent thread on the desktop app. It can list, read, launch, message, and organize threads across every project and every connected machine, and it hears back when the threads it launched finish or need you. docs/internals/home.md and docs/user/home.md describe it.

What changed

Port. The Home commits from #15 are replayed onto main, with upstream winning wherever it conflicts. Home also moved to v0.1.7's SecureRandom and per-project provider checks.

Restored from #15's dropped list:

  • ⌘⇧0 / Ctrl+Shift+0 opens Home. main moved global shortcuts to shortcuts/commandPaletteCommands.ts, and feat(home): port Home agent onto stable v0.1.6 #15 never wired the handler there.
  • Home's messages show "Home" as the sender, even when Home's thread lives on another environment.
  • "Open thread" on such a message opens Home wherever it is loaded.

Bugs fixed:

  • Home could not reach other machines (McpToolAccess.routed). Since feat(server): agents use linked environments through any T3 tool pingdotgg/t3code#16684, main sends every tool that takes a linked environment through PeerForwarding and strips environmentId before the handler runs, so Home's relay was unreachable. A full-access peer link could also bypass Home's no-delete rule. Now, when Home names another environment:
    • Tools that route Home (HOME_ROUTED_TOOLS in homeRouting.ts) reach Home's routing.
    • Home's other linked-environment tools refuse.
    • delegate_task has its own environment field and is unchanged.
    • New rows in the McpToolAccess.test.ts linked-environment table fail on the previous commit.
  • One Home call could run two or three times on another machine. HomeRelay built a new consumer on every registration change, each with its own handled set, and consumers could outlive a reconnect. The second run failed with "failed during create-thread" even though the thread existed. The relay now keeps one consumer. Test in HomeFleetHost.browser.test.tsx.
  • Relayed calls failed or vanished around re-registration and bursts. The same window re-registering now keeps the calls it owes (FleetBroker.test.ts). A retried launch keeps its command id, so it replays (FleetService.test.ts). The relay stream publishes every request, where stream atoms used to keep only the last of a chunk, which could drop one of two parallel calls.
  • A long Home title could split an emoji in a link. Titles are now cut by code point (threadLinks.test.ts).
  • Watch reports looked like your own messages. They are sent as createdBy: "system", which the shared resolver left unattributed. They now show "Sent by T3 Code". Test in userMessage.test.ts.
  • Settings → Home said "No providers available" whenever the first enabled provider wasn't ready (for example, Codex enabled but not installed). It now uses isProviderInstancePickerReady, as the model pickers do. Upstream has the same bug.

Agent context. Home adds t3_environment_list and t3_thread_watch. mcpToolListJsonBytes goes from 47,538 to 49,060, hence the agent-context-increase label. I didn't run the paid evals for the new tool text.

Verification

  • vp run check:changed: format, lint, knip, typecheck (40 packages), and the React Compiler check pass, and all 843 tests in 53 files pass, browser tests included.
  • End to end, through T3's Browser panel against a desktop-mode dev server plus a second local server standing in for another machine:
    • Turned Home on with Haiku. Home listed environments and projects and launched a thread in a local project. The watch report woke it, and it summarized the result.
    • Launched threads on the second server through the browser relay, and got watch reports from there. The files were created on the second server.
    • A launch while the second server was offline returned environment_unavailable and created nothing.
    • Three parallel remote reads and one launch produced exactly four calls on the second server, all successful. Before the relay fix, launches ran up to three times.
    • Live relay consumers stay at 1 after a reconnect. Before the fix it was 3.
    • The palette's "Open Home", ⌘⇧0, the sidebar entry, Start fresh, and turning Home off (watches cleared, shortcut inert) all work on this rebased code. "Open thread" was checked before the rebase.
    • To drive Home from a browser, the test run skipped the isElectron gates on the settings page and the relay host, and allowed desktop mode in dev-runner. None of that is in this PR.
Before: Settings → Home with Codex enabled but not installed After
before after

Home after a watch report, with the report labeled "Sent by T3 Code":

Home watch report

Three parallel remote calls and a launch, with no errors:

Parallel remote calls

Image links are presigned and expire on 2026-11-12 or 2026-11-13.

Not covered

  • The real Electron window, and the macOS keep-alive when it closes.
  • Mobile, which has no Home labels, same as upstream.
  • Relay requests that arrive during a re-registration were tested by unit test only, not live.
  • Review. Three rounds with Claude Opus 5.5 found the peer-link bypass, the relay and retry bugs, and the emoji cut, all fixed. The last fix commit (5e27c54ca7) has tests and a live run but no review of its own. Left as is: delegate_task can still use a peer link, and Home's RPCs aren't in CLIENT_GUARDED_RPC_SCOPES (the server still enforces them, and the screen only renders on the desktop's own hub). No reviewer from another model family ran: GPT-5.6 Sol, Grok 4.7, and Gemini 4 Argon were unavailable on the Cursor plan.

Built with Claude Opus 5.5 in Claude Code, running in T3 Code.

🤖 Generated with Claude Code

@amartya18 amartya18 added the agent-context-increase Accepts measured growth in agent context label Nov 5, 2026
@amartya18
amartya18 marked this pull request as ready for review November 5, 2026 17:20
@amartya18

Copy link
Copy Markdown
Owner Author

Closed by the owner: superseded by #17 and the new fork release setup.

@amartya18 amartya18 closed this Nov 5, 2026
amartya18 and others added 4 commits November 6, 2026 01:04
Port pingdotgg#15975 onto the fork's main. Built from the v0.1.6
port (fork PR #15), replayed onto main with four conflicts resolved.

Restores what the v0.1.6 port dropped:
- mod+shift+0 opens Home (handler in shortcuts/commandPaletteCommands).
- Watch reports render as "Sent by T3 Code", not as the user's own message.
- Messages Home sent are labeled "Home" even when its thread lives on another
  environment, and "Open thread" opens it on the hub.

Fixes Home settings offering no model when the first enabled provider is not
ready (for example Codex enabled but not installed).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
… links

Main forwards every tool that takes a linked environment through PeerForwarding
and strips environmentId first, so Home's routing never saw the target. When
Home names another environment, the tools that route Home now reach its own
routing, and its other linked-environment tools refuse instead of using a peer
link. That also keeps a full-access peer link from bypassing Home's no-delete
rule. delegate_task keeps its own environment field and is unchanged.

Also from review: a watch report needs createdBy "system" to show as T3 Code,
and "Open thread" for a Home sender opens it in whichever environment has it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
HomeRelay built a new consumer atom whenever its registration changed. A
new consumer started with an empty handled set and an immediate read, and
consumers could stay live after a reconnect, so one Home call ran on the
other environment two or three times. Launches then failed with "failed
during create-thread" even though the thread was created.

The relay now keeps one consumer. A new registration rebuilds it through
an atom, and the handled set lives with the relay.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
From review of the relay fix:
- The same window re-registering no longer fails the calls it still owes.
  They move to its new queue, along with anything not yet delivered.
- A retried Home launch keeps its command id, so it replays instead of
  failing because the thread already exists.
- The relay stream publishes every request. Stream atoms keep only the last
  value of a chunk, which could drop one of two parallel calls.
- A long Home thread title is cut by code point, so it cannot split an emoji.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@amartya18 amartya18 reopened this Nov 5, 2026
@amartya18
amartya18 force-pushed the t3code/home-agent-main branch from d9365e6 to 5e27c54 Compare November 5, 2026 20:36
@amartya18
amartya18 merged commit 444d0ad into main Nov 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-context-increase Accepts measured growth in agent context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant