Skip to content

Share any HTML file from the editor and the remote preview - #27608

Merged
brennanb2025 merged 4 commits into
mainfrom
brennanb2025/share-any-html-file
Oct 12, 2026
Merged

brennanb2025 merged 4 commits into
mainfrom
brennanb2025/share-any-html-file

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​425 $\color{#cf222e}{\Huge{\mathbf{−}}}$​32 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​393
Prod 12 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​261 $\color{#cf222e}{\Huge{\mathbf{−}}}$​95 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​166

ELI5

Today you can share an HTML page as an artifact only from a local browser tab. This adds the same Share button to HTML files open in the editor and to the rendered HTML preview Orca uses for files on other hosts. It also makes every place that shares a file use the same link for it.

What Changed

The problem:

  • Editor: Share was offered only for Markdown, not for an .html file.
  • Remote HTML preview (how Orca renders an HTML file that lives on another host): had no Share at all.
  • One file could end up with several links. Each surface built its own "which file is this?" key. A Windows path spelled C:/repo/a.html in one place and C:\repo\a.html in another got two different links. Re-sharing from the other surface created a second artifact instead of updating the first.
  • Signing in during Share read the file twice. If the first publish needed you to sign in again, Orca re-read the file before retrying. Anything that changed in between went out instead of what you clicked Share on.

After:

  • Editor: an HTML file shows the existing Share button, just like a Markdown file. It shares what's in the editor, including unsaved edits, the same way Markdown does.
  • Remote HTML preview: the toolbar shows the same Share button once the page has loaded. It reads the page from the host the preview is showing it from. If the workspace later resolves to a different host, Share still reads from, and publishes under, the host the preview was opened against.
  • One link per file per host: the editor, the preview and a local browser tab all build the key the same way, so sharing from any of them updates the same link.
  • Sign-in retry: Share reads the file once per click, before signing in, and the retry publishes that same content.

Mechanism:

  • One key function (fileArtifactSourceKey(owner, filePath) in lib/file-artifact-source-key.ts). It keeps main's key formats: a plain path for local files, the CLI's key for SSH, ['editor', environment, host, path] for paired hosts, and 'remote' in place of the host when the tab never recorded one. Windows drive and network-share paths are always spelled with backslashes, using the rule the browser tab already used for file:// URLs. The editor, the preview and the local browser tab all call it.
  • Editor: builds the key from the host route its tab recorded when it opened the file. The editor's Markdown-only share code becomes general editor share code (markdown-artifact-upload.ts → editor-artifact-upload.ts). HTML is recognised by .html / .htm, so files that only highlight as HTML, like .jsp, aren't offered.
  • Preview: the grant handle (the preview's permission to read files from the host) now keeps the location it was minted for. Share reads through that location with the ordinary preview reader (readRuntimeFilePreview) and keys from the same location. It never looks the host up again.
  • Publish flow: createRequest() runs once per click, before account connect and the retry loop.

No main-process or host change: publishing already runs in the desktop's own process from the bytes the renderer hands it.

Why

This is the first step of STA-10097 / STA-10098: an HTML page an agent makes in chat should be a regular file that you can open, edit and share like any other. A follow-up PR moves chat HTML into the workspace and drops the separate chat-visual viewer. For that to include sharing on remote hosts, the regular HTML surfaces need Share and one shared key, which is this PR.

Alternatives considered:

  • A share path just for chat HTML. Rejected: one more chat-only special case, and HTML files unrelated to chat would stay unshareable on remote hosts.
  • Look up the preview's host again when Share is clicked. Rejected: if the workspace has moved to another host, that could read one host's file and publish it under another's link. Keeping the grant's own location means the read and the key always come from the host the preview was minted against.
  • Re-read the file after signing in (the previous behaviour). Rejected: the retry could publish content the user never chose to share.

Linked Issue

STA-10097, STA-10098 (Linear)

Visual Proof

Live check on the M4Air at head 745b0011590 (all three PRs together): a hidden, isolated dev build with real Claude, plus a second isolated Orca paired to it as a remote host.

An .html file open in the editor has Share in its header (the share icon left of the ... menu):

HTML file in the editor with Share

On a paired remote host, opening the file gives the HTML preview tab, and its toolbar has Share:

Remote HTML preview with Share

Remote HTML preview beside its source, with Share

On the remote host, Share showed the same popover as on the local machine. That rig had no Orca account and sharing was off, so the popover asked for both.
Not checked live: an actual publish (needs a signed-in account) and an SSH-owned preview.

Testing

  • Unit tests:

    • file-artifact-source-key.test.ts: the editor, the preview and a local browser tab produce the same key for the same file. Covers local, paired, SSH, Windows C:/ vs C:\, and the 'remote' fallback.
    • doc-preview-artifact-share.test.ts: the preview reads from the grant's server; an SSH grant keeps its connection id, so the read fails closed and never reads locally; binary and unreachable cases; Share appears only for HTML with a minted grant.
    • doc-preview-grants.test.ts: the handle keeps the minted location after the workspace resolves to another host, until the grant is released.
    • HtmlDocPreview.toolbar.test.tsx: the toolbar's Share uses the minted grant's location, not the host the workspace resolves to later.
    • artifact-publish-flow.test.ts: the request is built once, before sign-in, and the auth retry publishes that same request.
    • editor-artifact-upload.test.ts, EditorPanelHeader.test.tsx: which files are shareable, and the button shows for any shareable document, not on diffs.
  • Also passed: tc:web, oxlint, changed-code quality gates, and the rest of orca-ci-checks (its bun-based typecheck:ci can't run on this machine).

  • I manually tested these changes locally (editor and remote-preview Share, live on head 745b0011590; no publish, no account)

  • Automated tests added/updated, or explained why not below

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

HTML could only be shared as an artifact from a local file:// browser tab.
The editor offered Share only for Markdown, and the document preview that
renders HTML on SSH and paired hosts had no Share at all.

The editor now shares HTML files too, and the document preview's toolbar
gets the same Share button, reading the page from its owning host. Both use
one source key per file per host, so either surface finds the link the
other published.

Co-Authored-By: Claude <noreply@anthropic.com>
…rant's host

The editor, the rendered preview and a local browser tab each built their own
share key, so one file could publish to several links: a Windows path spelled
C:/ in one place and C:\ in another, and the preview keyed from whichever host
the workspace resolved to at render time, not the host it was reading from.

One key function now serves every surface, with main's formats (local path,
the CLI's SSH key, ['editor', env, host, path] with the 'remote' fallback) and
Windows drive/UNC paths spelled with backslashes.

The preview's grant handle keeps the location it was minted for. Share reads
the page through that location and keys from it, so a later host change can't
move either; an SSH grant keeps its connection id, so its read fails closed
instead of reading a local file.

Publishing prepares the request once per click, before sign-in and the auth
retry, so a retry publishes what the user clicked Share on.

Co-Authored-By: Claude <noreply@anthropic.com>
@brennanb2025
brennanb2025 marked this pull request as ready for review October 12, 2026 18:37
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: eaf6e376-e1d3-4e15-bed5-c294aa7ec832

📥 Commits

Reviewing files that changed from the base of the PR and between d0f49fe and 75abf71.


You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f27c9072-8086-48df-b3e8-40077bf0ff79

📥 Commits

Reviewing files that changed from the base of the PR and between 81337c4 and d0f49fe.


📒 Files selected for processing (3)
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-artifact-share.test.ts
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-artifact-share.tsx
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-share-key-parity.test.ts

🚧 Files skipped from review as they are similar to previous changes (2)
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-artifact-share.test.ts
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-artifact-share.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.



📝 Walkthrough

Walkthrough

The changes add shared source-key and path-canonicalization utilities for artifact requests. Editor sharing now supports Markdown and HTML content, and HTML document previews can offer sharing based on their retained grant location. The publish flow prepares a request once before account checks and reuses it for retry attempts.


Priority: ➖ Normal

Merge Risk: 🟡 Moderate · up to d0f49

Re-sharing an existing Windows file may leave its old public link stale, and sharing the same runtime file from the editor and preview may create separate links. Resolve or explicitly accept these link-identity risks before merging.

Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 32.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 28 functions across 19 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly identifies the primary change: adding HTML sharing from the editor and remote preview.
Description check Passed The description is complete and aligned with the template. It explains the user impact, implementation, rationale, linked issues, visual proof, testing, platform considerations, and known limitations.…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c5ae48c5-f21d-4290-821e-e6764770d0ea
📥 Commits

Reviewing files that changed from the base of the PR and between aa1eca1 and 81337c4.

📒 Files selected for processing (19)
  • src/renderer/src/components/artifacts/artifact-publish-flow.test.ts
  • src/renderer/src/components/artifacts/artifact-publish-flow.ts
  • src/renderer/src/components/browser-pane/describe-page/browser-artifact-upload.ts
  • src/renderer/src/components/browser-pane/workspace-doc/HtmlDocPreview.toolbar.test.tsx
  • src/renderer/src/components/browser-pane/workspace-doc/HtmlDocPreview.tsx
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-artifact-share.test.ts
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-artifact-share.tsx
  • src/renderer/src/components/browser-pane/workspace-doc/doc-preview-toolbar.tsx
  • src/renderer/src/components/editor/EditorPanel.tsx
  • src/renderer/src/components/editor/EditorPanelHeader.test.tsx
  • src/renderer/src/components/editor/EditorPanelHeader.tsx
  • src/renderer/src/components/editor/EditorPanelShell.tsx
  • src/renderer/src/components/editor/editor-artifact-upload.test.ts
  • src/renderer/src/components/editor/editor-artifact-upload.ts
  • src/renderer/src/components/editor/markdown-artifact-upload.ts
  • src/renderer/src/lib/doc-preview-grants.test.ts
  • src/renderer/src/lib/doc-preview-grants.ts
  • src/renderer/src/lib/file-artifact-source-key.test.ts
  • src/renderer/src/lib/file-artifact-source-key.ts
💤 Files with no reviewable changes (1)
  • src/renderer/src/components/editor/markdown-artifact-upload.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment on lines +14 to +16
return /^[A-Za-z]:[\\/]/.test(filePath) || /^[\\/]{2}/.test(filePath)
? filePath.replaceAll('/', '\\')
: filePath

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Preserve updates to existing Windows links.

If a Windows editor tab previously published with a forward-slash sourceKey, this conversion assigns the same file a new backslash key. Re-sharing then creates a second link instead of updating the existing link. The old public link retains stale content. Preserve or migrate the previous key when publishing these files. The PR description also identifies this compatibility case.

Comment on lines +32 to +38
if (owner.runtimeEnvironmentId || (owner.executionHostId && owner.executionHostId !== 'local')) {
return JSON.stringify([
'editor',
owner.runtimeEnvironmentId,
owner.executionHostId ?? 'remote',
path
])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use one key for legacy editor tabs and runtime previews.

When an editor tab has runtimeEnvironmentId: 'server-1' but no recorded route, this branch produces ["editor","server-1","remote",path]. A preview grant for that file on server-1 produces ["editor","server-1","runtime:server-1",path]. Sharing the two surfaces therefore creates separate links for the same file and host. Align the fallback with the preview identity while retaining a way to update links already published under the fallback key.

…orkspaces

A preview of an SSH workspace a paired server proxies mints its grant on that
SSH target, so it already keys the file the same way the editor does; the new
test locks that in. Also corrects the SSH read comment: the connection id is
kept because dropping it would read the path on this machine.

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

Copy link
Copy Markdown
Contributor Author

Review status (quick review loop, 2026-10-12)

The problem this PR fixes. Before it, only Markdown files had a Share button in the editor, and the HTML preview of a file on a remote workspace had none. Different surfaces also built the link's identity for the same file differently. A Windows path spelled C:/… and the same path spelled C:\… counted as two files, and some surfaces ignored which host the file lives on. So sharing one file from two places could create two separate links.

What changes for you. Any HTML file can be shared from the editor header and from the remote HTML preview. Every surface (editor, preview, browser tab, and the chat visual in #27634) gives one file on one host the same link, so sharing it again updates that link instead of creating a new one. The preview shares the file from the host its preview was opened on, even if the selected host changes later. One visible difference: a Windows file previously shared under a C:/… spelling gets a new link the first time it is shared again.

This round. Fresh reviewers went through the whole diff, and one architecture pass covered all three stacked PRs. Then a readiness check ran on the final diff.

  • Fixed in d0f49fe3228:
    • A code comment wrongly said the SSH read is refused; it now gives the real reason the connection id is kept.
    • A new test pins that the preview and the editor give the same link for an SSH workspace that a paired server reaches for you.
  • Checked and refuted: the concern that the preview and the editor could give different links for such a workspace. A test with no mocks shows they already match, because the preview's access to the file is set up through the SSH connection first.
  • Deferred (small, narrow):
    • After clicking a link to another page inside the preview, Share still publishes the page the preview opened on. The toolbar's path, Copy path and Open source also name that first page, so the bar is consistent about what Share publishes.
    • Share is offered on a preview that failed to load; clicking it says "Orca couldn't read this file. Open it from a workspace and try again." On current main this covers every preview of a file on an SSH connection, because main no longer reads SSH files on the desktop. Nothing is read locally or published; the message is just misleading. A one-line follow-up can hide Share whenever the preview failed to load, the same rule that already disables markup there.

Verified.

  • Targeted tests: 69/69.
  • Web typecheck passes and the code-quality gate is clean.
  • The repo's CI checks pass locally, apart from the known local-only typecheck:ci failure.
  • The branch merges onto current main with no conflicts, and the web typecheck plus the targeted tests pass on that merged tree.
  • Earlier live QA on a paired host showed Share in the remote file's editor header and HTML preview (screenshots in the body).

Not verified.

@brennanb2025
brennanb2025 merged commit f89d51b into main Oct 12, 2026
30 checks passed
OrcaWin added a commit that referenced this pull request Oct 12, 2026
…#28110)

HtmlDocPreview.tsx reached 403 lines on main (#27608 + #27875), over the
400-line limit for .tsx, so lint and the pre-commit hook fail on any
branch that merges main. The focus handoff effect moves unchanged into
use-doc-preview-guest-focus.ts.

Co-authored-by: Orca Worker <orca-worker@localhost>
brennanb2025 pushed a commit that referenced this pull request Oct 15, 2026
…#28110)

HtmlDocPreview.tsx reached 403 lines on main (#27608 + #27875), over the
400-line limit for .tsx, so lint and the pre-commit hook fail on any
branch that merges main. The focus handoff effect moves unchanged into
use-doc-preview-guest-focus.ts.

Co-authored-by: Orca Worker <orca-worker@localhost>
(cherry picked from commit 5e83ca0)
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.

1 participant