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 - and 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 - headings, tables, bold, 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.