TDDAI Setup Scripts
This document contains the complete setup scripts used to configure TDDAI across the LLM Platform ecosystem.
Master Setup Scriptβ
#!/bin/bash
# setup-tddai-platform.sh
# Complete TDDAI setup for LLM Platform
echo "π Setting up TDDAI for LLM Platform..."
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Base directory
BASE_DIR="/Users/flux423/Sites/LLM"
# Function to create hook files
create_hooks() {
local project_path=$1
local project_name=$(basename "$project_path")
local project_type=$2
echo -e "${BLUE}Setting up $project_name...${NC}"
# Create directories
mkdir -p "$project_path/.claude/hooks"
mkdir -p "$project_path/.tddai"
# Create settings.json
cat > "$project_path/.claude/settings.json" << EOF
{
"hooks": {
"UserPromptSubmit": {
"command": "$project_path/.claude/hooks/tdd-context-injector.js"
},
"PreToolUse": {
"command": "$project_path/.claude/hooks/tdd-compliance-guardian.js"
}
}
}
EOF
# Create context injector
cat > "$project_path/.claude/hooks/tdd-context-injector.js" << 'EOF'
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
function injectTDDContext() {
const projectPath = path.resolve(__dirname, '../..');
const projectName = path.basename(projectPath);
// Read TDDAI configuration
let tddaiConfig = {};
const configPath = path.join(projectPath, 'tddai.config.yml');
if (fs.existsSync(configPath)) {
try {
const content = fs.readFileSync(configPath, 'utf8');
// Simple YAML parsing
const lines = content.split('\n');
const config = {};
let currentSection = null;
lines.forEach(line => {
const trimmed = line.trim();
if (trimmed.includes(':') && !trimmed.startsWith('#')) {
const [key, value] = trimmed.split(':').map(s => s.trim());
if (!value) {
currentSection = key;
config[currentSection] = {};
} else {
if (currentSection) {
config[currentSection][key] = value.replace(/['"]/g, '');
} else {
config[key] = value.replace(/['"]/g, '');
}
}
}
});
tddaiConfig = config;
} catch (e) {
tddaiConfig = {};
}
}
const coverageThreshold = tddaiConfig.testing?.coverageThreshold || 95;
const framework = tddaiConfig.testing?.framework || 'jest';
const context = \`
## TDD Context for Project: \${projectName}
**Project Type**: ${project_type}
**Framework**: \${framework}
**Coverage Target**: \${coverageThreshold}%
### TDD Requirements:
- β
RED: Write failing test first
- β
GREEN: Make test pass (minimal code)
- β
REFACTOR: Improve code while keeping tests green
- β
Coverage: \${coverageThreshold}% minimum
### Key Commands:
\\\`\\\`\\\`bash
# Run tests
npx tddai test
# Check TDD compliance
npx tddai validate --strict
# Run with coverage
npx tddai coverage
\\\`\\\`\\\`
**Important**: Follow TDD phases strictly. No code without failing tests first.
\`;
return context;
}
console.log(injectTDDContext());
EOF
# Create compliance guardian
cat > "$project_path/.claude/hooks/tdd-compliance-guardian.js" << 'EOF'
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
function checkTDDCompliance(toolName, args) {
const projectPath = path.resolve(__dirname, '../..');
const projectName = path.basename(projectPath);
// Read TDDAI configuration
let tddaiConfig = {};
const configPath = path.join(projectPath, 'tddai.config.yml');
if (fs.existsSync(configPath)) {
try {
const content = fs.readFileSync(configPath, 'utf8');
const lines = content.split('\n');
const config = {};
let currentSection = null;
lines.forEach(line => {
const trimmed = line.trim();
if (trimmed.includes(':') && !trimmed.startsWith('#')) {
const [key, value] = trimmed.split(':').map(s => s.trim());
if (!value) {
currentSection = key;
config[currentSection] = {};
} else {
if (currentSection) {
config[currentSection][key] = value.replace(/['"]/g, '');
} else {
config[key] = value.replace(/['"]/g, '');
}
}
}
});
tddaiConfig = config;
} catch (e) {
tddaiConfig = {};
}
}
const requireTestFirst = tddaiConfig.tdd?.requireTestFirst !== false;
const codeWritingTools = ['Edit', 'MultiEdit', 'Write'];
const isCodeWriting = codeWritingTools.includes(toolName);
if (isCodeWriting && requireTestFirst) {
const filePath = args?.file_path || '';
const isTestFile = filePath.includes('test') ||
filePath.includes('Test') ||
filePath.includes('spec') ||
filePath.includes('__tests__');
if (!isTestFile) {
return \`
β οΈ TDD COMPLIANCE CHECK - Project: \${projectName}
You're about to modify production code. Per TDD requirements:
1. β
Have you written a FAILING test first?
2. β
Is this the minimal code to make the test pass?
3. β
Are you in the GREEN or REFACTOR phase?
Continue only if you have failing tests that this code will make pass.
\`;
}
}
return null;
}
const toolName = process.argv[2];
const args = process.argv[3] ? JSON.parse(process.argv[3]) : {};
const warning = checkTDDCompliance(toolName, args);
if (warning) {
console.log(warning);
process.exit(1);
}
EOF
# Make hooks executable
chmod +x "$project_path/.claude/hooks/tdd-context-injector.js"
chmod +x "$project_path/.claude/hooks/tdd-compliance-guardian.js"
# Handle ES modules
if [ -f "$project_path/package.json" ] && grep -q '"type": "module"' "$project_path/package.json"; then
mv "$project_path/.claude/hooks/tdd-context-injector.js" "$project_path/.claude/hooks/tdd-context-injector.cjs"
mv "$project_path/.claude/hooks/tdd-compliance-guardian.js" "$project_path/.claude/hooks/tdd-compliance-guardian.cjs"
sed -i '' 's/\.js/.cjs/g' "$project_path/.claude/settings.json"
fi
# Create TDDAI config if missing
if [ ! -f "$project_path/.tddai/config.yaml" ]; then
cat > "$project_path/.tddai/config.yaml" << EOF
project:
name: $project_name
type: $project_type
root: $project_path
testing:
framework: ${3:-jest}
coverageThreshold: ${4:-95}
strictMode: false
ai:
enabled: true
providers:
primary: ollama
fallbacks: [anthropic, openai]
integrations:
claudeCode: true
gitHooks: true
ide: [cursor, vscode]
quality:
enforcePhases: false
autoFix: true
generateMissingTests: true
EOF
fi
echo -e "${GREEN}β Setup complete for $project_name${NC}"
}
# Setup TypeScript projects
echo -e "${YELLOW}Setting up _CommonNPM TypeScript projects...${NC}"
for project in "$BASE_DIR/_CommonNPM"/*; do
if [ -d "$project" ] && [ -f "$project/package.json" ]; then
create_hooks "$project" "typescript" "jest" "95"
fi
done
# Setup Drupal modules
echo -e "${YELLOW}Setting up _DrupalSource Modules...${NC}"
for module in "$BASE_DIR/_DrupalSource/Modules"/*; do
if [ -d "$module" ]; then
create_hooks "$module" "drupal-module" "phpunit" "80"
fi
done
# Setup Drupal recipes
echo -e "${YELLOW}Setting up _DrupalSource Recipes...${NC}"
for recipe in "$BASE_DIR/_DrupalSource/Recipes"/*; do
if [ -d "$recipe" ]; then
create_hooks "$recipe" "drupal-recipe" "phpunit" "80"
fi
done
# Setup Drupal themes
echo -e "${YELLOW}Setting up _DrupalSource Themes...${NC}"
for theme in "$BASE_DIR/_DrupalSource/Themes"/*; do
if [ -d "$theme" ]; then
create_hooks "$theme" "drupal-theme" "phpunit" "80"
fi
done
# Setup Models projects
echo -e "${YELLOW}Setting up Models projects...${NC}"
for model in "$BASE_DIR/Models"/*; do
if [ -d "$model" ]; then
create_hooks "$model" "typescript" "jest" "95"
fi
done
# Setup LLM-Tools projects
echo -e "${YELLOW}Setting up LLM-Tools projects...${NC}"
for tool in "$BASE_DIR/LLM-Tools"/*; do
if [ -d "$tool" ]; then
if [ -f "$tool/requirements.txt" ]; then
create_hooks "$tool" "python" "pytest" "90"
elif [ -f "$tool/docker-compose.yml" ]; then
create_hooks "$tool" "docker-service" "docker-test" "80"
else
create_hooks "$tool" "typescript" "jest" "95"
fi
fi
done
echo -e "${GREEN}π TDDAI setup complete for all projects!${NC}"
Individual Setup Scriptsβ
TypeScript Projects Setupβ
#!/bin/bash
# setup-typescript-tddai.sh
for project in /Users/flux423/Sites/LLM/_CommonNPM/*; do
if [ -d "$project" ] && [ -f "$project/package.json" ]; then
npx tddai init --project "$project" --type typescript --coverage 95
fi
done
Drupal Projects Setupβ
#!/bin/bash
# setup-drupal-tddai.sh
# Modules
for module in /Users/flux423/Sites/LLM/_DrupalSource/Modules/*; do
if [ -d "$module" ]; then
npx tddai init --project "$module" --type drupal-module --coverage 80
fi
done
# Recipes
for recipe in /Users/flux423/Sites/LLM/_DrupalSource/Recipes/*; do
if [ -d "$recipe" ]; then
npx tddai init --project "$recipe" --type drupal-recipe --coverage 80
fi
done
# Themes
for theme in /Users/flux423/Sites/LLM/_DrupalSource/Themes/*; do
if [ -d "$theme" ]; then
npx tddai init --project "$theme" --type drupal-theme --coverage 80
fi
done
Python Projects Setupβ
#!/bin/bash
# setup-python-tddai.sh
for project in /Users/flux423/Sites/LLM/LLM-Tools/*; do
if [ -f "$project/requirements.txt" ]; then
npx tddai init --project "$project" --type python --coverage 90
fi
done
Verification Scriptβ
#!/bin/bash
# verify-tddai-setup.sh
echo "Verifying TDDAI setup..."
# Function to check project
check_project() {
local project=$1
local name=$(basename "$project")
if [ -f "$project/.claude/settings.json" ] && [ -d "$project/.claude/hooks" ]; then
echo "β
$name: Setup complete"
else
echo "β $name: Missing Claude configuration"
fi
if [ -f "$project/.tddai/config.yaml" ] || [ -f "$project/tddai.config.yml" ]; then
echo " β TDDAI config present"
else
echo " β TDDAI config missing"
fi
}
# Check all project types
for dir in _CommonNPM _DrupalSource/Modules _DrupalSource/Recipes _DrupalSource/Themes Models LLM-Tools; do
echo "Checking $dir..."
for project in /Users/flux423/Sites/LLM/$dir/*; do
if [ -d "$project" ]; then
check_project "$project"
fi
done
done
Quick Fix Scriptsβ
Fix ES Module Issuesβ
#!/bin/bash
# fix-esm-hooks.sh
for project in $(find /Users/flux423/Sites/LLM -name "package.json" -exec dirname {} \;); do
if grep -q '"type": "module"' "$project/package.json" 2>/dev/null; then
if [ -d "$project/.claude/hooks" ]; then
for hook in "$project/.claude/hooks"/*.js; do
if [ -f "$hook" ]; then
mv "$hook" "${hook%.js}.cjs"
fi
done
sed -i '' 's/\.js/.cjs/g' "$project/.claude/settings.json"
fi
fi
done
Update All Hooksβ
#!/bin/bash
# update-all-hooks.sh
find /Users/flux423/Sites/LLM -name "tdd-context-injector.*" -o -name "tdd-compliance-guardian.*" | while read hook; do
# Update hook content
sed -i '' 's/95%/Coverage target from config/g' "$hook"
# Fix permissions
chmod +x "$hook"
done
Usageβ
-
Full Setup: Run the master setup script
./setup-tddai-platform.sh
-
Verify Setup: Check all projects
./verify-tddai-setup.sh
-
Fix Issues: Run specific fix scripts
./fix-esm-hooks.sh
-
Update Configuration: Modify individual configs
npx tddai config set coverage 90 --project ./my-project