Skip to content

Preserve disconnected terminal output and add recovery actions - #20726

Merged
Mitch Denny (mitchdenny) merged 23 commits into
mainfrom
mitchdenny-terminal-disconnect-treatment
Oct 17, 2026
Merged

Mitch Denny (mitchdenny) merged 23 commits into
mainfrom
mitchdenny-terminal-disconnect-treatment

Conversation

@mitchdenny

@mitchdenny Mitch Denny (mitchdenny) commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Description

Keep the last terminal screen visible when a workload exits or the connection drops, rather than clearing the output. Retained output includes text and Sixel/Kitty graphics, with a disconnect banner explaining what happened and how to recover.

  • Resource terminals: restart/start the owning resource through its advertised command, with existing confirmation and read-only checks. Include the exit code when the resource protocol reports one. Successful recovery reconnects the view even after automatic retries have been exhausted.
  • Docked terminals: close the owning tab without losing control of adjacent tabs.
  • Show terminal: collapse the banner into an inset top-right disconnect icon to uncover the retained screen. Click the icon to reopen recovery actions. The redundant bottom-right disconnected popup is suppressed; unrelated errors remain visible.

Uses stable Hex1b 0.173.0 across NuGet, npm, the vendored browser assets, and tool/MCP pins. NuGet packages are available through the approved internal feed; no temporary external restore source or Windows-helper copy workaround remains.

Screenshots / Recordings

Resource terminal — disconnected output and graphics remain visible, with Restart resource and Show terminal actions:

Resource terminal retaining its final output and graphics with recovery actions

Resource terminal — Show terminal collapses recovery to the padded floating icon:

Resource terminal with the recovery banner collapsed into a top-right icon

Redis REPL — Ctrl+C disconnects the docked terminal, offering Close tab and Show terminal:

Disconnected Redis REPL with Close tab and Show terminal actions

Redis REPL — collapsed recovery leaves the final PING/PONG output unobstructed:

Redis final PING and PONG output retained with a floating disconnect icon

Shell prompt identities are redacted. These captures illustrate the disconnect/recovery controls; resource messages additionally show a reported exit code when available.

User-facing usage

Run playground/Terminals, exit the shell resource, and use Restart resource to reconnect. Open Redis's REPL in the dock and send Ctrl+C, then use Show terminal to uncover its final output or Close tab to dismiss it.

Implementation

The browser retains its existing renderer through transport retries until a replacement receives its first frame. The backend drains the final browser-mirror frame before closing and gates recycled-terminal handshakes on producer reconnection, preventing an empty relay from replacing retained output. Explicit resource recovery resets the retry budget without weakening ordinary terminal-completion handling.

Regression coverage includes completion-before-mount races, restart after retry exhaustion, command outcomes, resource updates during command execution, and package pairing. Tool/MCP manifest changes explicitly select the Infrastructure.Tests consistency checks.

Validation

  • node --test tests/Aspire.Dashboard.Components.Tests/JavaScript/TerminalView.test.mjs — passed, 136 tests.
  • MSBUILDTERMINALLOGGER=false dotnet test --project tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj --no-launch-profile -- --filter-class '*Terminal*' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — passed, 269 tests.
  • MSBUILDTERMINALLOGGER=false dotnet test --project tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj --no-launch-profile -- --filter-class '*.DashboardCommandExecutorTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — passed, 8 tests.
  • MSBUILDTERMINALLOGGER=false dotnet test --project tests/Infrastructure.Tests/Infrastructure.Tests.csproj --no-launch-profile -- --filter-class 'Infrastructure.Tests.TestTriggerMap.*' --filter-class '*.DashboardTerminalScriptTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — passed, 298 tests.
  • From src/Aspire.Dashboard, npm run update-terminal-assets — passed; regenerated and verified stable 0.173.0 assets.
  • MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Managed/Aspire.Managed.csproj -v:minimal — passed with stable 0.173.0, zero warnings/errors and normal Windows helper copying.
  • MSBUILDTERMINALLOGGER=false dotnet restore src/Aspire.Managed/Aspire.Managed.csproj --force --no-http-cache -v:quiet — passed after removing the temporary external source. All three 0.173.0 package archives were separately downloaded and verified directly from dotnet-public.
  • MSBUILDTERMINALLOGGER=false dotnet build /t:UpdateXlf src/Aspire.Dashboard/Aspire.Dashboard.csproj — passed; localization files regenerated.
  • Earlier backend verification with the preceding alpha: MSBUILDTERMINALLOGGER=false dotnet test --project tests/Aspire.TerminalHost.Tests/Aspire.TerminalHost.Tests.csproj --no-launch-profile -- --filter-class '*.TerminalHostAppTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — passed, 25 tests; MSBUILDTERMINALLOGGER=false dotnet test --project tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj --no-launch-profile -- --filter-namespace 'Aspire.Dashboard.Tests.Terminal' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — passed, 112 tests.
  • Earlier live Chromium verification with the preceding alpha covered shell exit with retained text/Kitty/Sixel graphics, failed reconnect retention, resource restart, watch-driven dock closure, collapse/focus behavior, and Redis Ctrl+C. The later exit-code and review fixes have automated coverage above, but were not reverified live.

Known limitations

  • Hex1b 0.173.0 does not support offline selection/copy. Collapsing the banner uncovers retained output but does not enable disconnected selection; upstream support is a separate follow-up.
  • Docked-terminal completion does not currently expose a workload exit code through the pinned adapter/protocol. Missing codes remain unspecified; the last shell-command status is not substituted for process completion.

Security considerations

Retained output can contain sensitive workload data and remains visible until the view is closed or replaced. Existing dashboard authentication and resource-command confirmation/read-only checks remain in force. This change does not add a network endpoint or bypass command authorization. NuGet dependencies use approved internal feeds. No threat model or security review has been completed for this change.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 20726

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 20726"

@github-actions

This comment has been minimized.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The unapproved restore feed, concurrent resource enumeration, and missing test-input routing remain unresolved.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

Preserves disconnected terminal output in the Aspire dashboard and adds recovery controls without replacing the retained screen.

Changes:

  • Retains text and graphics through disconnects and failed retries.
  • Adds localized restart, close-tab, and collapsible recovery controls.
  • Updates paired Hex1b dependencies and adds lifecycle regression coverage.
File Description
tests/​Aspire.TerminalHost.Tests/​TerminalHostAppTests.cs Tests producer-gated viewer handshakes.
tests/​Aspire.Dashboard.Tests/​Terminal/​TerminalWebSocketTests.cs Tests final-frame draining.
tests/​Aspire.Dashboard.Components.Tests/​Shared/​TerminalSetupHelpers.cs Registers command execution support.
tests/​Aspire.Dashboard.Components.Tests/​Layout/​TerminalDockTests.cs Tests disconnected-tab closure.
tests/​Aspire.Dashboard.Components.Tests/​JavaScript/​TerminalView.test.mjs Tests retention, retries, and package pairing.
tests/​Aspire.Dashboard.Components.Tests/​Controls/​TerminalViewTests.cs Tests disconnect and collapse states.
tests/​Aspire.Dashboard.Components.Tests/​Controls/​TerminalDisconnectedBannerTests.cs Tests recovery actions and availability.
src/​Aspire.TerminalHost/​TerminalReplica.cs Passes producer readiness to listeners.
src/​Aspire.TerminalHost/​Hmp1UdsServerListenerFilter.cs Defers handshakes until producer connection.
src/​Aspire.TerminalHost/​DcpUpstreamAdapter.cs Exposes producer connection completion.
src/​Aspire.Dashboard/​wwwroot/​js/​README.md Documents dependency and retention changes.
src/​Aspire.Dashboard/​Terminal/​TerminalWebSocketProxy.cs Runs and drains the terminal mirror.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.zh-Hant.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.zh-Hans.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.tr.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.ru.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.pt-BR.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.pl.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.ko.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.ja.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.it.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.fr.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.es.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.de.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​xlf/​TerminalStrings.cs.xlf Adds recovery localization entries.
src/​Aspire.Dashboard/​Resources/​TerminalStrings.resx Defines recovery labels and messages.
src/​Aspire.Dashboard/​Resources/​TerminalStrings.Designer.cs Exposes new resource strings.
src/​Aspire.Dashboard/​package.json Updates the browser dependency.
src/​Aspire.Dashboard/​package-lock.json Locks the matching browser package.
src/​Aspire.Dashboard/​Components/​Layout/​TerminalDock.razor Connects recovery to tab closure.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor.js Retains disconnected renderers through retries.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor.css Styles disconnected output and overlays.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor.cs Tracks disconnect and collapse state.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor Displays recovery controls and errors.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalDisconnectedBanner.razor.css Styles the banner and collapsed icon.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalDisconnectedBanner.razor.cs Implements resource recovery and subscriptions.
src/​Aspire.Dashboard/​Components/​Controls/​TerminalDisconnectedBanner.razor Renders localized recovery actions.
NuGet.config Adds temporary Hex1b restore mappings.
docs/​specs/​with-terminal.md Documents retention and recovery behavior.
Directory.Packages.props Updates paired Hex1b packages.
.mcp.json Updates the Hex1b MCP pin.
.config/​dotnet-tools.json Updates the local Hex1b tool.
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file

Comment thread NuGet.config Outdated
Comment thread src/Aspire.Dashboard/Components/Controls/TerminalDisconnectedBanner.razor.cs Outdated
@github-actions

This comment has been minimized.

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

CI selection still skips the new package-pairing check for tool-manifest-only changes.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file
Previously missed (1)

In code that hasn't changed since last review

Medium severity Runtime input changes skip CI and lack explicit test routing

tests/​Aspire.Dashboard.Components.Tests/​JavaScript/​TerminalView.test.mjs:2192

These reads add runtime inputs to DashboardTerminalScriptTests.TerminalLifecycleAndPackageContract (tests/Infrastructure.Tests/WorkflowScripts/DashboardTerminalScriptTests.cs:11–15). However, eng/github-ci/ci-skip-entirely-patterns.txt:58 still excludes .config/dotnet-tools.json, so a tools-only version change skips CI and never runs the new pairing assertion. Remove that skip entry and route the manifest to test:Infrastructure.Tests alongside the terminal inputs in eng/github-ci/test-trigger-map.yml:137–148. Also route .mcp.json explicitly rather than relying on the unmapped-file full-matrix fallback. Add focused selector regression coverage for these inputs.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🟡 Changes recommended

Retained-renderer cleanup and recovery after retry exhaustion remain unresolved.

5 open findings
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment thread src/Aspire.Dashboard/Components/Controls/TerminalDisconnectedBanner.razor.cs Outdated
Comment thread src/Aspire.Dashboard/Components/Controls/TerminalView.razor.js Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🟡 Changes recommended

The previously reported resource-dictionary race remains supported by the code and can interrupt command-result reporting.

5 open findings
1 resolved since last review
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file

🧠 Review effort: Balanced

Comment thread src/Aspire.Dashboard/wwwroot/js/README.md Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

Coordinated transport shutdown, reconnection, and graphics retention warrant final human validation against stable Hex1b 0.173.0.

0 open findings

5 resolved since last review
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file

🧠 Review effort: Balanced

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI 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.

🔵 Needs a closer look

Cross-layer terminal lifecycle changes and unresolved error-handling defects require fixes and final human validation.

2 open findings
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file

🧠 Review effort: Balanced

Comment thread src/Aspire.Dashboard/Components/Controls/TerminalView.razor.js Outdated
Comment thread src/Aspire.Dashboard/Components/Controls/TerminalView.razor.js Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI 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.

🔵 Needs a closer look

Recovery-state defects remain, and the transport/renderer lifecycle needs final browser validation against the stable dependency.

1 open finding
2 resolved since last review
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file
Previously missed (1)

In code that hasn't changed since last review

Medium severity Renderer failure hides recovery after ended-view reconnect

src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor.js:727

If a connected view loses transport and its retry receives a 4000 close before any frame, the previous renderer stays in retainedClient while state.ended becomes true. A subsequent fatal renderer error sets mount-failed here, hiding the recovery banner and its Close tab action. The remaining Reconnect button does nothing because same-endpoint reconnects reject ended views. Use renderer-failed when the retained view has ended, and add coverage for transport loss → frameless 4000 retry → renderer failure.

🧠 Review effort: Balanced

Comment thread src/Aspire.Dashboard/Components/Controls/TerminalView.razor.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

Tests selector

Selects the full PR test matrix + all PR-gated jobs (ALL) — a rule matching 'Directory.Packages.props' selects ALL


Selection computed for commit bd193f5.

Copilot AI 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.

🔵 Needs a closer look

Cross-layer terminal lifecycle changes need final human validation, and a confirmed recovery-state defect remains unresolved.

0 open findings

1 resolved since last review
Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file
Previously missed (1)

In code that hasn't changed since last review

Medium severity Use renderer-failed for errors after pre-frame reconnect completion

src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor.js:727

If a reconnect receives close code 4000 before its first frame (for example, from CloseEndedAsync), the previous screen remains in retainedClient with state.ended true. A later fatal error in that renderer sets mount-failed here, hiding the recovery banner and its Close tab action. The replacement Reconnect button does nothing because same-URL reconnects reject ended views. Use renderer-failed when already ended, matching the completed-client branch, and add a regression covering transport loss → pre-frame completion on retry → retained-renderer failure.

🧠 Review effort: Balanced

Copilot AI 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.

🔵 Needs a closer look

Cross-process teardown and renderer recovery require final human validation against the stable runtime, alongside resolution of the retained correctness issue.

0 open findings

Files not reviewed (2)
  • src/Aspire.Dashboard/Resources/TerminalStrings.Designer.cs: Generated file
  • src/Aspire.Dashboard/package-lock.json: Generated file
Previously missed (1)

In code that hasn't changed since last review

Medium severity Mark frameless ended terminals as having unavailable output

src/​Aspire.Dashboard/​Components/​Controls/​TerminalView.razor.js:397

If the AppHost terminal ends before its first frame, CloseEndedAsync sends code 4000 without a projection. Neither state.client nor state.retainedClient exists, but clearing connectionError here makes the banner claim output was preserved and offer “Show terminal” over an empty view. The subsequent mount rejection cannot correct this because connectionFailed ignores ended terminals. Mark output unavailable when neither projection exists; an already-queued successful mount clears that error when it adopts its frame. Add a frameless-completion regression that also verifies the endpoint remains ended.

🧠 Review effort: Balanced

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@mitchdenny
Mitch Denny (mitchdenny) merged commit 1187811 into main Oct 17, 2026
848 of 851 checks passed
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 17.0 milestone Oct 17, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Pull request created: #1904

Generated by PR Documentation Check · copilot · auto · 73.5 AIC · ⌖ 17.7 AIC · ⊞ 20.4K

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1904 targeting release/17.0.

Signals fired: new_public_type (new TerminalDisconnectedBanner component), pr_body_has_user_facing_section (PR's "User-facing usage" section describing Restart resource / Close tab / Show terminal), and pr_body_has_cli_flag_mention (validation command mentions, a weaker signal but counted). Added a "Recover from a disconnected terminal" section to src/frontend/src/content/docs/dashboard/terminals.mdx covering: retained output (text + Sixel/Kitty graphics) on disconnect, the disconnect banner's recovery actions (Restart resource for resource terminals, Close tab for docked terminals, Show terminal to collapse/expand the banner), and the Hex1b 0.173.0 limitation that offline selection/copy isn't supported.

Note

This draft PR needs human review before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants