penknife

Your markdown has to leave home. Keep track of it.

penknife is a terminal home for a folder of markdown: browse it, search it, hand any file to anyone as clean rich text. When a copy lives on as a gist, know at a glance which side has drifted.

curl
curl -fsSL https://heider.cc/penknife.sh | bash
brew
brew install jhheider/tap/penknife
cargo
cargo install penknife

The tour

One folder, at your fingertips

Point it at an Obsidian vault, a notes directory, anywhere you keep .md files. Browse the tree, preview any file rendered, and full-text find across everything - all before you've signed into anything. Once files have gists, each shows its sync state, verified by content hash, not timestamp.

Recording of the penknife TUI: browsing a markdown tree, previewing a rendered file, and full-text finding 'Rust' across the folder

The real thing, recorded against the released binary: browse, preview, and find across a folder.

pShare, without an account

Renders the file to HTML and puts it on your clipboard as rich text. Paste into Google Docs, email, Slack, or Notion, with headings, tables, bold, and links intact. A deliberate snapshot; nothing to track, nothing to sign into.

zero setup

uSync, when you want it

Publishes the file as a GitHub Gist and treats it like a git remote: penknife records what was pushed, notices when either side moves, and shows the drift per file. The folder stays primary.

opt-in, per file

Scriptable

The same tools, headless

Every core verb works without the TUI, with disciplined exit codes and machine-readable output - stdout is the payload, stderr is for humans - so penknife slots into pipes, hooks, and CI.

zsh
$ penknife render -s notes.md > notes.html   # markdown → full HTML doc
$ penknife search "Rust"                      # grep your whole folder
./posts/rust-is-not-the-devil.md:1:# Rust is Not the Devil, Nor the Messiah
./posts/rust-is-not-the-devil.md:3:Rust is a tool, a powerful, occasionally
$ url=$(penknife push posts/edikt-launch.md)      # publish; stdout is the URL
$ penknife status -q || echo "something drifted"  # exit codes are the API

Also in the drawer

Small surface, sharp edges

Why it exists

A gist you share is a copy you can lose track of

You write in markdown, in a folder you own. But your writing has to leave that folder: a gist link in Slack, a doc for a colleague, a post on a blog. Which version is current? Did someone edit the shared one? You can't tell without opening each destination and eyeballing it.

penknife treats each published gist like a git remote: it records what was pushed, notices when either side moves, and shows the drift per file. The folder is primary; the gist is a downstream copy.

And when the destination isn't a gist at all (a manager's Doc, an email, a Slack message), penknife hands you the writing as rich text to paste: a deliberate snapshot with nothing to track. Two jobs, kept separate on purpose.

It is not a backup tool, not an editor, and not an Obsidian plugin. It's the missing seam between the folder where you write and the places your writing ends up.