Fix desktop file link downloads - #55720
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for identifying the missing raw-file-link normalization; current main still has that gap: preprocessMarkdown() does not produce a #media: href, so MarkdownLink() cannot reach MediaAttachment (apps/desktop/src/lib/markdown-preprocess.ts:384-386, apps/desktop/src/components/assistant-ui/markdown-text.tsx:284-313).
Problems
- The new generic-file handler opens
mediaExternalUrl(path)(apps/desktop/src/components/assistant-ui/markdown-text.tsx:222in this PR). Current main deliberately routes remote media throughdownloadGatewayMediaFile()(:133-145) becausemediaExternalUrl()falls back to client-localfile://when a remote connection lacks a query token (apps/desktop/src/lib/media.remote.test.ts:72-75). This regresses remote OAuth/no-token downloads fixed by03406ae2553e. isAbsoluteFileHref()rejects extensionless absolute files such as[README](/tmp/README)at PRapps/desktop/src/lib/markdown-preprocess.ts:163.
Suggested changes
- Salvage the preprocessing conversion, but preserve current main's authenticated
useOpenMediaFile()path for generic files. - Treat slash-prefixed paths as absolute without an extension check, and cover both extensionless paths and remote no-token downloads.
Automated hermes-sweeper review.
| className="font-semibold text-foreground underline underline-offset-4 decoration-current/20 wrap-anywhere" | ||
| href="#" | ||
| onClick={event => { | ||
| event.preventDefault() |
There was a problem hiding this comment.
This bypasses current main's useOpenMediaFile() bridge. mediaExternalUrl() falls back to file:// when a remote connection lacks a query token, so remote OAuth sessions again target the client's filesystem. Keep the current authenticated downloadGatewayMediaFile() path here.
| return true | ||
| } | ||
|
|
||
| const clean = href.split(/[?#]/, 1)[0] || '' |
There was a problem hiding this comment.
This rejects valid extensionless absolute files such as [README](/tmp/README). The matcher already restricts this path to slash-prefixed hrefs, so accept that form directly and add a regression test.
What does this PR do?
Fixes Hermes Desktop handling for local file links returned in assistant messages. Streamdown blocks raw
file://markdown links, and remote desktop sessions need gateway-local files to open through Hermes' authenticated download endpoint rather than the client's local filesystem. This PR normalizes local file markdown links into Hermes media links before markdown rendering and renders generic files as immediateOpen <name>links.Related Issue
Related: #44523, #44538
Type of Change
Changes Made
apps/desktop/src/lib/markdown-preprocess.tsto rewrite local file links to#media:links before Streamdown blocks them.apps/desktop/src/components/assistant-ui/markdown-text.tsxso generic file media links open directly through the existing media download path.apps/desktop/src/components/assistant-ui/markdown-file-links.test.tsxcovering remote file-link downloads.How to Test
npm run test:ui --workspace apps/desktop -- src/components/assistant-ui/markdown-file-links.test.tsx src/components/assistant-ui/markdown-text.test.ts src/lib/media.remote.test.ts src/lib/chat-messages.test.tsnpm run typecheck --workspace apps/desktopapps/desktop:npx eslint src/components/assistant-ui/markdown-file-links.test.tsx src/components/assistant-ui/markdown-text.tsx src/lib/markdown-preprocess.tsChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AScreenshots / Logs
Focused desktop tests and typecheck pass. The full
npm run lint --workspace apps/desktop -- ...script still reports pre-existing unrelated lint errors inapps/desktop/electron/titlebar-overlay-width.cjs; the three changed files lint cleanly with direct ESLint fromapps/desktop.