Function bodies 261 total
identifyLearnings function · javascript · L74-L97 (24 LOC)scripts/retrospective.js
function identifyLearnings(commits) {
const learnings = [];
// Look for patterns indicating learnings
if (commits.some(c => c.includes('fix:'))) {
learnings.push('Bug fixes indicate areas needing more testing');
}
if (commits.some(c => c.includes('refactor:'))) {
learnings.push('Refactoring suggests initial implementation could be improved');
}
if (commits.filter(c => c.includes('docs:')).length > 2) {
learnings.push('Multiple documentation updates suggest initial docs were incomplete');
}
// Check for reverts or fixes to recent commits
const revertPattern = /revert|undo|fix.*previous/i;
if (commits.some(c => revertPattern.test(c))) {
learnings.push('Reverts suggest need for better testing before commits');
}
return learnings;
}generateReport function · javascript · L99-L168 (70 LOC)scripts/retrospective.js
function generateReport() {
console.log('\n📊 Session Retrospective\n');
console.log('='.repeat(50));
const { commits, patterns } = analyzeGitHistory();
console.log(`\n📅 Period: ${options.since}`);
console.log(`📝 Total Commits: ${commits.length}`);
if (options.metrics) {
const metrics = getMetrics();
console.log('\n📈 Metrics:');
console.log(` Files Changed: ${metrics.filesChanged}`);
console.log(` Lines Added: ${metrics.insertions}`);
console.log(` Lines Removed: ${metrics.deletions}`);
console.log(` Net Change: ${metrics.insertions - metrics.deletions}`);
}
console.log('\n🔍 Commit Patterns:');
Object.entries(patterns)
.filter(([, count]) => count > 0)
.sort(([, a], [, b]) => b - a)
.forEach(([type, count]) => {
const percentage = Math.round((count / commits.length) * 100);
console.log(` ${type}: ${count} (${percentage}%)`);
});
console.log('\n💡 Recent Changes:');
commits.slice(0, 5).forEach(coupdateLearnings function · javascript · L170-L211 (42 LOC)scripts/retrospective.js
function updateLearnings(commits, patterns, learnings) {
const learningsFile = path.join(process.cwd(), 'LEARNINGS.md');
if (!fs.existsSync(learningsFile)) {
console.log('\n⚠️ LEARNINGS.md not found, skipping update');
return;
}
const date = new Date().toISOString().split('T')[0];
const entry = `
### Session Retrospective - ${date}
**Commits**: ${commits.length}
**Primary Focus**: ${Object.entries(patterns).sort(([,a], [,b]) => b - a)[0]?.[0] || 'mixed'}
#### Patterns Observed
${Object.entries(patterns)
.filter(([, count]) => count > 0)
.map(([type, count]) => `- ${type}: ${count}`)
.join('\n')}
#### Key Insights
${learnings.map(l => `- ${l}`).join('\n') || '- Session focused on implementation'}
---
`;
// Read current content
let content = fs.readFileSync(learningsFile, 'utf8');
// Find the Recent Session Learnings section and add entry
const marker = '## Recent Session Learnings';
const index = content.indexOf(marker);
if (index !getNextSessionNumber function · javascript · L36-L56 (21 LOC)scripts/session-history.js
function getNextSessionNumber(dateDir) {
if (!fs.existsSync(dateDir)) {
return '001';
}
const files = fs.readdirSync(dateDir);
const sessionFiles = files.filter(f => f.startsWith('session-'));
if (sessionFiles.length === 0) {
return '001';
}
// Extract numbers and find max
const numbers = sessionFiles
.map(f => f.match(/session-(\d{3})/))
.filter(m => m)
.map(m => parseInt(m[1]));
const maxNum = Math.max(...numbers, 0);
return String(maxNum + 1).padStart(3, '0');
}getLastSaveInfo function · javascript · L58-L67 (10 LOC)scripts/session-history.js
function getLastSaveInfo() {
if (fs.existsSync(LAST_SAVE_FILE)) {
try {
return JSON.parse(fs.readFileSync(LAST_SAVE_FILE, 'utf8'));
} catch {
return null;
}
}
return null;
}captureGitActivity function · javascript · L94-L142 (49 LOC)scripts/session-history.js
function captureGitActivity(sinceCommit = null) {
const activity = {
commits: [],
filesChanged: [],
branch: 'unknown',
newCommitsOnly: false
};
try {
// Get current branch
activity.branch = execSync('git branch --show-current', {encoding: 'utf8'}).trim();
// Get commits since last save or recent commits
let commitCommand = 'git log --oneline -20';
if (sinceCommit) {
// Only get commits since the specified commit
commitCommand = `git log --oneline ${sinceCommit}..HEAD`;
activity.newCommitsOnly = true;
}
const commits = execSync(commitCommand, {encoding: 'utf8'}).trim();
if (commits) {
activity.commits = commits.split('\n').map(c => {
const [hash, ...messageParts] = c.split(' ');
return {
hash: hash.substring(0, 7),
message: messageParts.join(' ')
};
});
}
// Get files changed in working directory
const changes = execSync('git statugetTestResultsFromCache function · javascript · L146-L155 (10 LOC)scripts/session-history.js
function getTestResultsFromCache() {
// This could read from a .test-results.json file if needed
// For now, just return empty results to avoid running tests
return {
lastRun: null,
passing: 0,
failing: 0,
skipped: true
};
}Repobility · severity-and-effort ranking · https://repobility.com
getLastCommitFromSave function · javascript · L158-L170 (13 LOC)scripts/session-history.js
function getLastCommitFromSave() {
const lastSave = getLastSaveInfo();
if (!lastSave || !lastSave.file) return null;
try {
const content = fs.readFileSync(lastSave.file, 'utf8');
// Extract the first commit hash from the previous save
const match = content.match(/- `([a-f0-9]{7})` /);
return match ? match[1] : null;
} catch {
return null;
}
}detectSessionType function · javascript · L173-L186 (14 LOC)scripts/session-history.js
function detectSessionType() {
// Check if running in test environment (but not just "testing" in description)
if (process.env.NODE_ENV === 'test' || process.argv[1]?.includes('test.js')) {
return 'test';
}
// Check if running automated (CI, cron, etc)
if (process.env.CI || process.env.GITHUB_ACTIONS) {
return 'automated';
}
// Default to manual
return 'manual';
}saveSession function · javascript · L189-L343 (155 LOC)scripts/session-history.js
function saveSession(description = '', options = {}) {
// Check environment variable to skip saves
if (process.env.SKIP_SESSION_SAVE === '1' || process.env.SKIP_SESSION_SAVE === 'true') {
return null;
}
// Detect session type and check if we should skip
const sessionType = options.sessionType || detectSessionType();
if (sessionType === 'test' && !options.forceSave && !options.testing) {
console.log('⏭️ Skipping test session save');
return null;
}
const sessionDir = getSessionDirectory();
const sessionNum = getNextSessionNumber(sessionDir);
const timestamp = getTimeString();
// Check for delta mode
const isDelta = options.delta || false;
const lastCommit = isDelta ? getLastCommitFromSave() : null;
// Determine filename
const baseFilename = `session-${sessionNum}-${timestamp}`;
const suffix = isDelta ? '-delta' : '';
const filename = description
? `${baseFilename}${suffix}-${description.replace(/[^a-z0-9]/gi, '-')}.txt`
saveDelta function · javascript · L345-L358 (14 LOC)scripts/session-history.js
function saveDelta() {
const lastSave = getLastSaveInfo();
if (!lastSave) {
console.log('⚠️ No previous save found, performing full save');
return saveSession('initial', { delta: false });
}
console.log('\n📝 Saving delta since last save...');
console.log(`Last save: ${lastSave.date} at ${lastSave.time}`);
// Use the new saveSession with delta option
return saveSession('', { delta: true });
}listSessions function · javascript · L360-L440 (81 LOC)scripts/session-history.js
function listSessions() {
console.log('\n📚 Session History\n');
console.log('='.repeat(50));
if (!fs.existsSync(SESSION_HISTORY_DIR)) {
console.log('No session history found');
return;
}
const dates = fs.readdirSync(SESSION_HISTORY_DIR)
.filter(d => /^\d{4}-\d{2}-\d{2}$/.test(d))
.sort()
.reverse();
if (dates.length === 0) {
console.log('No sessions saved yet');
return;
}
// Show recent sessions
dates.slice(0, 7).forEach(date => {
const dateDir = path.join(SESSION_HISTORY_DIR, date);
const files = fs.readdirSync(dateDir)
.filter(f => f.startsWith('session-'))
.sort();
if (files.length > 0) {
console.log(`\n📅 ${date}`);
files.forEach(file => {
// Skip metadata files if they still exist (backwards compatibility)
if (file.endsWith('.meta.json')) return;
const stats = fs.statSync(path.join(dateDir, file));
const size = (stats.size / 1024).toFixed(1);
archiveSessions function · javascript · L442-L477 (36 LOC)scripts/session-history.js
function archiveSessions(daysOld = 30) {
const archiveDir = path.join(SESSION_HISTORY_DIR, 'archive');
ensureDirectoryExists(archiveDir);
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysOld);
console.log(`\n📦 Archiving sessions older than ${daysOld} days...`);
console.log(`Cutoff date: ${cutoffDate.toISOString().split('T')[0]}`);
if (!fs.existsSync(SESSION_HISTORY_DIR)) {
console.log('No sessions to archive');
return;
}
const dates = fs.readdirSync(SESSION_HISTORY_DIR)
.filter(d => /^\d{4}-\d{2}-\d{2}$/.test(d));
let archivedCount = 0;
dates.forEach(date => {
const dateObj = new Date(date);
if (dateObj < cutoffDate) {
const sourcePath = path.join(SESSION_HISTORY_DIR, date);
const destPath = path.join(archiveDir, date);
// Move directory to archive
if (!fs.existsSync(destPath)) {
fs.renameSync(sourcePath, destPath);
console.log(` Archived: ${date}`);
showHelp function · javascript · L479-L505 (27 LOC)scripts/session-history.js
function showHelp() {
console.log(`
📚 Session History Manager
Usage: node scripts/session-history.js [command] [options]
Commands:
save [description] Save current session with optional description
delta Save only changes since last save
list List recent session history
archive [days] Archive sessions older than N days (default: 30)
help Show this help message
Examples:
npm run session:save
npm run session:save "feature-implementation"
npm run session:delta
npm run session:list
npm run session:archive 60
Notes:
- Sessions are organized by date in session-history/
- Delta saves only capture changes since last save
- Use 'save' for full session captures
- Archive old sessions to keep history organized
`);
}checkGitStatus function · javascript · L42-L69 (28 LOC)scripts/setup.js
function checkGitStatus(filepath) {
try {
// Check if file exists
if (!fs.existsSync(filepath)) {
return 'NEW_FILE';
}
// Check if file is tracked by git
try {
execSync(`git ls-files --error-unmatch "${filepath}"`, { stdio: 'ignore' });
} catch {
return 'UNTRACKED';
}
// Check for uncommitted changes
const diffOutput = execSync(`git diff --name-only "${filepath}"`, { encoding: 'utf8' });
const stagedOutput = execSync(`git diff --staged --name-only "${filepath}"`, { encoding: 'utf8' });
if (diffOutput.trim() || stagedOutput.trim()) {
return 'UNCOMMITTED';
}
return 'CLEAN';
} catch {
// If git commands fail, assume file is safe to modify
return 'UNKNOWN';
}
}Repobility (the analyzer behind this table) · https://repobility.com
isGitRepo function · javascript · L91-L98 (8 LOC)scripts/setup.js
function isGitRepo() {
try {
execSync('git status', { stdio: 'ignore' });
return true;
} catch {
return false;
}
}getAllFiles function · javascript · L106-L119 (14 LOC)scripts/setup.js
function getAllFiles(dir, files = []) {
if (!fs.existsSync(dir)) return files;
const items = fs.readdirSync(dir);
for (const item of items) {
const fullPath = path.join(dir, item);
if (fs.statSync(fullPath).isDirectory()) {
getAllFiles(fullPath, files);
} else {
files.push(fullPath);
}
}
return files;
}detectConflicts function · javascript · L122-L135 (14 LOC)scripts/setup.js
function detectConflicts(sourceDir, targetDir) {
const conflicts = [];
if (!fs.existsSync(targetDir)) return conflicts;
const sourceFiles = getAllFiles(sourceDir);
for (const file of sourceFiles) {
const relativePath = path.relative(sourceDir, file);
const targetPath = path.join(targetDir, relativePath);
if (fs.existsSync(targetPath)) {
conflicts.push(relativePath);
}
}
return conflicts;
}promptUser function · javascript · L138-L176 (39 LOC)scripts/setup.js
async function promptUser(conflicts) {
console.log('');
console.log(`⚠️ Found ${conflicts.length} existing file(s):`);
// Show first 5 conflicts
conflicts.slice(0, 5).forEach(file => {
console.log(` • ${file}`);
});
if (conflicts.length > 5) {
console.log(` ... and ${conflicts.length - 5} more`);
}
console.log('');
console.log('How would you like to proceed?');
console.log(' 1. Skip - Keep your existing files (recommended)');
console.log(' 2. Backup - Backup existing and install fresh');
console.log(' 3. Merge - Add only non-conflicting files');
console.log(' 4. Cancel - Exit without changes');
console.log('');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise((resolve) => {
rl.question('Choice [1-4]: ', (answer) => {
rl.close();
switch (answer.trim()) {
case '1': resolve('skip'); break;
case '2': resolve('backup'); break;
cdetermineStrategy function · javascript · L179-L188 (10 LOC)scripts/setup.js
async function determineStrategy(conflicts, options) {
if (conflicts.length === 0) return 'proceed';
if (options.skip) return 'skip';
if (options.backup) return 'backup';
if (options.force) return 'backup'; // Force is like backup but less interactive
if (options.interactive) return await promptUser(conflicts);
return 'skip'; // Default safe behavior
}copyRecursive function · javascript · L191-L242 (52 LOC)scripts/setup.js
function copyRecursive(source, target, skipExisting = false) {
// Create target directory if it doesn't exist
if (!options['dry-run'] && !fs.existsSync(target)) {
fs.mkdirSync(target, { recursive: true });
}
const items = fs.readdirSync(source);
let copied = 0;
let skipped = 0;
for (const item of items) {
const sourcePath = path.join(source, item);
const targetPath = path.join(target, item);
if (fs.statSync(sourcePath).isDirectory()) {
const result = copyRecursive(sourcePath, targetPath, skipExisting);
copied += result.copied;
skipped += result.skipped;
} else {
const gitStatus = checkGitStatus(targetPath);
const fileSize = fs.statSync(sourcePath).size;
if (skipExisting && fs.existsSync(targetPath)) {
skipped++;
if (options['dry-run']) {
dryRunData.skippedFiles.push({ path: targetPath, reason: 'exists', gitStatus });
}
} else {
if (options['dry-run']) backupDirectory function · javascript · L245-L252 (8 LOC)scripts/setup.js
function backupDirectory(dir) {
if (!fs.existsSync(dir)) return null;
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
const backupPath = `${dir}.backup-${timestamp}`;
fs.renameSync(dir, backupPath);
return backupPath;
}safeCopy function · javascript · L255-L291 (37 LOC)scripts/setup.js
function safeCopy(source, target, strategy, name) {
let result = { copied: 0, skipped: 0, backedUp: null };
switch (strategy) {
case 'proceed':
// No conflicts, just copy
result = copyRecursive(source, target);
break;
case 'skip':
// Skip all conflicts
console.log(` ⏭️ Preserving existing ${name}`);
result.skipped = getAllFiles(source).length;
break;
case 'backup':
// Backup existing and copy fresh
if (fs.existsSync(target)) {
result.backedUp = backupDirectory(target);
console.log(` 📦 Backed up to ${path.basename(result.backedUp)}`);
}
result = copyRecursive(source, target);
break;
case 'merge':
// Only copy non-conflicting files
result = copyRecursive(source, target, true);
break;
case 'cancel':
console.log('❌ Setup cancelled');
process.exit(0);
break;
}
return result;
}All rows above produced by Repobility · https://repobility.com
mergePackageJson function · javascript · L311-L480 (170 LOC)scripts/setup.js
async function mergePackageJson(sourcePackagePath, targetPackagePath, options) {
// Check if source package.json exists
if (!fs.existsSync(sourcePackagePath)) {
return { added: 0, skipped: 0, conflicts: [] };
}
// Check if target package.json exists
if (!fs.existsSync(targetPackagePath)) {
// Create new package.json with essential scripts
const newPackage = {
name: path.basename(process.cwd()),
version: '1.0.0',
description: '',
scripts: ESSENTIAL_SCRIPTS,
devDependencies: {}
};
fs.writeFileSync(targetPackagePath, JSON.stringify(newPackage, null, 2));
console.log(' ✅ Created package.json with Claude scripts');
return { added: Object.keys(ESSENTIAL_SCRIPTS).length, skipped: 0, conflicts: [] };
}
// Read target package.json
const targetPackage = JSON.parse(fs.readFileSync(targetPackagePath, 'utf8'));
const backupPath = targetPackagePath + '.backup-' + new Date().toISOString().replace(/[:.]/g, '-').slcopyScriptsDirectory function · javascript · L483-L536 (54 LOC)scripts/setup.js
function copyScriptsDirectory(sourceDir, targetDir) {
const scriptsNeeded = new Set();
// Extract script file references from ESSENTIAL_SCRIPTS
for (const scriptContent of Object.values(ESSENTIAL_SCRIPTS)) {
const matches = scriptContent.match(/node scripts\/([^.\s]+\.js)/g);
if (matches) {
matches.forEach(match => {
const filename = match.replace('node scripts/', '');
scriptsNeeded.add(filename);
});
}
}
// Create scripts directory if it doesn't exist
if (!options['dry-run'] && !fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
let copied = 0;
let skipped = 0;
// Copy needed script files
for (const scriptFile of scriptsNeeded) {
const sourcePath = path.join(sourceDir, scriptFile);
const targetPath = path.join(targetDir, scriptFile);
if (fs.existsSync(sourcePath)) {
const gitStatus = checkGitStatus(targetPath);
const fileSize = fs.statSync(sourcePath).sizdisplayDryRunResults function · javascript · L539-L616 (78 LOC)scripts/setup.js
function displayDryRunResults() {
console.log('\n⚠️ SAFETY WARNINGS:');
console.log('────────────────────');
if (dryRunData.safetyWarnings.length > 0) {
dryRunData.safetyWarnings.forEach(warning => {
console.log(`• ${warning}`);
});
} else {
console.log('• None - repository is clean ✅');
}
console.log('\n✅ SAFE TO ADD:');
console.log('───────────────');
console.log(`• ${dryRunData.newFiles.length} new files in .claude/commands/`);
console.log(`• ${dryRunData.newFiles.filter(f => f.path.includes('.claude/agents')).length} new files in .claude/agents/`);
console.log('• Configuration files: CLAUDE.md, AGENTS.md');
if (dryRunData.packageJsonChanges) {
console.log('\n📦 PACKAGE.JSON CHANGES:');
console.log('───────────────────────');
const changes = dryRunData.packageJsonChanges;
console.log(`• Would add ${changes.added} new scripts`);
if (changes.conflicts && changes.conflicts.length > 0) {
console.log(`• Would conflicmain function · javascript · L619-L780 (162 LOC)scripts/setup.js
async function main() {
// Define source and target paths
const sourceCommands = path.join(__dirname, '../.claude/commands');
const targetCommands = '.claude/commands';
const sourceAgents = path.join(__dirname, '../.claude/agents');
const targetAgents = '.claude/agents';
// Check if source files exist
if (!fs.existsSync(sourceCommands)) {
console.log('❌ Source commands not found. Make sure you\'re running from the correct package.');
process.exit(1);
}
// Create .claude directory if it doesn't exist
if (!fs.existsSync('.claude')) {
if (!options['dry-run']) {
fs.mkdirSync('.claude', { recursive: true });
console.log('✅ Created .claude directory');
}
}
// Detect conflicts
const commandConflicts = detectConflicts(sourceCommands, targetCommands);
const agentConflicts = detectConflicts(sourceAgents, targetAgents);
const allConflicts = [...new Set([...commandConflicts, ...agentConflicts])];
// Determine strategy
const detectTestFramework function · javascript · L24-L60 (37 LOC)scripts/tdd.js
function detectTestFramework(packageJson) {
try {
// If packageJson provided (for testing), use it
if (packageJson) {
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
if (deps.jest) return 'jest';
if (deps.vitest) return 'vitest';
if (deps.mocha) return 'mocha';
if (deps.jasmine) return 'jasmine';
if (deps['@playwright/test']) return 'playwright';
if (deps.cypress) return 'cypress';
return 'unknown';
}
// Otherwise read from filesystem
if (fs.existsSync('package.json')) {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
return detectTestFramework(pkg);
}
// Python frameworks
if (fs.existsSync('pytest.ini') || fs.existsSync('setup.cfg')) return 'pytest';
if (fs.existsSync('manage.py')) return 'django';
// Ruby
if (fs.existsSync('Gemfile')) {
const gemfile = fs.readFileSync('Gemfile', 'utf8');
if (ggetTestCommand function · javascript · L62-L82 (21 LOC)scripts/tdd.js
function getTestCommand(framework) {
// If no framework provided, detect it
if (!framework) {
framework = detectTestFramework();
}
switch (framework) {
case 'jest':
return 'npx jest --watch';
case 'vitest':
return 'npx vitest';
case 'mocha':
return 'npx mocha --watch';
case 'pytest':
return 'pytest --tb=short -v';
case 'rspec':
return 'rspec --format documentation';
default:
return 'npm test';
}
}startTDD function · javascript · L84-L130 (47 LOC)scripts/tdd.js
function startTDD(featureName) {
if (!featureName) {
console.log('❌ Please specify a feature name');
console.log('Usage: /tdd start <feature-name>');
process.exit(1);
}
console.log('🚀 Starting TDD Workflow');
console.log('========================');
console.log('');
console.log(`Feature: ${featureName}`);
console.log(`Test Framework: ${detectTestFramework()}`);
console.log('');
// Create TDD tracking file
const tddFile = `.tdd-session-${Date.now()}.md`;
const content = `# TDD Session: ${featureName}
Date: ${new Date().toISOString()}
Framework: ${detectTestFramework()}
## Red Phase
- [ ] Write failing test
- [ ] Verify test fails for the right reason
## Green Phase
- [ ] Write minimal code to pass
- [ ] Verify test passes
## Refactor Phase
- [ ] Improve code structure
- [ ] Ensure tests still pass
## Progress Log
`;
fs.writeFileSync(tddFile, content);
console.log('📝 TDD Cycle:');
console.log('');
console.log(` ${colors.red}1. REredPhase function · javascript · L132-L183 (52 LOC)scripts/tdd.js
function redPhase() {
console.log(`${colors.red}🔴 RED Phase - Write Failing Test${colors.reset}`);
console.log('===================================');
console.log('');
console.log('Guidelines:');
console.log(' 1. Write the smallest possible failing test');
console.log(' 2. Test one behavior at a time');
console.log(' 3. Name test clearly: test_should_[expected_behavior]');
console.log(' 4. Run test to verify it fails');
console.log('');
console.log('Example test structure:');
const framework = detectTestFramework();
switch (framework) {
case 'jest':
case 'vitest':
console.log(`
describe('Feature', () => {
it('should do expected behavior', () => {
// Arrange
const input = ...;
// Act
const result = functionToTest(input);
// Assert
expect(result).toBe(expected);
});
});`);
break;
case 'pytest':
console.log(`
def test_should_do_expected_behavior():
# ArrangCitation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
greenPhase function · javascript · L185-L201 (17 LOC)scripts/tdd.js
function greenPhase() {
console.log(`${colors.green}🟢 GREEN Phase - Make Test Pass${colors.reset}`);
console.log('==================================');
console.log('');
console.log('Guidelines:');
console.log(' 1. Write MINIMAL code to pass the test');
console.log(' 2. Don\'t worry about elegance yet');
console.log(' 3. Hard-code values if needed');
console.log(' 4. Focus only on making test green');
console.log('');
console.log('Anti-patterns to avoid:');
console.log(' ❌ Adding untested functionality');
console.log(' ❌ Over-engineering the solution');
console.log(' ❌ Refactoring before test passes');
console.log('');
console.log(`Run: ${colors.yellow}${getTestCommand()}${colors.reset}`);
}refactorPhase function · javascript · L203-L221 (19 LOC)scripts/tdd.js
function refactorPhase() {
console.log(`${colors.blue}🔵 REFACTOR Phase - Improve Code${colors.reset}`);
console.log('===================================');
console.log('');
console.log('Refactoring checklist:');
console.log(' □ Remove duplication');
console.log(' □ Improve naming');
console.log(' □ Extract methods/functions');
console.log(' □ Simplify conditionals');
console.log(' □ Apply design patterns');
console.log('');
console.log('Rules:');
console.log(' ✅ Tests must stay green');
console.log(' ✅ Refactor production code OR tests (not both)');
console.log(' ✅ Make small, incremental changes');
console.log(' ✅ Run tests after each change');
console.log('');
console.log(`Run: ${colors.yellow}${getTestCommand()}${colors.reset}`);
}runTests function · javascript · L223-L252 (30 LOC)scripts/tdd.js
function runTests(watch = false) {
console.log('🧪 Running Tests');
console.log('================');
console.log('');
const testCmd = getTestCommand();
console.log(`Command: ${testCmd}`);
console.log('');
try {
if (watch) {
// Start test watcher
console.log('Starting test watcher... (Press Ctrl+C to stop)');
const child = spawn(testCmd, { shell: true, stdio: 'inherit' });
child.on('error', (error) => {
console.error(`Error: ${error.message}`);
});
} else {
// Run tests once
const result = execSync(testCmd.replace('--watch', ''), { encoding: 'utf8' });
console.log(result);
}
} catch {
console.log(`${colors.red}Tests failed!${colors.reset}`);
console.log('');
console.log('This is expected in the RED phase.');
console.log('Make sure tests fail for the right reason.');
}
}showCycle function · javascript · L254-L280 (27 LOC)scripts/tdd.js
function showCycle() {
console.log('🔄 TDD Cycle Overview');
console.log('====================');
console.log('');
console.log(`${colors.red}┌─────────────┐${colors.reset}`);
console.log(`${colors.red}│ 1. RED │${colors.reset} Write a failing test`);
console.log(`${colors.red}└──────┬──────┘${colors.reset}`);
console.log(' │');
console.log(`${colors.green}┌──────▼──────┐${colors.reset}`);
console.log(`${colors.green}│ 2. GREEN │${colors.reset} Make test pass (minimal code)`);
console.log(`${colors.green}└──────┬──────┘${colors.reset}`);
console.log(' │');
console.log(`${colors.blue}┌──────▼──────┐${colors.reset}`);
console.log(`${colors.blue}│ 3. REFACTOR │${colors.reset} Improve code (tests stay green)`);
console.log(`${colors.blue}└──────┬──────┘${colors.reset}`);
console.log(' │');
console.log(' └────────┐');
console.log(' ↓');
console.log(' Repeat cycle');
console.log('');
console.log('showStats function · javascript · L282-L317 (36 LOC)scripts/tdd.js
function showStats() {
console.log('📊 TDD Statistics');
console.log('=================');
console.log('');
// Count test files
try {
const testFiles = execSync('find . -name "*.test.*" -o -name "*.spec.*" | grep -v node_modules | wc -l', { encoding: 'utf8' }).trim();
console.log(`Test files: ${testFiles}`);
// Check coverage if available
if (fs.existsSync('coverage/coverage-summary.json')) {
const coverage = JSON.parse(fs.readFileSync('coverage/coverage-summary.json', 'utf8'));
const total = coverage.total;
console.log('');
console.log('Coverage:');
console.log(` • Lines: ${total.lines.pct}%`);
console.log(` • Branches: ${total.branches.pct}%`);
console.log(` • Functions: ${total.functions.pct}%`);
console.log(` • Statements: ${total.statements.pct}%`);
}
// Recent test commits
const testCommits = execSync('git log --oneline --grep="test" -5 2>/dev/null', { encoding: 'utf8' });showHelp function · javascript · L319-L339 (21 LOC)scripts/tdd.js
function showHelp() {
console.log('🧪 TDD (Test-Driven Development) Commands');
console.log('=========================================');
console.log('');
console.log('Available commands:');
console.log(' /tdd start <feature> - Start TDD session for feature');
console.log(' /tdd red - Guidelines for RED phase');
console.log(' /tdd green - Guidelines for GREEN phase');
console.log(' /tdd refactor - Guidelines for REFACTOR phase');
console.log(' /tdd test [--watch] - Run tests (with optional watch)');
console.log(' /tdd cycle - Show TDD cycle overview');
console.log(' /tdd stats - Show testing statistics');
console.log(' /tdd help - Show this help message');
console.log('');
console.log('Example workflow:');
console.log(' 1. /tdd start user-auth');
console.log(' 2. /tdd red (write failing test)');
console.log(' 3. /tdd green (make test pass)');
console.log(' 4. /tdd rexec function · javascript · L17-L24 (8 LOC)scripts/todo-github.js
function exec(command) {
try {
return execSync(command, { encoding: 'utf8', stdio: 'pipe' }).trim();
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
}formatIssue function · javascript · L26-L37 (12 LOC)scripts/todo-github.js
function formatIssue(issue) {
const parts = issue.split('\t');
const number = parts[0];
const state = parts[1];
const title = parts[2];
const labels = parts[3] || '';
const stateIcon = state === 'OPEN' ? '🔵' : '✅';
const labelStr = labels ? ` [${labels}]` : '';
return `${stateIcon} #${number}: ${title}${labelStr}`;
}Repobility · severity-and-effort ranking · https://repobility.com
listIssues function · javascript · L39-L60 (22 LOC)scripts/todo-github.js
function listIssues(filter = 'open') {
console.log(`\n📋 GitHub Issues (${filter}):`);
console.log('─'.repeat(50));
const stateFlag = filter === 'all' ? '' : `--state ${filter}`;
const command = `gh issue list ${stateFlag} --limit 30 --json number,state,title,labels,updatedAt --template '{{range .}}{{.number}}\t{{.state}}\t{{.title}}\t{{range .labels}}{{.name}} {{end}}\t{{.updatedAt}}{{println}}{{end}}'`;
const output = exec(command);
if (!output) {
console.log('No issues found');
return;
}
const issues = output.split('\n').filter(Boolean);
issues.forEach(issue => {
console.log(formatIssue(issue));
});
console.log('─'.repeat(50));
console.log(`Total: ${issues.length} issues`);
}createIssue function · javascript · L62-L73 (12 LOC)scripts/todo-github.js
function createIssue(title, body = '', labels = []) {
console.log(`\n➕ Creating issue: "${title}"`);
const labelFlag = labels.length > 0 ? `--label "${labels.join(',')}"` : '';
const bodyFlag = body ? `--body "${body}"` : '';
const command = `gh issue create --title "${title}" ${bodyFlag} ${labelFlag}`;
const result = exec(command);
console.log(`✅ Issue created: ${result}`);
return result;
}closeIssue function · javascript · L75-L84 (10 LOC)scripts/todo-github.js
function closeIssue(number, comment = '') {
console.log(`\n✅ Closing issue #${number}`);
if (comment) {
exec(`gh issue comment ${number} --body "${comment}"`);
}
exec(`gh issue close ${number}`);
console.log(`Issue #${number} closed`);
}reopenIssue function · javascript · L86-L95 (10 LOC)scripts/todo-github.js
function reopenIssue(number, comment = '') {
console.log(`\n🔄 Reopening issue #${number}`);
if (comment) {
exec(`gh issue comment ${number} --body "${comment}"`);
}
exec(`gh issue reopen ${number}`);
console.log(`Issue #${number} reopened`);
}showIssue function · javascript · L103-L109 (7 LOC)scripts/todo-github.js
function showIssue(number) {
console.log(`\n📄 Issue #${number} Details:`);
console.log('─'.repeat(50));
const issue = exec(`gh issue view ${number}`);
console.log(issue);
}showStats function · javascript · L111-L132 (22 LOC)scripts/todo-github.js
function showStats() {
console.log('\n📊 Issue Statistics:');
console.log('─'.repeat(50));
const openCount = exec('gh issue list --state open --limit 999 --json number --jq "length"');
const closedCount = exec('gh issue list --state closed --limit 999 --json number --jq "length"');
console.log(`🔵 Open: ${openCount}`);
console.log(`✅ Closed: ${closedCount}`);
console.log(`📈 Total: ${parseInt(openCount) + parseInt(closedCount)}`);
// Get label distribution
console.log('\n🏷️ Label Distribution:');
const labels = exec('gh issue list --state open --limit 999 --json labels --jq "[.[].labels[].name] | group_by(.) | map({label: .[0], count: length})"');
if (labels && labels !== '[]') {
const labelData = JSON.parse(labels);
labelData.forEach(item => {
console.log(` ${item.label}: ${item.count}`);
});
}
}showHelp function · javascript · L134-L162 (29 LOC)scripts/todo-github.js
function showHelp() {
console.log(`
📋 GitHub Issue Todo Management
Usage: node scripts/todo-github.js <command> [options]
Commands:
list [filter] List issues (open/closed/all, default: open)
add <title> [body] Create new issue
done <number> Close an issue
reopen <number> Reopen an issue
comment <number> Add comment to issue
show <number> Show issue details
stats Show issue statistics
help Show this help
Examples:
node scripts/todo-github.js list
node scripts/todo-github.js add "Fix login bug"
node scripts/todo-github.js done 42
node scripts/todo-github.js comment 42 "Working on this"
Labels:
Priority: ${LABELS.priority.join(', ')}
Type: ${LABELS.type.join(', ')}
Status: ${LABELS.status.join(', ')}
Area: ${LABELS.area.join(', ')}
`);
}CrossLaggedResultsAnalyzer.__init__ method · python · L29-L48 (20 LOC)src/analysis/analyze_crosslagged_results.py
def __init__(self, results_dir: str = "output/full_comparison"):
"""Initialize analyzer with results directory.
Args:
results_dir: Path to directory containing cross-lagged model results.
"""
self.results_dir = Path(results_dir)
# Check if directory exists
if not self.results_dir.exists():
raise ValueError(f"Results directory not found: {self.results_dir}")
# Load comparison tables if they exist
self.comparison_df = None
self.summary_df = None
# Store loaded results
self.fixed_results = {}
self.estimated_results = {}
self.cumulative_results = {}Repobility (the analyzer behind this table) · https://repobility.com
CrossLaggedResultsAnalyzer.load_comparison_tables method · python · L50-L65 (16 LOC)src/analysis/analyze_crosslagged_results.py
def load_comparison_tables(self) -> None:
"""Load comparison tables from results directory."""
raw_path = self.results_dir / "model_comparison_raw.csv"
summary_path = self.results_dir / "analysis_summary.csv"
if raw_path.exists():
self.comparison_df = pd.read_csv(raw_path)
print(f"Loaded comparison table: {len(self.comparison_df)} rows")
else:
print(f"Warning: Comparison table not found: {raw_path}")
if summary_path.exists():
self.summary_df = pd.read_csv(summary_path)
print(f"Loaded summary table: {len(self.summary_df)} rows")
else:
print(f"Warning: Summary table not found: {summary_path}")CrossLaggedResultsAnalyzer.load_individual_results method · python · L67-L89 (23 LOC)src/analysis/analyze_crosslagged_results.py
def load_individual_results(self) -> None:
"""Load individual model results from subdirectories."""
print("\n" + "=" * 70)
print("LOADING INDIVIDUAL MODEL RESULTS")
print("=" * 70)
# Load fixed lag results
fixed_dir = self.results_dir / "fixed_lag"
if fixed_dir.exists():
print(f"\nLoading fixed lag results from: {fixed_dir}")
self._load_fixed_results(fixed_dir)
# Load estimated lag results
estimated_dir = self.results_dir / "estimated_lag"
if estimated_dir.exists():
print(f"\nLoading estimated lag results from: {estimated_dir}")
self._load_estimated_results(estimated_dir)
# Load cumulative lag results
cumulative_dir = self.results_dir / "cumulative_lag"
if cumulative_dir.exists():
print(f"\nLoading cumulative lag results from: {cumulative_dir}")
self._load_cumulative_results(cumulative_dir)CrossLaggedResultsAnalyzer._load_fixed_results method · python · L91-L114 (24 LOC)src/analysis/analyze_crosslagged_results.py
def _load_fixed_results(self, fixed_dir: Path) -> None:
"""Load fixed lag model results."""
for var_dir in fixed_dir.iterdir():
if var_dir.is_dir():
var_name = var_dir.name
self.fixed_results[var_name] = {}
for lag_dir in var_dir.iterdir():
if lag_dir.is_dir() and "lag_" in lag_dir.name:
# Extract lag value from directory name
lag_str = lag_dir.name.replace("lag_", "").replace("days", "")
try:
lag_value = float(lag_str)
except ValueError:
continue
# Load posterior summary
summary_path = lag_dir / "posterior_summary.csv"
if summary_path.exists():
try:
summary_df = pd.read_csv(summary_path)