feat: copy the output panel to the system clipboard (#11)

New app-level `copy` / `copy all` / `copy last` command (ADR-0041).
Delivery is OSC 52 *and* a best-effort native write (arboard), always
both — OSC 52 acceptance is undetectable, so a true fallback can't be
built. Payload is the panel's plain text exactly as rendered (tags,
✓/✗, box-drawing), drift-locked to render_output_line. arboard added
--no-default-features (X11-only; OSC 52 covers Wayland).

Amends ADR-0003's command registry; requirements V6.
This commit is contained in:
claude@clouddev1
2026-06-02 14:23:21 +00:00
parent 1ea376be26
commit d0c8f9d5d2
25 changed files with 1203 additions and 13 deletions
+6
View File
@@ -186,6 +186,7 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
("help.app.messages", &[]),
("help.app.undo", &[]),
("help.app.redo", &[]),
("help.app.copy", &[]),
("help.ddl.create", &[]),
("help.ddl.sql_create_table", &[]),
("help.ddl.sql_drop_table", &[]),
@@ -291,6 +292,7 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
("parse.usage.export", &[]),
("parse.usage.help", &[]),
("parse.usage.import", &[]),
("parse.usage.copy", &[]),
("parse.usage.load", &[]),
("parse.usage.messages", &[]),
("parse.usage.mode", &[]),
@@ -468,6 +470,10 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
("mode.show_simple", &[]),
("mode.unknown", &["value"]),
("mode.usage", &[]),
// ---- copy (ADR-0041) ----
("copy.done", &["count"]),
("copy.nothing", &[]),
("copy.unknown", &["value"]),
// ---- DbError Display fallback ----
("db.error.invalid_value", &["detail"]),
("db.error.io", &["detail"]),
+12
View File
@@ -224,6 +224,9 @@ help:
import <zip> [as <t>] Unpack <zip> into a new project and
switch to it. <t> overrides the target
name (else taken from the zip).
copy [all|last] Copy the output panel to the system
clipboard (`copy last` copies just the
most recent command's output).
# In-app `help` command output (ADR-0024 §help_id). The
# renderer iterates the command REGISTRY and translates each
# CommandNode's `help_id` — so a newly-registered command
@@ -266,6 +269,8 @@ help:
undo — undo the last change (with confirmation)
redo: |-
redo — redo the last undone change (with confirmation)
copy: |-
copy [all|last] — copy the output panel to the clipboard (`copy last` = the most recent command)
ddl:
create: |-
create table <T> with pk [<col>(<type>), ...] — create a table
@@ -563,6 +568,7 @@ parse:
messages: "messages | messages short | messages verbose"
undo: "undo"
redo: "redo"
copy: "copy | copy all | copy last"
# ---- Pre-submit diagnostics (ADR-0027) -------------------------------
# Surfaced by the validity indicator and the hint panel before
@@ -852,6 +858,12 @@ messages:
set_verbose: "messages: verbose"
unknown: "unknown messages mode '{value}' (expected 'short' or 'verbose')"
# ---- copy (app-level command, ADR-0041) -----------------------------
copy:
done: "copied {count} line(s) to the clipboard"
nothing: "nothing to copy — the output panel is empty"
unknown: "unknown copy target '{value}' (expected 'all' or 'last')"
# ---- Database-error fallback wording + cascade summaries ------------
db:
# DbError variants — fallback Display wording for paths that