Repository navigation
fix(extensions): open status and widget links in a new tab - #1377
Conversation
An OSC 8 hyperlink in an extension status, widget or custom panel rendered as a plain anchor, so clicking a preview link navigated the Pi Web tab away from its session. They now open in a new tab, like links in chat Markdown. Fixes agegr#1374 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Opening all links in a new tab works for my use case—thanks for the fix! I can imagine an extension linking to another session within Pi Web, where staying in the same tab might be preferable. But that’s hypothetical, not a requirement from me, so I’m happy with the simpler approach. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks. I checked ansi_up 6.0.6's source. It only emits anchors for http/https (a scheme allowlist), and it HTML-escapes both the URL and the text, so any I pushed one commit that mirrors the change into |
Fixes #1374
Problem
An extension that shows a link through
ctx.ui.setStatus()(or a widget / custom panel) with an OSC 8 hyperlink renders it as a plain<a href>. Clicking it navigates the Pi Web tab away from the session. On a phone or tablet there is no modifier-click to avoid that.Reproduce on
mainAdd a global extension, e.g.
~/.pi/agent/extensions/status-link.js:Open a session and send anything that starts its runtime (
!trueis enough).The status bar shows
Preview: example.com. Its DOM is<a href="https://example.com/">example.com</a>, and clicking it replaces the Pi Web page.Cause
components/AnsiText.tsxreturnsansi_up's HTML as is, andansi_upemits OSC 8 links without atarget. Chat Markdown already opens such links withtarget="_blank" rel="noopener noreferrer"(components/MarkdownBody.tsx), so the two kinds of links behaved differently.Fix
AnsiTextaddstarget="_blank" rel="noopener noreferrer"to the anchorsansi_upproduces. This covers the status bar, widgets and custom panels, which all render throughAnsiText. It is safe to do on the string:ansi_upescapes HTML in the text, so<a href="can only come from its own hyperlink output, and it only emitshttp/httpslinks.The issue suggested keeping same-host links in the current tab. I kept one rule for all of them instead, the same rule chat Markdown uses for absolute links, so a link behaves the same wherever pi shows it. Happy to change that if you prefer the host check.
Checks
components/AnsiText.test.mjs: an OSC 8 link gets the new-tab attributes, and link-like text stays escaped.npm test(2871 passed, 0 failed),node_modules/.bin/tsc --noEmit,npm run lint.docs/agents/sessions.md.🤖 Generated with Claude Code