Skip to main content

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.5 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 repo catalog can list fallback aliases per tier; a Bora project may opt in so each session fuzzy-matches those aliases to models this host can run. Bora does not choose models. Skip this unless you want cost-efficiency routing.

Skills for agentic tools. Claude Code, Cursor, and OpenCode get a ten-skill pack (bora-designbora-executebora-tddbora-finish). Install user-level or --project so the pack is committed with the repo.


Contents


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 executego 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 and, if synced, the project routing.yaml. Informational; no network.
bora dev routing sync <path> --host … (--available … | --probe …) Resolve routing.yaml for this host. --probe is the only network I/O in Bora.
bora dev report build <path> [--force] Assemble the project’s Completion document from ticket ## Completion report fragments. Draft — never overwrites without --force.
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 want cost-efficiency routing or already use a 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.

Two layers, kept deliberately separate:

  • Preferences — the repo catalog, .bora/models.yaml. What you want per tier, repo-wide. init and upgrade never create this file.
  • Resolution — a per-project routing.yaml, beside the Requirements file. What a given host actually has, and how it maps to tiers. Generated by bora dev routing sync, then freely hand-editable — a hand-edited tier is pinned and survives the next sync.
# .bora/models.yaml — preferences, repo-wide
routing:
  enabled: true
  tiers:
    premium:
      - grok latest high
      - claude opus
      - gpt-5
    standard:
      - composer
      - sonnet
      - gpt-5-mini
    economy:
      - glm latest
      - haiku
      - gpt-5-nano
    local:
      - ollama
  skills:
    bora-review: economy

Each tier is an ordered list of aliases (YAML lists are canonical; comma-separated strings work; a 0.7.0 single string is a one-item list).

Project opt-in — briefing routing: true. bora dev init asks (default no); --routing / --no-routing for scripts. Non-TTY init does not prompt. On opt-in, init writes a stub routing.yaml alongside the new project.

Session sync resolves routing.yaml against models the current host can actually run, and writes the result — resolved slugs and every model the endpoint offered, so an alias that matches nothing becomes an editable line instead of a question asked every session:

bora dev routing sync <project_path> --host cursor --available models.txt

Cursor, Claude Code, and OpenCode are first-class this way: the agent supplies the available-model list; the CLI never queries those products on its own. For an endpoint that exposes its own model list over HTTP (Ollama, an OpenAI-compatible gateway), pass --probe instead of --available:

bora dev routing sync <project_path> --host ollama-local --probe http://localhost:11434 --probe-key-env OLLAMA_KEY

--probe is the only network I/O anywhere in Bora, and only runs when you pass it in that invocation. The credential named by --probe-key-env is read from the environment at call time and never written to any file, printed, or logged.

bora dev routing show <project_path>
bora dev routing resolve <project_path> --host cursor --available models.txt

show prints the repo catalog’s ordered candidates, whether this project opted in, and — if routing.yaml exists — its sync date, host, and per-tier resolution with [pinned] markers. resolve is read-only, matching against an injected list without writing anything; sync is what actually updates routing.yaml. Missing catalog yaml → Status: disabled, not an error.

OmniRoute remains optional: opaque aliases in the catalog still work when they appear in the host’s available set. Pricing and provider selection stay outside Bora.


Ticket completion fragments and the Completion document

Each ticket template includes a ## Completion report section — Outcome / Files / Errors / Verify — that bora-review fills in before marking a ticket done. One ticket, one writing agent: no shared file, no lock, no clobber between tickets worked in parallel.

When the board is done, bora-finish runs:

bora dev report build <project_path>

This merges every ticket’s fragment, in ticket order, into (YYYY-MM-DD) {ProjectName} Completion.md beside the Requirements file — the same artifact Bora’s own release notes already use. It cross-checks each ticket’s claimed file list against git diff --name-only over that ticket’s reviewed commit range, flagging any mismatch rather than picking a side. It also generates a testing-guide skeleton from each ticket’s acceptance criteria, for the finishing agent to complete in prose.

Unlike Status.md, this document is a draft a human edits — re-running report build without --force never overwrites an existing Completion document; it writes a .new sibling with a diff instead.


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.

0.7.0 → 0.7.5: catalog tiers may be lists; per-project routing: true opt-in; bora dev routing resolve matches an injected available-model list. upgrade does not create models.yaml or add opt-in to existing briefings.

0.7.5 → 0.8.0: bora dev routing sync writes a per-project routing.yaml (resolved slugs plus the full available inventory; hand-edits are pinned); --probe adds opt-in HTTP discovery for Ollama/OpenAI-compatible endpoints — the only network I/O in Bora, and only when passed. Tickets gain a ## Completion report section; bora dev report build assembles the project’s Completion document from them. upgrade does not create routing.yaml, does not add routing: true to existing briefings, and does not delete an existing routing_cache (still read as a 0.7.5-compatibility fallback).

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.md is generated. Update tickets, then bora dev status <path>.
  • Commit message: {ticket-id} {task-id}: {title}. One commit per plan task. Bora does not run git commit; the agent does, after Commit criteria pass.
  • AGENTS.md is root-only. upgrade refreshes the managed region only.
  • Decisions go in the Requirements file. There is no decision command.

Contributing

python -m pytest tests/ -v
Module Role
cli.py dev / write commands
routing.py Model tiers, catalog lists, session match
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

bora-0.8.0.tar.gz (93.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bora-0.8.0-py3-none-any.whl (72.3 kB view details)

Uploaded Python 3

File details

Details for the file bora-0.8.0.tar.gz.

File metadata

  • Download URL: bora-0.8.0.tar.gz
  • Upload date:
  • Size: 93.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bora-0.8.0.tar.gz
Algorithm Hash digest
SHA256 5007871d94d3acf103a13937dd786e82618306d1c565bb0aef6674a4690b1089
MD5 970e7a7674b29d82f9f8e0e1098421c8
BLAKE2b-256 a8c83fe4499b58ee929b1df7d1fd17837d68b121770cf6f19645983be65129f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for bora-0.8.0.tar.gz:

Publisher: publish.yml on tonyknight/Bora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bora-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: bora-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 72.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bora-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 34019500e9d0dcd939df331bbb3a7955b8f1e6714232c04113e16556f42743a9
MD5 212026126db74f2882713c6fd5eedadd
BLAKE2b-256 5b48ef3c78b3e2a32fa0246aadd884e613428ba6019279d3c55d60405b307fff

See more details on using hashes here.

Provenance

The following attestation bundles were made for bora-0.8.0-py3-none-any.whl:

Publisher: publish.yml on tonyknight/Bora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 files

0.7.0

2 files

0.6.0

2 files

0.5.5

2 files

0.5.0

2 files

0.4.5

2 files

0.3.5

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page