Prepare for public launch: comprehensive examples, docs, and tooling
This commit adds everything needed for a successful public launch: **New Documentation** - SECURITY.md: Security policy and best practices - CLAUDE.md: Complete agent instructions for contributing to beads - Enhanced README with pain points, FAQ, troubleshooting sections - Added Taskwarrior to comparison table with detailed explanation **Installation** - install.sh: One-liner installation script with platform detection - Auto-detects OS/arch, tries go install, falls back to building from source - Updated README with prominent installation instructions **Examples** (2,268+ lines of working code) - examples/python-agent/: Full Python implementation of agent workflow - examples/bash-agent/: Shell script agent with colorized output - examples/git-hooks/: Pre-commit, post-merge, post-checkout hooks with installer - examples/claude-desktop-mcp/: Documentation for future MCP server integration - examples/README.md: Overview of all examples **Dogfooding** - Initialized bd in beads project itself (.beads/beads.db) - Created issues for roadmap (MCP server, migrations, demos, 1.0 milestone) - Exported to .beads/issues.jsonl for git versioning **Visual Assets** - Added screenshot showing agent using beads to README intro - Placed in .github/images/ following GitHub conventions This addresses all launch readiness items: ✅ Security policy ✅ Working agent examples (Python, Bash) ✅ Git hooks for automation ✅ FAQ addressing skeptics ✅ Troubleshooting common issues ✅ Easy installation ✅ Dogfooding our own tool ✅ Pain points that create urgency Ready to ship! 🚀 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# Python Agent Example
|
||||
|
||||
A simple Python script demonstrating how an AI agent can use bd to manage tasks.
|
||||
|
||||
## Features
|
||||
|
||||
- Finds ready work using `bd ready --json`
|
||||
- Claims tasks by updating status
|
||||
- Simulates discovering new issues during work
|
||||
- Links discovered issues with `discovered-from` dependency
|
||||
- Completes tasks and moves to the next one
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.7+
|
||||
- bd installed: `go install github.com/steveyegge/beads/cmd/bd@latest`
|
||||
- A beads database initialized: `bd init`
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Make the script executable
|
||||
chmod +x agent.py
|
||||
|
||||
# Run the agent
|
||||
./agent.py
|
||||
```
|
||||
|
||||
## What It Does
|
||||
|
||||
1. Queries for ready work (no blocking dependencies)
|
||||
2. Claims the highest priority task
|
||||
3. "Works" on the task (simulated)
|
||||
4. If the task involves implementation, discovers a testing task
|
||||
5. Creates the new testing task and links it with `discovered-from`
|
||||
6. Completes the original task
|
||||
7. Repeats until no ready work remains
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
🚀 Beads Agent starting...
|
||||
|
||||
============================================================
|
||||
Iteration 1/10
|
||||
============================================================
|
||||
|
||||
📋 Claiming task: bd-1
|
||||
🤖 Working on: Implement user authentication (bd-1)
|
||||
Priority: 1, Type: feature
|
||||
|
||||
💡 Discovered: Missing test coverage for this feature
|
||||
✨ Creating issue: Add tests for Implement user authentication
|
||||
🔗 Linking bd-2 ← discovered-from ← bd-1
|
||||
✅ Completing task: bd-1 - Implemented successfully
|
||||
|
||||
🔄 New work discovered and linked. Running another cycle...
|
||||
```
|
||||
|
||||
## Integration with Real Agents
|
||||
|
||||
To integrate with a real LLM-based agent:
|
||||
|
||||
1. Replace `simulate_work()` with actual LLM calls
|
||||
2. Parse the LLM's response for discovered issues/bugs
|
||||
3. Use the issue ID to track context across conversations
|
||||
4. Export/import JSONL to share state across agent sessions
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
```python
|
||||
# Create an agent with custom behavior
|
||||
agent = BeadsAgent()
|
||||
|
||||
# Find specific types of work
|
||||
ready = agent.run_bd("ready", "--priority", "1", "--assignee", "bot")
|
||||
|
||||
# Create issues with labels
|
||||
agent.run_bd("create", "New task", "-l", "urgent,backend")
|
||||
|
||||
# Query dependency tree
|
||||
tree = agent.run_bd("dep", "tree", "bd-1")
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
- [../bash-agent/](../bash-agent/) - Bash version of this example
|
||||
- [../claude-desktop-mcp/](../claude-desktop-mcp/) - MCP server for Claude Desktop
|
||||
Executable
+148
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple AI agent workflow using bd (Beads issue tracker).
|
||||
|
||||
This demonstrates how an agent can:
|
||||
1. Find ready work
|
||||
2. Claim and execute tasks
|
||||
3. Discover new issues during work
|
||||
4. Link discoveries back to parent tasks
|
||||
5. Complete work and move on
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class BeadsAgent:
|
||||
"""Simple agent that manages tasks using bd."""
|
||||
|
||||
def __init__(self):
|
||||
self.current_task = None
|
||||
|
||||
def run_bd(self, *args) -> dict:
|
||||
"""Run bd command and parse JSON output."""
|
||||
cmd = ["bd"] + list(args) + ["--json"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
|
||||
if result.stdout.strip():
|
||||
return json.loads(result.stdout)
|
||||
return {}
|
||||
|
||||
def find_ready_work(self) -> Optional[dict]:
|
||||
"""Find the highest priority ready work."""
|
||||
ready = self.run_bd("ready", "--limit", "1")
|
||||
|
||||
if isinstance(ready, list) and len(ready) > 0:
|
||||
return ready[0]
|
||||
return None
|
||||
|
||||
def claim_task(self, issue_id: str) -> dict:
|
||||
"""Claim a task by setting status to in_progress."""
|
||||
print(f"📋 Claiming task: {issue_id}")
|
||||
return self.run_bd("update", issue_id, "--status", "in_progress")
|
||||
|
||||
def create_issue(self, title: str, description: str = "",
|
||||
priority: int = 2, issue_type: str = "task") -> dict:
|
||||
"""Create a new issue."""
|
||||
print(f"✨ Creating issue: {title}")
|
||||
args = ["create", title, "-p", str(priority), "-t", issue_type]
|
||||
if description:
|
||||
args.extend(["-d", description])
|
||||
return self.run_bd(*args)
|
||||
|
||||
def link_discovery(self, discovered_id: str, parent_id: str):
|
||||
"""Link a discovered issue back to its parent."""
|
||||
print(f"🔗 Linking {discovered_id} ← discovered-from ← {parent_id}")
|
||||
subprocess.run(
|
||||
["bd", "dep", "add", discovered_id, parent_id, "--type", "discovered-from"],
|
||||
check=True
|
||||
)
|
||||
|
||||
def complete_task(self, issue_id: str, reason: str = "Completed"):
|
||||
"""Mark task as complete."""
|
||||
print(f"✅ Completing task: {issue_id} - {reason}")
|
||||
return self.run_bd("close", issue_id, "--reason", reason)
|
||||
|
||||
def simulate_work(self, issue: dict) -> bool:
|
||||
"""Simulate doing work on an issue.
|
||||
|
||||
In a real agent, this would call an LLM, execute code, etc.
|
||||
Returns True if work discovered new issues.
|
||||
"""
|
||||
issue_id = issue["id"]
|
||||
title = issue["title"]
|
||||
|
||||
print(f"\n🤖 Working on: {title} ({issue_id})")
|
||||
print(f" Priority: {issue['priority']}, Type: {issue['issue_type']}")
|
||||
|
||||
# Simulate discovering a bug while working
|
||||
if "implement" in title.lower() or "add" in title.lower():
|
||||
print("\n💡 Discovered: Missing test coverage for this feature")
|
||||
new_issue = self.create_issue(
|
||||
f"Add tests for {title}",
|
||||
description=f"While implementing {issue_id}, noticed missing tests",
|
||||
priority=1,
|
||||
issue_type="task"
|
||||
)
|
||||
self.link_discovery(new_issue["id"], issue_id)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def run_once(self) -> bool:
|
||||
"""Execute one work cycle. Returns True if work was found."""
|
||||
# Find ready work
|
||||
issue = self.find_ready_work()
|
||||
|
||||
if not issue:
|
||||
print("📭 No ready work found.")
|
||||
return False
|
||||
|
||||
# Claim the task
|
||||
self.claim_task(issue["id"])
|
||||
|
||||
# Do the work (simulated)
|
||||
discovered_new_work = self.simulate_work(issue)
|
||||
|
||||
# Complete the task
|
||||
self.complete_task(issue["id"], "Implemented successfully")
|
||||
|
||||
if discovered_new_work:
|
||||
print("\n🔄 New work discovered and linked. Running another cycle...")
|
||||
|
||||
return True
|
||||
|
||||
def run(self, max_iterations: int = 10):
|
||||
"""Run the agent for multiple iterations."""
|
||||
print("🚀 Beads Agent starting...\n")
|
||||
|
||||
for i in range(max_iterations):
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Iteration {i+1}/{max_iterations}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
if not self.run_once():
|
||||
break
|
||||
|
||||
print("\n✨ Agent finished!")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point."""
|
||||
try:
|
||||
agent = BeadsAgent()
|
||||
agent.run()
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running bd: {e}", file=sys.stderr)
|
||||
print(f"Make sure bd is installed: go install github.com/steveyegge/beads/cmd/bd@latest")
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n👋 Agent interrupted by user")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user