Skip to content

fix(web): open markdown file links that climb out of the workspace - #16770

Closed
macodev00 wants to merge 1 commit into
pingdotgg:mainfrom
macodev00:cursor/file-link-dotdot-redo1-b3e1
Closed

macodev00 wants to merge 1 commit into
pingdotgg:mainfrom
macodev00:cursor/file-link-dotdot-redo1-b3e1

Conversation

@macodev00

Copy link
Copy Markdown
Contributor

What Changed

Markdown file links collapse . and .. lexically in resolveMarkdownFileLinkTarget, after ~/ expansion and before the workspace-membership check. resolvePathLinkTarget is unchanged, so terminal, Git, preview, and file-manager links are untouched. A link that lands outside the workspace becomes an absolute host path. An in-workspace link such as docs/guide/../readme.md stays a workspace file. POSIX /, drive roots (C:\, C:/), backslash UNC (\\server\share), and forward-slash UNC (//server/share) stay intact, and .. does not climb above them. :line and :line:column suffixes are preserved. The server still rejects escaping relative paths. apps/mobile is unchanged.

Why

A relative markdown link such as ../other/notes.md was joined onto the workspace root and left .. in the string. Membership treated /…/project/../other/notes.md as the workspace-relative path ../other/notes.md, and the server rejected it. Absolute and ~/ forms of the same file already opened as host files.

Fixes #16354. This supersedes #16754, which was rejected because it normalized paths inside the shared resolver and collapsed //server/share/dir/../file.md to /server/share/file.md.

Verification

  • Base: upstream/main 655dfbe8ba87f0f9ef1d6fad83c20634634653aa
  • Head: 83dfa3b0659d420e0e0a9ee4bd4fd5f1822fb73c
  • Platform: Linux 6.12.94+ x86_64, Node v24.13.1

Commands and results:

  • vp test run apps/web/src/terminal-links.test.ts apps/web/src/markdown-links.test.ts — 2 files, 101 tests passed
  • vp run --filter @t3tools/web typecheck — exit 0
  • vp run --filter @t3tools/web test — 458 files, 6162 tests passed (108.68s)
  • vp run knip:check — exit 0
  • vp check — all 5061 files formatted; 0 errors and 894 warnings in 4850 files (warnings pre-existing)

Manual check: workspace /tmp/fx/project, sibling file /tmp/fx/other/notes.md, and links.md with [notes.md](../other/notes.md) plus in-workspace [readme.md](docs/guide/../readme.md). Opened links.md in the Files panel rendered markdown preview, hovered the notes.md chip, then clicked it. Before: tooltip /tmp/fx/project/../other/notes.md; click shows breadcrumbs project / .. / other / notes.md and “The requested path is outside the workspace.” That sentence is the preview panel’s mapping of the server workspace_path_outside_root rejection, whose raw message is Failed to read workspace file '../other/notes.md' in '/tmp/fx/project'. After: tooltip /tmp/fx/other/notes.md; click opens the host file, breadcrumbs tmp / fx / other / notes.md, heading SIBLING_NOTES_OUTSIDE_WORKSPACE.

Surfaces: web Files preview (desktop uses the same web UI). Mobile, providers, and contracts were left alone.

Limitations: collapse is lexical and does not follow symlinks; an incomplete UNC path such as //server/../file.md is left unchanged; this was not run on Windows.

UI Changes

Before

before: 01-rendered-link

before: 02-tooltip-path

before: 03-after-click

before recording

[before.mp4 (download)](https://raw.githubusercontent.com/macodev00/t3code/9a069c6f43588df151703253e43e11b8e557e4ac/issue-16354/before/recording.mp4)

After

after: 01-rendered-link

after: 02-tooltip-path

after: 03-after-click

after recording

[after.mp4 (download)](https://raw.githubusercontent.com/macodev00/t3code/9a069c6f43588df151703253e43e11b8e557e4ac/issue-16354/after/recording.mp4)

Checklist

  • One problem: markdown .. links outside the workspace fail to open
  • Collapse is limited to markdown file-link membership; shared resolvePathLinkTarget is unchanged
  • POSIX, drive, \\server\share, and //server/share roots stay intact
  • Server still rejects escaping relative paths; mobile untouched
  • Focused tests, web typecheck, web test suite, vp run knip:check, and vp check passed
  • Before/after screenshots and hover-click recordings linked above
  • Supersedes fix(web): open file links that climb out of the workspace #16754

A relative link such as ../other/notes.md was joined onto the workspace
root and left .. in the path. Workspace membership treated that string as
a project file, and the server rejected the escaping relative path.

Collapse . and .. lexically on markdown file links only, after ~/ expansion
and before the membership check, so a link outside the workspace opens as
a host file. Roots stay intact, including //server/share.
@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 Oct 7, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR changes production markdown-link resolution and adds substantial cross-platform path normalization for workspace and host-file targets. Although the scope is focused and well tested, the bespoke handling of POSIX, Windows, UNC, home, and position-suffix paths is complex enough to merit human review.

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

@coderabbitai

coderabbitai Bot commented Oct 7, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 20dc280f-49b6-4da4-aeb8-66193aeef440
📥 Commits

Reviewing files that changed from the base of the PR and between b77108b and 83dfa3b.

📒 Files selected for processing (4)
  • apps/web/src/markdown-links.test.ts
  • apps/web/src/markdown-links.ts
  • apps/web/src/terminal-links.test.ts
  • apps/web/src/terminal-links.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.


📝 Walkthrough

Walkthrough

Markdown file-link resolution now collapses lexical . and .. segments before checking workspace membership. The change adds a path-normalization helper and tests for workspace, host, and rooted paths.

Changes

File Link Path Resolution

Layer / File(s) Summary
Lexical path normalization
apps/web/src/terminal-links.ts, apps/web/src/terminal-links.test.ts
Adds collapseLexicalDotSegments to collapse . and .. while preserving roots, separators, trailing separators, and line or column suffixes. Tests cover POSIX, drive, home, UNC, and relative paths.
Markdown link resolution
apps/web/src/markdown-links.ts, apps/web/src/markdown-links.test.ts
Applies lexical normalization to Markdown targets before workspace membership is determined. Tests cover links resolving inside and outside the workspace, including home expansion and position suffixes.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 83dfa

Outside-workspace Markdown links can open as host files, and no actionable issue remains that would prevent merging after normal checks.

Architecture Summary

Architecture risk: 🟡 Medium · up to 83dfa

The change affects 1 system.

Changed systems: apps/web

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — apps/web (ui) was modified; 4 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/web/src/markdown-links.test.ts: Added expectations that parent-relative links resolving outside the workspace produce host-file paths with no workspace-relative path, including links passed through resolveInlineCodeFileLinkMeta and paths containing explicit parent segments.
  • observed — Modified behavior in apps/web/src/markdown-links.test.ts: Added cases confirming that parent segments collapsing within the workspace resolve to normalized paths and retain workspace-relative paths, including resolution from a separate containing directory.
  • observed — Modified behavior in apps/web/src/markdown-links.test.ts: Added cases confirming line and column suffixes survive path normalization for both outside-workspace parent links and in-workspace collapsed paths.
  • observed — Modified behavior in apps/web/src/markdown-links.test.ts: Added cases confirming home-directory expansion occurs before parent-segment collapse, on POSIX and Windows paths, with outside-workspace paths remaining non-relative to the workspace.

Reliability and maintainability

  • inferred — Risk-relevant change factors for apps/web: blast_radius_1; direct_dependents_1
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: Markdown file links that climb out of the workspace can open.
Description check ✅ Passed The description explains the problem and change, identifies the scope, links issue #16354, and gives detailed test results and before-and-after UI evidence. It does not explicitly state that the issue…
Linked Issues check ✅ Passed Issue #16354 requires parent-relative Markdown and inline-code file links to open files outside the workspace, while links that remain inside continue to use workspace-relative paths. `resolveMarkdown…
Out of Scope Changes check ✅ Passed The changes support issue #16354. collapseLexicalDotSegments is used only by the Markdown file-link resolver; resolvePathLinkTarget behavior remains unchanged. Its tests cover the path forms neede…
Approvability ✅ Passed This is a focused Markdown file-link bug fix. The pull request changes only four files under apps/web/src: the resolver, the lexical path helper, and their tests. The diff does not change a product …
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@macodev00

Copy link
Copy Markdown
Contributor Author

Superseded; redoing from scratch.

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.

[Bug]: A file link with ../ to a file outside the workspace fails to open

1 participant