agentleFS
jackchukajackchuka/skills/p-clipboard-copy/SKILL.md

p-clipboard-copy

Skill15 starsChanged 9 days agoMITView on GitHub

Pull copy-worthy fragments out of the ongoing session — commands, code blocks, file paths, URLs, IDs, queries, message drafts, error snippets, diffs — and push them into the macOS clipboard history as separate entries, stripped of markdown fences, shell prompts and line numbers, ordered so the most relevant one is what Cmd+V pastes. Message drafts are copied as rich text so bold and bullet lists survive pasting into Slack. Use when the user says "copy that", "clip this", "copy the command and the path", "put those on my clipboard", "clip the last few things", or "/p-clipboard-copy".

  • Reads credentials

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 1 is distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Default: the last ~3 assistant turns plus any user turn that named something concrete.

    line 47
  2. Very specific:

    Prefer ranking a formatted draft #1 when it is a close call.

    line 79
  3. Very specific:

    Wait for the answer. Skip this step only with --yes.

    line 95
  4. Very specific:

    Write each selected fragment to its own file in the scratchpad directory, named NN-<type>.txt, then hand them to the script in reverse …

    line 99
  5. Very specific:

    Always pass files, never inline strings — inline text gets mangled by shell quoting on anything containing quotes, backticks, $, or …

    line 117
  6. Distinctive:

    When an entry below #1 is rich, add one line: recall it in Raycast, then Cmd+K -> "Paste as...

    line 129
  7. Very specific:

    Strip fences: Remove `` ``` delimiters and the language tag.

    line 150
  8. Very specific:

    Write the HTML as a fragment with no <html>/<body> wrapper.

    line 183

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Clipboard Copy

Copy several useful fragments from this session into clipboard history at once, each as its own entry, each containing only the part worth pasting.

The user has a clipboard history manager, so copying 3-6 items is cheap and useful. The value of this skill is extraction quality, not volume: a command without its $ prompt, a path without the prose around it, a query without the explanation. Never copy a whole assistant message — that is what the built-in /copy is for.

Arguments

  • [hint] — free text narrowing what to grab: /p-clipboard-copy the sql and the pod name. With no hint, auto-detect from the recent turns.
  • --all — widen the scan from the last few turns to the whole session.
  • --yes — skip the confirmation step and copy immediately.
  • --delay SEC — seconds between copies. Default 0.7.

Scan window

Default: the last ~3 assistant turns plus any user turn that named something concrete. With --all, the whole session. If a hint names something older than the window, search the whole session for it regardless.

Workflow

1. Collect candidates

Walk the scan window and pull out every fragment that matches the taxonomy below. A candidate is one clipboard entry — never bundle two unrelated things into one entry, and never split something that is only useful whole (a multi-line command with && is one entry).

Drop anything that is:

  • Already trivially retypable (ls, cd .., a single digit).
  • Prose or explanation rather than an artifact.
  • A near-duplicate of another candidate — keep the most complete version.
  • Secret material: tokens, passwords, private keys, .env values. Skip these silently unless the user's hint asked for them by name.

2. Rank, then propose

Rank by how likely the user is to paste it next. Signals, strongest first:

  1. The hint named it.
  2. It is the thing the last turn was actually about — the command just written, the URL just created.
  3. It is an action the user must now take elsewhere (run this, open this, paste this into a PR).
  4. It is an identifier they will need to reference again.

Prefer ranking a formatted draft #1 when it is a close call. Any entry can carry formatting, but only the top-ranked one pastes rich on a plain Cmd+V — the rest need an extra action when recalled from history (see below).

Print a numbered table, ranked most relevant first:

#TypePreviewSize
1draft (rich)*Shipped this week* — 3 bullets412 B
2urlhttps://github.com/org/repo/pull/4236 B
3pathsrc/handler/auth.go:11824 B

Truncate previews to ~60 chars. Then stop and ask:

Copy all 3? (ok / just 1,3 / drop 2 / also <thing>)

Wait for the answer. Skip this step only with --yes.

3. Copy

Write each selected fragment to its own file in the scratchpad directory, named NN-<type>.txt, then hand them to the script in reverse relevance order — least relevant first, most relevant last — so the top-ranked item is the active clipboard and the rest stack behind it in history:

scripts/clip.sh /scratch/03-path.txt /scratch/02-url.txt /scratch/01-command.txt

For a formatted draft, also write a sibling NN-draft.html next to its .txt. The script picks it up automatically — no flag, and it works for any number of entries:

# 01-draft.html sits beside 01-draft.txt and is detected
scripts/clip.sh /scratch/03-path.txt /scratch/02-url.txt /scratch/01-draft.txt

Always pass files, never inline strings — inline text gets mangled by shell quoting on anything containing quotes, backticks, $, or newlines.

Then report where each item landed in the history:

Clipboard history (Cmd+V pastes #1):
  1. draft  rich — bold and bullets paste formatted
  2. url    https://github.com/org/repo/pull/42
  3. path   src/handler/auth.go:118

When an entry below #1 is rich, add one line: recall it in Raycast, then Cmd+K -> "Paste as... RTF" to keep the formatting.

Detection taxonomy

TypeWhat lands on the clipboard
commandThe bare command. No $/%/> prompt, no fence, no trailing comment, no surrounding explanation.
codeThe block body only, original indentation preserved, no fence and no language tag.
pathAbsolute path, or path:line when a specific line was cited. Repo-relative only if the user was working relative.
urlThe bare URL. No markdown link syntax, no trailing punctuation from the sentence.
idCommit SHA, branch name, PR/issue number, pod or container name, resource ID, ticket key.
draftCommit message, PR body, Slack message, email text. Plain text, plus an HTML flavor when it has formatting — see below.
querySQL, GraphQL, jq expression, BigQuery statement — the query alone.
errorThe log or stack trace lines themselves, no commentary.
diffPatch text that would apply cleanly with git apply.

Extraction rules

These are the "only the necessary part" rules. Apply all of them:

  • Strip fences. Remove ``` delimiters and the language tag.
  • Strip prompts. Leading $ , % , > , # on shell lines.
  • Strip line numbers. Output from cat -n, grep -n, or a Read tool result carries 12→ or 12: prefixes — remove them and restore original indentation.
  • Strip ANSI escapes from captured terminal output.
  • Strip markdown link syntax — [text](url) becomes the URL when the candidate is a url, the text when it is a draft.
  • No trailing newline on single-line values (paths, URLs, IDs) so pasting into a form field or another shell does not submit early.
  • Keep the trailing newline on multi-line blocks (code, diffs, drafts).
  • Never truncate the payload. Previews are truncated; clipboard entries are not.

Rich text for drafts

Slack's composer converts Markdown as you type, never on paste. Pasted *bold* and **bold** both show literal asterisks, and - item stays a dash. The only thing that pastes as real formatting is a rich flavor on the pasteboard.

To make an entry rich, write a sibling .html file next to its .txt. The script detects it and puts three flavors on the pasteboard: plain text, HTML and RTF (converted from the HTML with textutil).

Any number of entries can be rich, but they do not behave identically:

EntryHow it pastes formatted
Rank #1 (the live clipboard)Cmd+V — renders rich straight away, no extra step
Anything recalled from historyCmd+K -> "Paste as... RTF" in Raycast

Plain Enter on a history entry pastes the plain-text flavor, and "Paste as... HTML" does not render — RTF is the flavor that survives the round trip. This was verified on this machine, not assumed.

Write the HTML as a fragment with no <html>/<body> wrapper. Escape &, < and > in the content itself. All of these are verified to render in Slack:

MarkdownHTML to emit
**bold**<b>bold</b>
*italic* / _italic_<i>italic</i>
~~strike~~<s>strike</s>
`code`<code>code</code>
```block```<pre>block</pre>
[text](url)<a href="url">text</a>
> quote<blockquote>quote</blockquote>
- item<ul><li>item</li></ul>
nested - itemnested <ul> inside the parent <li> — renders correctly
1. item<ol><li>item</li></ol>
line break<br>
# Heading<b>Heading</b><br> — Slack has no heading element

Emit a heading as exactly <b>text</b><br>. The script keys off that shape and inserts a break before each such heading in both flavors, so Cmd+V and "Paste as... RTF" render identically. Without it a heading sits flush against the list or paragraph above it. Inline bold mid-sentence is never followed by <br>, so it is left alone, and a heading at the very start gets no leading blank line.

The RTF conversion passes -inputencoding UTF-8. Without it textutil falls back to the system codepage and mangles every non-ASCII character — em dashes, • bullets, accented letters, kana all arrive as mojibake.

The plain-text file is still required: it is the fallback anywhere rich text is not accepted, and what plain Enter pastes from history. Make it readable rather than marked up — drop emphasis markers, use • for bullets, indent nested bullets four spaces, and render links as text (url).

Notes

  • Why 0.7s. Raycast polls the pasteboard roughly every 0.5s. Measured on this machine: copies spaced 1.2s and 0.7s apart are all captured; copies spaced 0.3s apart are overwritten before the poll and lost, leaving only the last one. 0.7 is the calibrated floor with margin. Raising item count costs (N-1) x 0.7s.
  • No trailing sleep is needed — the final item stays on the pasteboard and gets picked up by the next poll whatever happens.
  • The user's current clipboard is overwritten, but it is already in their history, so nothing is lost.
  • Other clipboard managers: Maccy and Paste also poll. If entries go missing, raise --delay.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.