Skip to main content

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​

  1. Full Setup: Run the master setup script

    ./setup-tddai-platform.sh
  2. Verify Setup: Check all projects

    ./verify-tddai-setup.sh
  3. Fix Issues: Run specific fix scripts

    ./fix-esm-hooks.sh
  4. Update Configuration: Modify individual configs

    npx tddai config set coverage 90 --project ./my-project