Skip to content

feat(desktop): open threads from deep links - #5071

Closed
danyeah wants to merge 3 commits into
pingdotgg:mainfrom
danyeah:feat/desktop-thread-deep-links
Closed

danyeah wants to merge 3 commits into
pingdotgg:mainfrom
danyeah:feat/desktop-thread-deep-links

Conversation

@danyeah

@danyeah danyeah commented Jul 31, 2026 •

Copy link
Copy Markdown

Problem

External applications can launch T3 Code through its existing URL scheme, but the desktop app cannot select the referenced thread. Integrations such as hardware controllers and notification actions can only focus the app, leaving the user to find the conversation manually.

Closes #4996.

What changed

  • Parse only t3code://threads/<environmentId>/<threadId> destinations, using t3code-dev in development.
  • Handle macOS open-url, initial process arguments, and Windows/Linux second-instance launches.
  • Buffer the latest destination until the backend, main window, preload bridge, and renderer are ready.
  • Reveal the main window and navigate through the existing typed /$environmentId/$threadId route.
  • Validate the IPC payload and safely ignore malformed or unsupported URLs.
  • Document the external desktop deep-link contract.

There are no server or authentication changes and no visual UI changes.

Verification

  • Targeted tests: 6 files, 80 tests passed.
  • Desktop, web, and contracts typechecks passed.
  • Targeted lint and formatting checks passed.
  • Manually verified on macOS that a deep link opens the exact existing thread.

Built with OpenAI Codex (GPT-5) in the Codex app.


Open in Devin Review

Note

Medium Risk
Changes desktop startup, single-instance, and window/IPC timing paths; routing uses existing thread routes with no server or auth changes, and coverage is strong in unit tests.

Overview
Adds end-to-end handling for t3code://threads/<environmentId>/<threadId> (and t3code-dev in development) so external apps can focus T3 Code and open a specific thread.

Ingress: strict URL parsing, macOS open-url captured at startup via a small buffer, initial process argv, and Windows/Linux second-instance command lines. Valid deep-link args are stripped on relaunch so updater-driven restarts do not re-navigate.

Delivery: lifecycle dispatches parsed targets to DesktopWindow.dispatchDeepLink, which keeps only the latest target until the backend is ready, the main window exists, and the renderer main frame has finished loading, then sends desktop:deep-link IPC and reveals the window. Preload validates payloads and exposes onDeepLink on desktopBridge.

Renderer: DesktopDeepLinkHost subscribes and **router.navigate**s to the existing /$environmentId/$threadId route. Contracts add DesktopDeepLinkTarget; user docs describe the external URL contract.

Reviewed by Cursor Bugbot for commit b196ead. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add thread deep-link support to the desktop app

  • Parses and validates <scheme>://threads/<environmentId>/<threadId> URLs into typed targets via parseDesktopDeepLink in DesktopDeepLink.ts
  • Captures macOS open-url events early at startup via a singleton buffer so no links are lost before the Effect runtime is ready
  • DesktopLifecycle dispatches deep links from initial argv, the macOS open-url buffer, and second-instance events to DesktopWindow
  • DesktopWindow queues the latest deep-link target and sends it over IPC only after the main window finishes loading, then reveals the window
  • DesktopDeepLinkHost.tsx subscribes to window.desktopBridge.onDeepLink in the renderer and navigates the router to the target thread route on receipt

Macroscope summarized b196ead.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3297e424-04c6-4fa8-b302-d005de34ae42

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 31, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (deep link handling via t3code:// URLs) with new IPC channels, lifecycle integrations, and navigation workflows. New features of this scope warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@gsimone

gsimone commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Human-side comment: This is my clanker's finding while trying to get the codex micro bridge I'm building to open threads via the agent keys.

Clanker comment for clankers

I pulled b196eadc078227c88d23dde8f808447c5a646d97 and tested this on macOS 26.0.1 / Apple Silicon with Electron 41.5.0, using an isolated copy of real local T3 thread data.

The running-instance path looks good:

  • A valid t3code-dev://threads/<environmentId>/<threadId> opened the exact immutable thread.
  • A query-bearing malformed link was ignored without changing the current route.
  • Two links delivered in quick succession deterministically left the second thread selected.
  • The parser, main/preload IPC validation, latest-target buffering, typed renderer navigation, and production/dev scheme separation all look appropriately scoped. I did not find a security or performance concern in those paths.

All CI runs successfully [sic]

There is one cold-start blocker. Starting the dev bundle with a valid URL present in argv does not leave the requested thread selected:

T3 Code (Dev) Launcher --remote-debugging-port=9333 \
  t3code-dev://threads/<environmentId>/<existingThreadId>

Observed evidence:

  1. ps showed the complete URL in the Electron process argv.
  2. desktop.lifecycle.register parsed it, and the trace recorded successful desktop.window.dispatchDeepLink plus later desktop.window.flushPendingDeepLink spans.
  3. After the backend and renderer finished booting, the renderer URL was t3code-dev://app/#/draft/<draftId>, not the requested thread.
  4. Sending the same URL to that now-running process immediately navigated to t3code-dev://app/#/<environmentId>/<existingThreadId>.

So parsing and macOS delivery work; the initial target is being lost or superseded during renderer/environment startup. The current tests mock lifecycle dispatch, window queuing, preload buffering, and route mapping independently, so they do not cover this end-to-end ordering race.

I recommend holding the initial target until the renderer/environment is ready to accept authoritative navigation (or making it the initial renderer route), then adding a cold-start integration test that boots on /, delivers the buffered target, completes environment bootstrap, and asserts the final route remains the requested thread. Happy to retest an updated commit against the same real-device bridge workflow.


@danyeah I think the suggested change can be stacked on this, imo it's not a crazy big blocker

@t3dotgg

t3dotgg commented Aug 28, 2026

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch sends only a thread ID through desktop IPC, which is ambiguous when the same ID exists on more than one server. #8246 includes both the environment and thread IDs and handles cold-start readiness.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Open a specific desktop thread via t3code://

3 participants