Skip to content

fix(web): prompt links work for encoded thread IDs - #32959

Open
unlockdigital wants to merge 1 commit into
pingdotgg:mainfrom
unlockdigital:fix/upstream-mcp-prompt-links-20261108
Open

unlockdigital wants to merge 1 commit into
pingdotgg:mainfrom
unlockdigital:fix/upstream-mcp-prompt-links-20261108

Conversation

@unlockdigital

Copy link
Copy Markdown

Problem

Opening an existing MCP thread's URL with ?prompt=hello leaves the composer empty and the prompt query in the URL. TanStack Router encodes an ID such as mcp:example as mcp%3Aexample, while isThreadRoutePathname compares the pathname with the raw ID, so the prompt effect skips the matching thread.

Change

Split the pathname into its two route segments and decode each once before comparing the environment and thread IDs. Extra path segments and malformed escapes return false. The regressions cover real router navigation, encoded slashes, a literal-percent ID, double encoding, and navigation away.

Scope and approval

This is a small, focused fix for an obvious bug under CONTRIBUTING.md: it restores the documented existing-thread prompt-link workflow. The route-ownership guard from #19326 still protects a thread during navigation away. The patch is limited to the helper and its existing test file. #19203 reuses the same helper for message links; this fixes the current prompt path independently.

Verification

  • From apps/web, vp test run --project unit src/threadRoutes.test.ts: the two encoded-route regressions fail against unchanged upstream ade473018d; all 12 tests pass with the fix. The router case asserts both the encoded pathname and its decoded parameters. Failing run, passing run.
  • vp run check:changed ade473018d32003658b7d38693e083ee2e314bd8 --concurrency 2 passes formatting, lint, both Knip checks, affected typechecks, the 12 tests, and the React compiler check. Check log.
  • Local web client on macOS, Node 26.12.1, isolated state and a stopped MCP thread created through the free Replay provider: before, an empty composer and retained ?prompt=hello; after, hello in the composer and the query removed. An existing draft stays intact until Replace draft is clicked. SPA navigation places another thread's linked prompt in that destination and preserves the original draft. Reproduction and URL-state transcript.

The captures compare initial upstream 20fcc6ca with that base plus this patch. Updating to ade473018d changes neither the two route files nor the prompt-link consumer; the automated red/green and changed-file checks above were rerun on the updated base.

Before

Before: the MCP conversation opens with an empty composer

After

After: the same conversation has hello in the composer

Local check setup: upstream's existing office-font alias uses URL.pathname, which leaves the space in this checkout path as %20 and prevents the root test runner from starting. The same startup failure reproduced on unchanged upstream. The passing check used a temporary filesystem alias, removed afterward; repository configuration is unchanged. Baseline startup failure.

Packaged desktop link dispatch, native mobile, and relay/tunnel connections were not exercised. The Browser recording endpoint failed, so the client evidence is raw screenshots plus the observed composer/URL states.

Implemented and verified with GPT-6.1 Sol (xhigh) through the Codex harness in T3 Code.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Nov 8, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at b8a544f

Macroscope's review found this PR approvable — Prompt links now recognize encoded environment and thread IDs while retaining strict route matching. The change only enables draft placement, with existing replacement confirmation and no automatic prompt submission.

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

@coderabbitai

coderabbitai Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

isThreadRoutePathname now compares decoded environment and thread path segments. Tests cover encoded IDs, malformed paths, extra segments, and memory-router navigation.

Changes: Thread route matching

Layer / File(s) Summary
Decoded pathname matching
apps/web/src/threadRoutes.ts, apps/web/src/threadRoutes.test.ts
The matcher decodes environment and thread segments before comparing them with the reference. It returns false for malformed encoding or paths with an unexpected structure. Tests cover encoded IDs and memory-router navigation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested labels: bugfix

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to b8a54

The change addresses encoded thread links, and no actionable merge-blocking risk remains in the supplied evidence.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title "fix(web): prompt links work for encoded thread IDs" names the main change. The changeset updates isThreadRoutePathname in apps/web/src/threadRoutes.ts so it splits the pathname into segment…
Description check Passed The description follows the repository template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section gives the bug, the expected behavior, and the cause. The Cha…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "fix(web): prompt links work for encoded thread IDs" names the main change. The changeset updates isThreadRoutePathname in apps/web/src/threadRoutes.ts so it splits the pathname into segments and decodes the environment and thread IDs before comparing them. That lets the prompt effect match threads whose IDs TanStack Router percent-encodes, such as mcp:example. The title is specific, follows conventional commit style, and fits the changed files and their summary.

Full details: Description check

Explanation

The description follows the repository template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section gives the bug, the expected behavior, and the cause. The Change section explains the decode-and-compare fix and the regression tests. The Scope section links CONTRIBUTING.md and the prompt-link docs, and it explains why the fix is small and focused. The Verification section lists the focused test run, the changed-files check, the manual client run, the before and after screenshots, and the checks that were not run. The template's optional agent-attribution line is present. Minor gaps: the Scope section does not link a triaged issue or a maintainer approval comment, and the description cites a fix for an obvious bug without a prior issue. The template allows that exemption when the author explains why the fix qualifies, which the author does.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between ade4730 and b8a544f.

Files selected for processing: 2

  • apps/web/src/threadRoutes.test.ts
  • apps/web/src/threadRoutes.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

@maria-rcks

maria-rcks commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified head b8a544f1191574137046a4ab152004ae7f76b11d on a linux boat vm using the real dev web app, repository playwright, /usr/bin/google-chrome, and codex gpt-6.1-sol through the local provider proxy. no mocks, replay, or fixtures. the project was added through the web ui; real mcp threads and provider turns were created through the running server.

  • reproduced on github/main at 7171fdd7716b05dc1b4be40c26ac78e8bb35f80c: the encoded mcp%3A... thread opens, but ?prompt=hello leaves the composer empty and remains in the url.
  • stopped main, started the exact pr head with isolated state, and opened the same app-created thread and prompt: hello appears in the composer and the prompt query disappears.
  • opening the link does not submit a turn. the server still reported one completed run until i clicked the web send button. a second linked prompt sent through that button reached codex and returned LINK_VERIFIED in the same thread.
  • existing drafts remain until clicking Replace draft. clicking a prompt link in another real codex reply opens the correct destination, preserves both drafts, and replaces only the destination after confirmation.
  • blacksmith: all 12 route tests passed. vp run check:changed ade473018d32003658b7d38693e083ee2e314bd8 --concurrency 2 passed format, lint, both knip checks, affected typechecks, route tests, and the react compiler check. git.cafe reported 31/31 ci checks successful. no source changes were needed.

before, main:

main: real codex reply with an empty composer after opening the prompt link

after, exact pr head and matching conversation:

pr: the same codex conversation has hello in the composer

existing draft stays until replace draft is clicked, then the linked prompt appears

command and observed-state transcript. inspected the captures and verified uploaded video playback and seeking in t3's player.

Not verified

packaged electron link dispatch, native ios/android, macos/windows, relay/tunnel connections, and other providers were not exercised on this linux vm. the changed helper is used by the web client; these checks prove the local web and real codex path. the first pr page load spent several minutes in vite's ChatView.tsx transform before rendering; subsequent verification completed without a ten-minute stall.

This branch has not been deployed

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

Labels

size:S 10-29 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.

2 participants