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:
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