Skip to main content

A structured initialization framework for collaborative human & AI coding projects

Project description

Bora

Brazilian Portuguese for slang for let's go. A contraction of the more formal "vamos embora"

A structured initialization framework for collaborative human & AI coding projects

bora is a small CLI that scaffolds and maintains a documentation convention designed for working with AI coding agents across multiple sessions and multiple models. The files it generates live alongside your code in version control, so any model — Claude, GPT, Gemini, or local models — can read them and get oriented before writing a line.

Why

When you collaborate with AI on a project that takes more than one session, two problems compound:

  1. Context decay. Every new chat starts from zero. You re-explain the project from memory, often inconsistently.
  2. Model switching cost. Different models see different versions of your project. Switching means re-briefing.

bora addresses both by keeping a small, structured set of Markdown files in your repo:

  • AGENTS.md — operating instructions for AI agents.
  • docs/ai/Project.md — what we're building and why.
  • docs/ai/Architecture.md — how we've decided to build it, plus a decision log.
  • docs/ai/Tasks.md — auto-generated dashboard of current work.
  • docs/ai/tickets/*.md — the tickets themselves, with YAML frontmatter and Markdown body.

Start a new project by creating a blank repository and initialize bora. Then edit the Project.md file with what you want to build. Collaborate with your deired agent on the Architecture.md file to encapsulate design choices. Then, collaborate with your agent to create task Tickets. The 'Tasks.md' file is auto generated by bora to give you a status view of the current state of your project.

The CLI handles the mechanics: ticket creation with chronological IDs, status updates, frontmatter validation, dashboard regeneration, and briefing assembly with an optional token budget.

Installation

bora is a Python CLI. The recommended way to install Python CLIs globally is pipx, which puts the bora command on your PATH without polluting your system Python.

Option 1: pipx (recommended)

If you don't already have pipx:

# macOS
brew install pipx
pipx ensurepath

# Linux / WSL
python3 -m pip install --user pipx
python3 -m pipx ensurepath

# Windows (PowerShell)
python -m pip install --user pipx
python -m pipx ensurepath

After pipx ensurepath you may need to open a new terminal so the updated PATH takes effect.

Then install bora:

# Once published to PyPI:
pipx install bora

# Until then, install directly from GitHub:
pipx install git+https://github.com/yourname/bora.git

Verify:

bora --version

To upgrade later:

pipx upgrade bora

To uninstall:

pipx uninstall bora

Option 2: pip --user

If you don't want to install pipx, you can use pip --user:

pip install --user bora
# or, from GitHub:
pip install --user git+https://github.com/yourname/bora.git

This installs into your user site-packages and puts the bora script in your user binary directory (typically ~/.local/bin on Linux/macOS, %APPDATA%\Python\Scripts on Windows). If bora isn't found after install, see Troubleshooting PATH below.

Option 3: Development install

If you've cloned the repository and want to hack on bora:

git clone https://github.com/yourname/bora.git
cd bora
pip install -e .

The -e flag installs in editable mode, so changes to the source take effect without reinstalling.

Troubleshooting PATH

If you installed with pip --user and get bora: command not found, your user binary directory probably isn't on PATH.

Find where pip installed the script:

python3 -m site --user-base

The script lives in <user-base>/bin on Linux/macOS or <user-base>\Scripts on Windows. Add that directory to your shell's PATH — for bash/zsh, append to ~/.bashrc or ~/.zshrc:

export PATH="$HOME/.local/bin:$PATH"

Then source the file or open a new terminal.

This is the main reason pipx is recommended: it handles PATH for you.

Quick start

cd /path/to/your/repo
bora init claude                       # scaffold + install the bora skill for Claude Code
$EDITOR docs/ai/Project.md             # describe what you're building
bora ticket new "Set up database" --priority high
bora ticket set 01 status in-progress  # fuzzy id match works
bora status                            # regenerate Tasks.md
bora context --budget 8000             # print briefing for a fresh model session

bora init accepts one or more tool names (claude, opencode, or all) to install the bora skill in the same step. Run plain bora init if you only want the docs scaffold and no skill.

To brief a new chat session with a model, bora context prints all the files an AI agent should read, in order. Pipe it to your clipboard:

bora context | pbcopy            # macOS
bora context | xclip -selection clipboard  # Linux with xclip
bora context | clip              # Windows

Paste it as the first message of your conversation.

Commands

Command What it does
bora init [tool ...] Scaffold AGENTS.md and docs/ai/. Optionally install the bora skill for one or more tools (claude, opencode, all). Add --skill-global to install at the user-level location instead of in this repo.
bora ticket new "<title>" Create a new ticket. Options: --type, --priority, --parent.
bora ticket list List tickets. Filters: --status, --type, --priority, --blocked.
bora ticket show <id> Print a ticket's contents. Fuzzy ID match supported.
bora ticket set <id> <field> <value> Update a frontmatter field.
bora ticket subtask <id> <sub-id> <status> Update a frontmatter subtask's status.
bora ticket note <id> "<text>" Append a dated entry to the body Notes section.
bora status Regenerate Tasks.md.
bora context [--budget N] Print briefing content, optionally token-bounded.
bora lint Validate frontmatter and cross-references.
bora decision new "<title>" Append a templated decision entry to Architecture.md.
bora skill install <tool> Install the bora skill for an AI tool (claude, opencode, all).
bora skill uninstall <tool> Remove the bora skill for an AI tool.
bora skill list Show where the bora skill is installed for each known tool.

Run bora <command> --help for full options on any command.

Conventions

  • Ticket IDs are YYYYMMDD-NN-slug. The CLI generates them; don't pick your own.
  • Tasks.md is auto-generated. Never hand-edit it. Update tickets and run bora status.
  • Subtasks live in two places by design. Major subtasks go in frontmatter (queryable, appear in Tasks.md aggregation). Small subtasks are body checkboxes (counted but not aggregated by id).
  • Decisions append to Architecture.md. Don't rewrite history; add new entries when the design evolves.
  • AGENTS.md is the entry point for any AI tool. Tools like Claude Code, Cursor, and others increasingly look for this file at repo root.

Working with multiple models

bora is model-agnostic by design. It produces plain Markdown and YAML that any LLM can read. Patterns that work well:

  • For chat-only models (web Claude, ChatGPT, etc.), run bora context --budget <N> and paste the output as your first message. The model now has the same briefing every other model gets.
  • For agentic tools with file access (Claude Code, Cursor, Aider), the model reads AGENTS.md and follows its instructions to discover the rest. The CLI is callable from the agent's shell, so the model can run bora ticket set ... directly as work progresses.
  • For local models, the same flow works. Smaller models (under ~14B) may struggle with structured frontmatter — run bora lint after any model writes to a ticket file to catch errors.

Installing the bora skill

Claude Code, OpenCode, and several other agentic tools support skills — directories containing a SKILL.md file that the agent loads on demand when its description matches the current task. bora ships with a skill that briefs the agent on how to use the CLI and maintain the docs/ai/ files correctly.

For new projects, the simplest way is to install it as part of bora init:

cd /path/to/your/repo
bora init claude            # scaffold + install for Claude Code
bora init opencode          # scaffold + install for OpenCode
bora init claude opencode   # scaffold + install for both
bora init all               # same as above

Tool names are case-insensitive (Claude, claude, and CLAUDE all work). By default bora init <tool> installs the skill inside the current repo so it ships with the project; pass --skill-global to install at the user-level location instead.

For projects already initialized — or if you want to install/uninstall the skill on its own — use the skill command group.

Install globally (default) so every project gets it:

bora skill install claude            # ~/.claude/skills/bora/SKILL.md
bora skill install opencode          # ~/.config/opencode/skills/bora/SKILL.md
bora skill install all               # both at once

Or install per-project so the skill ships with the repo:

cd /path/to/repo
bora skill install claude --project  # ./.claude/skills/bora/SKILL.md

Inspect what's installed where:

bora skill list

Remove cleanly:

bora skill uninstall claude          # global
bora skill uninstall all --project   # everything in this repo

bora skill uninstall only deletes a SKILL.md whose YAML frontmatter declares name: bora — it won't clobber a skill it didn't install. Pass --force to override.

Tool Global path Project path
claude ~/.claude/skills/bora/SKILL.md ./.claude/skills/bora/SKILL.md
opencode ~/.config/opencode/skills/bora/SKILL.md ./.opencode/skills/bora/SKILL.md

OpenCode also reads from ~/.claude/skills/, so if you've installed for Claude you'll get the skill in OpenCode for free. Installing explicitly to OpenCode's own location is still the cleanest setup.

Contributing

Contributions welcome. The code is in bora/:

  • paths.py — repo-root detection and shared constants.
  • ticket.py — frontmatter parsing, fuzzy ID matching, body progress.
  • templates.py — scaffolded files (AGENTS.md, Project.md, etc.).
  • lint.py — validation rules.
  • status.pyTasks.md generation.
  • create.py — chronological ID generation.
  • context.py — briefing assembly.
  • skill.py — SKILL.md template and per-tool install/uninstall logic.
  • cli.py — Click-based command surface.

Before opening a PR, run through the smoke test in a scratch directory:

mkdir /tmp/test-bora && cd /tmp/test-bora && git init
bora init
bora ticket new "Test ticket" --priority high
bora ticket set 01 status in-progress
bora status
bora lint

License

MIT. See LICENSE if added, or change in pyproject.toml to taste.

Project details


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.2.0.tar.gz (31.3 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.2.0-py3-none-any.whl (32.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: bora-0.2.0.tar.gz
  • Upload date:
  • Size: 31.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bora-0.2.0.tar.gz
Algorithm Hash digest
SHA256 ff133d1484e8f60a4f5f0701d07a32d26709ca33aa9a6d888ecf8158fddbd38b
MD5 58187153c7b2e2e821c72b8225e42dc4
BLAKE2b-256 b165331fff5da8208763288799f64ec0ed4ef55fe8c83131149ecbf8f7ef203a

See more details on using hashes here.

Provenance

The following attestation bundles were made for bora-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: bora-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 32.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bora-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6588e5fd1a7d6db896aa4401afea844d10a7a502e53e44109bbdb63f59445b3c
MD5 98e532badb132ad47c2eea5bcaf81745
BLAKE2b-256 8da7621362ee155846d00a5a79efd03d4f535be85102d1865a29fb12481004f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for bora-0.2.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.

Supported by

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