AI-native version control CLI for safe AI-assisted development.
Project description
teaBag — How to Use
teaBag is a CLI for AI-native version control: it keeps your main codebase safe while AI tools edit code in isolated workspaces, and it records every run (prompt, intent, and diff) so you can review, compare, and merge changes in a structured way.
The CLI command is tb.
Installation
From the teaBag project root:
pip install -e .
This installs the tb command. Requires Python 3.10+ and a git repository (recommended) for diff capture.
Quick Start
cd /path/to/your/project
# 1. Initialize teaBag (creates .teabag/, workspaces/, .ai_history/, env_store/)
tb init
# 2. Create a workspace for an AI agent
tb spawn agent_1
# 3. Human fills prompt.json (tb spawn creates a default with _teabag section)
# AI reads prompt.json and writes intent.json (only intent.json first)
# 4. Point your AI at workspaces/agent_1 to edit code, then record the run
tb run agent_1
# 5. List runs
tb list-runs
# 6. When done, remove the workspace
tb delete-workspace agent_1
Your main project files stay untouched; all AI edits live under workspaces/agent_1/. Each tb run creates a snapshot under .ai_history/run_001/, run_002/, and so on.
Directory Layout
After tb init, your repo looks like this:
your_project/
├── .teabag/ # Config and metadata
│ ├── config.json
│ ├── experiments.json
│ └── snapshots/ # Workspace snapshots (see below)
├── .ai_history/ # Recorded runs (immutable: intent.json and all artifacts are read-only after creation)
│ └── run_001/
│ ├── prompt.json # or prompt.md (human prompt; _teabag section in .json)
│ ├── intent.json
│ ├── diff.patch
│ ├── metadata.json
│ ├── environment.json # Python version, packages
│ ├── tests.json # If teabag.json test_command is set
│ └── metrics.json # If teabag.json metrics_script is set
├── workspaces/ # One directory per agent
│ └── agent_1/
│ ├── venv # Symlink to shared env (or ENV_PATH file)
│ ├── prompt.json # default from tb spawn; human fills "prompt"; AI reads and writes intent.json
│ └── intent.json # written by AI from prompt.json
├── env_store/ # Shared virtualenvs (keyed by Python + requirements.txt)
└── src/ # Your real code (unchanged until you accept a run)
Workspaces and Shared Environments
Creating a workspace
tb spawn agent_1
tb spawn agent_2
Each workspace gets a directory under workspaces/ and a shared Python virtualenv (same Python version and repo-root requirements.txt share one env). The env is created under env_store/<hash>/ and linked as workspaces/<name>/venv.
Installing or changing packages
Use the workspace’s venv so all agents sharing that env see the same packages:
# From project root — no need to activate
workspaces/agent_1/venv/bin/pip install requests
workspaces/agent_1/venv/bin/pip install -r requirements.txt
workspaces/agent_1/venv/bin/pip uninstall -y some-package
Or activate first (Linux/macOS):
source workspaces/agent_1/venv/bin/activate
pip install requests
deactivate
If you change requirements.txt at the repo root, existing workspaces keep their current env until you delete and re-spawn them; new workspaces will use a new env hash.
Listing and pruning environments
tb env list # List registered shared envs
tb env prune # Remove missing envs from the registry
Recording a Run
Flow: prompt.json → AI writes intent.json → apply only those changes → then run the rest.
tb spawncreates a defaultprompt.jsonin the workspace with a_teabagsection so the AI always knows to produceintent.json.- Human fills the
promptfield inprompt.json(the task for the model). - AI reads
prompt.json, writesintent.json(with at leastintent.goal; optionallyintent.files_to_modify,parent_experiment). The_teabagsection ensures the AI generates intent.json before editing other files. - Then run
tb run agent_1to record the run (and optionally run tests/metrics).
Default prompt.json (created by tb spawn; human fills "prompt"):
{
"_teabag": {
"version": 1,
"instructions": "Read this prompt and write intent.json in this workspace. intent.json must have: \"intent\" object with \"goal\" (string, required), and optionally \"files_to_modify\" (array of file paths), \"parent_experiment\" (string). Do not modify any other files until intent.json is written.",
"required_intent_fields": ["intent.goal"],
"optional_intent_fields": ["intent.files_to_modify", "parent_experiment", "prompt"]
},
"prompt": "Optimize the database queries in db/query.py to reduce the N+1 problem."
}
Example intent.json (AI-written from that prompt):
{
"parent_experiment": "exp_001",
"prompt": "optimize database queries",
"intent": {
"files_to_modify": ["db/query.py"],
"goal": "reduce N+1 query problem"
}
}
You can use prompt.md instead of prompt.json (no default template); the AI must still write intent.json.
tb run agent_1
This creates a new run (e.g. .ai_history/run_002/) with copies of the prompt file, intent.json, diff.patch, metadata.json, and environment.json (and optionally tests.json / metrics.json from teabag.json). intent.json and all run artifacts are made read-only so the record cannot be modified after creation.
Inspecting and Comparing Runs
List all runs:
tb list-runs
Show full details for one run (metadata, intent, environment, tests/metrics summary):
tb runs show run_002
Compare two runs (diff size, test exit code, metrics):
tb runs compare run_001 run_002
Rank runs by test result, time, or diff size:
tb runs rank # Prefer passing tests, then newest
tb runs rank --by time # Newest first
tb runs rank --by diff # Smallest diff first
Applying Changes to the Main Repo
Accept a single run
Apply a run’s diff to the repo and mark its experiment as accepted:
tb runs accept run_002
Check first without modifying files:
tb runs accept run_002 --dry-run
Requires the patch command (e.g. brew install patch on macOS).
Merge the best runs automatically
Apply the top runs (ranked by tests, then time) that do not touch the same files as already-accepted runs:
tb merge best # Apply the single best non-conflicting run
tb merge best --limit 3 # Apply up to 3
tb merge best --limit 2 --dry-run # Only print what would be applied
See a merge plan for one run
tb merge plan run_002
Shows the run’s goal, touched files, test result, and whether it conflicts (overlapping files) with any already-accepted run.
Automation: Tests and Metrics
Put a teabag.json file in the repository root to run tests and an optional metrics script every time you run tb run <agent_name>.
Example:
{
"test_command": "pytest -q",
"test_timeout": 120,
"metrics_script": "scripts/collect_metrics.sh"
}
| Field | Description |
|---|---|
test_command |
Shell command run from the workspace directory. Exit code and output are stored in tests.json. |
test_timeout |
Timeout in seconds (default: 300). |
metrics_script |
Path (relative to repo root) to a script run from the workspace. Output is stored in metrics.json. |
If test_command is omitted, no tests run and tests.json is not created. If metrics_script is omitted or the file is missing, no metrics run. environment.json is always written for every run.
Snapshots and Multi-Agent Workflows
Workspace snapshot
Save a copy of a workspace (excluding venv) for later use or as a template:
tb workspace snapshot agent_1
This creates .teabag/snapshots/agent_1_<ISO8601>/.
Spawn many agents at once
# Create 5 workspaces: agent_1 .. agent_5
tb agents spawn 5
# Create 5 workspaces from a snapshot (use the snapshot directory name)
tb agents spawn 5 --template agent_1_20250116T120000Z
Task: create a task and spawn agents
Create a task and spawn N workspaces in one step:
tb task run "optimize database layer" --agents 3
This creates a task, spawns agent_1, agent_2, agent_3, and associates them with the task. Then run your AI in each workspace and record with tb run agent_1, etc.
List tasks:
tb task list
Command Reference
| Command | Description |
|---|---|
tb init |
Initialize teaBag in the current repo. |
tb spawn <agent_name> |
Create a workspace and link shared venv. |
tb run <agent_name> |
Record a run (prompt.json with _teabag + human prompt; AI must have written intent.json). |
tb list-runs |
List all recorded runs. |
tb runs show <run_id> |
Show full run details. |
tb runs compare <run_a> <run_b> |
Compare two runs. |
tb runs rank [--by tests|time|diff] |
Rank runs. |
tb runs accept <run_id> [--dry-run] |
Apply run’s diff to the repo. |
tb merge best [--limit K] [--dry-run] |
Apply best K non-conflicting runs. |
tb merge plan <run_id> |
Show merge plan and conflicts. |
tb workspace snapshot <agent_name> |
Snapshot workspace to .teabag/snapshots/. |
tb agents spawn <n> [--template NAME] |
Spawn n workspaces (agent_1 .. agent_n). |
tb task run "desc" [--agents N] [--template NAME] |
Create task and spawn N agents. |
tb task list |
List tasks. |
tb delete-workspace <agent_name> |
Remove a workspace. |
tb env list |
List shared environments. |
tb env prune |
Prune missing envs from registry. |
You can pass --repo-root /path/to/repo to any command (except init) to run from another directory.
Examples
Example 1: Single agent, then accept
tb init
tb spawn agent_1
# ... You fill prompt.json, AI writes intent.json and edits workspaces/agent_1/ ...
tb run agent_1
tb list-runs
tb runs show run_001
tb runs accept run_001 --dry-run
tb runs accept run_001
tb delete-workspace agent_1
Example 2: Multiple runs, compare and pick one
tb init
tb spawn agent_1
# First experiment
# Human fills "prompt" in workspaces/agent_1/prompt.json; AI writes intent.json (here, manual for demo)
echo '{"intent":{"goal":"add caching"}}' > workspaces/agent_1/intent.json
tb run agent_1
# Second experiment (new prompt in prompt.json, AI writes new intent.json)
echo '{"intent":{"goal":"use Redis"}}' > workspaces/agent_1/intent.json
tb run agent_1
tb runs compare run_001 run_002
tb runs rank
tb merge plan run_002
tb runs accept run_002
tb delete-workspace agent_1
Example 3: Parallel agents and merge best
tb init
tb task run "refactor auth module" --agents 3
# ... run AI in workspaces/agent_1, agent_2, agent_3; add intent + prompt in each ...
tb run agent_1
tb run agent_2
tb run agent_3
tb runs rank
tb merge best --limit 1 --dry-run
tb merge best --limit 1
tb delete-workspace agent_1
tb delete-workspace agent_2
tb delete-workspace agent_3
Example 4: Snapshot as template for more agents
tb init
tb spawn agent_1
# ... set up workspace with baseline code, intent, prompt ...
tb workspace snapshot agent_1
# Snapshot created: .teabag/snapshots/agent_1_20250116T120000Z
tb agents spawn 4 --template agent_1_20250116T120000Z
# Now agent_1, agent_2, agent_3, agent_4 all start from that snapshot
Troubleshooting
-
"intent.json not found"
AI must readprompt.json(orprompt.md) and writeintent.jsonwithintent.goalbeforetb run. -
"Neither prompt.json nor prompt.md found"
Runtb spawnto get a defaultprompt.json, or addprompt.json/prompt.mdand fill the human prompt. -
"Workspace for agent X does not exist"
Runtb spawn <agent_name>first. -
"patch failed" / "patch: command not found"
Installpatch(e.g.brew install patch). Required fortb runs acceptandtb merge best. -
Symlinks not supported (e.g. some Windows setups)
teaBag writesworkspaces/<agent_name>/ENV_PATHwith the absolute path to the env. Use that path to call pip or activate. -
merge best applies nothing
All runs may already be accepted, or every candidate conflicts (touches the same files as an accepted run). Usetb runs rankandtb merge plan <run_id>to inspect. -
Template snapshot not found
Use the snapshot directory name under.teabag/snapshots/(e.g.agent_1_20250116T120000Z), not a full path. -
Diff is empty
Diff usesgit diffwhen the repo has a.gitdirectory. For non-git projects, runs are still recorded butdiff.patchmay be a placeholder.
Project details
Release history Release notifications | RSS feed
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 teabag-0.1.0.tar.gz.
File metadata
- Download URL: teabag-0.1.0.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.7.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5759bae197e58dce79e700154c8f3e0b0b73d1a008bb52cd0c3a6562296d17a8
|
|
| MD5 |
e80fe0f207e2daa7282830179f169cc0
|
|
| BLAKE2b-256 |
efd1188bb230b7043dea36cee9eb301d4989aed97204c141a6c708b66428b4d0
|
File details
Details for the file teabag-0.1.0-py3-none-any.whl.
File metadata
- Download URL: teabag-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.7.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
faf5891064d7e348712758455bf62d08d1524b207c97798c708c4b8fd64f9833
|
|
| MD5 |
46f0a6513cfd56a6a3ac051b23277795
|
|
| BLAKE2b-256 |
9a2a665f2aff53f1cd6a0db77dcf2e843caa310317d3425a667d72d66ebcef82
|