feat: Copy / Insert / Replace buttons on assistant messages

Each assistant message in the inline prompt history now renders a
small toolbar with three action buttons:

  📋 复制  — copy the rendered assistant content (the markdown
             source, not the rendered HTML) to the clipboard via
             navigator.clipboard.writeText, with a fallback to a
             hidden textarea + execCommand for non-secure contexts.
  ↪ 插入  — insert the content at the current editor cursor. Uses
             cell.editor.getCursorPosition() + the cell source to
             compute the offset, then sharedModel.setSource to splice
             the text in. Falls back to appending if the cursor can't
             be read.
  ⟳ 替换  — replace the entire cell source with the assistant content
             via sharedModel.setSource.

User messages and the textarea/send/cancel UI are unchanged; the
toolbar only appears on rendered assistant (markdown) messages.

Implementation:
  - OpenCodeInlinePrompt now stores the cell (private _cell) so the
    button handlers can act on it.
  - New private methods: _copyToClipboard, _insertAtCursor,
    _replaceCell. Each shows a Notification on success/failure.
  - Added import { Notification } from '@jupyterlab/apputils' (the
    prompt file didn't import it before; cell_actions does, so the
    test mock already provides the static methods).
  - style/base.css: .opencode-msg-toolbar (flex row) and
    .opencode-msg-btn (small bordered button) styles.
  - Test fake cell now has an editor stub returning cursor (0,0) so
    the Insert test produces a deterministic offset. jsdom lacks
    navigator.clipboard; the test stubs it globally.

Tests:
  - jest 33/33 (was 29; +4 new: toolbar renders 3 buttons only on
    assistant, Replace sets source, Insert splices at offset 0, Copy
    calls clipboard.writeText with the content).
  - pytest 37/37 (no server changes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
tao.chen
2026-07-23 19:13:28 +08:00
co-authored by Claude Fable 5
parent ce59502e97
commit cb3576c83a
3 changed files with 248 additions and 2 deletions
+22
View File
@@ -111,6 +111,28 @@
color: var(--jp-ui-font-color0, #000);
}
.opencode-inline-prompt .opencode-msg-toolbar {
display: flex;
gap: 4px;
margin-bottom: 4px;
}
.opencode-inline-prompt .opencode-msg-btn {
border: 1px solid var(--jp-border-color2, #ccc);
background: var(--jp-layout-color1, #fff);
padding: 1px 6px;
border-radius: 3px;
cursor: pointer;
font-size: var(--jp-ui-font-size0, 11px);
line-height: 1.4;
color: var(--jp-ui-font-color1, #333);
}
.opencode-inline-prompt .opencode-msg-btn:hover {
background: var(--jp-layout-color2, #f7f7f7);
border-color: var(--jp-border-color1, #999);
}
.opencode-inline-prompt .opencode-inline-history pre {
background: var(--jp-layout-color1, #fff);
padding: 6px 8px;