π¦ clawpypaste
May 27, 2026 Β· View on GitHub
A macOS menu bar app that surfaces grabbable blocks from your active Claude Code session β fenced code, tool output, file paths, URLs, whole messages, markdown, tables β so you can click to copy instead of mouse-selecting across wrapped lines in your terminal.
Reads the session JSONL Claude Code already writes to disk. No accessibility prompts for the basic features, no terminal scraping, no plugins.
Install
macOS 13 (Ventura) or newer. Notarized & signed with Developer ID β no Gatekeeper warnings.
Homebrew (recommended)
brew install --cask krisbradley/tap/clawpypaste
open /Applications/clawpypaste.app
The cask installs clawpypaste.app into /Applications and symlinks the binary as /opt/homebrew/bin/clawpypaste (or /usr/local/bin/clawpypaste on Intel) so you can use the CLI from any shell.
Direct download
Grab the notarized clawpypaste.zip from the latest release, unzip, drag clawpypaste.app into /Applications, double-click.
From source
Requires the Swift toolchain (xcode-select --install is enough).
git clone https://github.com/krisbradley/clawpypaste.git
cd clawpypaste
make install
This builds + signs + installs to /Applications/clawpypaste.app and symlinks clawpypaste onto your PATH.
Launch at login
After installing by any of the methods above:
clawpypaste --enable-login
Or right-click the menu bar π¦ β Launch at login.
Usage
| Action | How |
|---|---|
| Open the popover | Click the π¦ in the menu bar, or press ββ₯V |
| Move selection | β / β (Shift+arrow jumps by 10) |
| Copy selected block | Return (popover auto-dismisses) |
| Focus search field | / |
| Drag a block to another app | Click-and-hold, then drag |
| Pin / unpin | Click the star, or right-click β Pin |
| Switch session | Click the session name in the header |
| Browse history across sessions | Session menu β All sessions (history) |
| Open detached window | Right-click π¦ β "Open window" |
| Quit | Right-click π¦ β "Quit" |
Right-click any block forβ¦
- Edit and copyβ¦ β open the content in a TextEditor sheet; edit then copy
- Fill in valuesβ¦ β when the block contains
{{placeholder}}tokens, opens a labeled form to substitute values before copying - Copy without markdown β strips
**bold**,*italic*,`code`, headings, lists, blockquotes, link syntax (great for Slack DMs) - Copy as pretty JSON β when the block parses as JSON
- Wrap as code fence β wrap a non-code block as
```langfor posting elsewhere - Copy as Markdown / TSV (Slack) / CSV β on detected markdown tables
- Copy humanized β on prose blocks with AI-typical punctuation or phrases (strips em-dashes, smart quotes, "Certainly!", "I hope this helps!", etc.)
- Inject into Claude prompt β pastes the block into whatever app was focused before the popover opened (requires Accessibility permission on first use)
- Pin / Unpin
CLI
The same binary doubles as a CLI for shell scripts:
clawpypaste last [kind] # print the most recent block (optionally of a kind) to stdout
clawpypaste search <query> # list blocks containing the query
clawpypaste paste <id> # copy a specific block to the clipboard
clawpypaste list [kind] # list all blocks (id, kind, lines, preview)
clawpypaste kinds # list valid kind names
clawpypaste --enable-login # register as a Login Item
Example: vim "$(clawpypaste last code > /tmp/snippet && echo /tmp/snippet)" β drop the most recent code block into a file and open it.
Block kinds
| Kind | Source | Default copy | Special copy-as |
|---|---|---|---|
| Code | Fenced code in assistant text, Write/Edit content for non-prose files, Bash commands | Raw text | β |
| Markdown | ```md fences, Write/Edit to .md/.txt/README | Raw markdown | Humanized (if AI punct) |
| Table | Pipe-delimited tables | Raw markdown | Markdown / TSV (Slack) / CSV |
| Tool output | Result of any tool call | Raw text | Pretty JSON (if applicable) |
| Tool input | Other tool inputs (queries, prompts) | Raw text | β |
| Path | File paths in prose (/Users/...) | Raw path | β |
| URL | http(s) URLs in prose | Raw URL | β |
| Message | Whole assistant message | Raw markdown | Humanized (if AI punct) |
| Section | Markdown section under a heading | Raw markdown | β |
How it works
Claude Code writes every session to a JSONL file under ~/.claude/projects/<encoded-project-dir>/<uuid>.jsonl. Each line is a typed record: a user message, an assistant message with content blocks (text / thinking / tool_use), a tool result, or metadata like custom-title / agent-color.
clawpypaste:
- Finds the active session β newest mtime under
~/.claude/projects/(or whichever you switched to via the session menu) - Watches the file with a
DispatchSourcefor incremental writes - Re-parses on change (debounced 150ms) into typed
SessionRecords - Extracts blocks by walking each record: code fences, markdown tables, file paths and URLs in prose, markdown sections, tool inputs/outputs, whole assistant messages
- Dedupes by content hash so the same block doesn't appear twice
- Renders in SwiftUI inside an
NSPopover, with syntax highlighting for code and inline-markdown rendering for prose
History mode lazily extends the same pipeline across every JSONL under ~/.claude/projects/, caching per file by mtime so reopens are cheap.
The Carbon RegisterEventHotKey API powers the global ββ₯V hotkey. SMAppService.mainApp powers Launch at Login. CGEvent powers the "Inject into Claude prompt" paste (the only feature that requires Accessibility permission).
Development
make run # swift run (no .app bundle, no signing)
make build # build signed .app bundle
make install # build + drop in /Applications + symlink CLI + launch
make clean # remove build artifacts
make uninstall # remove installed app + disable login item + remove CLI symlink
# debug parsing without the GUI
clawpypaste dump
Releases are cut by ./release.sh (builds, signs with Developer ID, notarizes, staples, zips).
License
MIT. See LICENSE.