Turn the work you already did into a LinkedIn post — without leaving your editor.
postcommit is a Claude Code plugin that reads your
real dev work — git history plus your Claude Code session transcript — and drafts
candidate LinkedIn posts about it. You trigger it with /post, review the drafts, and
post the one you like. Nothing is auto-published.
- 🔒 Local-only. Extraction and drafting run entirely on your machine. No transcripts, diffs, or drafts leave it.
- ✍️ Grounded in real work. Drafts are built from your actual commits and session — the writer never invents numbers, errors, or file names.
- ⚡ Manual and low-friction. One command, three drafts, saved to disk. Optional ambient nudges when a session looks post-worthy.
Most "AI writes your LinkedIn post" tools start from a blank prompt and produce generic slop. postcommit starts from what you actually did today — the diff, the debugging detour, the tiny tool you built — and turns that specificity into a draft worth posting.
The design bet is simple and testable: feeding the tool the real work should produce a post meaningfully better than just asking Claude, in the same session, "write a post about what we just did." If it doesn't, there's no product. That honesty test (see Is it actually better?) is the north star, not feature breadth.
/post <window>
→ extract deterministic: git state + session transcript → a "work bundle"
(masks secrets, caps the diff, skips sidechains — all local)
→ post-writer a Claude subagent turns the bundle into 3 candidate drafts
→ save drafts land in .postcommit/drafts/<UTC-ISO>.md and open in your editor
Two layers keep it honest: deterministic code (an installable Python package does the extraction, scoring, and state) and a prompt/taste layer (the post-writer subagent that actually writes). The command, skill, and hooks are thin glue between them.
Two pieces: the Python package (does the work) and the Claude Code plugin (wires /post
and the hooks into Claude Code — both call the package).
1. Install the CLI:
uv tool install postcommit
# or: pipx install postcommit / pip install postcommitThe core is dependency-free stdlib, so it installs anywhere. postcommit --version
should now work on your PATH.
2. Install the plugin. This repo is its own plugin marketplace:
/plugin marketplace add AvivVegh/postcommit
/plugin install postcommit
That registers the /post and /post-snooze commands, the extract skill, the
post-writer subagent, and the two hooks. Uninstalling removes all of them automatically
— no manual settings.json editing.
To update later: uv tool upgrade postcommit for the CLI, /plugin update postcommit
for the plugin.
Do real work in a repo with Claude Code, then:
/post 1d
The window argument accepts:
| Form | Example | Meaning |
|---|---|---|
| Duration | 1d, 4h, 30m |
Work in the last N days/hours/minutes |
| Keyword | today |
Since midnight local time |
| Git range | HEAD~3..HEAD, main..HEAD |
A commit range |
| Date | since=2026-07-01 |
Since a calendar date |
You get three drafts in three fixed angles — a debugging story, a counterintuitive
lesson, and a tiny tool share — saved to .postcommit/drafts/<UTC-ISO>.md and
opened in your editor. The angles are fixed on purpose so you can compare output
apples-to-apples over time.
The built-in honesty check:
- Run
/post 1dafter real work. - In the same session, also ask: "Write a LinkedIn post about what we just did." — the DIY baseline.
- Compare. Is the tool's draft clearly better? Would you post it? Would you post the DIY one?
If the tool clearly wins, it's earning its keep. If they're a tie, the specificity isn't paying off yet.
So you don't have to remember /post, two Claude Code hooks make the recommendation
ambient — both instant, deterministic, and local (no model calls):
SessionEndcheaply scores whether the session was post-worthy (commits/churn since your last post + transcript signals like real prompts, edits, duration, debugging keywords). If it clears the bar, it stages a lightweight recommendation. If you already ran/postthis session, it just advances the watermark instead.SessionStartsurfaces that recommendation as a one-line nudge — but only if there's unposted post-worthy work, at most once per day, and never while snoozed.
Controlling nudges:
/postacts on the recommendation and clears it./post-snooze [days]hushes nudges for this repo (default 3 days).postcommit state showinspects all state;snooze/unsnooze/mark-posted/resetare also available aspostcommit state <verb>.
Everything above is free and local. postcommit also ships a separate, opt-in cloud
MCP server, postcommit-cloud-mcp, that passes already-approved draft text to the
hosted postcommit-cloud API so drafts can be created, scheduled, and published to
LinkedIn from any MCP host. It's deliberately split from the local tooling — the
local "nothing leaves the machine" guarantee holds because this is the only piece that
touches the network, and only ever with approved draft text.
uv tool install 'postcommit[cloud]'
postcommit-cloud-mcp login # opens your browser, stores a token in ~/.postcommit/credentials.jsonlogin runs a local loopback handoff: it opens the postcommit-cloud dashboard, waits
for the browser to hand a token back to a one-shot 127.0.0.1 server, and writes it
(chmod 600) to ~/.postcommit/credentials.json. postcommit-cloud-mcp logout deletes
that file. Tokens are refreshed automatically from there — no env vars required for
normal use.
Tools: create_post, list_posts, update_post, delete_post, linkedin_status,
linkedin_disconnect.
Optional configuration (env vars):
POSTCOMMIT_CLOUD_API_URL— REST API base URL. Defaults to the production gateway; point it at a local backend for dev.POSTCOMMIT_DASHBOARD_URL— dashboard base URL whose/cli-authpage completes the loopback login. Defaults to the production dashboard.POSTCOMMIT_CLOUD_TOKEN— paste a Firebase id_token directly instead of runninglogin(handy for CI/scripting).POSTCOMMIT_FIREBASE_API_KEY— only needed to refresh a token when it's not already stored bylogin.
Privacy is a design constraint, not a setting:
- The extraction and drafting path never touches the network. The core package is stdlib-only.
- Extraction masks secrets, caps the diff (~40k chars), keeps ≤10 lines per code snippet, and skips
isSidechaintranscript records. - The only networked component is the optional
postcommit-cloud-mcpserver, and it sends approved draft text only — never raw code or transcripts.
Contributions welcome. To hack on postcommit locally without publishing:
scripts/link-local.sh # editable install + symlink command/skill/agent + register hooks
scripts/link-local.sh --unlink # undoThis installs the package as an editable uv tool (so postcommit tracks your
checkout), symlinks the command/skill/subagent into ~/.claude/, and registers the
hooks. Idempotent; won't overwrite non-symlink files. Restart Claude Code once after
linking. Use this or the published plugin, not both — they register the same hooks
two different ways.
Tests are stdlib unittest — no pytest, no extra deps:
scripts/run-tests.sh # or: python3 -m unittest discover -s testsLint: ruff check postcommit tests hooks and bandit -r postcommit hooks.
pyproject.toml # installable package; entry points below
postcommit/ # the package — all deterministic logic
__main__.py # `postcommit` CLI: extract | state | hook | install
extract.py # git + session-transcript → work bundle (masks secrets, caps diff)
scoring.py # post-worthiness signals + scoring
state.py # per-repo/global state (watermark, snooze, recommendation)
hooks.py # SessionEnd / SessionStart logic
serve.py # `postcommit-mcp` — local-only MCP server ([mcp] extra)
cloud_config.py / cloud_auth.py / cloud_client.py # stdlib cloud REST client + auth seam
cloud_login.py # loopback browser login (stdlib)
serve_cloud.py # `postcommit-cloud-mcp` — networked MCP server ([cloud] extra)
install.py # write the skill adapter into a host (~/.claude)
data/skill.md # the thin skill adapter, shipped as package data
commands/post.md # /post <window> — the manual trigger
commands/post-snooze.md # /post-snooze [days] — hush the nudge
skills/postcommit-extract/SKILL.md # thin skill adapter (mirror of data/skill.md)
agents/post-writer.md # the writer subagent — the LinkedIn taste layer
hooks/ # hooks.json + the two thin shims that call the CLI
tests/ # stdlib unittest suite
scripts/link-local.sh # dev-only local install
Entry points: postcommit (CLI), postcommit-mcp (local MCP server, [mcp]
extra), postcommit-cloud-mcp (cloud MCP server, [cloud] extra).
The subagent prompt is the product. agents/post-writer.md is the taste/template
layer that decides whether a draft reads human or like slop. Iterate there first when
improving output quality.
MIT.