Bora
Bora — Brazilian Portuguese slang for let's go
Bora keeps your AI collaborator oriented across sessions, models, and projects — using Markdown that lives in git.
A new chat starts from zero. Switching models starts the briefing over. Bora fixes both by putting the project’s source of truth in the repo: what you’re building, the spec, the tickets, and the commit-sized plan for each ticket. Any model that can read files can pick up where the last one left off.
Bora 0.7.0 has two profiles:
| Profile | For | You type | The agent runs |
|---|---|---|---|
dev |
Software | init, skill install, upgrade, and go in chat |
Tickets, plans, lint, status, TDD, review |
write |
Manuscripts | init, chapter, status |
Research logs and briefings — never the manuscript |
Capabilities (dev)
Project-level planning in git. Each software effort is a directory under docs/ai/<Codebase>/<Target>/<Project>/. The briefing, Requirements, tickets, and per-ticket implementation plans are ordinary Markdown + YAML. They diff, branch, and review like code. There is no plans/ folder and no cloud board: the plan for a ticket is a ## Implementation plan section on that ticket (T01, T02, …).
A defined workflow cycle. Human and agent agree architecture, then write Requirements. You say go. The agent creates tickets from the Tasks Breakdown, plans each ticket, implements with TDD, verifies, reviews, and continues until the board is empty. You watch commits of the form {ticket-id} T01: …. Merge and PR stay your git.
Optional model routing. Skills declare a provider-neutral model_tier. A router such as OmniRoute can map premium / standard / economy / local to models. Bora does not choose models. Skip this unless you already route.
Skills for agentic tools. Claude Code, Cursor, and OpenCode get a ten-skill pack (bora-design → bora-execute → bora-tdd → bora-finish). Install user-level or --project so the pack is committed with the repo.
Contents
- Install
- Quick start (dev)
- Workflow cycle
- What’s in the repo
- Commands
- Skills
- Optional model routing
- Writers
- Upgrading
- Contributing
Install
# pipx (recommended)
brew install pipx && pipx ensurepath # macOS; then open a new terminal
pipx install git+https://github.com/tonyknight/Bora.git
bora --version
# Later
pipx upgrade bora # CLI only — then in each repo:
bora dev upgrade # refresh AGENTS.md + installed skills
pip install --user bora works if ~/.local/bin is on PATH. From a clone: pipx install -e .
Every repo has a profile in .bora/profile.json (dev or write). Commands from the other profile exit with an error.
Quick start (dev)
Once on the machine, once per project. Example: a Share Extension in an existing photo app.
pipx install git+https://github.com/tonyknight/Bora.git
bora dev skill install all # or claude / cursor / opencode
# add --project to commit skills in this repo
cd ~/src/PhotoApp
bora dev init "PhotoApp/iOS/Share Extension" --tags Codebase,Target,Project
Edit the dated briefing (what/why — not Requirements yet):
$EDITOR "docs/ai/PhotoApp/iOS/Share Extension/(YYYY-MM-DD) Share Extension.md"
In a new agent session:
Work in
docs/ai/PhotoApp/iOS/Share Extension. Discuss architecture with me before filling Requirements. Do not create tickets yet.
Approve Requirements, then say go. The agent walks the board. Skill install is required for that cycle; without it you have Markdown only.
You type init, skill install, and upgrade. Ticket, plan, lint, and status are agent API (bora dev ticket … still works if you need them). Chat-only models: bora dev context "PhotoApp/iOS/Share Extension" and paste.
Workflow cycle
Briefing (what / why)
→ discuss architecture
→ Requirements (spec, tests, commit criteria, Tasks Breakdown)
→ you say go
→ tickets (from the breakdown)
→ plan on the ticket (T01…)
→ TDD → verify → review → next ticket
→ board empty → finish (merge / PR / keep)
Gates: no tickets until Requirements are approved; no production code until that ticket has an implementation plan; no done without the Requirements Commit criteria. After go, the agent does not ask whether to continue.
bora-execute may isolate work in a git worktree and record origin_branch on the briefing. Finish merges only to that branch.
What’s in the repo
bora dev init "QromaCore/Hamburg/Gallery Refactor" creates:
AGENTS.md ← agent instructions (repo root, once)
.bora/profile.json ← profile lock (dev)
docs/ai/QromaCore/Hamburg/Gallery Refactor/
(YYYY-MM-DD) Gallery Refactor.md
(YYYY-MM-DD) Gallery Refactor Requirements.md
Status.md ← generated; never hand-edit
tickets/
Multiple projects can share one repo. Every command takes an explicit <project_path> (last path segment is the project name). Deeper paths are fine.
| File | Role in git |
|---|---|
| Briefing | Intent — what and why |
| Requirements | Agreed spec. Tasks Breakdown becomes tickets. Not a commit script |
| Ticket | Work item + YAML state (status, depends_on, plan_status) + ## Implementation plan |
Status.md |
Dashboard regenerated by bora dev status <project_path> |
Ticket IDs are YYYYMMDD-NN-slug, unique per project. Don’t rename ticket files.
Dev commands
Every ticket/plan/status command requires <project_path> first.
| Command | What it does |
|---|---|
bora dev init <path> [--tags …] [--force] |
Scaffold briefing, Requirements, Status.md, tickets/. Writes root AGENTS.md only if missing. Don’t use --force to upgrade — use bora dev upgrade. |
bora dev ticket new | list | show | set | note | subtask |
Create and update tickets. set status done fills closed. |
bora dev plan show | set | task |
Implementation plan on the ticket. No bora dev plan new, no bora dev execute — go in chat starts bora-execute. |
bora dev status <path> |
Regenerate that project’s Status.md. |
bora dev context <path> [--budget N] |
Print a pasteable briefing for a fresh model. |
bora dev lint <path> |
Validate ticket frontmatter and cross-references. |
bora dev routing show <path> |
Print model-tier config. Informational; no network. |
bora dev upgrade |
Refresh managed AGENTS.md + already-installed skills. Does not touch project docs. |
bora dev skill install | uninstall | list |
Ten-skill pack for claude, cursor, opencode, or all. --project installs inside the repo. |
Removed since 0.4.5: bora dev project, bora dev decision (record decisions in Requirements).
AI tool skills
Agentic tools load a SKILL.md when its description matches the task. Bora ships ten:
| Skill | When |
|---|---|
bora |
Session start in a bora project |
bora-design |
Architecture before Requirements |
bora-plan |
Ticket needs ## Implementation plan |
bora-tdd |
Failing test → code → verify → commit |
bora-execute |
You said go / resume the board |
bora-worktree |
Optional git isolation at execute start |
bora-verify |
Before claiming tests/task/ticket/board complete |
bora-review |
After a ticket’s last commit, before done |
bora-debug |
Unexpected verify/build failure (not expected RED) |
bora-finish |
Board complete — merge to origin_branch, PR, or keep |
bora dev skill install all # user-level (~/.cursor/skills, ~/.claude/skills, …)
bora dev skill install cursor --project # committed at .cursor/skills/
bora dev skill list
bora dev skill uninstall cursor --project
Uninstall only removes bora-owned skill directories unless you pass --force.
| Tool | User-level | Project-level |
|---|---|---|
claude |
~/.claude/skills/ |
.claude/skills/ |
cursor |
~/.cursor/skills/ |
.cursor/skills/ |
opencode |
~/.config/opencode/skills/ |
.opencode/skills/ |
Optional model routing
Advanced. Ignore this unless you already use a model router. Not part of Quick start.
Bora does not choose models. Bora identifies the relative reasoning requirements of its workflows and optionally communicates those requirements to compatible routing systems.
On install/upgrade, each skill’s frontmatter includes model_tier: premium, standard, economy, or local. Hosts that don’t understand the field ignore it. Core skills never embed provider model names.
Add .bora/models.yaml yourself if you want mappings. init and upgrade never create it.
routing:
enabled: true
tiers:
premium: auto/smart
standard: auto/coding
economy: auto/cheap
local: auto/offline
skills:
bora-review: economy
tiers values are opaque identifiers for your router (for example an OmniRoute alias). skills overrides a default without editing installed SKILL.md files.
bora dev routing show <project_path> prints the effective table. Missing yaml → Status: disabled, not an error. Pricing, fallbacks, and provider selection stay in the router.
For writers
bora write init scaffolds a manuscript project. Agents log research; they never write the chapter file.
AGENTS.md
doc/ai/Project.md
Summary.md ← ephemeral briefing
Chapters/Chapter 001 - The Arrival/
001 - The Arrival.md ← author only
001 - ChapterProject.md ← beats, notes
001 - Research.md ← AI log
mkdir my-novel && cd my-novel
bora write init
bora write chapter "The Arrival"
bora write status # paste into a new chat; save reply as Summary.md
bora write skill install obsidian # optional vault prompt
Chapter IDs increment from the max existing ID (deleting a chapter does not reuse its number). bora write status archives Summary.md before printing a fresh briefing.
Working across models
Plain Markdown and YAML. Chat-only: paste bora dev context <path> or bora write status. Agentic tools: read AGENTS.md and the skill pack. Local models work the same; run bora dev lint <path> after they write tickets.
Upgrading
CLI upgrade does not rewrite a repo. In each project:
pipx upgrade bora
bora dev upgrade # AGENTS.md managed region + installed skills
0.6.0 → 0.7.0: skills gain model_tier. No .bora/models.yaml is created. Project docs are untouched. 0.6.x projects remain valid.
Do not use bora dev init --force as an upgrade path. Review git diff AGENTS.md and keep local rules under Project-specific instructions.
Older jumps (0.5.x skill pack, 0.4.5 hierarchy, 0.3.x dev/write split): run bora dev upgrade the same way. 0.4.5 replaced flat docs/ai/Project.md with hierarchical projects; there is no automated migration.
Dev conventions (short)
- Plans on the ticket, never Requirements, never
plans/. Status.mdis generated. Update tickets, thenbora dev status <path>.- Commit message:
{ticket-id} {task-id}: {title}. One commit per plan task. Bora does not rungit commit; the agent does, after Commit criteria pass. AGENTS.mdis root-only.upgraderefreshes the managed region only.- Decisions go in the Requirements file. There is no
decisioncommand.
Contributing
python -m pytest tests/ -v
| Module | Role |
|---|---|
cli.py |
dev / write commands |
routing.py |
Model tiers and .bora/models.yaml |
ticket.py / plan.py / status.py / lint.py |
Board |
skill.py / skill_pack.py |
Dev skill pack |
templates.py |
Scaffolded files |
upgrade.py |
bora dev upgrade |
writer_*.py |
Write profile |
License
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bora-0.7.0.tar.gz.
File metadata
- Download URL: bora-0.7.0.tar.gz
- Upload date:
- Size: 68.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2db1898c60833988328a85e6db9075aca9939b6397a1bdf72fa9355b7ffce0c2
|
|
| MD5 |
89696aac504cfc1df67b4ebc28f7d9d3
|
|
| BLAKE2b-256 |
e1b61cef53d40c6da3743ab12cbaeee6d095053bcc99a9615bb2f6292e2ef4db
|
Provenance
The following attestation bundles were made for bora-0.7.0.tar.gz:
Publisher:
publish.yml on tonyknight/Bora
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bora-0.7.0.tar.gz -
Subject digest:
2db1898c60833988328a85e6db9075aca9939b6397a1bdf72fa9355b7ffce0c2 - Sigstore transparency entry: 2499375125
- Sigstore integration time:
-
Permalink:
tonyknight/Bora@0887d74efa56363550e73217fed20eaf4962c860 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/tonyknight
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0887d74efa56363550e73217fed20eaf4962c860 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bora-0.7.0-py3-none-any.whl.
File metadata
- Download URL: bora-0.7.0-py3-none-any.whl
- Upload date:
- Size: 57.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cd1b7f1d9bac9ac9f874f70ef27a15a741a4774545167c71ec9779ee1b2fef4
|
|
| MD5 |
52f1478b7d0784695d3740783668ba85
|
|
| BLAKE2b-256 |
7d49fee2cdc40917ce6fcc8ef733b5ae15610bca135a4aa4de2537f5f4c4d82c
|
Provenance
The following attestation bundles were made for bora-0.7.0-py3-none-any.whl:
Publisher:
publish.yml on tonyknight/Bora
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bora-0.7.0-py3-none-any.whl -
Subject digest:
4cd1b7f1d9bac9ac9f874f70ef27a15a741a4774545167c71ec9779ee1b2fef4 - Sigstore transparency entry: 2499375226
- Sigstore integration time:
-
Permalink:
tonyknight/Bora@0887d74efa56363550e73217fed20eaf4962c860 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/tonyknight
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0887d74efa56363550e73217fed20eaf4962c860 -
Trigger Event:
push
-
Statement type: