-
Notifications
You must be signed in to change notification settings - Fork 0
Plans Command
bizarharness plan is a developer tool for creating local visual plans. A plan is a single source-of-truth .mdx file with an auto-generated HTML viewer/editor that runs in your browser via a tiny local server. Comments are stored in a sidecar JSON file. Everything is local — no network, no sharing, no remote storage.
# Create a new plan
bizarharness plan new my-featureThis creates plans/my-feature/ with four files, regenerates the HTML viewer, starts a local server on port 4321, and opens the viewer in your default browser. The server runs until you press Ctrl-C.
# Open an existing plan
bizarharness plan open my-feature
# List all plans
bizarharness plan list
# Delete a plan (with confirmation)
bizarharness plan delete my-feature
# Export the plan as MDX to stdout
bizarharness plan export my-feature > my-feature.mdx| Subcommand | Purpose |
|---|---|
new <slug> |
Create a new plan, regenerate HTML, start server, open browser |
open <slug> |
Open an existing plan in the browser (regenerates HTML first) |
list |
List all plans in the project, sorted by last edited |
delete <slug> |
Delete a plan directory (with confirmation prompt) |
export <slug> |
Print the plan's MDX content to stdout |
help |
Show usage |
The new and open subcommands start a local HTTP server. The server runs in the same process as the CLI and exits on Ctrl-C.
Each plan lives in its own directory:
plans/<slug>/
├── plan.mdx # source of truth — the plan content as MDX
├── plan.html # auto-generated viewer/editor (regenerable)
├── comments.json # comment data (regenerable from MDX)
└── meta.json # metadata — title, status, author, timestamps
-
plan.mdx— the source of truth. In git. -
meta.json— title, status, author, created, lastEdited. In git. -
plan.html— auto-generated from the template. Gitignored. -
comments.json— comment data. Gitignored.
The first time you run bizarharness plan new in a project, the CLI suggests adding these lines to .gitignore:
plans/*/plan.html
plans/*/comments.json
Slugs must:
- Be 1-64 characters long.
- Start with a lowercase alphanumeric character (
a-zor0-9). - Contain only lowercase alphanumerics and hyphens.
- Match the regex
^[a-z0-9][a-z0-9-]{0,63}$.
Examples: auth-redesign, v2-api, add-rate-limiting. Invalid: MyFeature (uppercase), -foo (starts with hyphen), feature_v2 (underscore not allowed).
When you open a plan in the browser, you see:
- Header — plan title, status, last edited, author.
- Table of contents — anchor links to all sections, auto-generated from headings.
-
Each section — rendered as styled HTML with:
- A "💬 Comments" button that opens a side panel showing all comments on that section.
- An "Add comment" textarea in the side panel.
- An "✏️ Edit" button at the top right that toggles all sections to editable textareas.
- Footer — Save / Discard buttons (only visible in edit mode).
When you click Save:
-
PUT /api/planwith the new MDX content. -
PUT /api/commentswith the new comments array. - The page reloads to re-render with the saved state.
When you add a comment:
-
POST /api/commentswith{ sectionId, text, author }. - The new comment appears in the side panel.
- The change persists to disk immediately (autosave).
The CLI writes these lines to your .gitignore the first time you run plan new in a project:
plans/*/plan.html
plans/*/comments.json
This keeps the source of truth (plan.mdx, meta.json) in version control while ignoring the regenerable viewer (plan.html) and the sidecar comments (comments.json).
If you want to commit comments to git (e.g., for shared review), remove the second line. If you want the HTML viewer in git (e.g., to publish as a static page), remove the first line.
The local server runs in the same process as the CLI. It:
- Tries port 4321 first, falls back to 4322, 4323, etc. (max 10 attempts).
- Binds to
127.0.0.1(localhost only). - Serves the HTML viewer at
GET /<slug>/. - Exposes the MDX source at
GET /api/plan(text/plain). - Exposes comments at
GET /api/comments(application/json). - Accepts saves at
PUT /api/planandPUT /api/comments. - Accepts new comments at
POST /api/comments. - Logs every request to stderr.
- Cleans up on SIGINT / SIGTERM.
The server has no external dependencies. It's a small Node http server, no framework, no CDN. Everything is local.
A typical workflow:
# 1. Draft a plan for a new feature
bizarharness plan new oauth-integration
# 2. Edit the plan in the browser (textareas toggle, save persists)
# Add sections, write the API contract, sketch the migration
# Leave comments for the team to review
# 3. Commit the source of truth
git add plans/oauth-integration/plan.mdx plans/oauth-integration/meta.json
git commit -m "docs(plan): draft oauth-integration plan"
# 4. Open the plan during standup
bizarharness plan open oauth-integration
# 5. Once the plan is approved, dispatch implementation
# (in opencode, with BizarHarness routing)
@tyr execute plans/oauth-integration/plan.mdx
# 6. When done, archive or delete
bizarharness plan delete oauth-integrationThe plan lives in your repo as long as the work is in flight. Once the implementation is merged, you can delete the plan directory (or keep it as a record of the design).
Next: Self-Improvement — how agents record lessons and improve over time.
Norse-pantheon multi-agent system for opencode.