Skip to content

Instantly share code, notes, and snippets.

@svenmalvik
Created January 31, 2026 22:20
Show Gist options
  • Select an option

  • Save svenmalvik/9a174835eabfc729749e2192a5b15f2e to your computer and use it in GitHub Desktop.

Select an option

Save svenmalvik/9a174835eabfc729749e2192a5b15f2e to your computer and use it in GitHub Desktop.
#!/bin/bash
# Feature Workflow Automation
# Automates the feature development workflow using Claude CLI
# Based on the workflow defined in feature_workflow.md
set -e # Exit on error
# Configuration
MAX_ITERATIONS=5
MAX_LOC=300
MAX_REFACTOR_ROUNDS=10
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to log messages
log() {
local message="$1"
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
echo -e "${BLUE}[${timestamp}]${NC} $message"
}
# Function to check if output contains blocking questions (not informational)
has_blocking_questions() {
local output="$1"
# Only match questions that truly block progress - be more selective
# Avoid matching informational "?" in explanations
if echo "$output" | grep -qiE '(Which (approach|option|method|one)|Should I (proceed|continue|use)|Would you like me to|Ready to proceed\?|Please (choose|select)|waiting for.*input)'; then
return 0 # Has blocking questions
fi
return 1 # No blocking questions
}
# Function to run Claude CLI with automatic question resolution
run_claude() {
local prompt="$1"
local step_name="$2"
local max_followups=2 # Reduced from 5 - fail fast if stuck
local followup_count=0
echo ""
log "${GREEN}============================================================${NC}"
log "${GREEN}Step: $step_name${NC}"
log "${GREEN}============================================================${NC}"
echo ""
# Run Claude CLI with --continue flag and capture output
log "${YELLOW}⟳ Executing Claude CLI command...${NC}"
log "${YELLOW}Prompt: ${NC}$prompt"
echo ""
local output
output=$(claude -p "$prompt" --continue 2>&1 | tee /dev/tty)
# Check if output contains blocking questions and auto-answer them
while has_blocking_questions "$output" && [ $followup_count -lt $max_followups ]; do
followup_count=$((followup_count + 1))
log "${YELLOW}⟳ Detected blocking question, auto-selecting (followup $followup_count/$max_followups)...${NC}"
local followup_prompt="STOP ASKING QUESTIONS. Choose option 1 (or the first/recommended option) and execute it NOW.
Do not explain options. Do not ask for confirmation. Do not present alternatives.
Just proceed with the implementation using the simplest approach that works in this session."
log "${YELLOW}Followup Prompt: ${NC}$followup_prompt"
echo ""
output=$(claude -p "$followup_prompt" --continue 2>&1 | tee /dev/tty)
done
if [ $followup_count -ge $max_followups ]; then
log "${YELLOW}⚠ Reached max followups ($max_followups), proceeding to next step${NC}"
fi
log "${GREEN}✓ Step '$step_name' completed${NC}"
}
# Function to sanitize filename
sanitize_filename() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | cut -c1-50
}
# Function to find code files exceeding MAX_LOC
# Returns list of files with their line counts
find_long_files() {
local folder="$1"
local max_lines="$2"
# Find common code file extensions, count lines, filter by threshold
find "$folder" -type f \( \
-name "*.go" -o -name "*.py" -o -name "*.js" -o -name "*.ts" -o \
-name "*.jsx" -o -name "*.tsx" -o -name "*.java" -o -name "*.c" -o \
-name "*.cpp" -o -name "*.h" -o -name "*.hpp" -o -name "*.rs" -o \
-name "*.rb" -o -name "*.php" -o -name "*.swift" -o -name "*.kt" -o \
-name "*.scala" -o -name "*.cs" -o -name "*.sh" -o -name "*.bash" \
\) 2>/dev/null | while read -r file; do
local lines=$(wc -l < "$file" 2>/dev/null | tr -d ' ')
if [ "$lines" -gt "$max_lines" ]; then
echo "$file:$lines"
fi
done
}
# Main function
main() {
if [ $# -ne 1 ]; then
echo "Usage: $0 <spec_file.md>"
echo "Example: $0 docs/specs/my-feature-spec.md"
exit 1
fi
local spec_file="$1"
# Validate spec file exists
if [ ! -f "$spec_file" ]; then
echo -e "${RED}Error: Specification file not found: $spec_file${NC}"
exit 1
fi
# Create project folder based on spec filename
local spec_basename=$(basename "$spec_file" .md)
local project_folder="projects/${spec_basename}"
mkdir -p "$project_folder"
log "${BLUE}========================================${NC}"
log "${BLUE}Feature Workflow Automation${NC}"
log "${BLUE}========================================${NC}"
log "Spec File: $spec_file"
log "Project Folder: $project_folder"
echo ""
# Phase 1: Planning
log "${BLUE}========================================${NC}"
log "${BLUE}PHASE 1: PLANNING${NC}"
log "${BLUE}========================================${NC}"
# Instruction suffix to prevent questions
local NO_QUESTIONS="IMPORTANT: Do not ask questions or present options. Make autonomous decisions. Use the simplest approach that works in the current session. Proceed immediately."
# Step 1: Create Implementation Plan
run_claude "Read the specification file at $spec_file and create a detailed implementation plan based on it. All new code files must be created in the folder: $project_folder. Use the superpowers:writing-plans skill if available. $NO_QUESTIONS" "Create Implementation Plan"
# Step 2: Add Skill Application to Plan
run_claude "Add todo items to the plan for applying these skills after implementation: coding skill, security skill, and tracing skill. $NO_QUESTIONS" "Add Skill Applications to Plan"
# Step 3: Implement the Plan
run_claude "Start implementing the plan you created. Remember: all new code files must be created in the folder: $project_folder. $NO_QUESTIONS" "Implement the Plan"
# Phase 2: Test-Fix Loop
log ""
log "${BLUE}========================================${NC}"
log "${BLUE}PHASE 2: TEST-FIX LOOP${NC}"
log "${BLUE}========================================${NC}"
for iteration in $(seq 1 $MAX_ITERATIONS); do
log ""
log "${YELLOW}⟳ Test-Fix Iteration $iteration/$MAX_ITERATIONS${NC}"
# Step A: Test from user perspective and analyze results
log ""
log "${GREEN}============================================================${NC}"
log "${GREEN}Step: Test Feature (Iteration $iteration)${NC}"
log "${GREEN}============================================================${NC}"
echo ""
local test_prompt="Test the implemented feature from a user's perspective. Run the code/script as if you were the end user. After testing, you MUST end your response with exactly one of these lines:
TEST_RESULT: PASS
or
TEST_RESULT: FAIL
Use PASS only if all tests succeed with no errors. Use FAIL if there are any errors, failures, or issues. $NO_QUESTIONS"
log "${YELLOW}⟳ Executing Claude CLI command...${NC}"
log "${YELLOW}Prompt: ${NC}$test_prompt"
echo ""
local test_output
test_output=$(claude -p "$test_prompt" --continue 2>&1 | tee /dev/tty)
# Analyze the test output for pass/fail
if echo "$test_output" | grep -q "TEST_RESULT: PASS"; then
log "${GREEN}✓ All tests passed on iteration $iteration!${NC}"
break
fi
log "${RED}✗ Tests failed on iteration $iteration. Attempting fixes...${NC}"
# Step C: Fix errors found
run_claude "Fix the errors you found during testing. $NO_QUESTIONS" "Fix Errors (Iteration $iteration)"
# Step D: Apply skills (separate calls)
run_claude "Use the coding skill to review the code. All warnings must be fixed - do not leave any compiler warnings, linter warnings, or code quality warnings unresolved. $NO_QUESTIONS" "Apply Coding Skill (Iteration $iteration)"
run_claude "Use the security skill to check for vulnerabilities. $NO_QUESTIONS" "Apply Security Skill (Iteration $iteration)"
run_claude "Use the tracing skill to add proper logging/tracing. $NO_QUESTIONS" "Apply Tracing Skill (Iteration $iteration)"
run_claude "Use the code simplification skill to clean up the code. $NO_QUESTIONS" "Apply Code Simplification Skill (Iteration $iteration)"
done
# Phase 3: File Length Check Loop
log ""
log "${BLUE}========================================${NC}"
log "${BLUE}PHASE 3: FILE LENGTH CHECK${NC}"
log "${BLUE}========================================${NC}"
log "Checking for code files exceeding $MAX_LOC lines..."
local refactor_round=0
while [ $refactor_round -lt $MAX_REFACTOR_ROUNDS ]; do
refactor_round=$((refactor_round + 1))
# Find all long files
local long_files=$(find_long_files "$project_folder" "$MAX_LOC")
if [ -z "$long_files" ]; then
log "${GREEN}✓ All code files are under $MAX_LOC lines!${NC}"
break
fi
# Count how many long files
local file_count=$(echo "$long_files" | wc -l | tr -d ' ')
log "${YELLOW}⟳ Refactor Round $refactor_round/$MAX_REFACTOR_ROUNDS - Found $file_count file(s) exceeding $MAX_LOC lines:${NC}"
echo "$long_files" | while read -r entry; do
local filepath=$(echo "$entry" | cut -d: -f1)
local linecount=$(echo "$entry" | cut -d: -f2)
log " ${RED}$filepath ($linecount lines)${NC}"
done
# Build a list of files for Claude to refactor
local file_list=$(echo "$long_files" | cut -d: -f1 | tr '\n' ' ')
run_claude "The following code files exceed $MAX_LOC lines and need to be refactored into smaller, focused modules:
$long_files
For each file:
1. Split it into multiple smaller files (each under $MAX_LOC lines)
2. Extract logical components, utilities, or handlers into separate files
3. Update imports/exports to maintain functionality
4. Ensure no circular dependencies are created
5. Keep related code together in the same file
$NO_QUESTIONS" "Refactor Long Files (Round $refactor_round)"
# Verify the refactoring didn't break anything
run_claude "Run a quick smoke test to verify the refactored code still works correctly. $NO_QUESTIONS" "Verify Refactoring (Round $refactor_round)"
done
if [ $refactor_round -ge $MAX_REFACTOR_ROUNDS ]; then
local remaining=$(find_long_files "$project_folder" "$MAX_LOC")
if [ -n "$remaining" ]; then
log "${RED}⚠ Warning: Max refactor rounds reached. Some files still exceed $MAX_LOC lines:${NC}"
echo "$remaining" | while read -r entry; do
log " ${RED}$entry${NC}"
done
fi
fi
# Phase 4: Final Instructions
log ""
log "${BLUE}========================================${NC}"
log "${BLUE}PHASE 4: FINAL INSTRUCTIONS${NC}"
log "${BLUE}========================================${NC}"
run_claude "Provide clear instructions for the user on how to test and run what you implemented. Include: 1) Prerequisites or dependencies needed, 2) Step-by-step commands to run the feature, 3) Expected output or behavior, 4) Any configuration or environment variables required. Format as a clear, actionable guide. $NO_QUESTIONS" "Provide Testing and Running Instructions"
# Summary
log ""
log "${BLUE}========================================${NC}"
log "${BLUE}WORKFLOW SUMMARY${NC}"
log "${BLUE}========================================${NC}"
log "Spec File: $spec_file"
log "Project Folder: $project_folder"
log "${BLUE}========================================${NC}"
}
# Run main function
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment