build-in-public
v0.9.1
Published
CLI to automate build-in-public workflows — generate platform-tailored posts from git activity using Claude AI and publish to X, LinkedIn, Reddit, and HackerNews
Maintainers
Readme
bip: build in public CLI
Turn your coding sessions into shareable progress updates, straight from your git history. Works with Claude Code, Cursor, Copilot, Codex, or bip's own LLM key.

npm install -g build-in-publicInput (your git activity):
$ bip draft
Reading last 20 commits...
feat: add retina screenshot presets
fix: handle expired reddit tokensGenerated post (X, one of two variants):
Shipped retina-quality screenshot presets for social captures today.
Also fixed a silent token-expiry bug on the Reddit posting path.
Small releases, steady progress.Publishing:
$ bip post x
Posting to X... done. https://x.com/you/status/...Posts improve over time: bip remembers variant preferences, learns editing patterns, and adapts voice to match yours.
Features
- Multi-provider AI: HTTP-based drafting with a unified prompt pipeline across Anthropic (Claude), Zhipu GLM, OpenAI, Google Gemini, Cohere, DeepSeek, and Qwen
- Draft with your coding agent: no API key needed if you're already running Claude Code, Cursor, Copilot, or Codex (see AI Drafting)
- CLI setup for API keys:
bip auth aiwrites keys into the project.env, if you want bip to draft on its own instead (see AI Drafting) - Multi-Platform Posting: X, LinkedIn, Reddit, HackerNews with per-platform strategies
- Smart Memory: Tracks preferences, edit patterns, and avoids repetition
- Browser Fallback: Playwright when APIs fail; HackerNews uses automation (no submit API)
- Voice:
bip soulandbip soul evolverefinesoul.mdfrom your behavior - Project Context:
BUILD_IN_PUBLIC.md, skills, and memory injected into prompts - Draft Review: Two variants per platform, pick/edit/skip, then save or post
- Ship:
bip shipdrafts, screenshots, and packages every platform in one pass, posting only where you agree - Capture: Platform-sized screenshots (og/x/linkedin/reddit/hn presets, element targeting, retina scale) and browser session recordings, exportable to mp4 or GIF, plus live terminal/CLI recordings for tools that aren't web pages
- MCP server:
bip mcpexposes status/history/capture/draft-preview as MCP tools for Claude Code / Claude Desktop - Feedback:
bip feedbackrates or reports issues in seconds, no typing required (see Commands) - Tests: Vitest suite under
test/(see test/README.md)
See ROADMAP.md for what's next (smarter capture, MCP server, Claude Code skill).
Found a bug or have a thought on what's working or not? Run bip feedback. It takes a rating, a message, or both, and opens a pre-filled GitHub issue for you to review before it's submitted.
Telemetry
bip sends anonymous usage events (which commands run, on which OS/Node/bip version) to help prioritize what to build next. It never sends git content, drafts, file paths, credentials, or your email. A random ID identifies your install, not you.
Disable it any time with bip telemetry off, or set BIP_TELEMETRY=0 in your
environment. Check the current state with bip telemetry. The random ID and your
on/off preference live in ~/.buildpublic/telemetry.json, not in any project directory.
Install
npm install -g build-in-publicQuick Start
cd your-project
bip init # scaffold config, skills, soul template
bip soul # define your posting voice (optional)
bip auth ai # set LLM API key → writes ./.env (or: bip auth ai glm)
bip auth x # set up social platform credentials (after bip init)
bip draft # generate posts from git activity
bip post # publish to platformsLoad order: a .env file in the current working directory is loaded automatically when you run bip. You can still use export ANTHROPIC_API_KEY=... if you prefer.
Usage
1. Initialize
bip initThis scaffolds into your project:
BUILD_IN_PUBLIC.md: your project's story, committed to git.buildpublic/config.json: credentials and platform config (gitignored).buildpublic/soul.md: your posting voice and personality (committed).buildpublic/skills/: per-platform posting strategies (committed).buildpublic/memory/: posting history and preference tracking (gitignored).buildpublic/posts/: saved draft JSON files.buildpublic/captures/: screenshots and videos (gitignored).claude/skills/build-in-public/SKILL.md: a Claude Code skill so bip works directly from Claude Code and Claude Desktop (see MCP Server)
bip init also asks which of a few archetypes best matches what you're doing (solo dev / open source, indie SaaS founder, career-visibility engineer) and pre-fills soul.md and the Target Audience/Preferred Platforms/Post Style sections of BUILD_IN_PUBLIC.md with a real starting voice for it, or you can pick "Start blank" for the old empty-template behavior. Either way, everything is yours to edit afterward.
Don't want to set any of this up yet? bip draft --preview generates one post straight from your git activity with just an LLM API key. No init, no social credentials, nothing saved.
2. Define Your Voice
bip soulAn interactive questionnaire that creates soul.md, your posting personality:
- Tone: Casual, technical, enthusiastic...
- Perspective: I/me, we/us, third person...
- Recurring themes: Topics you post about
- Words and phrases to avoid: Things that don't sound like you
- Example post: For calibration
Soul evolves over time. After a few drafts, run bip soul evolve to refine it based on how you actually edit posts.
3. Customize Platform Skills
Each platform has a strategy file in .buildpublic/skills/:
| File | What it controls |
|-------|----------------|
| skills/x.md | Character limits, thread strategy, hooks, hashtag policy |
| skills/linkedin.md | Word count, opening hooks, professional tone, formatting |
| skills/reddit.md | Title style, peer tone, discussion format, self-promotion rules |
| skills/hackernews.md | Title constraints, Show HN/Ask HN format, technical focus |
Edit these files to change how bip writes for each platform. They're injected directly into the AI prompt.
4. AI Drafting
bip draft, bip evolve, and bip soul evolve can each write content two ways: with a coding agent you already have running, or with bip's own LLM API key. Pick whichever fits.
Recommended: use your coding agent, no API key needed. If you're already running Claude Code, Cursor, Copilot, Codex, or similar, let it write the content with the model you already have:
bip draft --context-only # prints git activity + project context + voice as JSON, no LLM call
# hand that to your coding agent, ask it to write the post
bip draft --apply variants.json # saves what it wrote as a real draft, no LLM callvariants.json looks like:
{
"posts": [
{ "platform": "x", "text": "Shipped platform-aware screenshot presets today..." }
],
"attachments": []
}bip evolve and bip soul evolve work the same way, but --apply <file> takes a plain text file with the full updated document instead of JSON:
bip evolve --context-only # prints project doc + git log + posting history as JSON
bip evolve --apply updated-doc.md # saves the updated BUILD_IN_PUBLIC.md
bip soul evolve --context-only # prints current soul.md + edit history as JSON
bip soul evolve --apply updated-soul.mdIf the agent speaks MCP (see MCP Server), it can call bip_context/bip_save_draft, bip_evolve_context/bip_evolve_apply, or bip_soul_context/bip_soul_apply directly instead of shelling out. Either way, this only saves content; bip post is still the step that reviews and publishes a draft.
Alternative: bip generates content on its own, if you don't have a coding agent running. This needs at least one provider key in the environment.
Recommended: interactive setup (writes or updates ./.env in the project root):
bip auth ai # pick provider, paste key
bip auth ai glm # set GLM_API_KEY only
bip auth ai anthropic # set ANTHROPIC_API_KEY only
bip auth ai --list # show which provider env vars are set (masked)Environment variables (any one you configure can be used; see src/ai/providers.ts for the full list):
| Provider | Variable |
|-----------|----------------------|
| Anthropic | ANTHROPIC_API_KEY |
| OpenAI | OPENAI_API_KEY |
| Google | GOOGLE_API_KEY |
| Cohere | COHERE_API_KEY |
| DeepSeek | DEEPSEEK_API_KEY |
| Qwen | QWEN_API_KEY |
| GLM | GLM_API_KEY |
Multiple keys: If more than one provider is configured, bip prompts you to choose (or use BIP_AI_PROVIDER=glm, or bip draft --provider glm). You can save a default in .buildpublic/config.json as aiProvider when prompted.
5. Set Up Platform Credentials
bip auth x # X (Twitter) API keys
bip auth linkedin # LinkedIn access token + person URN
bip auth reddit # Reddit client ID + secret
bip auth hackernews # HN username + password (browser automation only)
bip auth --list # check credential status for all platformsThe main bip auth menu also includes AI / LLM API keys alongside social platforms.
| Platform | What you need | Where to get it | |----------|---------------|----------------| | X | App Key, App Secret, Access Token, Access Token Secret | developer.x.com | | LinkedIn | Access Token + Person URN | linkedin.com/developers | | Reddit | Client ID + Secret | reddit.com/prefs/apps (create a "script" app) | | HackerNews | Username + password | Your regular HN login (browser automation only) |
Credentials are stored in .buildpublic/config.json (automatically gitignored).
Workflow
Ship (draft + screenshot + package, in one command)
bip shipThe one-command version of draft, screenshot, and manual-export together, for when you just finished coding and want everything ready in one pass:
- Same drafting flow as
bip draft: git summary, optional focus, 2 variants per platform, pick/edit/skip. - Screenshots automatically, once per platform's crop, using a URL you save
the first time you're asked (
previewUrlin.buildpublic/config.json), never re-prompted after that. - Writes a manual-export folder (text + screenshot) for every accepted platform by default, so a ready-to-copy-paste package always exists, whether or not you post automatically next.
- For each platform with credentials configured, asks
Post to X now?(defaults to no), same API-then-browser-fallback behavior asbip post.
Prints the package folder path up front and again at the end, so it's usable
even if you decline every auto-post prompt. bip draft and bip post still
work exactly as before if you'd rather do it in two steps.
Generate Posts
bip draft
bip draft --provider glm # non-interactive when multiple keys exist- Reads your last 20 commits, changed files, and diff
- Shows a git summary, confirm before calling the API
- Asks if this post should focus on anything specific (optional, press Enter to skip)
- Sends everything to the configured LLM with:
BUILD_IN_PUBLIC.mdcontextsoul.mdvoice- Platform
skills - Posting
memory(variant prefs, edit rate, common edits, recent topics, posts to avoid repeating) - Your focus answer, if you gave one
- Returns 2 variants per platform: pick one, edit inline, or skip
- Saves draft to
.buildpublic/posts/YYYY-MM-DD-HHmmss.json - Records your variant choice and any edits to memory
Drafted text never uses em dashes and avoids generic AI phrasing like "game-changer", "seamless", and "unlock". This is enforced in the system prompt, not just a suggestion in the skill files.
If BUILD_IN_PUBLIC.md hasn't been updated in 30+ days, bip will nudge you to run bip evolve.
Publish
bip post # publish to all platforms
bip post x # publish to X only
bip post --dry-run # preview with character counts, no API callsFor each platform, bip post asks what to do: post now (official API first, falling back to Playwright browser automation), or save for manual copy-paste if you don't have API/developer access to a platform. Manual saves write post.txt (plus any screenshot) to .buildpublic/posts/<draft-id>/<platform>/ so you can open the folder, copy the text, and paste it in yourself, no account setup required. If both the API and browser attempts fail, bip offers the manual save as a fallback instead of leaving you with nothing. HackerNews always uses Playwright (no official submit API).
Evolve Your Project Doc
bip evolveThe AI reads your current BUILD_IN_PUBLIC.md, recent git log (50 commits), package.json, and posting history, then proposes updates section by section:
- Project Description: Deepens based on what's been shipped
- Tech Stack: Detects new/removed dependencies
- Milestones: Checks off completed items, suggests new ones based on recent direction
- Target Audience & Post Style: Only touches if clearly outdated
You review, edit, or discard each change. Adds a <!-- Last evolved: YYYY-MM-DD --> comment at the top.
Evolve Your Voice
bip soul evolveAnalyzes your posting memory (which variants you pick, how you edit AI-generated text, what you add or remove) and proposes soul.md refinements. Examples:
- "You consistently remove hashtags" → adds to your Avoid section
- "You always shorten LinkedIn posts" → notes conciseness preference in Tone
- "You prefer direct openers over questions" → updates hook style in Style
How the AI Prompt Works
When you run bip draft, the prompt is assembled from four sources:
┌─────────────────────────────────┐
│ System prompt │
│ ├── Base strategist instructions │
│ ├── Platform skills (from skills/*.md) │
│ └── Soul / voice (from soul.md) │
├─────────────────────────────────┤
│ User prompt │
│ ├── BUILD_IN_PUBLIC.md project context │
│ ├── Memory (variant prefs, edit rate, │
│ │ recent topics, posts to avoid) │
│ ├── Git activity (commits, diff, files)│
│ └── Output format instructions │
└─────────────────────────────────┘Everything except base instructions is editable by you.
Commands
| Command | Description |
|---------|-------------|
| bip init | Scaffold config, skills, soul template, and directories |
| bip auth | Interactive menu: AI keys or social platforms |
| bip auth ai [provider] | Save an LLM API key into .env (--list to show status) |
| bip auth <platform> | Save credentials for x, linkedin, reddit, or hackernews |
| bip auth --list | Show credential status for all social platforms |
| bip ship | Draft, auto-screenshot, and package every platform in one pass; optionally post |
| bip draft | Generate 2 post variants per platform from git activity (needs an LLM key) |
| bip draft --provider <id> | Force provider when multiple API keys exist |
| bip draft --preview | See one generated post with only an LLM key, no bip init needed, nothing saved |
| bip draft --context-only | Print the draft context as JSON, no LLM key needed, for drafting with your own coding agent |
| bip draft --apply <file> | Save posts drafted elsewhere (a JSON file of { posts, attachments }) as a real draft |
| bip post [platform] | Publish latest draft (optionally to one platform) |
| bip post --dry-run | Preview posts with character counts, no API calls |
| bip soul | Interactive questionnaire to create or redo soul.md |
| bip soul evolve | Propose soul.md refinements from posting patterns (needs an LLM key) |
| bip soul evolve --context-only / --apply <file> | Same, but evolve with your own coding agent instead of an LLM key |
| bip evolve | Update BUILD_IN_PUBLIC.md from recent project activity (needs an LLM key) |
| bip evolve --context-only / --apply <file> | Same, but evolve with your own coding agent instead of an LLM key |
| bip doctor | Check your setup for common issues |
| bip status | See platforms, credentials, recent drafts, and a posting-cadence nudge |
| bip history | Browse past drafts with content previews |
| bip metrics | Show engagement (likes/comments) for previously posted drafts on X, Reddit, and HackerNews |
| bip capture screenshot <url> | Save a screenshot (full-page by default) |
| bip capture screenshot <url> --preset x | Crop to a platform card size: og, x, linkedin, reddit, hn, desktop, mobile |
| bip capture screenshot <url> --selector <css> | Capture just one element instead of the page |
| bip capture screenshot <url> --scale 2 | Retina-quality output |
| bip capture screenshot <url> --wait-for <css> --delay <ms> | Wait for late-rendering content before capturing |
| bip capture record <url> | Record a browser session as webm (press Enter to stop) |
| bip capture record <url> --format mp4 | Same, then convert to mp4 (needs ffmpeg) |
| bip capture record <url> --format gif | Same, then convert to a GIF (needs ffmpeg; --gif-width, --gif-fps to tune it) |
| bip capture terminal | Record a live CLI/terminal session, not a web page (exit or Ctrl+D to stop) |
| bip capture terminal --format gif | Same, then convert to a GIF (needs agg; --theme to tune it) |
| bip mcp | Start bip as an MCP server (stdio), see MCP Server |
| bip feedback | Rate bip or send feedback, opens a pre-filled GitHub issue |
| bip feedback "message" | Send a message directly, skips the interactive prompt |
| bip feedback --rating <1-5> | Send just a rating, no click needed, sent instantly, no GitHub issue opens |
| bip telemetry | Show whether anonymous usage tracking is on, and your anonymous ID |
| bip telemetry off / on | Disable or re-enable anonymous usage tracking |
MCP Server
bip mcp runs bip as an MCP server over stdio, so
Claude Code or Claude Desktop can call it directly instead of you shelling out to a
separate terminal. Tools exposed:
| Tool | What it does |
|------|--------------|
| bip_status | Project name, platform credential status, recent drafts, cadence nudge |
| bip_history | Past drafts with previews (limit optional) |
| bip_capture_screenshot | Same options as bip capture screenshot (preset, selector, scale, waitFor, delay, fullPage) |
| bip_context | Recommended way to draft. Returns the git activity, project context, voice, and platform strategy bip would send to an LLM, without calling one. Draft the post yourself, then save it with bip_save_draft |
| bip_save_draft | Saves posts you drafted (posts, attachments optional) as a real draft. Does not publish |
| bip_draft_preview | Fallback when no coding agent is available: generates post variants using bip's own configured LLM key (platforms, provider, focus). Does not save or publish |
| bip_evolve_context | Recommended way to evolve BUILD_IN_PUBLIC.md. Returns the current doc, git log, package.json, and posting history bip would send to an LLM, without calling one |
| bip_evolve_apply | Saves a BUILD_IN_PUBLIC.md you evolved (content), stamping today's date |
| bip_soul_context | Recommended way to evolve soul.md. Returns the current soul.md, edit history, and posting stats bip would send to an LLM, without calling one |
| bip_soul_apply | Saves a soul.md you evolved (content), stamping today's date |
There is no bip_post tool. None of these tools publish anything: bip_save_draft,
bip_evolve_apply, and bip_soul_apply only write local files. The variant picking,
editing, and platform-by-platform post/manual/skip choices in bip post are
interactive by design, and publishing to a real social account isn't something an
MCP tool call should be able to trigger silently. Use the CLI for the actual publish
step.
Add it to Claude Desktop / Claude Code's MCP config:
{
"mcpServers": {
"build-in-public": {
"command": "bip",
"args": ["mcp"]
}
}
}Claude Code skill
bip init scaffolds .claude/skills/build-in-public/SKILL.md automatically. No
separate install step. It tells Claude Code to use the MCP tools above when connected,
fall back to the CLI otherwise, and never script or fake bip draft/bip post's
interactive prompts to save or publish on your behalf; that step always comes back to
you.
Local Data Structure
your-project/
├── BUILD_IN_PUBLIC.md # project context (committed)
└── .buildpublic/
├── config.json # credentials, platforms, optional aiProvider (gitignored)
├── soul.md # voice / personality (committed)
├── skills/ # platform strategies (committed)
│ ├── x.md
│ ├── linkedin.md
│ ├── reddit.md
│ └── hackernews.md
├── memory/ # posting history + prefs (gitignored)
│ ├── posting-history.json
│ └── preferences.json
├── posts/ # saved drafts
├── captures/ # screenshots + videos (gitignored)
└── hn-state.json # HN session cookies (gitignored)Requirements
- Node.js: 18+
- Either a coding agent (Claude Code, Cursor, Copilot, Codex) or at least one LLM API key for drafting, evolving BUILD_IN_PUBLIC.md, and evolving soul.md. See AI Drafting.
ffmpegonly if you usebip capture record --format mp4or--format gif. Plainbip capture record(webm) and all screenshots work without it.- Playwright's Chromium: installed automatically the first time a screenshot or recording actually runs (one-time, roughly 300MB). No manual step needed.
asciinemaand, optionally,aggonly if you usebip capture terminal.asciinemarecords the session (brew install asciinema),aggconverts it to a GIF with--format gif(brew install agg). Not needed for any other command.
Contributing
Issues and pull requests are welcome. See CONTRIBUTING.md for development setup, running tests, the architecture overview, and the npm publish process.
Troubleshooting
Common Issues
"API Error: Unable to connect to API: Self-signed certificate detected"
This can happen with corporate proxies or network inspection. Solutions:
Set NODE_EXTRA_CA_CERTS (recommended):
export NODE_EXTRA_CA_CERTS=/path/to/your-ca-bundle.pemInsecure workaround (last resort):
export NODE_TLS_REJECT_UNAUTHORIZED=0
"bip is not initialized in this project"
Run bip init first to scaffold the .buildpublic/ directory.
Platform credentials not working
Run bip auth --list to check which platforms have credentials configured. Re-run bip auth <platform> if needed.
LLM key not found / wrong provider
Run bip auth ai --list. Ensure you run bip from the project directory that contains your .env, or export the variable in your shell.
Tests failing with process.cwd() errors
The testing framework uses isolated test directories. Ensure test cleanup is working properly in test/setup.ts.
License
MIT
Acknowledgments
- LLM providers (Anthropic, OpenAI, Zhipu, and others) for content generation
- Commander.js for CLI parsing
- Playwright for browser automation
- Vitest for the testing framework
- All platform providers for their APIs and documentation
