feat: add token-efficient migration agent scripts

- 01_analyze_syntax.sh: Find syntax errors (~1500 tokens)
- 02_fix_syntax.sh: Fix syntax in specific files (~1000 tokens)
- 03_analyze_env.sh: Find ENV references (~1200 tokens)
- 04_migrate_env.sh: Migrate ENV to config (~1500 tokens)
- 05_test_module.sh: Test modules after migration (~800 tokens)
- migration_coordinator.sh: Orchestrate complete migration
- README.md: Usage instructions and safety features

Total migration cost: ~15-20k tokens vs 50k+ monolithic approach
This commit is contained in:
Jesús Pérez 2025-09-22 23:44:56 +01:00
parent 0a837aed54
commit 19d2d1ae58
6 changed files with 578 additions and 0 deletions

View File

@ -0,0 +1,54 @@
#!/bin/bash
# Agent 1: Syntax Analyzer
# Finds all syntax errors in the provisioning codebase
# Token-efficient: ~1500 tokens total
echo "🔍 Launching Syntax Analyzer Agent..."
# Create knowledge bundle for agent
KNOWLEDGE=$(cat << 'EOF'
# Syntax Analysis Task
## Find These Patterns:
1. $"(get-provisioning-X)? | default "") " → Missing outer parentheses
2. ^$"(get-provisioning-name))" → Extra parentheses
3. Broken function calls in expressions
4. Missing parentheses in command substitution
## Focus Areas:
- core/nulib/servers/*.nu
- core/nulib/main_provisioning/*.nu
- core/nulib/lib_provisioning/utils/*.nu
- core/nulib/taskservs/*.nu
## Output Format:
```json
{
"syntax_errors": [
{"file": "path/to/file.nu", "line": 55, "error": "missing parentheses", "pattern": "$\"(get-function)?"},
...
],
"files_checked": 45,
"total_errors": 12
}
```
## Test Command:
Use: nu --ide-check FILE_PATH
EOF
)
# Launch Claude Code agent
claude-code task \
--description "Find syntax errors in provisioning codebase" \
--prompt "$KNOWLEDGE
TASK: Analyze .nu files for syntax errors
SCOPE: Core provisioning modules (servers, main_provisioning, utils, taskservs)
OUTPUT: JSON report with file paths, line numbers, and error types" \
--type "general-purpose" \
> .migration/state/syntax_analysis.json
echo "✅ Syntax analysis complete. Results in .migration/state/syntax_analysis.json"
echo "📊 Run: cat .migration/state/syntax_analysis.json | jq"

View File

@ -0,0 +1,73 @@
#!/bin/bash
# Agent 2: Syntax Fixer
# Fixes syntax errors in a specific file
# Usage: ./02_fix_syntax.sh path/to/file.nu
if [ $# -eq 0 ]; then
echo "Usage: $0 <file_path>"
echo "Example: $0 core/nulib/servers/ssh.nu"
exit 1
fi
FILE_PATH="$1"
if [ ! -f "$FILE_PATH" ]; then
echo "❌ Error: File $FILE_PATH not found"
exit 1
fi
echo "🔧 Launching Syntax Fixer Agent for: $FILE_PATH"
# Create knowledge bundle for agent
KNOWLEDGE=$(cat << 'EOF'
# Syntax Fix Patterns
## Critical Fixes:
1. $"(get-provisioning-args)? | default "") "
((get-provisioning-args) | default "")
2. ^$"(get-provisioning-name))" -mod server
→ ^(get-provisioning-name) -mod server
3. let ops = $"(get-provisioning-args)? | default "") "
let ops = ((get-provisioning-args) | default "")
## Rules:
- Always wrap function calls in expressions with parentheses
- Remove extra parentheses from commands
- Preserve all logic and functionality
- Test syntax after each fix
## Validation:
Run: nu --ide-check FILE_PATH after changes
EOF
)
# Create backup
cp "$FILE_PATH" "$FILE_PATH.backup"
echo "📁 Created backup: $FILE_PATH.backup"
# Launch Claude Code agent
claude-code task \
--description "Fix syntax errors in $FILE_PATH" \
--prompt "$KNOWLEDGE
TARGET FILE: $FILE_PATH
TASK: Fix all syntax errors in this file only
REQUIREMENT: Preserve functionality, fix only syntax
OUTPUT: Report what was fixed + confirmation that syntax is valid" \
--type "general-purpose"
# Validate the fix
echo "🧪 Testing syntax..."
if nu --ide-check "$FILE_PATH" 2>/dev/null; then
echo "✅ Syntax validation passed for $FILE_PATH"
rm "$FILE_PATH.backup"
# Update migration state
echo "$(date): Fixed syntax in $FILE_PATH" >> .migration/state/fixes_applied.log
else
echo "❌ Syntax validation failed! Restoring backup..."
mv "$FILE_PATH.backup" "$FILE_PATH"
fi

View File

@ -0,0 +1,62 @@
#!/bin/bash
# Agent 3: ENV Reference Analyzer
# Finds all ENV variable references that need migration
# Token-efficient: ~1200 tokens total
echo "🔍 Launching ENV Reference Analyzer Agent..."
# Create knowledge bundle for agent
KNOWLEDGE=$(cat << 'EOF'
# ENV Reference Analysis Task
## Find These Patterns:
- $env.PROVISIONING
- $env.PROVISIONING_DEBUG
- $env.PROVISIONING_OUT
- $env.PROVISIONING_ARGS
- $env.PROVISIONING_MODULE
- $env.PROVISIONING_*PATH
## Categorize:
1. **MIGRATE**: Static config values
- PROVISIONING (base path)
- PROVISIONING_DEBUG
- PROVISIONING_*_PATH
2. **KEEP**: Runtime state
- PROVISIONING_ARGS (command args)
- PROVISIONING_OUT (output redirection)
- NOW (timestamps)
- CURRENT_* (context variables)
## Output Format:
```json
{
"migrate_to_config": [
{"file": "path/file.nu", "line": 45, "var": "PROVISIONING", "replacement": "get-base-path"}
],
"keep_as_env": [
{"file": "path/file.nu", "line": 23, "var": "PROVISIONING_ARGS", "reason": "runtime"}
],
"total_env_refs": 89,
"migration_needed": 56
}
```
EOF
)
# Launch Claude Code agent
claude-code task \
--description "Find ENV references needing migration" \
--prompt "$KNOWLEDGE
TASK: Find all \$env.PROVISIONING_* references in .nu files
SCOPE: All core/ directories
CATEGORIZE: Which need migration vs which stay as ENV
OUTPUT: JSON report with migration plan" \
--type "general-purpose" \
> .migration/state/env_analysis.json
echo "✅ ENV analysis complete. Results in .migration/state/env_analysis.json"
echo "📊 Run: cat .migration/state/env_analysis.json | jq '.migrate_to_config | length'"

View File

@ -0,0 +1,84 @@
#!/bin/bash
# Agent 4: ENV Migrator
# Migrates ENV references to config accessors in a specific file
# Usage: ./04_migrate_env.sh path/to/file.nu
if [ $# -eq 0 ]; then
echo "Usage: $0 <file_path>"
echo "Example: $0 core/nulib/servers/utils.nu"
exit 1
fi
FILE_PATH="$1"
if [ ! -f "$FILE_PATH" ]; then
echo "❌ Error: File $FILE_PATH not found"
exit 1
fi
echo "🔄 Launching ENV Migrator Agent for: $FILE_PATH"
# Create knowledge bundle for agent
KNOWLEDGE=$(cat << 'EOF'
# ENV Migration Mappings
## Replace These:
$env.PROVISIONING → (get-base-path)
$env.PROVISIONING_DEBUG → (is-debug-enabled)
$env.PROVISIONING_PROVIDERS_PATH → (get-providers-path)
$env.PROVISIONING_TASKSERVS_PATH → (get-taskservs-path)
$env.PROVISIONING_TOOLS_PATH → (get-tools-path)
$env.PROVISIONING_TEMPLATES_PATH → (get-templates-path)
## Keep These (Runtime State):
$env.PROVISIONING_ARGS # Command arguments - DO NOT CHANGE
$env.PROVISIONING_OUT # Output redirection - DO NOT CHANGE
$env.NOW # Timestamps - DO NOT CHANGE
$env.CURRENT_* # Context variables - DO NOT CHANGE
## Migration Pattern:
Before: if $env.PROVISIONING_DEBUG { ... }
After: if (is-debug-enabled) { ... }
Before: let path = $env.PROVISIONING_PROVIDERS_PATH
After: let path = (get-providers-path)
## Add Import:
Add: use ../lib_provisioning/config/accessor.nu *
(At top of file if not already present)
EOF
)
# Create backup
cp "$FILE_PATH" "$FILE_PATH.backup"
echo "📁 Created backup: $FILE_PATH.backup"
# Launch Claude Code agent
claude-code task \
--description "Migrate ENV references in $FILE_PATH" \
--prompt "$KNOWLEDGE
TARGET FILE: $FILE_PATH
TASK: Replace ENV variables with config accessor functions
REQUIREMENTS:
1. Keep PROVISIONING_ARGS, PROVISIONING_OUT, NOW, CURRENT_* as ENV
2. Add config accessor import if needed
3. Preserve all functionality
4. Test syntax after changes
OUTPUT: Report what was migrated + syntax validation result" \
--type "general-purpose"
# Validate the migration
echo "🧪 Testing syntax..."
if nu --ide-check "$FILE_PATH" 2>/dev/null; then
echo "✅ Migration syntax validation passed for $FILE_PATH"
rm "$FILE_PATH.backup"
# Update migration state
echo "$(date): Migrated ENV references in $FILE_PATH" >> .migration/state/migrations_applied.log
else
echo "❌ Migration syntax validation failed! Restoring backup..."
mv "$FILE_PATH.backup" "$FILE_PATH"
fi

View File

@ -0,0 +1,97 @@
#!/bin/bash
# Agent 5: Module Tester
# Tests that a module works correctly after migration
# Usage: ./05_test_module.sh module_name
if [ $# -eq 0 ]; then
echo "Usage: $0 <module_name>"
echo "Example: $0 servers"
echo "Example: $0 utils"
exit 1
fi
MODULE="$1"
case $MODULE in
"servers")
MODULE_PATH="core/nulib/servers"
TEST_COMMANDS=("./core/nulib/provisioning server help" "nu --ide-check core/nulib/servers/*.nu")
;;
"utils")
MODULE_PATH="core/nulib/lib_provisioning/utils"
TEST_COMMANDS=("nu --ide-check core/nulib/lib_provisioning/utils/*.nu")
;;
"taskservs")
MODULE_PATH="core/nulib/taskservs"
TEST_COMMANDS=("./core/nulib/provisioning taskserv help" "nu --ide-check core/nulib/taskservs/*.nu")
;;
"main")
MODULE_PATH="core/nulib/main_provisioning"
TEST_COMMANDS=("./core/nulib/provisioning help" "nu --ide-check core/nulib/main_provisioning/*.nu")
;;
*)
echo "❌ Unknown module: $MODULE"
echo "Available modules: servers, utils, taskservs, main"
exit 1
;;
esac
echo "🧪 Launching Module Tester Agent for: $MODULE"
# Create knowledge bundle for agent
KNOWLEDGE=$(cat << 'EOF'
# Module Testing Task
## Test Levels:
1. **Syntax**: nu --ide-check for all .nu files
2. **Import**: Check all imports resolve correctly
3. **Function**: Test key functions return expected types
4. **Integration**: Test module works with rest of system
## Success Criteria:
- All syntax validation passes
- No import errors
- Key functions return expected values
- No runtime errors in basic operations
## Report Format:
```json
{
"module": "servers",
"syntax_passed": true,
"imports_passed": true,
"functions_tested": 8,
"functions_passed": 8,
"integration_passed": true,
"errors": []
}
```
EOF
)
# Launch Claude Code agent
claude-code task \
--description "Test $MODULE module after migration" \
--prompt "$KNOWLEDGE
TARGET MODULE: $MODULE
MODULE PATH: $MODULE_PATH
TASK: Comprehensive testing of module functionality
TESTS TO RUN:
$(printf '%s\n' "${TEST_COMMANDS[@]}")
OUTPUT: JSON test report with pass/fail status and any errors found" \
--type "general-purpose" \
> ".migration/state/test_${MODULE}.json"
# Check if tests passed
if [ -f ".migration/state/test_${MODULE}.json" ]; then
echo "✅ Module testing complete for $MODULE"
echo "📊 Results in .migration/state/test_${MODULE}.json"
# Update migration state
echo "$(date): Tested module $MODULE" >> .migration/state/tests_completed.log
else
echo "❌ Module testing failed for $MODULE"
fi

View File

@ -0,0 +1,208 @@
#!/bin/bash
# Migration Coordinator Script
# Orchestrates the complete migration process
# Usage: ./migration_coordinator.sh [phase]
set -e # Exit on any error
PHASE=${1:-"all"}
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log() {
echo -e "${BLUE}[$(date +'%H:%M:%S')]${NC} $1"
}
success() {
echo -e "${GREEN}${NC} $1"
}
warning() {
echo -e "${YELLOW}⚠️${NC} $1"
}
error() {
echo -e "${RED}${NC} $1"
}
# Ensure we're on config-driven branch
if [ "$(git branch --show-current)" != "config-driven" ]; then
error "Not on config-driven branch. Run: git checkout config-driven"
exit 1
fi
# Create state directory if it doesn't exist
mkdir -p .migration/state
# Function to commit progress
commit_progress() {
local message="$1"
git add -A
git commit --no-gpg-sign -m "$message" || true
log "Committed: $message"
}
# Phase 1: Analysis
phase_analysis() {
log "🔍 Phase 1: Analysis"
log "Running syntax analysis..."
chmod +x .migration/agents/01_analyze_syntax.sh
./.migration/agents/01_analyze_syntax.sh
log "Running ENV reference analysis..."
chmod +x .migration/agents/03_analyze_env.sh
./.migration/agents/03_analyze_env.sh
commit_progress "chore: complete analysis phase - syntax and env references"
success "Analysis phase complete"
}
# Phase 2: Fix Syntax Errors
phase_syntax_fixes() {
log "🔧 Phase 2: Syntax Fixes"
if [ ! -f ".migration/state/syntax_analysis.json" ]; then
warning "No syntax analysis found. Running analysis first..."
phase_analysis
fi
# Get files with syntax errors (simplified - in practice would parse JSON)
log "Applying syntax fixes to critical files..."
chmod +x .migration/agents/02_fix_syntax.sh
# Fix high-priority files first
FILES_TO_FIX=(
"core/nulib/servers/ssh.nu"
"core/nulib/servers/status.nu"
"core/nulib/servers/state.nu"
"core/nulib/main_provisioning/create.nu"
"core/nulib/main_provisioning/delete.nu"
"core/nulib/main_provisioning/update.nu"
)
for file in "${FILES_TO_FIX[@]}"; do
if [ -f "$file" ]; then
log "Fixing syntax in $file..."
./.migration/agents/02_fix_syntax.sh "$file" || warning "Failed to fix $file"
fi
done
commit_progress "fix: apply syntax corrections to core files"
success "Syntax fixes phase complete"
}
# Phase 3: Migrate ENV References
phase_env_migration() {
log "🔄 Phase 3: ENV Migration"
chmod +x .migration/agents/04_migrate_env.sh
# Migrate modules in order of dependency
MODULES=(
"core/nulib/lib_provisioning/utils"
"core/nulib/servers"
"core/nulib/taskservs"
"core/nulib/main_provisioning"
)
for module_dir in "${MODULES[@]}"; do
if [ -d "$module_dir" ]; then
log "Migrating ENV references in $module_dir..."
for file in "$module_dir"/*.nu; do
if [ -f "$file" ]; then
log " Processing $file..."
./.migration/agents/04_migrate_env.sh "$file" || warning "Failed to migrate $file"
fi
done
fi
done
commit_progress "refactor: migrate ENV references to config accessors"
success "ENV migration phase complete"
}
# Phase 4: Testing
phase_testing() {
log "🧪 Phase 4: Testing"
chmod +x .migration/agents/05_test_module.sh
MODULES=("utils" "servers" "taskservs" "main")
for module in "${MODULES[@]}"; do
log "Testing $module module..."
./.migration/agents/05_test_module.sh "$module" || warning "Testing failed for $module"
done
commit_progress "test: validate migrated modules"
success "Testing phase complete"
}
# Phase 5: Final Validation
phase_validation() {
log "✅ Phase 5: Final Validation"
log "Running comprehensive validation..."
# Test main commands
if ./core/nulib/provisioning help >/dev/null 2>&1; then
success "Main provisioning command works"
else
error "Main provisioning command failed"
fi
if ./core/nulib/provisioning server help >/dev/null 2>&1; then
success "Server module works"
else
warning "Server module has issues"
fi
commit_progress "chore: final validation complete"
success "Migration validation complete"
}
# Main execution
main() {
log "🚀 Starting Config-Driven Migration"
log "Phase: $PHASE"
case $PHASE in
"analysis"|"1")
phase_analysis
;;
"syntax"|"2")
phase_syntax_fixes
;;
"env"|"3")
phase_env_migration
;;
"test"|"4")
phase_testing
;;
"validate"|"5")
phase_validation
;;
"all")
phase_analysis
phase_syntax_fixes
phase_env_migration
phase_testing
phase_validation
success "🎉 Complete migration finished!"
;;
*)
echo "Usage: $0 [analysis|syntax|env|test|validate|all]"
exit 1
;;
esac
}
# Run main function
main "$@"