Skip to content

feat(markdown): keep links to common desktop apps (obsidian://, vscode://, zoommtg://) (#1108) - #1118

Open
agegr wants to merge 1 commit into
mainfrom
feat/markdown-app-links
Open

agegr wants to merge 1 commit into
mainfrom
feat/markdown-app-links

Conversation

@agegr

@agegr agegr commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Links such as obsidian://open?vault=… lost their href and rendered as dead text in chat and in the file preview: the sanitize schema allowed only web, mail and file: links, and the URL transform strips the rest.

  • lib/markdown.ts: a fixed list of app schemes passes both the sanitizer (links only; images from them stay blocked) and a new markdownAppUrlTransform, used where no local-file handler is present. file: links keep their existing handling.
    • notes: obsidian, logseq, notion; editors: vscode, vscode-insiders, cursor, zed, jetbrains; meetings/chat: zoommtg, zoomus, msteams, slack
    • An allowlist rather than "any scheme but javascript:": the text comes from the model and from repository files, and OS handlers such as ms-msdt: and search-ms: have been exploited through clicked links. No setting or env var; more schemes can be added by PR.
  • components/MarkdownBody.tsx: app links open with target="_blank" rel="noopener noreferrer" like other chat links.
  • components/FileViewer.tsx: behaviour change — web and app links in the markdown preview now also open in a new tab; they used to replace Pi Web in the current tab. Relative, in-page (#…) and local-file links are unchanged.

Tests: lib/markdown.test.mjs (both pipelines, raw HTML links, blocked schemes javascript:, vbscript:, data:, blob:, ms-msdt:, search-ms:, intent:, unknown ones, images), components/MarkdownBody.test.mjs, components/FileViewer.test.mjs. tsc, eslint, npm test pass.

Closes #1108

🤖 Generated with Claude Code

…e://, zoommtg://) (#1108)

The sanitize schema allowed only web, mail and file: links, so links such as
obsidian://open?vault=... lost their href and rendered as dead text in chat
and in the file preview. A fixed list of note, editor and meeting app schemes
now passes both the schema and the URL transform. It is an allowlist rather
than "anything but javascript:" because the text comes from the model and
from repository files, and OS handlers such as ms-msdt: and search-ms: have
been exploited through clicked links.

These links open in a new tab with noopener/noreferrer like other external
chat links. The file preview now does the same for its web and app links,
which used to replace Pi Web in the current tab; relative, in-page and local
file links are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: allow external URL schemes (obsidian://, zoommtg://, ...) in the md preview

1 participant