Documentation

CleanCopy is a macOS command-line app: a native clipboard helper for Apple Silicon and Intel, plus a pure TypeScript cleanup engine. Text in, text out — no side effects.

Install

Requires macOS 12 (Monterey) or later and Node.js 22 or later. The package refuses installation on other operating systems rather than installing a command that cannot work.

$ npm install --global cleancopy-cli
$ cleancopy doctor # helper, configuration, and state directory ready?

The npm package is cleancopy-cli; the installed command is cleancopy.

To upgrade, install again and restart the watcher — the running watcher keeps the old version until it restarts. Settings, the event log, and login autostart carry over on their own.

$ npm install --global cleancopy-cli
$ cleancopy stop && cleancopy start

Uninstall in this order — the stop must run while the cleancopy command still exists:

$ cleancopy stop --disable-autostart
$ npm uninstall --global cleancopy-cli

Settings and the content-free event log stay in ~/.cleancopy; delete that directory yourself if you do not want to keep them.

Commands
cleancopy clean
read text from stdin, print the cleaned text
cleancopy start
start watching the clipboard (background)
cleancopy stop
stop the background watcher; --disable-autostart also removes login autostart
cleancopy status
show watcher, helper, log, and autostart status
cleancopy doctor
check that the helper, configuration, and state directory are ready
cleancopy config
show or change settings — mode auto|manual, the revert hotkey
cleancopy autostart
show login autostart; on starts CleanCopy at login, off stops and removes it
cleancopy run
run the watcher in the foreground, printing event lines (debugging)
cleancopy --help
show help

Clean the clipboard once, without the watcher:

$ pbpaste | cleancopy clean | pbcopy

With the watcher running, copies made while a supported terminal is frontmost are cleaned in place. Copy, then paste as usual. That is the default auto mode.

In manual mode (cleancopy config mode manual) the gesture is a double copy — press Cmd+C twice in quick succession on the same selection, and the second copy triggers the clean. If a clean ever goes wrong, the revert hotkey — cmd+ctrl+z by default, working in both modes — puts the original copy back.

--explain

Prints, per block, what it was judged to be and why — to stderr, so the cleaned text on stdout stays pipeable.

$ cleancopy clean --explain < copied-output.txt
inferred wrap column: 52
[prose] reflow=true conf=0.9 (reads-like-prose)  "The deploy failed because the staging config was…"
    block L1→L2 join score=4 [at-right-edge+2, dangling-word+1, …]
[table] reflow=false conf=0.9 (aligned-columns)  "$ kubectl get pods"
Pipeline

Four stages, pure text in, text out. Mixed copies are judged block by block.

1 normalize — always-safe tidy-ups: invisible characters, exotic spaces, escape codes, the shared left margin.
2 segment — split the copy into blocks at blank lines, so mixed copies are judged block by block.
3 classify — judge each block: prose, list, code, table, trace, data — or unsure.
4 transform — reflow only confidently identified prose and lists; everything else passes through verbatim.
Supported terminals

CleanCopy only considers copies made when a supported terminal is frontmost. Everything else is discarded before its text is read.

TerminaliTerm2AlacrittykittyWezTermWarpHyperGhosttyTermius + common variants

Editors with built-in terminals are intentionally excluded, because their copies may be source code from an editor pane.

Environment

Add an unsupported terminal by bundle identifier:

$ export CLEANCOPY_TERMINALS=com.example.my-terminal
$ cleancopy start

For a login-started watcher, set the variable before running cleancopy autostart on; the launch agent preserves it. Re-run cleancopy autostart on after changing the variable or after switching Node installations.

Logs

The event log at ~/.cleancopy/cleancopy.log records content-free summaries such as cleaned copy from iTerm2 (12 lines → 4). Clipboard contents are never written to disk.

Privacy

Nothing leaves your machine — there is no network code in the package.

Clipboard contents are never written to disk. The event log at ~/.cleancopy/cleancopy.log records content-free summaries only — like cleaned copy from iTerm2 (12 lines → 4).
Pasteboard items marked concealed or transient — password-manager items — are never read.
Only copies made while a supported terminal is frontmost are considered. Everything else is discarded before its text is read.
Editors with built-in terminals are intentionally excluded — their copies may be source code from an editor pane.
Development

Developing, testing, and using the published CLI requires Node.js 22 or later.

$ npm install
$ npm test
$ npm run typecheck
$ npm run build
$ npm run build:helper
$ npm run release:check

release:check builds the universal native helper, runs the full suite, and shows the exact npm tarball contents. Helper integration tests use a private pasteboard — never your real clipboard.

Contributing

Real-world terminal output makes the cleanup engine safer. Add a fixture and run npm test:

test/fixtures/<short-name>/input.txt
test/fixtures/<short-name>/expected.txt

Fixtures that protect code, logs, and tables from accidental prose reflow are especially valuable.