feat: render chat markdown links#41
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 51e7d264df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let without_fragment = without_scheme.split('#').next().unwrap_or(&without_scheme); | ||
| let without_query = without_fragment | ||
| .split('?') | ||
| .next() |
There was a problem hiding this comment.
Preserve literal '#' and '?' in non-URL file paths
The new sanitization in strip_file_path_metadata now unconditionally splits every incoming path on # and ?, even when the input is already a plain filesystem path rather than a file:// URL. On POSIX systems those characters are valid filename characters, so opening files such as notes#draft.md or query?plan.sql via open_path_in_target will resolve to the wrong truncated path and fail. This is a regression for existing callers (for example file-diff open actions) that pass raw repo paths.
Useful? React with 👍 / 👎.
| const EXTERNAL_SCHEME_PATTERN = /^([A-Za-z][A-Za-z0-9+.-]*):(.*)$/u; | ||
| const RELATIVE_PATH_PREFIX_PATTERN = /^(~\/|\.{1,2}\/)/u; | ||
| const RELATIVE_FILE_PATH_PATTERN = /^[A-Za-z0-9._@-]+(?:\/[A-Za-z0-9._@-]+)+(?::\d+){0,2}$/u; | ||
| const RELATIVE_FILE_NAME_PATTERN = /^[A-Za-z0-9._@-]+\.[A-Za-z0-9_-]+(?::\d+){0,2}$/u; |
There was a problem hiding this comment.
Avoid treating domain-like tokens as local file paths
The current filename heuristic accepts any dotted token (RELATIVE_FILE_NAME_PATTERN), so plain text like example.com is parsed as a local file and resolved to ${workspacePath}/example.com instead of being left as text or a URL. In chat output this creates false-positive clickable file links that attempt to open non-existent files, which is especially common when assistants mention hostnames without http://.
Useful? React with 👍 / 👎.
Summary
Add simple Markdown rendering for chat messages with robust URL and file-path link handling.
Context
Chat messages previously relied on plain text / filename-style parsing, which made Markdown output less readable and caused link handling to be inconsistent. External URLs need to open in the system browser, while file references should resolve reliably and open in the IDE or Finder/file manager without crashing on malformed URL-like input.
Changes
react-markdownandremark-gfm.~/paths, Windows drive/UNC paths,file://URLs, line/column suffixes, and#LxCyfragments.http/httpslinks to the system browser.Key Implementation Details
The link resolver borrows the defensive parts of t3code’s approach while keeping our UI simple: safe percent decoding, guarded
file://parsing, query/hash stripping, external-scheme rejection, POSIX root guardrails, and workspace-relative resolution. The backend opener now mirrors the same cleanup as a safety net before resolving paths against the workspace.Use Cases
https://github.com/...and clicking it opens the browser.src/components/chat/ChatMarkdown.tsx:42and clicking it opens the file in Cursor/Finder.[file](file:///Users/me/project/src/main.tsx#L12C4)resolve as file links instead of browser links.Testing
Validated locally with:
Manual verification should cover:
https://...andfile://...hrefs and confirm each opens through the correct path.