Guide for AI-assisted development in this repository. Since all code is written with AI assistance, following these practices helps maintain quality and avoid technical debt.
Treat AI-generated code like work from a capable but context-limited junior developer:
- Always review generated code line by line before committing
- Understand what you're committing - if you can't explain it, don't merge it
- Question complexity - 9 out of 10 times, AI suggests overly complicated approaches. Ask for simpler alternatives
- Validate logic, not just syntax - AI produces syntactically correct but logically flawed code regularly
Don't start coding immediately:
- Request architectural options first
- Discuss trade-offs before writing code
- Define acceptance criteria upfront
- Break large tasks into smaller, reviewable chunks
Poor context yields poor results. Always include:
- Relevant existing code files
- Exact error messages and stack traces
- Database schemas and API contracts
- Version numbers and environment details
- Examples of desired patterns from the codebase
This project follows standard Go conventions:
# Format code
go fmt ./...
# Run linter (configured in .golangci.yml)
golangci-lint run
# Run tests
go test ./...Use conventional commits format:
<type>: <description>
Types:
feat: New feature
fix: Bug fix
refactor: Code reorganization (no behavior change)
docs: Documentation only
test: Adding or updating tests
chore: Maintenance tasks
perf: Performance improvements
Examples from this repo:
feat: add keyboard shortcut to toggle dangerous modefix: prefer stored daemon_session when finding task tmux windowrefactor: extract memory injection into separate function
Follow the existing package structure:
internal/
├── config/ # Configuration management
├── db/ # Database layer (CRUD, queries)
├── executor/ # Background task processing
├── github/ # GitHub API integration
├── hooks/ # Task lifecycle hooks
├── mcp/ # Model Context Protocol
├── server/ # SSH server
└── ui/ # Terminal UI components
Package Guidelines:
- Keep packages focused on a single responsibility
- Use
internal/for non-exported packages - Place tests alongside source files (
*_test.go)
- Database operations: All CRUD functions need tests
- Business logic: Executor logic, state transitions
- Parsing/transformation: URL parsing, input detection
- Bug fixes: Add a test that would have caught the bug
Follow the existing patterns in this codebase:
func TestFeatureName(t *testing.T) {
// Setup: Create temporary database
tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "test.db")
db, err := Open(dbPath)
if err != nil {
t.Fatalf("failed to open database: %v", err)
}
defer db.Close()
// Test the feature
result, err := db.SomeOperation()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Assert expectations
if result != expected {
t.Errorf("expected %v, got %v", expected, result)
}
}# Run all tests
make test
# Run specific package tests
go test ./internal/db/...
# Run with verbose output
go test -v ./...
# Run specific test
go test -run TestFeatureName ./internal/db/Before merging AI-generated code, verify:
- No hardcoded secrets - API keys, passwords, tokens
- Input validation - User inputs sanitized before use
- SQL injection prevention - Using parameterized queries
- Error messages - Don't leak sensitive information
- File operations - Validate paths, prevent traversal
Watch for these common AI security mistakes:
- Hardcoded credentials in examples that get committed
- Missing input validation on user-provided data
- Overly permissive error handling that swallows important errors
- Insecure defaults that should be opt-in
AI gets you 70% of the way quickly, but the final 30% requires careful engineering. Watch for:
- Bug fixes that create new bugs
- Accumulated complexity from quick fixes
- Missing edge case handling
- Inconsistent patterns across the codebase
- Small, focused changes - Easier to review and less likely to introduce issues
- Incremental testing - Test after each change, not at the end
- Pattern consistency - Match existing code style and patterns
- Explicit over clever - Readable code beats "clever" solutions
Question AI-generated code that:
- Adds dependencies for simple tasks
- Creates abstractions for single-use cases
- Uses complex patterns where simple ones work
- Includes commented-out code or TODOs
- Has functions longer than ~50 lines
- Read relevant existing code to understand patterns
- Check for similar implementations in the codebase
- Identify files that will be modified
- Consider impact on other components
- Make changes incrementally
- Run tests frequently (
make test) - Run linter before committing (
golangci-lint run) - Keep commits atomic and focused
- Self-review - Read through all changes as a reviewer would
- Run full test suite -
make test - Check linting -
golangci-lint run - Test manually - Run the app and verify behavior
- Update documentation - If behavior changes, update docs
## Summary
Brief description of what changed and why.
## Changes
- List of specific changes made
## Testing
- How the changes were tested
- Any manual testing steps
## Screenshots (if UI changes)Follow Go's explicit error handling:
// Good: Check errors explicitly
result, err := doSomething()
if err != nil {
return fmt.Errorf("failed to do something: %w", err)
}
// Bad: Ignoring errors silently
result, _ := doSomething() // Don't do this unless intentionalSome errors are intentionally ignored (configured in .golangci.yml):
- Cleanup operations (closing files, connections)
- Logging operations
- Fire-and-forget calls where failure is acceptable
Document why when ignoring errors:
// Ignore close error - we're done with the file anyway
_ = file.Close()- Package comments - Brief description of package purpose
- Exported functions - Document behavior, parameters, return values
- Complex logic - Explain the "why", not the "what"
- Avoid obvious comments - Don't comment self-explanatory code
Update documentation when:
- Adding new features or commands
- Changing existing behavior
- Adding new configuration options
- Modifying the database schema
make build # Build binaries
make test # Run tests
make lint # Run linter (requires golangci-lint)
go fmt ./... # Format code| File | Purpose |
|---|---|
AGENTS.md |
AI agent guide (architecture, schema) |
DEVELOPMENT.md |
Development practices (this file) |
.golangci.yml |
Linter configuration |
Makefile |
Build and deployment commands |
- Check existing code for patterns
- Run
make helpfor available commands - Review recent commits for style examples