From clipboard
Copy the core content of the last answer to the macOS clipboard via the clipboard-copy helper. Formats output based on content type. /clipboard slack for rich text.
How this skill is triggered — by the user, by Claude, or both
Slash command
/clipboard:clipboardThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<post-update-broadcast>
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
node "${CLAUDE_PLUGIN_ROOT}/bin/check-broadcast"
fi
If the command produces output, the clipboard plugin was updated since the last time you saw the broadcast on this machine. Show the output verbatim in a markdown block, prefixed with one short sentence ("clipboard was updated; here is what changed."). Then continue with the rest of this skill.
If the command produces no output, say nothing about updates and proceed.
The helper writes the sentinel only when stdout was non-empty, so a silent
run does not mark the version as seen. In agents that do not set
CLAUDE_PLUGIN_ROOT the broadcast is intentionally skipped; that is the
guard's purpose, not an oversight.
Copy the core content of your last answer to the macOS clipboard via clipboard-copy (the helper that invokes pbcopy and pbcopy-html under the hood). No confirmation, no explanation. Just copy.
| Argument | Effect |
|---|---|
| (none) | Plain text via clipboard-copy (wraps pbcopy) |
slack | Rich text (HTML) via clipboard-copy --html (wraps pbcopy-html). Inline code, bold, and lists render correctly when pasted into Slack. Tables are converted to ASCII in a <pre> block (Slack does not support HTML tables) |
slack → generate HTML and use clipboard-copy --html (see section "Slack mode"). No argument → plain text via clipboard-copy| Type | Recognition | Formatting |
|---|---|---|
| JSON | JSON object/array in answer | Pretty-printed JSON, leave intact |
| Code | Literal source, commands, or JSON in a code block (NOT prose/a prompt that merely happens to be fenced) | Exact code without markdown fences |
| Command | Shell command(s) | Commands, one per line |
| Email/letter | Salutation, sign-off, formal tone | Paragraphs separated by double newline |
| Slack/chat | Informal tone, short message | Continuous text, single newlines between paragraphs |
| List | Enumeration, bullet points | Preserve list formatting with - prefix |
| Explanation/prose | Running text, explanation | Continuous paragraphs, double newline between paragraphs |
| Table | Table data in answer | GitHub-flavored markdown table with `--- |
Mixed content: When an answer contains code blocks with surrounding explanation, "Code" always wins over "Explanation/prose". The user wants to copy the code, not read the explanation in another window. Copy only the code blocks, leave the prose out.
"Code wins" decides which content to copy, not whether to preserve wrapping. A fenced block that is actually a prompt, an email, or instructions is prose, not Code: copy it (it is the core content) and reflow its hard wraps per the reflow rule above. Only literal source/commands/JSON stay byte-for-byte.
The reason to call clipboard is to get pure, re-flowable content. Hard line breaks in the middle of a sentence (the ~70-80 char wrapping Claude Code adds to its output, or manual wrapping you put in a fenced block) paste as ugly mid-sentence breaks in any target that does its own wrapping (chat, GitHub, docs, a prompt field). Collapse them.
A block being shown inside a ``` fence is NOT a reason to preserve its wrapping. The fence is a display choice in the chat, not a signal about the content. If the fenced text is a prompt, an email, instructions, or any prose (not literal source/commands/JSON), reflow it exactly like prose. This is the most common miss: copying a fenced prompt verbatim drags every hard wrap into the paste.
Claude Code output often contains:
**bold**, `code`, ### headers)- or * Always remove:
**, *, _)#, ##, etc.)Keep:
`technical terms` always stay)JSON: Use jq . formatting. No extra processing.
Code: Exact code from the code block. No markdown fences. With multiple blocks: separate with one blank line.
Command: Only the command itself, no explanation. Multiple commands on separate lines.
Email/letter: Plain text with paragraphs. No markdown. Double newline between paragraphs.
Slack/chat: Continuous text. Single newline only at a real paragraph break. No unnecessary line breaks.
Explanation/prose: Continuous paragraphs. No bullets unless the original structure requires it. Merge terminal line-wrapping into continuous sentences.
Table: GitHub-flavored markdown with pipe-formatting and ---|---|--- separator between header and body. Pasteable in GitHub issues, PRs, Notion, Slack (with GFM support).
The clipboard-copy helper lives in this plugin's bin/ directory and is not
on $PATH. In Claude Code the plugin root is ${CLAUDE_PLUGIN_ROOT}; in
another agent, resolve the plugin root from where this skill file was loaded
(two directories up) and substitute it. The helper always points at the active
install, so there is no stale-cache or uninstalled-plugin failure mode to
defend against.
Use a heredoc to avoid formatting issues:
"${CLAUDE_PLUGIN_ROOT}/bin/clipboard-copy" <<'CLIPBOARD'
[content here]
CLIPBOARD
Note: <<'CLIPBOARD' (single quotes) is literal; variables, command substitution, and backticks are not expanded. This is usually what you want. Only use <<"CLIPBOARD" (double quotes) when you explicitly want $VAR, $(...) or backticks to be evaluated; then content with literal $, ` or \ must be escaped. Choose the heredoc variant that requires the least escaping for the specific content.
When the slack argument is provided, generate HTML instead of plain text and call clipboard-copy --html:
"${CLAUDE_PLUGIN_ROOT}/bin/clipboard-copy" --html <<'CLIPBOARD'
[HTML content here]
CLIPBOARD
clipboard-copy --html passes the HTML through pbcopy-html.swift, which places it on the clipboard as rich text (via NSPasteboard). Slack picks this up and renders formatting correctly. A plain text fallback (HTML tags stripped) is also included for apps that do not support rich text.
The slack argument exists specifically to produce rich text. If you are tempted to switch this back to Slack-native mrkdwn syntax (single-asterisk *bold*, • bullets, triple-backtick tables) because rich text paste feels unreliable somewhere, do not. That regression has been made before and reverted. The user has explicitly stated that rich text is the entire point of slack: bold must paste as bold, not as the literal characters *bold*. The frontmatter description ("for rich text") and the plugin description in plugin.json ("pbcopy-html for Slack rich text") are load-bearing, not stale text.
Plain-text mrkdwn does survive consistently across Slack desktop, web, and mobile, but that consistency was a worse-of-both: a user who reads the pasted message before sending sees *bold* instead of bold formatting. The user does not want that. If a specific HTML construct genuinely renders worse than its mrkdwn equivalent in some Slack client, narrow the fix to that construct (alternative HTML element, ASCII fallback, narrower wrapper); do not flip the whole mode back to plain text.
Convert the content to HTML before passing it to clipboard-copy --html:
| Markdown | HTML |
|---|---|
`code` | <code>code</code> |
**bold** | <b>bold</b> |
*italic* or _italic_ | <i>italic</i> |
- list item | <li>list item</li> (in <ul>) |
1. numbered | <li>numbered</li> (in <ol>) |
| Empty line | <br><br> |
| Line break | <br> (newlines in HTML source are ignored by rich text paste, ALWAYS use <br> for line breaks) |
[text](url) | <a href="url">text</a> |
| Special characters | NEVER escape with HTML entities (&, >, <, "). Many apps (Slack, Notion, Teams) render entities literally on rich text paste: > appears as the text ">" instead of ">". Write &, >, < directly. Only escape when the character would break an HTML tag (e.g. < immediately before a letter). |
Do NOT wrap the full content in <html> or <body> tags. Rich text paste expects HTML fragments, not complete documents.
Slack does NOT support <table> HTML elements. A <table> is flattened to unreadable text without structure.
NEVER use <table>, <tr>, <th>, or <td> tags in Slack mode.
Convert tables to ASCII format in a <pre> block. Slack renders <pre> as a monospace code block, keeping columns neatly aligned.
<pre>
Requirement | Current state | Gap
-------------------------------|-------------------------|---------------------------
Load management at panel level | SensorMaxPowerLimiter | Depends on sensor data
Priority per user profile | Planner on departure | Concept does not exist
</pre>
Rules for ASCII tables in <pre>:
| (space-pipe-space)---...|---... line<pre> (no <code>, <b>, etc.)Markdown content:
De job is goed uitgevoerd. Alle platforms uit `PLATFORM_TIMEOUTS` zijn **volledig** backfilled.
Becomes:
"${CLAUDE_PLUGIN_ROOT}/bin/clipboard-copy" --html <<'CLIPBOARD'
De job is goed uitgevoerd. Alle platforms uit <code>PLATFORM_TIMEOUTS</code> zijn <b>volledig</b> backfilled.
CLIPBOARD
After copying, confirm with one line:
[type] copied: "[first ~30 characters]..."
Examples:
JSON copied: "{"name":"my-project","vers..."Code copied: "def calculate_price(kwh..."Slack message copied: "Hey team, de deploy van..."Table copied (slack/rich text): "De job is goed uitgev..."If the immediately preceding answer has no copyable core (clipboard confirmation, login, skill invocation), look further back in the conversation. "Last answer" means the last answer with substantive content, not necessarily the chronologically last one.
Only when there is no copyable content anywhere in the recent conversation (e.g. session just started, only questions asked), report briefly:
No copyable content found in the conversation.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub epologee/laicluse-agent-fieldkit --plugin clipboard