diff --git a/examples/01-basic-workflow.sh b/examples/01-basic-workflow.sh new file mode 100755 index 0000000..bbe3414 --- /dev/null +++ b/examples/01-basic-workflow.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# Example: Basic grit workflow — single agent +# +# Demonstrates: init → claim → work → done + +set -euo pipefail + +PROJECT_DIR=$(mktemp -d) +echo "=== Creating sample project in $PROJECT_DIR ===" + +# Create a sample git repo with some code +cd "$PROJECT_DIR" +git init -q +mkdir -p src + +cat > src/math.ts << 'EOF' +export function add(a: number, b: number): number { + return a + b; +} + +export function subtract(a: number, b: number): number { + return a - b; +} + +export function multiply(a: number, b: number): number { + return a * b; +} + +export function divide(a: number, b: number): number { + if (b === 0) throw new Error("division by zero"); + return a / b; +} +EOF + +git add -A && git commit -q -m "initial commit" + +# 1. Initialize grit +echo "" +echo "=== Step 1: grit init ===" +grit init + +# 2. See what symbols are available +echo "" +echo "=== Step 2: grit symbols ===" +grit symbols + +# 3. Agent claims functions to work on +echo "" +echo "=== Step 3: Agent claims 'add' and 'subtract' ===" +grit claim -a agent-1 -i "add input validation" \ + "src/math.ts::add" \ + "src/math.ts::subtract" + +# 4. Check lock status +echo "" +echo "=== Step 4: grit status ===" +grit status + +# 5. Agent works in its isolated worktree +echo "" +echo "=== Step 5: Agent edits files in worktree ===" +WORKTREE="$PROJECT_DIR/.grit/worktrees/agent-1" +cat > "$WORKTREE/src/math.ts" << 'EOF' +export function add(a: number, b: number): number { + if (typeof a !== "number" || typeof b !== "number") throw new Error("invalid input"); + return a + b; +} + +export function subtract(a: number, b: number): number { + if (typeof a !== "number" || typeof b !== "number") throw new Error("invalid input"); + return a - b; +} + +export function multiply(a: number, b: number): number { + return a * b; +} + +export function divide(a: number, b: number): number { + if (b === 0) throw new Error("division by zero"); + return a / b; +} +EOF + +# 6. Done: auto-commit, rebase, merge, release locks +echo "" +echo "=== Step 6: grit done ===" +grit done -a agent-1 + +# 7. Verify clean state +echo "" +echo "=== Step 7: Final status (should be empty) ===" +grit status + +echo "" +echo "=== Done! Changes merged back to main branch ===" +git log --oneline -5 + +# Cleanup +rm -rf "$PROJECT_DIR" diff --git a/examples/02-parallel-agents.sh b/examples/02-parallel-agents.sh new file mode 100755 index 0000000..b4b69f7 --- /dev/null +++ b/examples/02-parallel-agents.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +# Example: Parallel agents — 3 agents working on the same file simultaneously +# +# Demonstrates: multiple claims on different functions in the SAME file, +# parallel worktrees, sequential done (merge serialization) + +set -euo pipefail + +PROJECT_DIR=$(mktemp -d) +echo "=== Creating sample project in $PROJECT_DIR ===" + +cd "$PROJECT_DIR" +git init -q +mkdir -p src + +cat > src/auth.ts << 'EOF' +export function validateToken(token: string): boolean { + return token.length > 0; +} + +export function refreshToken(token: string): string { + return token + "-refreshed"; +} + +export function revokeToken(token: string): void { + console.log("revoked:", token); +} + +export function generateToken(user: string): string { + return btoa(user + ":" + Date.now()); +} + +export function parseToken(token: string): { user: string; exp: number } { + const decoded = atob(token); + const [user, exp] = decoded.split(":"); + return { user, exp: parseInt(exp) }; +} +EOF + +git add -A && git commit -q -m "initial commit" + +# Initialize +grit init +echo "" +echo "=== Symbols indexed ===" +grit symbols + +# 3 agents claim different functions in the SAME file +echo "" +echo "=== Agent 1: claims validateToken + parseToken ===" +grit claim -a agent-1 -i "add JWT validation" \ + "src/auth.ts::validateToken" \ + "src/auth.ts::parseToken" + +echo "" +echo "=== Agent 2: claims refreshToken ===" +grit claim -a agent-2 -i "add expiry check" \ + "src/auth.ts::refreshToken" + +echo "" +echo "=== Agent 3: claims generateToken ===" +grit claim -a agent-3 -i "use crypto.randomUUID" \ + "src/auth.ts::generateToken" + +echo "" +echo "=== Status: 3 agents, same file, no conflicts ===" +grit status + +# Agent 2 tries to claim a symbol already held by Agent 1 +echo "" +echo "=== Agent 2 tries to claim parseToken (held by Agent 1) ===" +grit claim -a agent-2 -i "also want parseToken" \ + "src/auth.ts::parseToken" 2>&1 || echo " → Blocked as expected!" + +# Each agent edits in their own worktree +echo "" +echo "=== Agents work in parallel worktrees ===" +ls -la .grit/worktrees/ + +# Agent 1 finishes +echo "" +echo "=== Agent 1: done ===" +grit done -a agent-1 + +# Agent 2 finishes +echo "" +echo "=== Agent 2: done ===" +grit done -a agent-2 + +# Agent 3 finishes +echo "" +echo "=== Agent 3: done ===" +grit done -a agent-3 + +echo "" +echo "=== Final status: all locks released ===" +grit status + +echo "" +echo "=== Git log: each agent's merge is a separate commit ===" +git log --oneline -10 + +rm -rf "$PROJECT_DIR" diff --git a/examples/03-session-pr.sh b/examples/03-session-pr.sh new file mode 100755 index 0000000..6b435a4 --- /dev/null +++ b/examples/03-session-pr.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Example: Session workflow — feature branch + GitHub PR +# +# Demonstrates: session start → agents work → session pr → session end +# NOTE: This example requires a GitHub remote to create PRs. +# Run it in a real repo with `gh` CLI configured. + +set -euo pipefail + +echo "=== Session Workflow ===" +echo "This example shows the full session lifecycle." +echo "Run it in a real git repo with a GitHub remote." +echo "" + +# 1. Start a session (creates branch grit/) +echo "$ grit session start auth-refactor" +echo " → Creates branch grit/auth-refactor" +echo " → Records base branch for PR" +echo "" + +# 2. Agents claim and work +echo "$ grit claim -a agent-1 -i 'add JWT' src/auth.ts::validateToken" +echo "$ grit claim -a agent-2 -i 'add OAuth' src/auth.ts::oauthLogin" +echo " → Each agent gets an isolated worktree" +echo "" + +# 3. Check session status +echo "$ grit session status" +echo " → Shows: branch, base, active agents, locked symbols" +echo "" + +# 4. Agents finish +echo "$ grit done -a agent-1" +echo "$ grit done -a agent-2" +echo " → Each merge is serialized (no conflicts)" +echo "" + +# 5. Create PR +echo "$ grit session pr --title 'Auth refactor: JWT + OAuth'" +echo " → Pushes branch to origin" +echo " → Creates GitHub PR with session summary" +echo "" + +# 6. End session +echo "$ grit session end" +echo " → Cleans up expired locks" +echo " → Switches back to base branch" +echo "" + +echo "=== Full command sequence ===" +cat << 'CMD' +grit init +grit session start auth-refactor + +grit claim -a agent-1 -i "add JWT validation" src/auth.ts::validateToken +grit claim -a agent-2 -i "add OAuth flow" src/auth.ts::oauthLogin + +# ... agents edit in .grit/worktrees/agent-{1,2}/ ... + +grit done -a agent-1 +grit done -a agent-2 + +grit session pr --title "Auth refactor: JWT + OAuth" +grit session end +CMD diff --git a/examples/04-s3-backend.sh b/examples/04-s3-backend.sh new file mode 100755 index 0000000..88e9b32 --- /dev/null +++ b/examples/04-s3-backend.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# Example: S3-compatible backend — distributed lock coordination +# +# Demonstrates: configuring grit to use S3/R2/MinIO for locks, +# enabling multi-machine agent coordination. + +set -euo pipefail + +echo "=== S3 Backend Configuration ===" +echo "" +echo "By default, grit uses SQLite (local). For distributed teams" +echo "or cloud-based agents, switch to an S3-compatible backend." +echo "" + +echo "--- AWS S3 ---" +cat << 'CMD' +export AWS_ACCESS_KEY_ID=... +export AWS_SECRET_ACCESS_KEY=... + +grit init +grit config set-s3 --bucket my-grit-locks --region us-east-1 +grit config show +CMD + +echo "" +echo "--- Cloudflare R2 ---" +cat << 'CMD' +export AWS_ACCESS_KEY_ID=... # R2 API token +export AWS_SECRET_ACCESS_KEY=... + +grit init +grit config set-s3 \ + --bucket grit-locks \ + --endpoint https://.r2.cloudflarestorage.com \ + --region auto +CMD + +echo "" +echo "--- MinIO (self-hosted) ---" +cat << 'CMD' +export AWS_ACCESS_KEY_ID=minioadmin +export AWS_SECRET_ACCESS_KEY=minioadmin + +grit init +grit config set-s3 \ + --bucket grit-locks \ + --endpoint http://localhost:9000 \ + --region us-east-1 +CMD + +echo "" +echo "--- Google Cloud Storage (S3-compatible) ---" +cat << 'CMD' +export AWS_ACCESS_KEY_ID=... # HMAC key +export AWS_SECRET_ACCESS_KEY=... + +grit init +grit config set-s3 \ + --bucket grit-locks \ + --endpoint https://storage.googleapis.com \ + --region auto +CMD + +echo "" +echo "--- Switch back to local ---" +cat << 'CMD' +grit config set-local +grit config show +CMD + +echo "" +echo "=== How S3 locking works ===" +echo "Each lock is an S3 object:" +echo " Key: .grit/locks/{url_encoded_symbol_id}" +echo " Body: JSON LockEntry (agent, intent, TTL, timestamp)" +echo "" +echo "Atomic acquisition via conditional PUT (If-None-Match: *)" +echo " → Only one agent can create the lock object" +echo " → Race conditions handled with retry logic" diff --git a/examples/05-claude-code-integration.sh b/examples/05-claude-code-integration.sh new file mode 100755 index 0000000..ee6c536 --- /dev/null +++ b/examples/05-claude-code-integration.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# Example: Using grit with Claude Code (or any AI coding tool) +# +# Demonstrates: how an AI agent can use grit to coordinate +# with other agents on the same codebase. + +set -euo pipefail + +echo "=== Grit + Claude Code Integration ===" +echo "" +echo "Add this to your CLAUDE.md or agent system prompt:" +echo "" + +cat << 'PROMPT' +## Multi-Agent Coordination (grit) + +This repo uses grit for parallel agent coordination. +Before editing functions, claim them to prevent conflicts. + +### Before editing +```bash +# See what symbols exist +grit symbols --file src/auth.ts + +# Claim the functions you need +grit claim -a $AGENT_ID -i "your intent" \ + "src/auth.ts::validateToken" \ + "src/auth.ts::refreshToken" +``` + +### After editing +```bash +# Merge your changes and release locks +grit done -a $AGENT_ID +``` + +### Check for conflicts +```bash +# See who holds what +grit status + +# Plan before claiming +grit plan -a $AGENT_ID -i "add caching to auth" +``` + +### If blocked +```bash +# Wait and retry with heartbeat +grit heartbeat -a $AGENT_ID # refresh your TTL + +# Or check what's available +grit symbols --file src/auth.ts +# → shows which functions are free vs locked +``` +PROMPT + +echo "" +echo "=== Multi-agent orchestration script ===" +echo "" + +cat << 'SCRIPT' +#!/usr/bin/env bash +# Launch 3 Claude Code agents in parallel with grit coordination + +REPO_DIR=$(pwd) +grit init +grit session start feature-sprint + +# Agent 1: backend auth +claude -p "You are agent-1. Run: grit claim -a agent-1 -i 'auth' src/auth.ts::validateToken +Edit the function in .grit/worktrees/agent-1/src/auth.ts +Then run: grit done -a agent-1" & + +# Agent 2: backend API +claude -p "You are agent-2. Run: grit claim -a agent-2 -i 'api' src/api.ts::handleRequest +Edit the function in .grit/worktrees/agent-2/src/api.ts +Then run: grit done -a agent-2" & + +# Agent 3: frontend +claude -p "You are agent-3. Run: grit claim -a agent-3 -i 'ui' src/App.tsx::render +Edit the function in .grit/worktrees/agent-3/src/App.tsx +Then run: grit done -a agent-3" & + +# Wait for all agents +wait + +# Create PR with all changes +grit session pr --title "Feature sprint: auth + API + UI" +grit session end +SCRIPT diff --git a/examples/06-monitoring.sh b/examples/06-monitoring.sh new file mode 100755 index 0000000..ffa9ed1 --- /dev/null +++ b/examples/06-monitoring.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# Example: Monitoring and maintenance +# +# Demonstrates: status, watch, gc, heartbeat + +set -euo pipefail + +echo "=== Monitoring & Maintenance ===" +echo "" + +echo "--- Real-time event stream ---" +cat << 'CMD' +# Terminal 1: start watching +grit watch +# Output: +# [CLAIMED] agent=agent-1 symbols=[src/auth.ts::login] +# [CLAIMED] agent=agent-2 symbols=[src/api.ts::handler] +# [DONE] agent=agent-1 symbols=[src/auth.ts::login] +CMD + +echo "" +echo "--- Lock status ---" +cat << 'CMD' +grit status +# Output: +# * agent-1 -- add validation +# | src/auth.ts::validateToken (2026-03-19T14:30:00Z) [ttl=600s] +# | src/auth.ts::parseToken (2026-03-19T14:30:00Z) [ttl=600s] +# * agent-2 -- fix OAuth flow +# | src/auth.ts::oauthLogin (2026-03-19T14:31:00Z) [ttl=600s] +# +# 3/44 symbols locked +CMD + +echo "" +echo "--- Heartbeat (keep locks alive) ---" +cat << 'CMD' +# Refresh TTL for long-running agents +grit heartbeat -a agent-1 --ttl 1800 # extend to 30 minutes + +# Useful in a loop for very long tasks: +while agent_is_running; do + grit heartbeat -a agent-1 + sleep 300 # every 5 minutes +done +CMD + +echo "" +echo "--- Garbage collection ---" +cat << 'CMD' +# Clean up expired locks (agent crashed, TTL exceeded) +grit gc +# Output: Cleaned up 2 expired locks. + +# Run periodically via cron: +# */5 * * * * cd /path/to/repo && grit gc +CMD + +echo "" +echo "--- Symbol inspection ---" +cat << 'CMD' +# List all symbols +grit symbols + +# Filter by file +grit symbols --file auth + +# Plan: check availability + get claim command +grit plan -a my-agent -i "refactor auth middleware" +# Output: +# Planning for: refactor auth middleware +# Relevant symbols: +# > src/auth.ts::validateToken [function] FREE +# > src/auth.ts::refreshToken [function] LOCKED (agent-2) +# > src/auth.ts::revokeToken [function] FREE +# +# Claim with: +# grit claim -a my-agent -i "refactor auth middleware" \ +# "src/auth.ts::validateToken" "src/auth.ts::revokeToken" +CMD