Skip to content

fix(commands): copy commands say when the clipboard refused (#1250 row 9) - #1421

Merged
Juliusolsson05 merged 3 commits into
mainfrom
fix/copy-last-response-failure
Sep 27, 2026
Merged

Juliusolsson05 merged 3 commits into
mainfrom
fix/copy-last-response-failure

Conversation

@Juliusolsson05

@Juliusolsson05 Juliusolsson05 commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Refs #1250 (row 9). #1250 is a batch issue, so the other rows stay open.

Problem

  • Copy Last Response (paneCommands.ts) wrote to the clipboard fire-and-forget and then always showed "Copied to clipboard". When Electron refused the write (for example, the document is not focused after the palette or a context menu), the rejection went unhandled, under a toast that claimed the opposite.
  • Copy Resume Command (sessionCommands.ts) caught its failure but showed copy failed: <DOMException message>: raw browser text (q22).

Change

  • Copy Last Response awaits the write. It says "Copied to clipboard" only after the write succeeds; otherwise it shows "Couldn't copy to the clipboard. Click into the app and try again."
  • Copy Resume Command shows the same sentence on failure. Its success toast is unchanged.
  • Browser Pocket's pick (no composer) no longer swallows a refused write under "Element copied"; it says the refusal.
  • The assistant-message and code-block pickers use the same sentence instead of "Clipboard write failed".
  • The sentence is one constant: lib/clipboardFailure.ts.

Plan: docs/plans/2026-09-27-copy-last-response-failure.md.

Tests (the failure cases are red on main; the success case is green by design)

New copyCommands.clipboard.renderer.test.ts runs the real commands. The runtime entries are the recorded rendering bundle 2026-05-20T19-11-51-193-d4a44a16; the clipboard is the one stubbed edge.

  • A refused Copy Last Response shows the failure sentence and never "Copied".
  • A successful one writes the recorded response and says "Copied".
  • A refused resume copy shows the fixed sentence without the browser text.
  • The command stays pending and silent until a deferred write settles.
  • pick.renderer.test.ts: a refused pick copy says so and never "Element copied".
  • The wording is asserted literally.

Verification

  • rm -rf .tsc-out; npx tsc -b: clean.
  • NODE_ENV=test npx vitest run on features/workspace/commands, features/browser-pocket, workspace/hook/actions and useKeybinds: 452/452.
  • Review round 1: the disposition is in the PR comments.
  • The app was not launched.

🤖 Generated with Claude Code

Juliusolsson05 and others added 2 commits September 27, 2026 05:21
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w 9)

Copy Last Response awaited nothing and always said Copied; it now awaits the
write and shows a fixed failure sentence on rejection. Copy Resume Command's
failure uses the same sentence instead of the raw DOMException text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Juliusolsson05 Juliusolsson05 added type:bug Something works wrong class:C3-silent-failure The app knows it failed and does not say sev:P3 Minor labels Sep 27, 2026
…e shared sentence (#1421 review)

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

Copy link
Copy Markdown
Owner Author

Review disposition, round 1 (head d3f1a6bf)

Verdicts: a FIX-BEFORE-MERGE, b FIX-BEFORE-MERGE, c MERGE-READY.

Finding Disposition
a1: a refused copy reports ran to commands.run callers Declined. Throwing would make runGuarded add its own "Command failed: " toast, so every human path would get two messages for one failure. The commands.run contract already says ran means only that the dispatcher returned, and tells the caller to observe the app.
a2: nothing pinned that the command stays pending until the write settles Fixed. A deferred-write test: the command is not settled and silent before the write, then says "Copied". It fails with a fire-and-forget .then.
b1: Browser Pocket's pick (no composer) swallowed a refused write and said "Element copied" Fixed: it says the refusal. The test in pick.renderer.test.ts fails on the old pick.
b2 / c1: the wording was compared against the constant only Fixed: it is asserted literally.
c2: the assistant-message picker and the code-block picker said "Clipboard write failed" Fixed: both use the shared sentence. The constant moved to lib/clipboardFailure.ts.
c3 (nit): "red on main" is true suite-level; the success case is green by design Acknowledged; the body says which tests are red.

Verification:

  • npx tsc -b: clean.
  • features/workspace/commands, features/browser-pocket, workspace/hook/actions and useKeybinds: 452/452.

🤖 Generated with Claude Code

@Juliusolsson05
Juliusolsson05 merged commit 94c6a29 into main Sep 27, 2026
2 checks passed
@Juliusolsson05
Juliusolsson05 deleted the fix/copy-last-response-failure branch September 27, 2026 15:03
Juliusolsson05 added a commit that referenced this pull request Sep 27, 2026
pick.renderer.test.ts: keep #1421's refused-copy test and this PR's
cancelled pick, which now resolves { kind: 'cancelled' } rather than null.
pick.ts auto-merged with both the outcome handling and the checked
clipboard write.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

class:C3-silent-failure The app knows it failed and does not say sev:P3 Minor type:bug Something works wrong

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant