Skip to main content

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.

  1. tb spawn creates a default prompt.json in the workspace with a _teabag section so the AI always knows to produce intent.json.
  2. Human fills the prompt field in prompt.json (the task for the model).
  3. AI reads prompt.json, writes intent.json (with at least intent.goal; optionally intent.files_to_modify, parent_experiment). The _teabag section ensures the AI generates intent.json before editing other files.
  4. Then run tb run agent_1 to 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 read prompt.json (or prompt.md) and write intent.json with intent.goal before tb run.

  • "Neither prompt.json nor prompt.md found"
    Run tb spawn to get a default prompt.json, or add prompt.json / prompt.md and fill the human prompt.

  • "Workspace for agent X does not exist"
    Run tb spawn <agent_name> first.

  • "patch failed" / "patch: command not found"
    Install patch (e.g. brew install patch). Required for tb runs accept and tb merge best.

  • Symlinks not supported (e.g. some Windows setups)
    teaBag writes workspaces/<agent_name>/ENV_PATH with 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). Use tb runs rank and tb 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 uses git diff when the repo has a .git directory. For non-git projects, runs are still recorded but diff.patch may be a placeholder.

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

teabag-0.1.0.tar.gz (22.2 kB view details)

Uploaded Source

Built Distribution

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

teabag-0.1.0-py3-none-any.whl (21.1 kB view details)

Uploaded Python 3

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

Hashes for teabag-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5759bae197e58dce79e700154c8f3e0b0b73d1a008bb52cd0c3a6562296d17a8
MD5 e80fe0f207e2daa7282830179f169cc0
BLAKE2b-256 efd1188bb230b7043dea36cee9eb301d4989aed97204c141a6c708b66428b4d0

See more details on using hashes here.

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

Hashes for teabag-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 faf5891064d7e348712758455bf62d08d1524b207c97798c708c4b8fd64f9833
MD5 46f0a6513cfd56a6a3ac051b23277795
BLAKE2b-256 9a2a665f2aff53f1cd6a0db77dcf2e843caa310317d3425a667d72d66ebcef82

See more details on using hashes here.

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