
Devloop
- 1 installs
- Updated March 16, 2026
- 89jobrien/pjlib
devloop is a Claude Code skill that helps run and interpret the DevLoop development observability tool - a Rust TUI for git activity and Claude session analysis - and contribute to its codebase.
About
devloop is a Claude Code skill that helps developers run and interpret the DevLoop development observability tool, a Rust TUI that visualizes git activity and Claude AI sessions. It wraps DevLoop commands like just analyze, just logs, and just export, and explains council-mode analysis, health scores, and risk levels for a branch before merging. It also guides contributors working on DevLoop's own hexagonal-architecture Rust codebase. A developer uses it to get a pre-merge health read on a branch and to review past Claude sessions against commits.
- Helper for the DevLoop Rust-based development observability tool
- Runs and interprets council-mode branch analysis with 0.0-1.0 health scores
- Correlates git activity with Claude Code sessions to surface productivity patterns
Devloop by the numbers
- 1 all-time installs (skills.sh)
- Ranked #982 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
devloop capabilities & compatibility
Free skill; DevLoop's AI analysis needs an OPENAI_API_KEY or ANTHROPIC_API_KEY
- Capabilities
- branch analysis · code review · development observability · session review
- Works with
- github · openai · anthropic
- Use cases
- code review · debugging
- Pricing
- Bring your own API key
- Requires keys
- OPENAI_API_KEYORANTHROPIC_API_KEY
What devloop says it does
DevLoop is a Rust-based development observability tool that provides a TUI for visualizing git activity and Claude AI sessions.
npx skills add https://github.com/89jobrien/pjlib --skill devloopAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| Last updated | March 16, 2026 |
| Repository | 89jobrien/pjlib ↗ |
What it does
Run DevLoop branch analysis and interpret council-mode health scores before merging, and navigate DevLoop's Rust codebase.
Who is it for?
Running DevLoop council-mode branch analysis and interpreting health scores before a merge
Skip if: Projects not using the DevLoop tool or its Rust codebase
When should I use this skill?
You are running devloop, analyzing a branch, interpreting council mode, or working on the DevLoop Rust codebase
What you get
A council-mode health read (0.0-1.0), risk level, and recommendations per branch, plus guidance on the DevLoop codebase.
- branch health score
- council-mode analysis with risk level and recommendations
- JSON timeline export
By the numbers
- 5 council-mode analyst perspectives
- health scores on a 0.0-1.0 scale with 4 quality bands
Files
DevLoop Development Observability Skill
A comprehensive helper for working with the DevLoop development observability tool - both using it to analyze development patterns and contributing to its development.
Overview
DevLoop is a Rust-based development observability tool that provides a TUI for visualizing git activity and Claude AI sessions. This skill helps you:
1. Run DevLoop commands - Quick access to analysis, logs, export, and TUI 2. Interpret analysis results - Understand council mode insights and health scores 3. Analyze development patterns - Review git activity and Claude session metadata 4. Develop DevLoop itself - Navigate hexagonal architecture and BAML schemas
When to Use This Skill
Use this skill when you need to:
- Run DevLoop analysis on a branch and interpret the results
- Understand council mode perspectives (Strict Critic, Creative Explorer, etc.)
- Review Claude Code session transcripts and development patterns
- Work on DevLoop's codebase (architecture, BAML, GKG integration)
- Debug or extend DevLoop features
- Generate development observability insights
Prerequisites
For using DevLoop:
- DevLoop installed and built (
just runworks) - Git repository to analyze
OPENAI_API_KEYorANTHROPIC_API_KEY(for AI analysis)
For DevLoop development:
- Rust toolchain (edition 2024)
justcommand runner- Optional: GKG server for code structure integration
Core Capabilities
1. DevLoop Commands Wrapper
Quick access to common DevLoop commands with context about when and how to use them.
Available Commands:
# AI branch analysis (single perspective)
just analyze [BRANCH]
# AI branch analysis (multi-role council mode)
just analyze --council [BRANCH]
# View Claude Code session transcripts
just logs [SESSION]
# Export timeline data as JSON
just export
# Start the interactive TUI
just run
# Development commands
just dev # Debug mode
just test # Run tests
just fmt # Format code
just check # Quick compile check
just relay # WebSocket relay serverWhen to use each command:
analyze- Quick health check on a branch before merginganalyze --council- Deep analysis from multiple AI perspectives (security, performance, creativity, etc.)logs- Review past Claude Code sessions and development historyexport- Get structured data for custom analysis or reportingrun- Interactive exploration of git activity and timeline
2. Branch Analysis Helper
Council Mode Perspectives:
DevLoop's council analysis provides insights from 5 different AI roles:
1. Strict Critic - Conservative risk assessment, focuses on potential issues 2. Creative Explorer - Innovation opportunities, creative solutions 3. General Analyst - Balanced view, overall health assessment 4. Security Reviewer - Security concerns, vulnerability detection 5. Performance Analyst - Performance implications, optimization opportunities
Interpreting Results:
Health scores range from 0.0 to 1.0:
- 0.8-1.0 - Excellent, ready to merge
- 0.6-0.8 - Good, minor improvements suggested
- 0.4-0.6 - Fair, address recommendations before merging
- 0.0-0.4 - Poor, significant issues need attention
Each analyst provides:
health_score- Numeric assessmentrisk_level- "low" | "medium" | "high"insights- Array of specific observationsrecommendations- Actionable suggestions
Example workflow:
# Run council analysis on current branch
just analyze --council
# Review different perspectives
# - Check Strict Critic for blockers
# - Review Security Reviewer for vulnerabilities
# - Consider Creative Explorer for enhancements
# - Use General Analyst for overall decision
# If health score < 0.6, address recommendations
# Then re-run analysis before merging3. Development Observability
Git Activity Analysis:
DevLoop tracks:
- Branch lifetime and activity patterns
- Commit frequency and timing
- Session correlation with commits
- Development rhythm and focus areas
Claude Session Metadata:
Located in:
~/.claude/projects/- Project configurations~/.claude/transcripts/- Session transcripts
DevLoop correlates sessions with git activity to:
- Identify which sessions led to which commits
- Detect context switches and multitasking
- Measure time between planning (sessions) and implementation (commits)
- Surface productivity patterns
Productivity Insights:
- Session-to-commit lag - Time between AI assistance and implementation
- Branch focus - Single vs. multi-branch development patterns
- Commit batching - Small frequent commits vs. large batches
- AI reliance - Correlation between session frequency and code quality
4. DevLoop Development
Architecture Overview:
DevLoop uses hexagonal (ports-and-adapters) architecture:
┌─────────────────────────────────────────┐
│ TUI Layer (crates/cli) │
│ - Ratatui UI components │
│ - App<T, B, I> generic over adapters │
└───────────────┬─────────────────────────┘
│ Trait boundaries
┌───────────────▼─────────────────────────┐
│ Domain Layer (crates/components) │
│ - Pure domain models (zero deps) │
│ - Trait-based ports: │
│ • TimelineProvider │
│ • BranchAggregator │
│ • InsightProvider │
└───────────────┬─────────────────────────┘
│ Trait implementations
┌───────────────▼─────────────────────────┐
│ Adapter Layer (crates/cli/adapters) │
│ - GitAdapter (git2-based) │
│ - BamlAdapter (AI analysis) │
│ - GkgAdapter (code structure) │
│ - UnifiedAdapter (composition) │
│ - CouncilAdapter (multi-role AI) │
└─────────────────────────────────────────┘Key Design Principles:
1. Domain purity - components/src/domain.rs has zero external dependencies 2. Dependency injection - App receives trait objects, not concrete types 3. Testability - Trait boundaries enable test doubles without mocking 4. Serializable schema - components/src/schema.rs for cross-runtime rendering
Workspace Crates:
- `crates/cli` - Main TUI application (ratatui), entry point, adapters
- `crates/components` - Domain models, ports (traits), git adapter
- `crates/baml` - AI analysis schemas and generated client
- `crates/slides` - BAML-powered slide generation with ppt-rs
- `crates/devloop-cli` - Non-interactive CLI for agents/scripting
- `crates/relay` - WebSocket broadcast server for events
BAML Development:
BAML files define AI analysis functions in crates/baml/baml_src/:
// Function definition
function AnalyzeBranch_StrictCritic(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
) -> BranchInsight {
client CustomGPT5Mini
prompt #"
You are a STRICT CRITIC reviewing a development branch.
Branch: {{ branch_name }}
Commits: {{ commit_count }}
Sessions: {{ session_count }}
Recent commits:
{{ commits }}
Recent sessions:
{{ sessions }}
Focus on risks, issues, and conservative assessment.
{{ ctx.output_format }}
"#
}BAML Best Practices (from rules/baml.md):
- Classes use PascalCase, fields use snake_case
- All fields need
@descriptionannotations - Always end prompts with
{{ ctx.output_format }} - Use Mini models for simple extraction, full models for reasoning
- Define clients in
clients.bamlfor reusability - Descriptive test names:
test analyze_active_feature_branch
GKG Integration:
GitLab Knowledge Graph provides code structure:
// Fetch code definitions
let definitions = gkg_adapter.get_definitions("src/main.rs").await?;
// Fetch code references
let references = gkg_adapter.get_references("function_name").await?;
// Get repository map
let repo_map = gkg_adapter.get_repo_map().await?;GKG Setup (v0.25.0+):
# Stop server before indexing
gkg server stop
# Index project
gkg index .
# Start server
gkg server startImportant: v0.25.0+ removed HTTP indexing API - use CLI directly.
Common Development Tasks:
# Run tests
just test
# Run specific package tests
cargo test -p devloop-cli
# Format all code
just fmt
# Lint
cargo clippy --workspace
# Quick compile check
just check
# Clean build artifacts
just clean
# Simultaneous relay + TUI dev
zellij --layout devloop-layout.kdlWorkflow Examples
Example 1: Pre-merge Branch Analysis
# Scenario: About to merge feature/auth branch
# Goal: Ensure branch is ready for merge
# Step 1: Run council analysis
just analyze --council feature/auth
# Step 2: Review health scores
# - All analysts > 0.6? Proceed
# - Any analyst < 0.6? Address recommendations
# Step 3: Check specific concerns
# - Security Reviewer: Any vulnerabilities?
# - Performance Analyst: Any bottlenecks?
# - Strict Critic: Any blockers?
# Step 4: If issues found, fix and re-analyze
# ... make fixes ...
just analyze --council feature/auth
# Step 5: Merge when all greenExample 2: Development Pattern Analysis
# Scenario: Want to understand my development rhythm
# Goal: Identify productivity patterns
# Step 1: Start TUI to explore timeline
just run
# Step 2: Navigate to BranchList view
# - See all branches with activity
# - Note branch lifetimes and commit counts
# Step 3: Drill into specific branch
# - View timeline of commits and sessions
# - Identify session-to-commit lag
# - Detect context switches
# Step 4: Export data for custom analysis
just export > timeline.json
# Step 5: Analyze patterns
# - How often do I switch branches?
# - What's my session-to-commit lag?
# - Do I batch commits or commit frequently?Example 3: Adding a New BAML Analyst
# Scenario: Want to add "Documentation Reviewer" role
# Goal: Extend council with docs-focused perspective
# Step 1: Create BAML function
# Edit crates/baml/baml_src/analysis.baml
function AnalyzeBranch_DocsReviewer(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
) -> BranchInsight {
client CustomGPT5Mini
prompt #"
You are a DOCUMENTATION REVIEWER.
Focus on:
- README updates
- Code comments
- API documentation
- User-facing docs
Branch: {{ branch_name }}
{{ commits }}
{{ sessions }}
{{ ctx.output_format }}
"#
}
# Step 2: Add test case
test analyze_docs_heavy_branch {
functions [AnalyzeBranch_DocsReviewer]
args {
branch_name "feature/docs"
commits "Add API docs\nUpdate README"
sessions "Planning docs structure"
commit_count 3
session_count 1
}
}
# Step 3: Regenerate BAML client
cd crates/baml
baml-cli generate
# Step 4: Update CouncilAdapter
# Edit crates/cli/src/adapters/council.rs
# Add DocsReviewer to council members
# Step 5: Test
just test-pkg devloop-cli
just analyze --councilExample 4: Debugging GKG Integration
# Scenario: GKG integration not working
# Goal: Diagnose and fix GKG connectivity
# Step 1: Check GKG server status
gkg server status
# If stopped, start it:
gkg server start
# Step 2: Verify indexing
gkg server stop
gkg index .
gkg server start
# Step 3: Test GKG connectivity
curl http://localhost:27495/health
# Step 4: Check environment variables
echo $GKG_SERVER_URL
# Should be http://localhost:27495 or unset (uses default)
# Step 5: Run DevLoop with GKG debug
RUST_LOG=devloop_cli::adapters::gkg=debug just run
# Step 6: Verify graceful degradation
# UnifiedAdapter should work even if GKG unavailable
# Check logs for "GKG unavailable" warnings vs errorsTips and Best Practices
For Using DevLoop:
1. Run council mode for important branches - Single analyst is quick but may miss insights 2. Export data regularly - Build historical analysis of development patterns 3. Review session transcripts - Learn from past AI interactions 4. Use health scores as guidelines - Not absolute truth, but useful signals
For DevLoop Development:
1. Keep domain pure - Never add external deps to components/src/domain.rs 2. Test through traits - Create test doubles, don't mock concrete types 3. Follow BAML rules - PascalCase classes, snake_case fields, always @description 4. Handle GKG gracefully - UnifiedAdapter must work without GKG server 5. Document architecture decisions - Update CLAUDE.md and architecture docs 6. Run full test suite - just test before committing 7. Format religiously - just fmt to maintain consistency
Troubleshooting
"Command not found: just"
- Install
just:cargo install justorbrew install just
"BAML client not found"
- Regenerate client:
cd crates/baml && baml-cli generate
"GKG server unavailable"
- Start server:
gkg server start - Or let UnifiedAdapter degrade gracefully (it's designed for this)
"No API key found"
- Set
OPENAI_API_KEYorANTHROPIC_API_KEY - For BAML:
export OPENAI_API_KEY=sk-...
"Health score seems wrong"
- Council mode uses multiple perspectives - compare all analysts
- Single analyst may be overly optimistic or pessimistic
- Health scores are signals, not absolute truth
"Tests failing after BAML changes"
- Regenerate client:
cd crates/baml && baml-cli generate - Update test expectations if schema changed
- Run
just test-pkg devloop-clifor faster iteration
Resources
Project Files:
/Users/joe/dev/devloop/CLAUDE.md- Main project documentation/Users/joe/dev/devloop/justfile- Command definitions/Users/joe/dev/devloop/TESTING_CHECKLIST.md- Comprehensive test guide/Users/joe/dev/devloop/crates/components/src/domain.rs- Core domain models/Users/joe/dev/devloop/crates/baml/baml_src/- BAML schemas/Users/joe/.claude/rules/baml.md- BAML style guide
Key Concepts:
- Hexagonal Architecture (Ports and Adapters)
- Domain-Driven Design (Pure domain layer)
- BAML (Boundary AI Modeling Language)
- GKG (GitLab Knowledge Graph)
External Documentation:
- BAML: https://docs.boundaryml.com/
- Ratatui: https://ratatui.rs/
- GKG: https://gitlab-org.gitlab.io/rust/knowledge-graph/
Skill Maintenance
This skill should be updated when:
- New DevLoop commands are added to
justfile - Council roles are added/removed
- Architecture patterns change (e.g., new adapter types)
- BAML schema conventions evolve
- GKG integration approach changes
Version: 1.0.0 Last Updated: 2026-03-15 Maintained By: DevLoop contributors
# DevLoop Skill Configuration
# This file contains metadata and configuration for the DevLoop skill
# Skill metadata
SKILL_NAME="devloop"
SKILL_VERSION="1.0.0"
SKILL_CREATED="2026-03-15"
SKILL_UPDATED="2026-03-15"
# Skill compatibility
DEVLOOP_MIN_VERSION="main" # Works with main branch (ratatui conversion)
CLAUDE_CODE_MIN_VERSION="1.0.0"
# Feature flags
ENABLE_GKG_INTEGRATION=true # GKG features (optional)
ENABLE_BAML_HELPERS=true # BAML development helpers
ENABLE_ARCHITECTURE_GUIDE=true # Architecture patterns
ENABLE_HELPER_SCRIPTS=true # Bash helper scripts
# Script permissions
# These scripts should be executable
EXECUTABLE_SCRIPTS=(
"scripts/analyze-branch.sh"
"scripts/check-health.sh"
"scripts/validate-skill.sh"
)
# Resource files
# These are reference documentation
RESOURCE_FILES=(
"resources/architecture-patterns.md"
"resources/baml-quick-reference.md"
)
# Documentation files
DOCUMENTATION=(
"SKILL.md"
"README.md"
"INDEX.md"
"CHANGELOG.md"
)
# External dependencies (optional)
# These enhance functionality but are not required
OPTIONAL_DEPS=(
"just" # Command runner
"gkg" # GitLab Knowledge Graph
"baml-cli" # BAML code generation
)
# Required environment variables
# At least one of these must be set for BAML functionality
REQUIRED_ENV=(
"OPENAI_API_KEY"
"ANTHROPIC_API_KEY"
)
# Skill capabilities
# What this skill can help with
CAPABILITIES=(
"run-devloop-commands"
"interpret-analysis-results"
"understand-development-patterns"
"navigate-architecture"
"develop-baml-schemas"
"create-adapters"
"write-tests"
"debug-gkg-integration"
)
# Quick reference paths
# Commonly accessed files
QUICK_PATHS=(
"domain=/Users/joe/dev/devloop/crates/components/src/domain.rs"
"ports=/Users/joe/dev/devloop/crates/components/src/ports.rs"
"adapters=/Users/joe/dev/devloop/crates/cli/src/adapters/"
"baml_src=/Users/joe/dev/devloop/crates/baml/baml_src/"
"baml_client=/Users/joe/dev/devloop/crates/baml/baml_client/"
"justfile=/Users/joe/dev/devloop/justfile"
"claude_md=/Users/joe/dev/devloop/CLAUDE.md"
"baml_rules=/Users/joe/.claude/rules/baml.md"
)
# Validation
# Run this to validate skill structure
VALIDATE_COMMAND="./scripts/validate-skill.sh"
# Health check
# Run this to check environment
HEALTH_CHECK_COMMAND="./scripts/check-health.sh"
DevLoop Skill Changelog
All notable changes to the DevLoop skill will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-03-15
Added
Core Skill Definition
- Created
SKILL.mdwith comprehensive DevLoop helper documentation - Four main capability areas: commands, analysis, observability, development
- Workflow examples for common tasks
- Tips and best practices sections
- Troubleshooting guide
Resource Documentation
resources/architecture-patterns.md- 10 key hexagonal architecture patterns- Domain model design
- Port definition (traits)
- Adapter implementation
- Dependency injection
- Adapter composition
- Test doubles
- BAML integration
- Error handling
- Graceful degradation
- Council pattern
resources/baml-quick-reference.md- Complete BAML development guide- Naming conventions
- Type system reference
- Class and function patterns
- Client definitions
- Test patterns
- Prompt engineering tips
- DevLoop-specific examples
- Common mistakes to avoid
Helper Scripts
scripts/analyze-branch.sh- Wrapper for DevLoop branch analysis- Supports
--councilflag - Auto-detects current branch
- Provides result interpretation
- Color-coded output
scripts/check-health.sh- Development environment health check- Validates Rust toolchain
- Checks DevLoop build status
- Verifies API keys
- Tests GKG server (optional)
- Checks Git repository status
- Validates Claude directories
- Verifies BAML setup
scripts/validate-skill.sh- Skill structure validation- Checks required files exist
- Validates script executability
- Verifies markdown structure
- Checks file sizes
- Validates shell script syntax
- Tests shebangs
Documentation
README.md- Skill overview and structure guideINDEX.md- Quick navigation and lookup referenceCHANGELOG.md- This file
Design Decisions
Hexagonal Architecture Focus
- Emphasized ports-and-adapters pattern throughout skill
- Clear separation between domain, ports, and adapters
- Test doubles over mocking frameworks
- Dependency injection for flexibility
BAML Integration
- Detailed BAML patterns specific to DevLoop
- Council pattern for multi-perspective analysis
- Client selection guidance (Mini vs. Full models)
- Prompt engineering best practices
Practical Examples
- All patterns include concrete code examples
- Real DevLoop code structure referenced
- Step-by-step workflows for common tasks
- Anti-patterns highlighted to avoid
Helper Scripts Philosophy
- Executable bash scripts for common tasks
- Color-coded output for clarity
- Comprehensive health checks
- Educational output (explain what's happening)
Target Audience
This skill targets two main user groups:
1. DevLoop Users - Running analysis, interpreting results, understanding development patterns 2. DevLoop Developers - Working on DevLoop codebase, understanding architecture, extending features
Coverage
DevLoop Commands Covered:
just run- Start TUIjust analyze [--council] [BRANCH]- Branch analysisjust logs [SESSION]- View transcriptsjust export- Export timeline JSONjust test- Run testsjust fmt- Format codejust check- Quick compile checkjust relay- WebSocket relay
Architecture Patterns Covered:
- Domain-driven design
- Hexagonal architecture
- Ports and adapters
- Dependency injection
- Test doubles
- BAML integration
- GKG integration
- Council pattern
- Error handling
- Graceful degradation
BAML Topics Covered:
- File structure
- Naming conventions
- Type system
- Class definitions
- Function definitions
- Client definitions
- Test patterns
- Prompt engineering
- Regeneration workflow
- DevLoop-specific examples
File Structure
skills/devloop/
├── SKILL.md # Main skill (7,200+ words)
├── README.md # Overview (900+ words)
├── INDEX.md # Navigation (1,100+ words)
├── CHANGELOG.md # This file
├── resources/
│ ├── architecture-patterns.md # 10 patterns (5,300+ words)
│ └── baml-quick-reference.md # BAML guide (3,800+ words)
└── scripts/
├── analyze-branch.sh # ~80 lines
├── check-health.sh # ~200 lines
└── validate-skill.sh # ~150 linesTotal: 18,000+ words of documentation, 430+ lines of helper scripts
Quality Standards
Documentation:
- Clear section hierarchy
- Concrete code examples
- Real file paths
- Cross-references between files
- Index for quick lookup
Scripts:
- POSIX-compliant bash
- Set
-euo pipefailfor safety - Color-coded output
- Error handling
- Usage documentation in comments
Code Examples:
- Tested patterns from actual DevLoop code
- Both good and bad examples shown
- Anti-patterns highlighted
- Complete, runnable snippets
Dependencies
Runtime:
- Bash 3.2+ (macOS default)
- DevLoop project environment
- Optional:
just,gkg,baml-cli
No external dependencies for the skill itself - all bash and markdown.
Future Enhancements
Potential future additions:
- Performance analysis scripts - Benchmark DevLoop components
- Migration guides - For major architecture changes
- Video tutorials - Screencast references for complex workflows
- Interactive examples - REPL-like examples for BAML
- Docker setup - Containerized DevLoop development environment
- CI/CD patterns - GitHub Actions examples for DevLoop projects
- Additional analysts - New council roles as they're added
- Plugin system - If DevLoop adds plugin architecture
Known Limitations
Current version does not include:
- Video or interactive content (markdown/script only)
- Automated tests for the skill itself
- Integration with Claude Code's skill system beyond standard structure
- Platform-specific variants (Linux/Windows adaptations)
Acknowledgments
- DevLoop architecture by DevLoop contributors
- BAML patterns from Boundary ML documentation
- Hexagonal architecture from Alistair Cockburn's original work
- Skill structure following Claude Code best practices
---
Version History
[1.0.0] - 2026-03-15
Initial release with comprehensive DevLoop helper functionality.
---
Maintenance Notes
When to Update This Skill
Update when:
- [ ] New DevLoop commands added to
justfile - [ ] Council analysts added/removed/modified
- [ ] Architecture patterns change (new ports, adapters)
- [ ] BAML conventions evolve
- [ ] GKG integration approach changes
- [ ] New best practices emerge
- [ ] Helper scripts need enhancement
- [ ] Documentation gaps identified
Update Checklist
When updating: 1. [ ] Update relevant sections in SKILL.md 2. [ ] Add/modify patterns in resources/ if needed 3. [ ] Update or add helper scripts in scripts/ 4. [ ] Update INDEX.md if navigation changes 5. [ ] Update README.md if structure changes 6. [ ] Add entry to this CHANGELOG 7. [ ] Increment version number 8. [ ] Update "Last Updated" dates 9. [ ] Run validation: ./scripts/validate-skill.sh 10. [ ] Test helper scripts manually
Version Numbering
- Major (X.0.0): Breaking changes, major restructuring
- Minor (x.X.0): New features, new sections, new scripts
- Patch (x.x.X): Bug fixes, typos, small improvements
---
Maintained by: DevLoop contributors License: Same as DevLoop project
DevLoop Skill - Quick Navigation Index
Fast lookup for common DevLoop tasks and references.
Need to...
Run DevLoop Commands
→ See: SKILL.md → Section "1. DevLoop Commands Wrapper"
Quick commands:
just analyze [BRANCH] # Single analyst
just analyze --council [BRANCH] # Multiple perspectives
just logs [SESSION] # View transcripts
just export # JSON timeline
just run # Start TUIHelper script:
./skills/devloop/scripts/analyze-branch.sh --council---
Understand Analysis Results
→ See: SKILL.md → Section "2. Branch Analysis Helper"
Health score interpretation:
- 0.8-1.0: Excellent (merge ready)
- 0.6-0.8: Good (minor fixes)
- 0.4-0.6: Fair (address issues)
- 0.0-0.4: Poor (major concerns)
Council roles: 1. Strict Critic → Conservative risk 2. Creative Explorer → Innovation 3. General Analyst → Balanced view 4. Security Reviewer → Vulnerabilities 5. Performance Analyst → Optimization
---
Analyze Development Patterns
→ See: SKILL.md → Section "3. Development Observability"
Data sources:
- Git activity (commits, branches)
~/.claude/projects/(project config)~/.claude/transcripts/(AI sessions)
Insights:
- Session-to-commit lag
- Branch focus patterns
- Commit batching behavior
- AI reliance metrics
---
Work on DevLoop Architecture
→ See: resources/architecture-patterns.md
Key patterns: 1. Domain Model Design → Pattern 1 2. Port Definition (Traits) → Pattern 2 3. Adapter Implementation → Pattern 3 4. Dependency Injection → Pattern 4 5. Adapter Composition → Pattern 5 6. Test Doubles → Pattern 6 7. BAML Integration → Pattern 7 8. Error Handling → Pattern 8 9. Graceful Degradation → Pattern 9 10. Council Pattern → Pattern 10
Quick architecture lookup:
Primary Adapters (UI)
↓ traits
Application Core (domain)
↓ traits
Secondary Adapters (infrastructure)---
Work with BAML Schemas
→ See: resources/baml-quick-reference.md
File locations:
- Source:
crates/baml/baml_src/*.baml - Generated:
crates/baml/baml_client/
Common tasks:
- Regenerate:
cd crates/baml && baml-cli generate - Test:
baml-cli test - Validate:
baml-cli validate
Naming cheat sheet:
- Classes/Functions/Clients:
PascalCase - Fields/Parameters/Tests:
snake_case - Always end prompts:
{{ ctx.output_format }} - All fields need:
@description
---
Add a New Council Analyst
→ See: resources/baml-quick-reference.md → Section "Adding a New Analyst"
Steps: 1. Create function in crates/baml/baml_src/analysis.baml 2. Add test case 3. Regenerate: baml-cli generate 4. Update CouncilAdapter in crates/cli/src/adapters/council.rs 5. Test: just test
Template:
function AnalyzeBranch_NewRole(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
) -> BranchInsight {
client CustomGPT5Mini
prompt #"
You are a [ROLE] reviewer.
Focus on: [specific concerns]
{{ commits }}
{{ sessions }}
{{ ctx.output_format }}
"#
}---
Create a New Adapter
→ See: resources/architecture-patterns.md → Pattern 3
Steps: 1. Define port trait (if needed) in components/src/ports.rs 2. Create adapter in cli/src/adapters/your_adapter.rs 3. Implement trait with #[async_trait] 4. Return domain types from components/src/domain.rs 5. Handle errors gracefully (return String or custom error) 6. Add to UnifiedAdapter if appropriate
Pattern:
pub struct YourAdapter { /* fields */ }
#[async_trait]
impl YourPort for YourAdapter {
async fn method(&self) -> Result<DomainType, String> {
// Implementation
}
}---
Write Tests with Test Doubles
→ See: resources/architecture-patterns.md → Pattern 6
Steps: 1. Create mock struct implementing trait 2. Inject into App or component under test 3. Assert on domain types
Pattern:
pub struct MockProvider {
data: Vec<DomainType>,
}
#[async_trait]
impl Port for MockProvider {
async fn get_data(&self) -> Result<Vec<DomainType>, String> {
Ok(self.data.clone())
}
}---
Debug GKG Integration
→ See: SKILL.md → Example 4: "Debugging GKG Integration"
Steps: 1. Check server: gkg server status 2. Reindex: gkg server stop && gkg index . && gkg server start 3. Test connectivity: curl http://localhost:27495/health 4. Check env: echo $GKG_SERVER_URL 5. Enable logging: RUST_LOG=devloop_cli::adapters::gkg=debug just run
Remember: UnifiedAdapter gracefully degrades if GKG unavailable.
---
Check Environment Health
→ Use: ./skills/devloop/scripts/check-health.sh
Checks:
- Rust toolchain ✓
justcommand runner ✓- DevLoop build status ✓
- API keys (OPENAI_API_KEY or ANTHROPIC_API_KEY) ✓
- GKG server (optional) ⚠
- Git repository ✓
- Claude directories ✓
- BAML setup ✓
---
Common Workflows
Pre-merge Branch Check
./skills/devloop/scripts/analyze-branch.sh --council feature/my-branch
# Review all council perspectives
# Address issues if health < 0.6
# Re-run analysis
# Merge when greenAdd New BAML Function
# 1. Edit crates/baml/baml_src/analysis.baml
# 2. Add test
# 3. Generate
cd crates/baml && baml-cli generate
# 4. Test
baml-cli test
# 5. Update Rust code
# 6. Run tests
just testCreate New Adapter
# 1. Define port trait (if needed)
# Edit: crates/components/src/ports.rs
# 2. Create adapter
# Edit: crates/cli/src/adapters/my_adapter.rs
# 3. Write tests
# Edit: crates/cli/tests/my_adapter_tests.rs
# 4. Run tests
just test---
File Locations Quick Reference
| What | Where |
|---|---|
| Domain models | crates/components/src/domain.rs |
| Port traits | crates/components/src/ports.rs |
| Adapters | crates/cli/src/adapters/ |
| BAML source | crates/baml/baml_src/ |
| BAML generated | crates/baml/baml_client/ |
| TUI app | crates/cli/src/app.rs |
| Main entry | crates/cli/src/main.rs |
| Tests | crates/*/tests/ |
| Commands | justfile |
| Project docs | CLAUDE.md |
| BAML rules | ~/.claude/rules/baml.md |
| Test guide | TESTING_CHECKLIST.md |
---
External Links
| Resource | URL |
|---|---|
| BAML Docs | https://docs.boundaryml.com/ |
| Ratatui | https://ratatui.rs/ |
| GKG Docs | https://gitlab-org.gitlab.io/rust/knowledge-graph/ |
| Rust Book | https://doc.rust-lang.org/book/ |
| async-trait | https://docs.rs/async-trait/ |
---
Skill Files
| File | Purpose |
|---|---|
SKILL.md | Main skill definition (read by Claude Code) |
README.md | Skill overview and structure |
INDEX.md | This file - quick navigation |
resources/architecture-patterns.md | Detailed architecture patterns |
resources/baml-quick-reference.md | BAML development guide |
scripts/analyze-branch.sh | Branch analysis wrapper |
scripts/check-health.sh | Environment health check |
---
Quick Command Reference
# Build & Run
just run # Build + run TUI (release)
just dev # Run TUI (debug)
just build # Build only
just clean # Clean build artifacts
# Analysis
just analyze [BRANCH] # Single analyst
just analyze --council # Council mode
# Logs & Export
just logs [SESSION] # View session transcripts
just export # Export timeline JSON
# Development
just test # Run all tests
just test-cli # CLI tests only
just test-pkg <PKG> # Specific package
just fmt # Format code
just check # Quick compile check
just lint # Clippy lints
# BAML
cd crates/baml
baml-cli generate # Regenerate client
baml-cli test # Run BAML tests
baml-cli validate # Validate schemas
# GKG
gkg server status # Check server
gkg server start # Start server
gkg server stop # Stop server
gkg index . # Index project
# Health Check
./skills/devloop/scripts/check-health.sh---
Need Help?
1. For DevLoop usage questions: See SKILL.md sections 1-3 2. For architecture questions: See resources/architecture-patterns.md 3. For BAML questions: See resources/baml-quick-reference.md 4. For environment issues: Run ./skills/devloop/scripts/check-health.sh 5. For project context: See CLAUDE.md
---
Last Updated: 2026-03-15 Version: 1.0.0
DevLoop Skill for Claude Code
Comprehensive helper skill for working with the DevLoop development observability tool.
What This Skill Provides
This skill helps you:
1. Run DevLoop commands - Quick access to just analyze, just logs, just export, just run 2. Interpret analysis results - Understand council mode insights, health scores, and recommendations 3. Analyze development patterns - Review git activity and Claude session metadata 4. Develop DevLoop itself - Navigate hexagonal architecture, BAML schemas, and GKG integration
Skill Structure
skills/devloop/
├── SKILL.md # Main skill definition (loaded by Claude Code)
├── README.md # This file
├── resources/ # Reference documentation
│ ├── architecture-patterns.md # Hexagonal architecture patterns
│ └── baml-quick-reference.md # BAML schema development guide
└── scripts/ # Helper scripts
├── analyze-branch.sh # Branch analysis wrapper
└── check-health.sh # Environment health checkQuick Start
Using the Skill
In Claude Code, this skill is automatically available when working in the DevLoop project. Ask questions like:
- "Analyze the current branch with council mode"
- "How do I interpret the health scores from DevLoop analysis?"
- "Explain the hexagonal architecture pattern used in DevLoop"
- "How do I add a new BAML analyst to the council?"
- "What's the difference between GitAdapter and UnifiedAdapter?"
Running Helper Scripts
Make scripts executable:
chmod +x skills/devloop/scripts/*.shCheck environment health:
./skills/devloop/scripts/check-health.shAnalyze a branch with guidance:
./skills/devloop/scripts/analyze-branch.sh --council feature/my-featureResources
Architecture Patterns
resources/architecture-patterns.md provides:
- Hexagonal architecture overview
- Domain model design patterns
- Port definition (trait-based interfaces)
- Adapter implementation examples
- Dependency injection patterns
- Test double creation
- BAML integration patterns
- Error handling strategies
- Graceful degradation (optional components)
- Council pattern (multi-perspective analysis)
Use this when:
- Adding new adapters
- Creating test doubles
- Understanding data flow
- Extending DevLoop's capabilities
BAML Quick Reference
resources/baml-quick-reference.md provides:
- BAML file structure and locations
- Naming conventions (PascalCase classes, snake_case fields)
- Type system (basic, optional, arrays, unions)
- Class and function definition patterns
- Client definitions (GPT-4o Mini, GPT-4o, Claude Sonnet)
- Test patterns
- Prompt engineering tips
- Common mistakes to avoid
- DevLoop-specific examples (council analysts)
Use this when:
- Creating new BAML functions
- Adding analysts to the council
- Writing BAML tests
- Debugging BAML schemas
- Choosing appropriate LLM models
When to Use This Skill
For DevLoop Users
Use this skill when you want to:
- Run branch analysis and understand the results
- Review development patterns and productivity insights
- Export timeline data for custom analysis
- Understand what different council analysts focus on
- Troubleshoot DevLoop setup issues
Example prompts:
- "Run council analysis on my current branch"
- "What does a health score of 0.65 mean?"
- "Show me my development patterns from the last week"
- "Explain the difference between Strict Critic and Creative Explorer"
For DevLoop Developers
Use this skill when you want to:
- Understand DevLoop's architecture
- Add new features (analyzers, adapters, views)
- Create or modify BAML schemas
- Work with GKG integration
- Write tests using the hexagonal architecture
Example prompts:
- "How do I add a new BAML analyst to the council?"
- "Explain the data flow from GitAdapter to the TUI"
- "Show me how to create a test double for BranchAggregator"
- "What's the pattern for graceful GKG degradation?"
- "How do I integrate a new data source using an adapter?"
Key Concepts
Council Analysis
DevLoop's unique multi-perspective AI analysis:
- Strict Critic - Conservative, risk-focused
- Creative Explorer - Innovation, opportunities
- General Analyst - Balanced assessment
- Security Reviewer - Security vulnerabilities
- Performance Analyst - Performance implications
Each provides independent insights, all synthesized into a comprehensive view.
Hexagonal Architecture
DevLoop separates concerns into three layers:
1. Domain Layer (components/src/domain.rs) - Pure business logic, zero dependencies 2. Ports (components/src/ports.rs) - Trait-based interfaces 3. Adapters (cli/src/adapters/) - Infrastructure implementations
This enables testability, flexibility, and clear separation of concerns.
BAML Integration
BAML (Boundary AI Modeling Language) defines AI functions:
- Type-safe AI function calls
- Schema-driven output validation
- Multiple LLM client support
- Test framework included
GKG Integration
GitLab Knowledge Graph provides code structure:
- Function and class definitions
- Code reference graph (call sites)
- Repository map (project structure)
- Optional - DevLoop degrades gracefully if unavailable
Troubleshooting
"Skill not loading"
Ensure you're in the DevLoop project directory (/Users/joe/dev/devloop). Claude Code loads skills from ./skills/ relative to the project root.
"Can't find helper scripts"
Make scripts executable:
chmod +x skills/devloop/scripts/*.sh"BAML examples don't work"
Regenerate the BAML client:
cd crates/baml
baml-cli generate"Architecture diagrams are unclear"
View resources/architecture-patterns.md for detailed ASCII diagrams and code examples showing data flow through the hexagonal architecture.
Maintenance
Update this skill when:
- New DevLoop commands are added to
justfile - Council analysts are added/removed/modified
- Architecture patterns change (new adapter types, new ports)
- BAML conventions evolve
- GKG integration approach changes
- New best practices emerge
Version
- Version: 1.0.0
- Created: 2026-03-15
- Last Updated: 2026-03-15
- Compatible with: DevLoop main branch (ratatui conversion complete)
Related Documentation
- Main project:
/Users/joe/dev/devloop/CLAUDE.md - BAML rules:
/Users/joe/.claude/rules/baml.md - Testing guide:
/Users/joe/dev/devloop/TESTING_CHECKLIST.md - Justfile:
/Users/joe/dev/devloop/justfile
Contributing
When extending this skill:
1. Update SKILL.md with new capabilities 2. Add detailed patterns to resources/ if needed 3. Create helper scripts in scripts/ for common tasks 4. Update this README with new sections 5. Increment version number 6. Update "Last Updated" date
License
Same license as DevLoop project.
DevLoop Architecture Patterns
Quick reference for common architectural patterns in DevLoop.
Hexagonal Architecture Overview
┌─────────────────────────────────────────┐
│ Primary Adapters (UI/CLI) │
│ - Ratatui TUI (crates/cli) │
│ - Non-interactive CLI (devloop-cli) │
│ - WebSocket relay (relay) │
└───────────────┬─────────────────────────┘
│
│ Application Ports (traits)
▼
┌─────────────────────────────────────────┐
│ Application Core (components) │
│ - Domain models (domain.rs) │
│ - Ports: TimelineProvider, │
│ BranchAggregator, │
│ InsightProvider │
│ - Pure business logic │
└───────────────┬─────────────────────────┘
│
│ Infrastructure Ports (traits)
▼
┌─────────────────────────────────────────┐
│ Secondary Adapters (Infrastructure) │
│ - GitAdapter (git2) │
│ - BamlAdapter (AI) │
│ - GkgAdapter (code structure) │
│ - CouncilAdapter (multi-role AI) │
│ - UnifiedAdapter (composition) │
└─────────────────────────────────────────┘Pattern 1: Domain Model Design
Rule: Domain models have ZERO external dependencies.
Good Example:
// crates/components/src/domain.rs
use std::collections::HashMap; // std only!
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BranchSummary {
pub name: String,
pub commit_count: usize,
pub session_count: usize,
pub first_activity: String,
pub last_activity: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BranchInsight {
pub branch_name: String,
pub health_score: f64,
pub risk_level: RiskLevel,
pub insights: Vec<String>,
pub recommendations: Vec<String>,
pub analyst_role: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RiskLevel {
Low,
Medium,
High,
}Bad Example:
// DON'T DO THIS - external dependency in domain!
use serde_json::Value; // External dep
use git2::Repository; // Infrastructure concern
pub struct BranchSummary {
pub repo: Repository, // ❌ Couples domain to git2
pub data: Value, // ❌ Couples domain to serde_json
}Pattern 2: Port Definition (Trait-Based)
Rule: Define ports as traits with async methods returning domain types.
Example:
// crates/components/src/ports.rs
use async_trait::async_trait;
use crate::domain::{BranchSummary, TimelineEntry, BranchInsight};
#[async_trait]
pub trait BranchAggregator: Send + Sync {
async fn get_branch_summary(&self, branch_name: &str) -> Result<BranchSummary, String>;
async fn list_branches(&self) -> Result<Vec<BranchSummary>, String>;
}
#[async_trait]
pub trait TimelineProvider: Send + Sync {
async fn get_timeline(&self, branch_name: &str) -> Result<Vec<TimelineEntry>, String>;
}
#[async_trait]
pub trait InsightProvider: Send + Sync {
async fn analyze_branch(&self, branch_name: &str) -> Result<BranchInsight, String>;
async fn analyze_council(&self, branch_name: &str) -> Result<Vec<BranchInsight>, String>;
}Why async_trait?
- Enables async methods in traits (stable Rust async fn in traits is still evolving)
- Required for
Send + Syncbounds on async trait methods
Pattern 3: Adapter Implementation
Rule: Adapters implement traits and handle external dependencies.
Example:
// crates/cli/src/adapters/git.rs
use async_trait::async_trait;
use git2::Repository;
use devloop_components::ports::BranchAggregator;
use devloop_components::domain::BranchSummary;
pub struct GitAdapter {
repo: Repository,
claude_projects_dir: PathBuf,
}
impl GitAdapter {
pub fn new(repo_path: &Path) -> Result<Self, String> {
let repo = Repository::open(repo_path)
.map_err(|e| format!("Failed to open repo: {}", e))?;
let claude_projects_dir = dirs::home_dir()
.ok_or("No home directory")?
.join(".claude/projects");
Ok(Self { repo, claude_projects_dir })
}
}
#[async_trait]
impl BranchAggregator for GitAdapter {
async fn get_branch_summary(&self, branch_name: &str) -> Result<BranchSummary, String> {
// Implementation using git2 crate
// Returns pure domain type (BranchSummary)
todo!()
}
async fn list_branches(&self) -> Result<Vec<BranchSummary>, String> {
// Implementation
todo!()
}
}Pattern 4: Dependency Injection
Rule: App is generic over adapters, receives trait objects.
Example:
// crates/cli/src/app.rs
pub struct App<T, B, I>
where
T: TimelineProvider,
B: BranchAggregator,
I: InsightProvider,
{
timeline_provider: Arc<T>,
branch_aggregator: Arc<B>,
insight_provider: Arc<I>,
view_state: ViewState,
}
impl<T, B, I> App<T, B, I>
where
T: TimelineProvider + 'static,
B: BranchAggregator + 'static,
I: InsightProvider + 'static,
{
pub fn new(
timeline_provider: Arc<T>,
branch_aggregator: Arc<B>,
insight_provider: Arc<I>,
) -> Self {
Self {
timeline_provider,
branch_aggregator,
insight_provider,
view_state: ViewState::BranchList,
}
}
pub async fn load_branches(&mut self) -> Result<(), String> {
let branches = self.branch_aggregator.list_branches().await?;
self.view_state = ViewState::BranchList(branches);
Ok(())
}
}Main function:
// crates/cli/src/main.rs
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let repo_path = std::env::current_dir()?;
// Create adapters
let git_adapter = Arc::new(GitAdapter::new(&repo_path)?);
let baml_adapter = Arc::new(BamlAdapter::new()?);
let unified = Arc::new(UnifiedAdapter::new(
git_adapter.clone(),
baml_adapter.clone(),
));
// Inject dependencies
let mut app = App::new(
unified.clone(), // TimelineProvider
unified.clone(), // BranchAggregator
unified, // InsightProvider
);
app.run().await?;
Ok(())
}Pattern 5: Adapter Composition
Rule: Compose multiple adapters into unified interface.
Example:
// crates/cli/src/adapters/unified.rs
pub struct UnifiedAdapter {
git: Arc<GitAdapter>,
baml: Arc<BamlAdapter>,
gkg: Option<Arc<GkgAdapter>>,
}
impl UnifiedAdapter {
pub fn new(git: Arc<GitAdapter>, baml: Arc<BamlAdapter>) -> Self {
let gkg = GkgAdapter::new().ok().map(Arc::new);
if gkg.is_none() {
eprintln!("Warning: GKG adapter unavailable, falling back to git-only mode");
}
Self { git, baml, gkg }
}
}
#[async_trait]
impl TimelineProvider for UnifiedAdapter {
async fn get_timeline(&self, branch_name: &str) -> Result<Vec<TimelineEntry>, String> {
// Delegate to git adapter
self.git.get_timeline(branch_name).await
}
}
#[async_trait]
impl InsightProvider for UnifiedAdapter {
async fn analyze_branch(&self, branch_name: &str) -> Result<BranchInsight, String> {
// Get git data
let summary = self.git.get_branch_summary(branch_name).await?;
// Optionally enrich with GKG data
let code_structure = if let Some(gkg) = &self.gkg {
gkg.get_repo_map().await.ok()
} else {
None
};
// Delegate to BAML for analysis
self.baml.analyze_with_context(summary, code_structure).await
}
}Pattern 6: Test Doubles
Rule: Create test doubles by implementing traits, no mocking framework needed.
Example:
// crates/cli/tests/test_doubles.rs
pub struct MockBranchAggregator {
branches: Vec<BranchSummary>,
}
impl MockBranchAggregator {
pub fn with_branches(branches: Vec<BranchSummary>) -> Self {
Self { branches }
}
}
#[async_trait]
impl BranchAggregator for MockBranchAggregator {
async fn get_branch_summary(&self, branch_name: &str) -> Result<BranchSummary, String> {
self.branches
.iter()
.find(|b| b.name == branch_name)
.cloned()
.ok_or_else(|| format!("Branch not found: {}", branch_name))
}
async fn list_branches(&self) -> Result<Vec<BranchSummary>, String> {
Ok(self.branches.clone())
}
}
// Use in tests
#[tokio::test]
async fn test_app_loads_branches() {
let mock_branches = vec![
BranchSummary {
name: "feature/test".to_string(),
commit_count: 3,
session_count: 1,
first_activity: "2026-03-10".to_string(),
last_activity: "2026-03-15".to_string(),
},
];
let mock_aggregator = Arc::new(MockBranchAggregator::with_branches(mock_branches));
let mock_timeline = Arc::new(MockTimelineProvider::empty());
let mock_insights = Arc::new(MockInsightProvider::empty());
let mut app = App::new(mock_timeline, mock_aggregator, mock_insights);
app.load_branches().await.unwrap();
// Assert app state
}Pattern 7: BAML Integration
Rule: BAML adapter wraps generated client, maps to domain types.
Example:
// crates/cli/src/adapters/baml.rs
use baml_client::baml_types::BranchInsight as BamlBranchInsight;
use devloop_components::domain::BranchInsight;
pub struct BamlAdapter {
client: baml_client::BamlClient,
}
impl BamlAdapter {
pub fn new() -> Result<Self, String> {
let client = baml_client::BamlClient::new();
Ok(Self { client })
}
async fn analyze_with_role(
&self,
branch_name: &str,
commits: &str,
sessions: &str,
commit_count: i64,
session_count: i64,
role: AnalystRole,
) -> Result<BranchInsight, String> {
let baml_result = match role {
AnalystRole::StrictCritic => {
self.client
.analyze_branch_strict_critic(branch_name, commits, sessions, commit_count, session_count)
.await
}
AnalystRole::CreativeExplorer => {
self.client
.analyze_branch_creative_explorer(branch_name, commits, sessions, commit_count, session_count)
.await
}
// ... other roles
};
let baml_insight = baml_result.map_err(|e| format!("BAML error: {}", e))?;
// Map BAML type to domain type
Ok(BranchInsight {
branch_name: baml_insight.branch_name,
health_score: baml_insight.health_score,
risk_level: map_risk_level(baml_insight.risk_level),
insights: baml_insight.insights,
recommendations: baml_insight.recommendations,
analyst_role: format!("{:?}", role),
})
}
}
fn map_risk_level(baml_level: String) -> RiskLevel {
match baml_level.to_lowercase().as_str() {
"low" => RiskLevel::Low,
"medium" => RiskLevel::Medium,
"high" => RiskLevel::High,
_ => RiskLevel::Medium, // Default
}
}Pattern 8: Error Handling
Rule: Adapters return domain-level errors (String or custom error type), not infrastructure errors.
Example:
// Good: Maps infrastructure error to domain error
impl GitAdapter {
async fn get_commits(&self, branch_name: &str) -> Result<Vec<Commit>, String> {
let branch_ref = self.repo
.find_branch(branch_name, git2::BranchType::Local)
.map_err(|e| format!("Branch not found: {}", e))?; // ✅ Map to String
// ... rest of implementation
Ok(commits)
}
}
// Bad: Leaks infrastructure error
impl GitAdapter {
async fn get_commits(&self, branch_name: &str) -> Result<Vec<Commit>, git2::Error> {
let branch_ref = self.repo
.find_branch(branch_name, git2::BranchType::Local)?; // ❌ Leaks git2::Error
Ok(commits)
}
}Pattern 9: Graceful Degradation
Rule: Optional adapters should fail gracefully, not crash the app.
Example:
// UnifiedAdapter with optional GKG
pub struct UnifiedAdapter {
git: Arc<GitAdapter>,
baml: Arc<BamlAdapter>,
gkg: Option<Arc<GkgAdapter>>, // Optional!
}
impl UnifiedAdapter {
pub fn new(git: Arc<GitAdapter>, baml: Arc<BamlAdapter>) -> Self {
let gkg = match GkgAdapter::new() {
Ok(adapter) => {
println!("GKG adapter initialized successfully");
Some(Arc::new(adapter))
}
Err(e) => {
eprintln!("Warning: GKG unavailable ({}), continuing without code structure data", e);
None
}
};
Self { git, baml, gkg }
}
async fn get_code_structure(&self, path: &str) -> Option<CodeStructure> {
match &self.gkg {
Some(gkg) => gkg.get_structure(path).await.ok(),
None => None, // Gracefully return None
}
}
}Pattern 10: Council Pattern (Multi-Perspective Analysis)
Rule: Run multiple analysts in parallel, aggregate results.
Example:
// crates/cli/src/adapters/council.rs
pub struct CouncilAdapter {
baml: Arc<BamlAdapter>,
}
impl CouncilAdapter {
pub fn new(baml: Arc<BamlAdapter>) -> Self {
Self { baml }
}
}
#[async_trait]
impl InsightProvider for CouncilAdapter {
async fn analyze_council(&self, branch_name: &str) -> Result<Vec<BranchInsight>, String> {
let summary = self.get_branch_summary(branch_name).await?;
// Define council roles
let roles = vec![
AnalystRole::StrictCritic,
AnalystRole::CreativeExplorer,
AnalystRole::GeneralAnalyst,
AnalystRole::SecurityReviewer,
AnalystRole::PerformanceAnalyst,
];
// Run analyses in parallel
let futures = roles.into_iter().map(|role| {
let baml = self.baml.clone();
let summary = summary.clone();
async move {
baml.analyze_with_role(
&summary.name,
&summary.commits,
&summary.sessions,
summary.commit_count as i64,
summary.session_count as i64,
role,
).await
}
});
let results = futures::future::join_all(futures).await;
// Collect successful results
let insights: Vec<BranchInsight> = results
.into_iter()
.filter_map(|r| r.ok())
.collect();
if insights.is_empty() {
Err("All council analyses failed".to_string())
} else {
Ok(insights)
}
}
}Quick Reference
| Pattern | Key Rule | Example Location |
|---|---|---|
| Domain Models | Zero external deps | components/src/domain.rs |
| Ports | Trait-based async | components/src/ports.rs |
| Adapters | Implement traits | cli/src/adapters/git.rs |
| DI | Generic over traits | cli/src/app.rs |
| Composition | Unified interface | cli/src/adapters/unified.rs |
| Test Doubles | Implement traits | cli/tests/test_doubles.rs |
| BAML Integration | Map generated types | cli/src/adapters/baml.rs |
| Error Handling | Domain-level errors | All adapters |
| Graceful Degradation | Optional adapters | cli/src/adapters/unified.rs |
| Council | Parallel multi-role | cli/src/adapters/council.rs |
Anti-Patterns to Avoid
❌ Concrete dependencies in App:
pub struct App {
git: GitAdapter, // Couples App to concrete type
}✅ Generic over traits:
pub struct App<B: BranchAggregator> {
git: Arc<B>, // App is generic, testable
}❌ External deps in domain:
use git2::Oid; // Don't do this!
pub struct Commit {
oid: Oid, // Couples domain to git2
}✅ Pure domain types:
pub struct Commit {
hash: String, // Pure std type
}❌ Leaking infrastructure errors:
async fn analyze(&self) -> Result<Insight, git2::Error> {
// ❌ Exposes git2 error to domain
}✅ Domain-level errors:
async fn analyze(&self) -> Result<Insight, String> {
// ✅ Generic error for domain layer
}Conclusion
These patterns enable:
- Testability - Easy test doubles without mocking
- Flexibility - Swap adapters without changing domain
- Maintainability - Clear separation of concerns
- Resilience - Graceful degradation when components fail
BAML Quick Reference for DevLoop
Fast reference for working with BAML schemas in DevLoop.
File Locations
crates/baml/
├── baml_src/ # Source BAML files (edit these)
│ ├── analysis.baml # Branch analysis functions
│ ├── clients.baml # LLM client definitions
│ └── types.baml # Domain type definitions
├── baml_client/ # Generated Rust code (don't edit!)
│ ├── mod.rs
│ └── ...
└── Cargo.tomlRegenerate BAML Client
After editing .baml files:
cd crates/baml
baml-cli generateOr from project root:
just baml-generate # If you add this to justfileNaming Conventions
| Element | Convention | Example |
|---|---|---|
| Classes | PascalCase | BranchInsight, UserProfile |
| Functions | PascalCase | AnalyzeBranch, ExtractData |
| Clients | PascalCase | CustomGPT5Mini, CustomSonnet4 |
| Fields | snake_case | branch_name, health_score |
| Parameters | snake_case | commit_count, session_count |
| Tests | snake_case | test_analyze_active_branch |
Type System
Basic Types
string // Text
int // Integer
float // Floating point
bool // BooleanOptional Types
field_name string? // May be null
field_name int? // May be nullArrays
items string[] // Array of strings
scores float[] // Array of floats
insights BranchInsight[] // Array of custom typesUnion Types (Enums)
status "pending" | "in_progress" | "complete"
risk_level "low" | "medium" | "high"
priority "p0" | "p1" | "p2" | "p3"Class Definition Pattern
class BranchInsight {
branch_name string @description("Name of the git branch being analyzed")
health_score float @description("Overall health score from 0.0 (poor) to 1.0 (excellent)")
risk_level "low" | "medium" | "high" @description("Risk level assessment")
insights string[] @description("Array of specific observations and findings")
recommendations string[] @description("Array of actionable suggestions for improvement")
analyst_role string @description("Role of the analyst providing this insight")
}Key points:
- Every field needs
@description - Use union types for constrained strings
- Arrays use
[]suffix - Optional fields use
?suffix
Function Definition Pattern
function AnalyzeBranch_StrictCritic(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
) -> BranchInsight {
client CustomGPT5Mini
prompt #"
You are a STRICT CRITIC reviewing a development branch.
Your role is to identify risks, issues, and potential problems.
Branch: {{ branch_name }}
Total commits: {{ commit_count }}
Total sessions: {{ session_count }}
Recent commit messages:
{{ commits }}
Recent session summaries:
{{ sessions }}
Provide a conservative risk assessment focusing on:
- Code quality concerns
- Potential bugs or issues
- Missing tests or documentation
- Technical debt
- Security vulnerabilities
{{ ctx.output_format }}
"#
}Key points:
- Function name is PascalCase
- Parameters are snake_case with type annotations
- Return type specified after
-> clientspecifies which LLM to usepromptuses heredoc syntax#"..."#- Always end with
{{ ctx.output_format }} - Template variables use
{{ variable_name }}
Client Definitions
GPT-4o Mini (Fast, Cheap)
client<llm> CustomGPT5Mini {
provider openai-responses
retry_policy Exponential
options {
model "gpt-4o-mini"
api_key env.OPENAI_API_KEY
}
}Use for:
- Simple extraction
- Classification tasks
- Quick analyses
- High-volume operations
GPT-4o (Standard)
client<llm> CustomGPT5 {
provider openai-responses
retry_policy Exponential
options {
model "gpt-4o"
api_key env.OPENAI_API_KEY
}
}Use for:
- Complex reasoning
- Detailed analysis
- Creative tasks
- Quality-critical operations
Claude Sonnet (Alternative)
client<llm> CustomSonnet4 {
provider anthropic
retry_policy Exponential
options {
model "claude-sonnet-4"
api_key env.ANTHROPIC_API_KEY
}
}Use for:
- Code analysis
- Technical writing
- Architecture decisions
Retry Policy
retry_policy Exponential {
max_retries 3
strategy {
type exponential_backoff
}
}Test Pattern
test analyze_active_feature_branch {
functions [AnalyzeBranch_StrictCritic]
args {
branch_name "feature/auth-refactor"
commits #"
Refactor OAuth flow (3 days ago)
Add token refresh logic (2 days ago)
Fix edge case in logout (1 day ago)
"#
sessions #"
Planning auth refactor (4 days ago)
Implementing OAuth (2 days ago)
"#
commit_count 5
session_count 2
}
}Key points:
- Test name is snake_case and descriptive
functionsarray lists which functions to testargsprovides test inputs- Use heredoc
#"..."#for multi-line strings - Include diverse test cases (happy path, edge cases)
Common BAML Patterns in DevLoop
Pattern 1: Multi-Role Analysis
// Define base insight type
class BranchInsight {
branch_name string @description("Branch name")
health_score float @description("Score 0.0-1.0")
risk_level "low" | "medium" | "high" @description("Risk assessment")
insights string[] @description("Observations")
recommendations string[] @description("Suggestions")
analyst_role string @description("Analyst role name")
}
// Define function for each role
function AnalyzeBranch_StrictCritic(...) -> BranchInsight { ... }
function AnalyzeBranch_CreativeExplorer(...) -> BranchInsight { ... }
function AnalyzeBranch_GeneralAnalyst(...) -> BranchInsight { ... }
function AnalyzeBranch_SecurityReviewer(...) -> BranchInsight { ... }
function AnalyzeBranch_PerformanceAnalyst(...) -> BranchInsight { ... }
// Synthesize multiple insights
function SynthesizeCouncilInsights(
insights: BranchInsight[]
) -> CouncilSynthesis {
client CustomGPT5
prompt #"
You are a meta-analyst synthesizing insights from multiple reviewers.
{% for insight in insights %}
## {{ insight.analyst_role }}
Health Score: {{ insight.health_score }}
Risk Level: {{ insight.risk_level }}
Insights:
{% for item in insight.insights %}
- {{ item }}
{% endfor %}
Recommendations:
{% for item in insight.recommendations %}
- {{ item }}
{% endfor %}
{% endfor %}
Synthesize into a coherent final assessment.
{{ ctx.output_format }}
"#
}
class CouncilSynthesis {
overall_health_score float @description("Aggregate health score")
consensus_risk_level "low" | "medium" | "high" @description("Consensus risk")
key_insights string[] @description("Most important insights across all analysts")
priority_recommendations string[] @description("Highest priority actions")
dissenting_opinions string[] @description("Significant disagreements between analysts")
}Pattern 2: Progressive Enhancement
// Base analysis (minimal data)
function AnalyzeBranch_Basic(
branch_name: string
commit_count: int
) -> BasicInsight {
client CustomGPT5Mini
prompt #"
Quick health check for {{ branch_name }} with {{ commit_count }} commits.
{{ ctx.output_format }}
"#
}
// Enhanced analysis (with git data)
function AnalyzeBranch_Enhanced(
branch_name: string
commits: string
commit_count: int
) -> EnhancedInsight {
client CustomGPT5Mini
prompt #"
Analyze {{ branch_name }}:
{{ commits }}
{{ ctx.output_format }}
"#
}
// Full analysis (with git + session data)
function AnalyzeBranch_Full(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
) -> FullInsight {
client CustomGPT5
prompt #"
Comprehensive analysis of {{ branch_name }}:
Commits ({{ commit_count }}):
{{ commits }}
Sessions ({{ session_count }}):
{{ sessions }}
{{ ctx.output_format }}
"#
}Pattern 3: Conditional Context
function AnalyzeBranch_WithOptionalGKG(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
code_structure: string? // Optional GKG data
) -> BranchInsight {
client CustomGPT5
prompt #"
Analyze branch: {{ branch_name }}
Commits: {{ commits }}
Sessions: {{ sessions }}
{% if code_structure %}
Code Structure (from GKG):
{{ code_structure }}
Use code structure to enhance your analysis.
{% else %}
Note: Code structure data unavailable.
{% endif %}
{{ ctx.output_format }}
"#
}Prompt Engineering Tips
1. Clear Role Definition
prompt #"
You are a SECURITY REVIEWER for a development branch.
Your primary focus is identifying security vulnerabilities and risks.
[rest of prompt]
"#2. Structured Input
prompt #"
Branch: {{ branch_name }}
Total commits: {{ commit_count }}
Total sessions: {{ session_count }}
Recent commit messages:
{{ commits }}
Recent session summaries:
{{ sessions }}
[analysis instructions]
"#3. Explicit Output Focus
prompt #"
[input context]
Focus your analysis on:
- Code quality and maintainability
- Test coverage
- Documentation completeness
- Performance implications
[output format]
"#4. Template Loops
prompt #"
{% for commit in commits %}
Commit {{ loop.index }}: {{ commit }}
{% endfor %}
"#5. Conditional Sections
prompt #"
{% if session_count > 0 %}
Sessions indicate active development with AI assistance.
{% else %}
No AI sessions detected - manual development.
{% endif %}
"#Common Mistakes
❌ Wrong Naming
// Bad
class branchInsight { ... } // Should be PascalCase
function analyze_branch() { ... } // Should be PascalCase
test TestOne { ... } // Should be snake_case
// Good
class BranchInsight { ... }
function AnalyzeBranch() { ... }
test analyze_active_branch { ... }❌ Missing Descriptions
// Bad
class BranchInsight {
branch_name string
health_score float
}
// Good
class BranchInsight {
branch_name string @description("Name of the git branch")
health_score float @description("Health score from 0.0 to 1.0")
}❌ Missing Output Format
// Bad
prompt #"
Analyze this branch:
{{ commits }}
"#
// Good
prompt #"
Analyze this branch:
{{ commits }}
{{ ctx.output_format }}
"#❌ Wrong Model for Task
// Bad - expensive model for simple task
function ExtractBranchName(text: string) -> string {
client CustomGPT5 // Overkill
prompt #"..."#
}
// Good - cheap model for simple task
function ExtractBranchName(text: string) -> string {
client CustomGPT5Mini // Appropriate
prompt #"..."#
}Debugging BAML
Check Generated Code
# After generating, check the Rust code
cat crates/baml/baml_client/mod.rsTest Individual Functions
# Run BAML tests
cd crates/baml
baml-cli test
# Run specific test
baml-cli test test_analyze_active_branchEnable BAML Logging
# In Rust code
std::env::set_var("BAML_LOG", "debug");
# Or in shell
export BAML_LOG=debug
just analyzeValidate Schema
cd crates/baml
baml-cli validateDevLoop-Specific Examples
Current Council Analysts
1. Strict Critic - AnalyzeBranch_StrictCritic
- Focus: Risks, issues, conservative assessment
- Use: Before merging critical branches
2. Creative Explorer - AnalyzeBranch_CreativeExplorer
- Focus: Innovation, opportunities, alternative approaches
- Use: For feature branches, brainstorming
3. General Analyst - AnalyzeBranch_GeneralAnalyst
- Focus: Balanced view, overall health
- Use: Default analysis, general assessment
4. Security Reviewer - AnalyzeBranch_SecurityReviewer
- Focus: Security vulnerabilities, auth issues
- Use: Branches touching authentication, data handling
5. Performance Analyst - AnalyzeBranch_PerformanceAnalyst
- Focus: Performance bottlenecks, optimization
- Use: Branches with algorithms, large data processing
Adding a New Analyst
// 1. Define function in analysis.baml
function AnalyzeBranch_DocsReviewer(
branch_name: string
commits: string
sessions: string
commit_count: int
session_count: int
) -> BranchInsight {
client CustomGPT5Mini
prompt #"
You are a DOCUMENTATION REVIEWER for development branches.
Focus on:
- README updates and completeness
- Code comments and docstrings
- API documentation
- User-facing documentation
- Changelog entries
Branch: {{ branch_name }}
Commits ({{ commit_count }}):
{{ commits }}
Sessions ({{ session_count }}):
{{ sessions }}
Assess documentation quality and completeness.
{{ ctx.output_format }}
"#
}
// 2. Add test
test analyze_docs_focused_branch {
functions [AnalyzeBranch_DocsReviewer]
args {
branch_name "feature/api-docs"
commits #"
Add OpenAPI spec (2 days ago)
Update README with examples (1 day ago)
Add code comments to main.rs (today)
"#
sessions #"
Planning documentation structure (3 days ago)
"#
commit_count 3
session_count 1
}
}
// 3. Regenerate
// $ cd crates/baml && baml-cli generate
// 4. Update CouncilAdapter in Rust
// Add AnalystRole::DocsReviewer to council membersQuick Checklist
Before committing BAML changes:
- [ ] Class names are PascalCase
- [ ] Field names are snake_case
- [ ] All fields have
@description - [ ] Functions end with
{{ ctx.output_format }} - [ ] Tests are descriptive snake_case
- [ ] Appropriate client selected (Mini vs. Full)
- [ ] Optional fields marked with
? - [ ] Arrays marked with
[] - [ ] Regenerated client:
baml-cli generate - [ ] Tests pass:
baml-cli test
Resources
- BAML Docs: https://docs.boundaryml.com/
- DevLoop BAML Rules:
/Users/joe/.claude/rules/baml.md - DevLoop BAML Source:
/Users/joe/dev/devloop/crates/baml/baml_src/ - Generated Client:
/Users/joe/dev/devloop/crates/baml/baml_client/
#!/usr/bin/env bash
# analyze-branch.sh - Helper script for DevLoop branch analysis
#
# Usage:
# ./analyze-branch.sh [OPTIONS] [BRANCH]
#
# Options:
# --council Use council mode (multiple AI perspectives)
# --help Show this help message
#
# Examples:
# ./analyze-branch.sh # Analyze current branch (single analyst)
# ./analyze-branch.sh --council # Analyze current branch (council mode)
# ./analyze-branch.sh feature/auth # Analyze specific branch
# ./analyze-branch.sh --council feature/auth # Analyze specific branch with council
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default values
COUNCIL_MODE=false
BRANCH=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--council)
COUNCIL_MODE=true
shift
;;
--help)
grep "^#" "$0" | sed 's/^# //' | sed 's/^#!//'
exit 0
;;
*)
BRANCH="$1"
shift
;;
esac
done
# Get current branch if not specified
if [[ -z "$BRANCH" ]]; then
BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo -e "${BLUE}Analyzing current branch: ${GREEN}$BRANCH${NC}"
else
echo -e "${BLUE}Analyzing branch: ${GREEN}$BRANCH${NC}"
fi
# Check if DevLoop is built
if ! command -v just &> /dev/null; then
echo -e "${RED}Error: 'just' command not found${NC}"
echo "Install with: cargo install just"
exit 1
fi
# Build command
CMD="just analyze"
if [[ "$COUNCIL_MODE" == true ]]; then
CMD="$CMD --council"
echo -e "${YELLOW}Using council mode (multiple perspectives)${NC}"
fi
CMD="$CMD $BRANCH"
# Run analysis
echo -e "${BLUE}Running: ${NC}$CMD"
echo ""
eval "$CMD"
# Interpret results
echo ""
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE}Analysis Complete${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
echo -e "${YELLOW}Interpreting Results:${NC}"
echo ""
echo -e "${GREEN}Health Score Ranges:${NC}"
echo " 0.8 - 1.0: Excellent (ready to merge)"
echo " 0.6 - 0.8: Good (minor improvements suggested)"
echo " 0.4 - 0.6: Fair (address recommendations)"
echo " 0.0 - 0.4: Poor (significant issues)"
echo ""
if [[ "$COUNCIL_MODE" == true ]]; then
echo -e "${GREEN}Council Perspectives:${NC}"
echo " 1. Strict Critic: Conservative risk assessment"
echo " 2. Creative Explorer: Innovation opportunities"
echo " 3. General Analyst: Balanced overall view"
echo " 4. Security Reviewer: Security concerns"
echo " 5. Performance Analyst: Performance implications"
echo ""
echo -e "${YELLOW}Next Steps:${NC}"
echo " 1. Review all perspectives"
echo " 2. Check if any analyst flagged serious issues"
echo " 3. Address high-priority recommendations"
echo " 4. Re-run analysis after fixes"
echo " 5. Merge when all scores > 0.6"
else
echo -e "${YELLOW}Tip:${NC} Use --council for multiple perspectives"
fi
#!/usr/bin/env bash
# check-health.sh - DevLoop development environment health check
#
# Usage:
# ./check-health.sh
#
# Checks:
# - Rust toolchain
# - just command runner
# - DevLoop build status
# - API keys for BAML
# - GKG server (optional)
# - Git repository status
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Counters
PASS=0
WARN=0
FAIL=0
check_pass() {
echo -e "${GREEN}✓${NC} $1"
((PASS++))
}
check_warn() {
echo -e "${YELLOW}⚠${NC} $1"
((WARN++))
}
check_fail() {
echo -e "${RED}✗${NC} $1"
((FAIL++))
}
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE}DevLoop Health Check${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
# Check Rust
echo -e "${BLUE}Checking Rust toolchain...${NC}"
if command -v rustc &> /dev/null; then
RUST_VERSION=$(rustc --version)
check_pass "Rust installed: $RUST_VERSION"
else
check_fail "Rust not found. Install from https://rustup.rs"
fi
# Check Cargo
if command -v cargo &> /dev/null; then
CARGO_VERSION=$(cargo --version)
check_pass "Cargo installed: $CARGO_VERSION"
else
check_fail "Cargo not found"
fi
echo ""
# Check just
echo -e "${BLUE}Checking command runner...${NC}"
if command -v just &> /dev/null; then
JUST_VERSION=$(just --version)
check_pass "just installed: $JUST_VERSION"
else
check_fail "just not found. Install with: cargo install just"
fi
echo ""
# Check DevLoop build
echo -e "${BLUE}Checking DevLoop build...${NC}"
if [[ -d "target/release" ]] || [[ -d "target/debug" ]]; then
check_pass "DevLoop has been built"
# Check if binary exists
if [[ -f "target/release/devloop-cli" ]] || [[ -f "target/debug/devloop-cli" ]]; then
check_pass "devloop-cli binary found"
else
check_warn "devloop-cli binary not found. Run: just build"
fi
else
check_warn "No build artifacts found. Run: just build"
fi
echo ""
# Check API keys
echo -e "${BLUE}Checking API keys for BAML...${NC}"
if [[ -n "${OPENAI_API_KEY:-}" ]]; then
check_pass "OPENAI_API_KEY is set"
elif [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
check_pass "ANTHROPIC_API_KEY is set"
else
check_fail "No API key found. Set OPENAI_API_KEY or ANTHROPIC_API_KEY"
fi
echo ""
# Check GKG (optional)
echo -e "${BLUE}Checking GKG integration (optional)...${NC}"
if command -v gkg &> /dev/null; then
GKG_VERSION=$(gkg --version 2>&1 | head -n1 || echo "unknown")
check_pass "GKG installed: $GKG_VERSION"
# Check GKG server
if curl -s http://localhost:27495/health &> /dev/null; then
check_pass "GKG server is running"
else
check_warn "GKG server not running. Start with: gkg server start"
fi
else
check_warn "GKG not installed (optional). DevLoop will work without it"
fi
echo ""
# Check Git repository
echo -e "${BLUE}Checking Git repository...${NC}"
if git rev-parse --git-dir &> /dev/null; then
check_pass "In a Git repository"
# Check if repo has commits
if git log -1 &> /dev/null 2>&1; then
check_pass "Repository has commit history"
# Count branches
BRANCH_COUNT=$(git branch -a | wc -l | tr -d ' ')
check_pass "Found $BRANCH_COUNT branches"
else
check_warn "Repository has no commits yet"
fi
else
check_fail "Not in a Git repository"
fi
echo ""
# Check Claude directories
echo -e "${BLUE}Checking Claude directories...${NC}"
if [[ -d "$HOME/.claude/projects" ]]; then
check_pass "Claude projects directory exists"
else
check_warn "Claude projects directory not found at ~/.claude/projects"
fi
if [[ -d "$HOME/.claude/transcripts" ]]; then
check_pass "Claude transcripts directory exists"
# Count transcripts
TRANSCRIPT_COUNT=$(find "$HOME/.claude/transcripts" -type f -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
check_pass "Found $TRANSCRIPT_COUNT transcript files"
else
check_warn "Claude transcripts directory not found at ~/.claude/transcripts"
fi
echo ""
# Check BAML
echo -e "${BLUE}Checking BAML setup...${NC}"
if [[ -d "crates/baml/baml_src" ]]; then
check_pass "BAML source directory exists"
# Count BAML files
BAML_FILES=$(find crates/baml/baml_src -name "*.baml" 2>/dev/null | wc -l | tr -d ' ')
check_pass "Found $BAML_FILES BAML files"
else
check_fail "BAML source directory not found"
fi
if [[ -d "crates/baml/baml_client" ]]; then
check_pass "BAML client directory exists"
else
check_warn "BAML client not generated. Run: cd crates/baml && baml-cli generate"
fi
if command -v baml-cli &> /dev/null; then
check_pass "baml-cli is installed"
else
check_warn "baml-cli not found. Install from https://docs.boundaryml.com"
fi
echo ""
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE}Summary${NC}"
echo -e "${BLUE}======================================${NC}"
echo -e "${GREEN}Passed: $PASS${NC}"
echo -e "${YELLOW}Warnings: $WARN${NC}"
echo -e "${RED}Failed: $FAIL${NC}"
echo ""
if [[ $FAIL -eq 0 ]]; then
if [[ $WARN -eq 0 ]]; then
echo -e "${GREEN}✓ All checks passed! DevLoop is ready.${NC}"
exit 0
else
echo -e "${YELLOW}⚠ Some optional components are missing.${NC}"
echo -e "${YELLOW} DevLoop will work, but some features may be limited.${NC}"
exit 0
fi
else
echo -e "${RED}✗ Some critical checks failed.${NC}"
echo -e "${RED} Please address the failures above before using DevLoop.${NC}"
exit 1
fi
#!/usr/bin/env bash
# validate-skill.sh - Validate DevLoop skill structure
#
# Usage:
# ./validate-skill.sh
#
# Checks:
# - Required files exist
# - Scripts are executable
# - Markdown files are valid
# - File permissions are correct
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Counters
PASS=0
FAIL=0
check_pass() {
echo -e "${GREEN}✓${NC} $1"
((PASS++))
}
check_fail() {
echo -e "${RED}✗${NC} $1"
((FAIL++))
}
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE}DevLoop Skill Validation${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
echo -e "${BLUE}Skill directory: ${NC}$SKILL_DIR"
echo ""
# Check required files
echo -e "${BLUE}Checking required files...${NC}"
required_files=(
"SKILL.md"
"README.md"
"INDEX.md"
"resources/architecture-patterns.md"
"resources/baml-quick-reference.md"
"scripts/analyze-branch.sh"
"scripts/check-health.sh"
"scripts/validate-skill.sh"
)
for file in "${required_files[@]}"; do
if [[ -f "$SKILL_DIR/$file" ]]; then
check_pass "Found: $file"
else
check_fail "Missing: $file"
fi
done
echo ""
# Check script executability
echo -e "${BLUE}Checking script permissions...${NC}"
scripts=(
"scripts/analyze-branch.sh"
"scripts/check-health.sh"
"scripts/validate-skill.sh"
)
for script in "${scripts[@]}"; do
if [[ -x "$SKILL_DIR/$script" ]]; then
check_pass "Executable: $script"
else
check_fail "Not executable: $script (run: chmod +x $SKILL_DIR/$script)"
fi
done
echo ""
# Check markdown structure
echo -e "${BLUE}Checking SKILL.md structure...${NC}"
if [[ -f "$SKILL_DIR/SKILL.md" ]]; then
# Check for required sections
required_sections=(
"# DevLoop Development Observability Skill"
"## Overview"
"## When to Use This Skill"
"## Prerequisites"
"## Core Capabilities"
"## Workflow Examples"
"## Tips and Best Practices"
"## Troubleshooting"
"## Resources"
)
for section in "${required_sections[@]}"; do
if grep -q "^$section" "$SKILL_DIR/SKILL.md"; then
check_pass "Section found: ${section#\# }"
else
check_fail "Section missing: ${section#\# }"
fi
done
else
check_fail "SKILL.md not found"
fi
echo ""
# Check file sizes (detect empty files)
echo -e "${BLUE}Checking file sizes...${NC}"
for file in "${required_files[@]}"; do
if [[ -f "$SKILL_DIR/$file" ]]; then
size=$(wc -c < "$SKILL_DIR/$file" | tr -d ' ')
if [[ $size -gt 100 ]]; then
check_pass "Non-empty: $file ($size bytes)"
else
check_fail "Too small: $file ($size bytes)"
fi
fi
done
echo ""
# Check for shell script syntax
echo -e "${BLUE}Checking shell script syntax...${NC}"
for script in "${scripts[@]}"; do
if [[ -f "$SKILL_DIR/$script" ]]; then
if bash -n "$SKILL_DIR/$script" 2>/dev/null; then
check_pass "Valid syntax: $script"
else
check_fail "Syntax error: $script"
fi
fi
done
echo ""
# Check for proper shebang
echo -e "${BLUE}Checking script shebangs...${NC}"
for script in "${scripts[@]}"; do
if [[ -f "$SKILL_DIR/$script" ]]; then
first_line=$(head -n1 "$SKILL_DIR/$script")
if [[ "$first_line" =~ ^#!/usr/bin/env\ bash$ ]] || [[ "$first_line" =~ ^#!/bin/bash$ ]]; then
check_pass "Valid shebang: $script"
else
check_fail "Invalid shebang: $script (found: $first_line)"
fi
fi
done
echo ""
# Check directory structure
echo -e "${BLUE}Checking directory structure...${NC}"
if [[ -d "$SKILL_DIR/resources" ]]; then
check_pass "resources/ directory exists"
else
check_fail "resources/ directory missing"
fi
if [[ -d "$SKILL_DIR/scripts" ]]; then
check_pass "scripts/ directory exists"
else
check_fail "scripts/ directory missing"
fi
echo ""
# Summary
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE}Summary${NC}"
echo -e "${BLUE}======================================${NC}"
echo -e "${GREEN}Passed: $PASS${NC}"
echo -e "${RED}Failed: $FAIL${NC}"
echo ""
if [[ $FAIL -eq 0 ]]; then
echo -e "${GREEN}✓ Skill validation passed!${NC}"
echo -e "${GREEN} The DevLoop skill is properly structured.${NC}"
exit 0
else
echo -e "${RED}✗ Skill validation failed.${NC}"
echo -e "${RED} Please fix the issues above.${NC}"
exit 1
fi
Related skills
FAQ
What does council mode do?
It analyzes a branch from 5 AI perspectives - Strict Critic, Creative Explorer, General Analyst, Security Reviewer, and Performance Analyst - each returning a health score, risk level, insights, and recommendations.
What prerequisites does DevLoop need?
DevLoop installed and built, a git repository, and an OPENAI_API_KEY or ANTHROPIC_API_KEY for AI analysis; contributing needs the Rust toolchain and the just command runner.