/**
 * TASKMASTER API ROUTES
 * ====================
 *
 * This module provides API endpoints for TaskMaster integration including:
 * - .taskmaster folder detection in project directories
 * - MCP server configuration detection
 * - TaskMaster state and metadata management
 */
import express from 'express';
import fs from 'fs';
import path from 'path';
import { promises as fsPromises } from 'fs';
import { spawn } from 'child_process';
import { extractProjectDirectory } from '../projects.js';
import { detectTaskMasterMCPServer } from '../utils/mcp-detector.js';
import { broadcastTaskMasterProjectUpdate, broadcastTaskMasterTasksUpdate } from '../utils/taskmaster-websocket.js';
import { orchestrationTaskService } from '../modules/orchestration/tasks/orchestration-task.service.js';
const router = express.Router();
/**
 * Check if TaskMaster CLI is installed globally
 * @returns {Promise<Object>} Installation status result
 */
async function checkTaskMasterInstallation() {
    return new Promise((resolve) => {
        // Check if task-master command is available
        const child = spawn('which', ['task-master'], {
            stdio: ['ignore', 'pipe', 'pipe'],
            shell: true
        });
        let output = '';
        let errorOutput = '';
        child.stdout.on('data', (data) => {
            output += data.toString();
        });
        child.stderr.on('data', (data) => {
            errorOutput += data.toString();
        });
        child.on('close', (code) => {
            if (code === 0 && output.trim()) {
                // TaskMaster is installed, get version
                const versionChild = spawn('task-master', ['--version'], {
                    stdio: ['ignore', 'pipe', 'pipe'],
                    shell: true
                });
                let versionOutput = '';
                versionChild.stdout.on('data', (data) => {
                    versionOutput += data.toString();
                });
                versionChild.on('close', (versionCode) => {
                    resolve({
                        isInstalled: true,
                        installPath: output.trim(),
                        version: versionCode === 0 ? versionOutput.trim() : 'unknown',
                        reason: null
                    });
                });
                versionChild.on('error', () => {
                    resolve({
                        isInstalled: true,
                        installPath: output.trim(),
                        version: 'unknown',
                        reason: null
                    });
                });
            }
            else {
                resolve({
                    isInstalled: false,
                    installPath: null,
                    version: null,
                    reason: 'TaskMaster CLI not found in PATH'
                });
            }
        });
        child.on('error', (error) => {
            resolve({
                isInstalled: false,
                installPath: null,
                version: null,
                reason: `Error checking installation: ${error.message}`
            });
        });
    });
}
async function readTaskMasterTasks(projectName) {
    const projectPath = await extractProjectDirectory(projectName);
    const tasksFilePath = path.join(projectPath, '.taskmaster', 'tasks', 'tasks.json');
    await fsPromises.access(tasksFilePath);
    const tasksContent = await fsPromises.readFile(tasksFilePath, 'utf8');
    const tasksData = JSON.parse(tasksContent);
    let tasks = [];
    let currentTag = 'master';
    if (Array.isArray(tasksData)) {
        tasks = tasksData;
    }
    else if (tasksData.tasks) {
        tasks = tasksData.tasks;
    }
    else if (tasksData[currentTag] && tasksData[currentTag].tasks) {
        tasks = tasksData[currentTag].tasks;
    }
    else if (tasksData.master && tasksData.master.tasks) {
        tasks = tasksData.master.tasks;
    }
    else {
        const firstTag = Object.keys(tasksData).find((key) => tasksData[key].tasks && Array.isArray(tasksData[key].tasks));
        if (firstTag) {
            tasks = tasksData[firstTag].tasks;
            currentTag = firstTag;
        }
    }
    const transformedTasks = tasks.map((task) => ({
        id: task.id,
        title: task.title || 'Untitled Task',
        description: task.description || '',
        status: task.status || 'pending',
        priority: task.priority || 'medium',
        dependencies: task.dependencies || [],
        createdAt: task.createdAt || task.created || new Date().toISOString(),
        updatedAt: task.updatedAt || task.updated || new Date().toISOString(),
        details: task.details || '',
        testStrategy: task.testStrategy || task.test_strategy || '',
        subtasks: task.subtasks || []
    }));
    return { projectPath, transformedTasks, currentTag };
}
// API Routes
/**
 * GET /api/taskmaster/installation-status
 * Check if TaskMaster CLI is installed on the system
 */
router.get('/installation-status', async (req, res) => {
    try {
        const installationStatus = await checkTaskMasterInstallation();
        // Also check for MCP server configuration
        const mcpStatus = await detectTaskMasterMCPServer();
        res.json({
            success: true,
            installation: installationStatus,
            mcpServer: mcpStatus,
            isReady: installationStatus.isInstalled && mcpStatus.hasMCPServer
        });
    }
    catch (error) {
        console.error('Error checking TaskMaster installation:', error);
        res.status(500).json({
            success: false,
            error: 'Failed to check TaskMaster installation status',
            installation: {
                isInstalled: false,
                reason: `Server error: ${error.message}`
            },
            mcpServer: {
                hasMCPServer: false,
                reason: `Server error: ${error.message}`
            },
            isReady: false
        });
    }
});
/**
 * GET /api/taskmaster/tasks/:projectName
 * Load actual tasks from .taskmaster/tasks/tasks.json
 */
router.get('/tasks/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        const { projectPath, transformedTasks, currentTag } = await readTaskMasterTasks(projectName);
        res.json({
            projectName,
            projectPath,
            tasks: transformedTasks,
            currentTag,
            totalTasks: transformedTasks.length,
            tasksByStatus: {
                pending: transformedTasks.filter(t => t.status === 'pending').length,
                'in-progress': transformedTasks.filter(t => t.status === 'in-progress').length,
                done: transformedTasks.filter(t => t.status === 'done').length,
                review: transformedTasks.filter(t => t.status === 'review').length,
                deferred: transformedTasks.filter(t => t.status === 'deferred').length,
                cancelled: transformedTasks.filter(t => t.status === 'cancelled').length
            },
            timestamp: new Date().toISOString()
        });
    }
    catch (error) {
        if (error?.code === 'ENOENT') {
            return res.json({
                projectName: req.params.projectName,
                tasks: [],
                message: 'No tasks.json file found'
            });
        }
        if (String(error?.message || '').includes('does not exist')) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${req.params.projectName}" does not exist`
            });
        }
        console.error('TaskMaster tasks loading error:', error);
        res.status(500).json({
            error: 'Failed to load TaskMaster tasks',
            message: error.message
        });
    }
});
/**
 * POST /api/taskmaster/sync-orchestration/:projectName
 * One-way sync: TaskMaster -> Orchestration tasks
 */
router.post('/sync-orchestration/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        const { transformedTasks } = await readTaskMasterTasks(projectName);
        const projectId = typeof req.body?.projectId === 'string' && req.body.projectId.trim()
            ? req.body.projectId.trim()
            : projectName;
        const syncedTasks = transformedTasks.map((task) => orchestrationTaskService.upsertFromTaskMaster({
            projectId,
            taskmasterId: String(task.id),
            title: task.title,
            description: task.description,
        }));
        res.json({
            success: true,
            projectName,
            projectId,
            synced: syncedTasks.length,
            tasks: syncedTasks,
            timestamp: new Date().toISOString(),
        });
    }
    catch (error) {
        if (error?.code === 'ENOENT') {
            return res.json({ success: true, projectName: req.params.projectName, synced: 0, tasks: [] });
        }
        console.error('TaskMaster orchestration sync error:', error);
        res.status(500).json({
            success: false,
            error: 'Failed to sync TaskMaster tasks to orchestration',
            message: error.message,
        });
    }
});
/**
 * GET /api/taskmaster/prd/:projectName
 * List all PRD files in the project's .taskmaster/docs directory
 */
router.get('/prd/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        const docsPath = path.join(projectPath, '.taskmaster', 'docs');
        // Check if docs directory exists
        try {
            await fsPromises.access(docsPath, fs.constants.R_OK);
        }
        catch (error) {
            return res.json({
                projectName,
                prdFiles: [],
                message: 'No .taskmaster/docs directory found'
            });
        }
        // Read directory and filter for PRD files
        try {
            const files = await fsPromises.readdir(docsPath);
            const prdFiles = [];
            for (const file of files) {
                const filePath = path.join(docsPath, file);
                const stats = await fsPromises.stat(filePath);
                if (stats.isFile() && (file.endsWith('.txt') || file.endsWith('.md'))) {
                    prdFiles.push({
                        name: file,
                        path: path.relative(projectPath, filePath),
                        size: stats.size,
                        modified: stats.mtime.toISOString(),
                        created: stats.birthtime.toISOString()
                    });
                }
            }
            res.json({
                projectName,
                projectPath,
                prdFiles: prdFiles.sort((a, b) => new Date(b.modified) - new Date(a.modified)),
                timestamp: new Date().toISOString()
            });
        }
        catch (readError) {
            console.error('Error reading docs directory:', readError);
            return res.status(500).json({
                error: 'Failed to read PRD files',
                message: readError.message
            });
        }
    }
    catch (error) {
        console.error('PRD list error:', error);
        res.status(500).json({
            error: 'Failed to list PRD files',
            message: error.message
        });
    }
});
/**
 * POST /api/taskmaster/prd/:projectName
 * Create or update a PRD file in the project's .taskmaster/docs directory
 */
router.post('/prd/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        const { fileName, content } = req.body;
        if (!fileName || !content) {
            return res.status(400).json({
                error: 'Missing required fields',
                message: 'fileName and content are required'
            });
        }
        // Validate filename
        if (!fileName.match(/^[\w\-. ]+\.(txt|md)$/)) {
            return res.status(400).json({
                error: 'Invalid filename',
                message: 'Filename must end with .txt or .md and contain only alphanumeric characters, spaces, dots, and dashes'
            });
        }
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        const docsPath = path.join(projectPath, '.taskmaster', 'docs');
        const filePath = path.join(docsPath, fileName);
        // Ensure docs directory exists
        try {
            await fsPromises.mkdir(docsPath, { recursive: true });
        }
        catch (error) {
            console.error('Failed to create docs directory:', error);
            return res.status(500).json({
                error: 'Failed to create directory',
                message: error.message
            });
        }
        // Write the PRD file
        try {
            await fsPromises.writeFile(filePath, content, 'utf8');
            // Get file stats
            const stats = await fsPromises.stat(filePath);
            res.json({
                projectName,
                projectPath,
                fileName,
                filePath: path.relative(projectPath, filePath),
                size: stats.size,
                created: stats.birthtime.toISOString(),
                modified: stats.mtime.toISOString(),
                message: 'PRD file saved successfully',
                timestamp: new Date().toISOString()
            });
        }
        catch (writeError) {
            console.error('Failed to write PRD file:', writeError);
            return res.status(500).json({
                error: 'Failed to write PRD file',
                message: writeError.message
            });
        }
    }
    catch (error) {
        console.error('PRD create/update error:', error);
        res.status(500).json({
            error: 'Failed to create/update PRD file',
            message: error.message
        });
    }
});
/**
 * GET /api/taskmaster/prd/:projectName/:fileName
 * Get content of a specific PRD file
 */
router.get('/prd/:projectName/:fileName', async (req, res) => {
    try {
        const { projectName, fileName } = req.params;
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        const filePath = path.join(projectPath, '.taskmaster', 'docs', fileName);
        // Check if file exists
        try {
            await fsPromises.access(filePath, fs.constants.R_OK);
        }
        catch (error) {
            return res.status(404).json({
                error: 'PRD file not found',
                message: `File "${fileName}" does not exist`
            });
        }
        // Read file content
        try {
            const content = await fsPromises.readFile(filePath, 'utf8');
            const stats = await fsPromises.stat(filePath);
            res.json({
                projectName,
                projectPath,
                fileName,
                filePath: path.relative(projectPath, filePath),
                content,
                size: stats.size,
                created: stats.birthtime.toISOString(),
                modified: stats.mtime.toISOString(),
                timestamp: new Date().toISOString()
            });
        }
        catch (readError) {
            console.error('Failed to read PRD file:', readError);
            return res.status(500).json({
                error: 'Failed to read PRD file',
                message: readError.message
            });
        }
    }
    catch (error) {
        console.error('PRD read error:', error);
        res.status(500).json({
            error: 'Failed to read PRD file',
            message: error.message
        });
    }
});
/**
 * POST /api/taskmaster/init/:projectName
 * Initialize TaskMaster in a project
 */
router.post('/init/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        // Check if TaskMaster is already initialized
        const taskMasterPath = path.join(projectPath, '.taskmaster');
        try {
            await fsPromises.access(taskMasterPath, fs.constants.F_OK);
            return res.status(400).json({
                error: 'TaskMaster already initialized',
                message: 'TaskMaster is already configured for this project'
            });
        }
        catch (error) {
            // Directory doesn't exist, we can proceed
        }
        // Run taskmaster init command
        const initProcess = spawn('npx', ['task-master', 'init'], {
            cwd: projectPath,
            stdio: ['pipe', 'pipe', 'pipe']
        });
        let stdout = '';
        let stderr = '';
        initProcess.stdout.on('data', (data) => {
            stdout += data.toString();
        });
        initProcess.stderr.on('data', (data) => {
            stderr += data.toString();
        });
        initProcess.on('close', (code) => {
            if (code === 0) {
                // Broadcast TaskMaster project update via WebSocket
                if (req.app.locals.wss) {
                    broadcastTaskMasterProjectUpdate(req.app.locals.wss, projectName, { hasTaskmaster: true, status: 'initialized' });
                }
                res.json({
                    projectName,
                    projectPath,
                    message: 'TaskMaster initialized successfully',
                    output: stdout,
                    timestamp: new Date().toISOString()
                });
            }
            else {
                console.error('TaskMaster init failed:', stderr);
                res.status(500).json({
                    error: 'Failed to initialize TaskMaster',
                    message: stderr || stdout,
                    code
                });
            }
        });
        // Send 'yes' responses to automated prompts
        initProcess.stdin.write('yes\n');
        initProcess.stdin.end();
    }
    catch (error) {
        console.error('TaskMaster init error:', error);
        res.status(500).json({
            error: 'Failed to initialize TaskMaster',
            message: error.message
        });
    }
});
/**
 * POST /api/taskmaster/add-task/:projectName
 * Add a new task to the project
 */
router.post('/add-task/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        const { prompt, title, description, priority = 'medium', dependencies } = req.body;
        if (!prompt && (!title || !description)) {
            return res.status(400).json({
                error: 'Missing required parameters',
                message: 'Either "prompt" or both "title" and "description" are required'
            });
        }
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        // Build the task-master add-task command
        const args = ['task-master-ai', 'add-task'];
        if (prompt) {
            args.push('--prompt', prompt);
            args.push('--research'); // Use research for AI-generated tasks
        }
        else {
            args.push('--prompt', `Create a task titled "${title}" with description: ${description}`);
        }
        if (priority) {
            args.push('--priority', priority);
        }
        if (dependencies) {
            args.push('--dependencies', dependencies);
        }
        // Run task-master add-task command
        const addTaskProcess = spawn('npx', args, {
            cwd: projectPath,
            stdio: ['pipe', 'pipe', 'pipe']
        });
        let stdout = '';
        let stderr = '';
        addTaskProcess.stdout.on('data', (data) => {
            stdout += data.toString();
        });
        addTaskProcess.stderr.on('data', (data) => {
            stderr += data.toString();
        });
        addTaskProcess.on('close', (code) => {
            console.log('Add task process completed with code:', code);
            console.log('Stdout:', stdout);
            console.log('Stderr:', stderr);
            if (code === 0) {
                // Broadcast task update via WebSocket
                if (req.app.locals.wss) {
                    broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectName);
                }
                res.json({
                    projectName,
                    projectPath,
                    message: 'Task added successfully',
                    output: stdout,
                    timestamp: new Date().toISOString()
                });
            }
            else {
                console.error('Add task failed:', stderr);
                res.status(500).json({
                    error: 'Failed to add task',
                    message: stderr || stdout,
                    code
                });
            }
        });
        addTaskProcess.stdin.end();
    }
    catch (error) {
        console.error('Add task error:', error);
        res.status(500).json({
            error: 'Failed to add task',
            message: error.message
        });
    }
});
/**
 * PUT /api/taskmaster/update-task/:projectName/:taskId
 * Update a specific task using TaskMaster CLI
 */
router.put('/update-task/:projectName/:taskId', async (req, res) => {
    try {
        const { projectName, taskId } = req.params;
        const { title, description, status, priority, details } = req.body;
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        // If only updating status, use set-status command
        if (status && Object.keys(req.body).length === 1) {
            const setStatusProcess = spawn('npx', ['task-master-ai', 'set-status', `--id=${taskId}`, `--status=${status}`], {
                cwd: projectPath,
                stdio: ['pipe', 'pipe', 'pipe']
            });
            let stdout = '';
            let stderr = '';
            setStatusProcess.stdout.on('data', (data) => {
                stdout += data.toString();
            });
            setStatusProcess.stderr.on('data', (data) => {
                stderr += data.toString();
            });
            setStatusProcess.on('close', (code) => {
                if (code === 0) {
                    // Broadcast task update via WebSocket
                    if (req.app.locals.wss) {
                        broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectName);
                    }
                    res.json({
                        projectName,
                        projectPath,
                        taskId,
                        message: 'Task status updated successfully',
                        output: stdout,
                        timestamp: new Date().toISOString()
                    });
                }
                else {
                    console.error('Set task status failed:', stderr);
                    res.status(500).json({
                        error: 'Failed to update task status',
                        message: stderr || stdout,
                        code
                    });
                }
            });
            setStatusProcess.stdin.end();
        }
        else {
            // For other updates, use update-task command with a prompt describing the changes
            const updates = [];
            if (title)
                updates.push(`title: "${title}"`);
            if (description)
                updates.push(`description: "${description}"`);
            if (priority)
                updates.push(`priority: "${priority}"`);
            if (details)
                updates.push(`details: "${details}"`);
            const prompt = `Update task with the following changes: ${updates.join(', ')}`;
            const updateProcess = spawn('npx', ['task-master-ai', 'update-task', `--id=${taskId}`, `--prompt=${prompt}`], {
                cwd: projectPath,
                stdio: ['pipe', 'pipe', 'pipe']
            });
            let stdout = '';
            let stderr = '';
            updateProcess.stdout.on('data', (data) => {
                stdout += data.toString();
            });
            updateProcess.stderr.on('data', (data) => {
                stderr += data.toString();
            });
            updateProcess.on('close', (code) => {
                if (code === 0) {
                    // Broadcast task update via WebSocket
                    if (req.app.locals.wss) {
                        broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectName);
                    }
                    res.json({
                        projectName,
                        projectPath,
                        taskId,
                        message: 'Task updated successfully',
                        output: stdout,
                        timestamp: new Date().toISOString()
                    });
                }
                else {
                    console.error('Update task failed:', stderr);
                    res.status(500).json({
                        error: 'Failed to update task',
                        message: stderr || stdout,
                        code
                    });
                }
            });
            updateProcess.stdin.end();
        }
    }
    catch (error) {
        console.error('Update task error:', error);
        res.status(500).json({
            error: 'Failed to update task',
            message: error.message
        });
    }
});
/**
 * POST /api/taskmaster/parse-prd/:projectName
 * Parse a PRD file to generate tasks
 */
router.post('/parse-prd/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        const { fileName = 'prd.txt', numTasks, append = false } = req.body;
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        const prdPath = path.join(projectPath, '.taskmaster', 'docs', fileName);
        // Check if PRD file exists
        try {
            await fsPromises.access(prdPath, fs.constants.F_OK);
        }
        catch (error) {
            return res.status(404).json({
                error: 'PRD file not found',
                message: `File "${fileName}" does not exist in .taskmaster/docs/`
            });
        }
        // Build the command args
        const args = ['task-master-ai', 'parse-prd', prdPath];
        if (numTasks) {
            args.push('--num-tasks', numTasks.toString());
        }
        if (append) {
            args.push('--append');
        }
        args.push('--research'); // Use research for better PRD parsing
        // Run task-master parse-prd command
        const parsePRDProcess = spawn('npx', args, {
            cwd: projectPath,
            stdio: ['pipe', 'pipe', 'pipe']
        });
        let stdout = '';
        let stderr = '';
        parsePRDProcess.stdout.on('data', (data) => {
            stdout += data.toString();
        });
        parsePRDProcess.stderr.on('data', (data) => {
            stderr += data.toString();
        });
        parsePRDProcess.on('close', (code) => {
            if (code === 0) {
                // Broadcast task update via WebSocket
                if (req.app.locals.wss) {
                    broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectName);
                }
                res.json({
                    projectName,
                    projectPath,
                    prdFile: fileName,
                    message: 'PRD parsed and tasks generated successfully',
                    output: stdout,
                    timestamp: new Date().toISOString()
                });
            }
            else {
                console.error('Parse PRD failed:', stderr);
                res.status(500).json({
                    error: 'Failed to parse PRD',
                    message: stderr || stdout,
                    code
                });
            }
        });
        parsePRDProcess.stdin.end();
    }
    catch (error) {
        console.error('Parse PRD error:', error);
        res.status(500).json({
            error: 'Failed to parse PRD',
            message: error.message
        });
    }
});
/**
 * GET /api/taskmaster/prd-templates
 * Get available PRD templates
 */
router.get('/prd-templates', async (req, res) => {
    try {
        // Return built-in templates
        const templates = [
            {
                id: 'web-app',
                name: 'Web Application',
                description: 'Template for web application projects with frontend and backend components',
                category: 'web',
                content: `# Product Requirements Document - Web Application

## Overview
**Product Name:** [Your App Name]
**Version:** 1.0
**Date:** ${new Date().toISOString().split('T')[0]}
**Author:** [Your Name]

## Executive Summary
Brief description of what this web application will do and why it's needed.

## Product Goals
- Goal 1: [Specific measurable goal]
- Goal 2: [Specific measurable goal]
- Goal 3: [Specific measurable goal]

## User Stories
### Core Features
1. **User Registration & Authentication**
   - As a user, I want to create an account so I can access personalized features
   - As a user, I want to log in securely so my data is protected
   - As a user, I want to reset my password if I forget it

2. **Main Application Features**
   - As a user, I want to [core feature 1] so I can [benefit]
   - As a user, I want to [core feature 2] so I can [benefit]
   - As a user, I want to [core feature 3] so I can [benefit]

3. **User Interface**
   - As a user, I want a responsive design so I can use the app on any device
   - As a user, I want intuitive navigation so I can easily find features

## Technical Requirements
### Frontend
- Framework: React/Vue/Angular or vanilla JavaScript
- Styling: CSS framework (Tailwind, Bootstrap, etc.)
- State Management: Redux/Vuex/Context API
- Build Tools: Webpack/Vite
- Testing: Jest/Vitest for unit tests

### Backend
- Runtime: Node.js/Python/Java
- Database: PostgreSQL/MySQL/MongoDB
- API: RESTful API or GraphQL
- Authentication: JWT tokens
- Testing: Integration and unit tests

### Infrastructure
- Hosting: Cloud provider (AWS, Azure, GCP)
- CI/CD: GitHub Actions/GitLab CI
- Monitoring: Application monitoring tools
- Security: HTTPS, input validation, rate limiting

## Success Metrics
- User engagement metrics
- Performance benchmarks (load time < 2s)
- Error rates < 1%
- User satisfaction scores

## Timeline
- Phase 1: Core functionality (4-6 weeks)
- Phase 2: Advanced features (2-4 weeks)  
- Phase 3: Polish and launch (2 weeks)

## Constraints & Assumptions
- Budget constraints
- Technical limitations
- Team size and expertise
- Timeline constraints`
            },
            {
                id: 'api',
                name: 'REST API',
                description: 'Template for REST API development projects',
                category: 'backend',
                content: `# Product Requirements Document - REST API

## Overview
**API Name:** [Your API Name]
**Version:** v1.0
**Date:** ${new Date().toISOString().split('T')[0]}
**Author:** [Your Name]

## Executive Summary
Description of the API's purpose, target users, and primary use cases.

## API Goals
- Goal 1: Provide secure data access
- Goal 2: Ensure scalable architecture
- Goal 3: Maintain high availability (99.9% uptime)

## Functional Requirements
### Core Endpoints
1. **Authentication Endpoints**
   - POST /api/auth/login - User authentication
   - POST /api/auth/logout - User logout
   - POST /api/auth/refresh - Token refresh
   - POST /api/auth/register - User registration

2. **Data Management Endpoints**
   - GET /api/resources - List resources with pagination
   - GET /api/resources/{id} - Get specific resource
   - POST /api/resources - Create new resource
   - PUT /api/resources/{id} - Update existing resource
   - DELETE /api/resources/{id} - Delete resource

3. **Administrative Endpoints**
   - GET /api/admin/users - Manage users (admin only)
   - GET /api/admin/analytics - System analytics
   - POST /api/admin/backup - Trigger system backup

## Technical Requirements
### API Design
- RESTful architecture following OpenAPI 3.0 specification
- JSON request/response format
- Consistent error response format
- API versioning strategy

### Authentication & Security
- JWT token-based authentication
- Role-based access control (RBAC)
- Rate limiting (100 requests/minute per user)
- Input validation and sanitization
- HTTPS enforcement

### Database
- Database type: [PostgreSQL/MongoDB/MySQL]
- Connection pooling
- Database migrations
- Backup and recovery procedures

### Performance Requirements
- Response time: < 200ms for 95% of requests
- Throughput: 1000+ requests/second
- Concurrent users: 10,000+
- Database query optimization

### Documentation
- Auto-generated API documentation (Swagger/OpenAPI)
- Code examples for common use cases
- SDK development for major languages
- Postman collection for testing

## Error Handling
- Standardized error codes and messages
- Proper HTTP status codes
- Detailed error logging
- Graceful degradation strategies

## Testing Strategy
- Unit tests (80%+ coverage)
- Integration tests for all endpoints
- Load testing and performance testing
- Security testing (OWASP compliance)

## Monitoring & Logging
- Application performance monitoring
- Error tracking and alerting
- Access logs and audit trails
- Health check endpoints

## Deployment
- Containerized deployment (Docker)
- CI/CD pipeline setup
- Environment management (dev, staging, prod)
- Blue-green deployment strategy

## Success Metrics
- API uptime > 99.9%
- Average response time < 200ms
- Zero critical security vulnerabilities
- Developer adoption metrics`
            },
            {
                id: 'mobile-app',
                name: 'Mobile Application',
                description: 'Template for mobile app development projects (iOS/Android)',
                category: 'mobile',
                content: `# Product Requirements Document - Mobile Application

## Overview
**App Name:** [Your App Name]
**Platform:** iOS / Android / Cross-platform
**Version:** 1.0
**Date:** ${new Date().toISOString().split('T')[0]}
**Author:** [Your Name]

## Executive Summary
Brief description of the mobile app's purpose, target audience, and key value proposition.

## Product Goals
- Goal 1: [Specific user engagement goal]
- Goal 2: [Specific functionality goal]
- Goal 3: [Specific performance goal]

## User Stories
### Core Features
1. **Onboarding & Authentication**
   - As a new user, I want a simple onboarding process
   - As a user, I want to sign up with email or social media
   - As a user, I want biometric authentication for security

2. **Main App Features**
   - As a user, I want [core feature 1] accessible from home screen
   - As a user, I want [core feature 2] to work offline
   - As a user, I want to sync data across devices

3. **User Experience**
   - As a user, I want intuitive navigation patterns
   - As a user, I want fast loading times
   - As a user, I want accessibility features

## Technical Requirements
### Mobile Development
- **Cross-platform:** React Native / Flutter / Xamarin
- **Native:** Swift (iOS) / Kotlin (Android)
- **State Management:** Redux / MobX / Provider
- **Navigation:** React Navigation / Flutter Navigation

### Backend Integration
- REST API or GraphQL integration
- Real-time features (WebSockets/Push notifications)
- Offline data synchronization
- Background processing

### Device Features
- Camera and photo library access
- GPS location services
- Push notifications
- Biometric authentication
- Device storage

### Performance Requirements
- App launch time < 3 seconds
- Screen transition animations < 300ms
- Memory usage optimization
- Battery usage optimization

## Platform-Specific Considerations
### iOS Requirements
- iOS 13.0+ minimum version
- App Store guidelines compliance
- iOS design guidelines (Human Interface Guidelines)
- TestFlight beta testing

### Android Requirements
- Android 8.0+ (API level 26) minimum
- Google Play Store guidelines
- Material Design guidelines
- Google Play Console testing

## User Interface Design
- Responsive design for different screen sizes
- Dark mode support
- Accessibility compliance (WCAG 2.1)
- Consistent design system

## Security & Privacy
- Secure data storage (Keychain/Keystore)
- API communication encryption
- Privacy policy compliance (GDPR/CCPA)
- App security best practices

## Testing Strategy
- Unit testing (80%+ coverage)
- UI/E2E testing (Detox/Appium)
- Device testing on multiple screen sizes
- Performance testing
- Security testing

## App Store Deployment
- App store optimization (ASO)
- App icons and screenshots
- Store listing content
- Release management strategy

## Analytics & Monitoring
- User analytics (Firebase/Analytics)
- Crash reporting (Crashlytics/Sentry)
- Performance monitoring
- User feedback collection

## Success Metrics
- App store ratings > 4.0
- User retention rates
- Daily/Monthly active users
- App performance metrics
- Conversion rates`
            },
            {
                id: 'data-analysis',
                name: 'Data Analysis Project',
                description: 'Template for data analysis and visualization projects',
                category: 'data',
                content: `# Product Requirements Document - Data Analysis Project

## Overview
**Project Name:** [Your Analysis Project]
**Analysis Type:** [Descriptive/Predictive/Prescriptive]
**Date:** ${new Date().toISOString().split('T')[0]}
**Author:** [Your Name]

## Executive Summary
Description of the business problem, data sources, and expected insights.

## Project Goals
- Goal 1: [Specific business question to answer]
- Goal 2: [Specific prediction to make]
- Goal 3: [Specific recommendation to provide]

## Business Requirements
### Key Questions
1. What patterns exist in the current data?
2. What factors influence [target variable]?
3. What predictions can be made for [future outcome]?
4. What recommendations can improve [business metric]?

### Success Criteria
- Actionable insights for stakeholders
- Statistical significance in findings
- Reproducible analysis pipeline
- Clear visualization and reporting

## Data Requirements
### Data Sources
1. **Primary Data**
   - Source: [Database/API/Files]
   - Format: [CSV/JSON/SQL]
   - Size: [Volume estimate]
   - Update frequency: [Real-time/Daily/Monthly]

2. **External Data**
   - Third-party APIs
   - Public datasets
   - Market research data

### Data Quality Requirements
- Data completeness (< 5% missing values)
- Data accuracy validation
- Data consistency checks
- Historical data availability

## Technical Requirements
### Data Pipeline
- Data extraction and ingestion
- Data cleaning and preprocessing
- Data transformation and feature engineering
- Data validation and quality checks

### Analysis Tools
- **Programming:** Python/R/SQL
- **Libraries:** pandas, numpy, scikit-learn, matplotlib
- **Visualization:** Tableau, PowerBI, or custom dashboards
- **Version Control:** Git for code and DVC for data

### Computing Resources
- Local development environment
- Cloud computing (AWS/GCP/Azure) if needed
- Database access and permissions
- Storage requirements

## Analysis Methodology
### Data Exploration
1. Descriptive statistics and data profiling
2. Data visualization and pattern identification
3. Correlation analysis
4. Outlier detection and handling

### Statistical Analysis
1. Hypothesis formulation
2. Statistical testing
3. Confidence intervals
4. Effect size calculations

### Machine Learning (if applicable)
1. Feature selection and engineering
2. Model selection and training
3. Cross-validation and evaluation
4. Model interpretation and explainability

## Deliverables
### Reports
- Executive summary for stakeholders
- Technical analysis report
- Data quality report
- Methodology documentation

### Visualizations
- Interactive dashboards
- Static charts and graphs
- Data story presentations
- Key findings infographics

### Code & Documentation
- Reproducible analysis scripts
- Data pipeline code
- Documentation and comments
- Testing and validation code

## Timeline
- Phase 1: Data collection and exploration (2 weeks)
- Phase 2: Analysis and modeling (3 weeks)
- Phase 3: Reporting and visualization (1 week)
- Phase 4: Stakeholder presentation (1 week)

## Risks & Assumptions
- Data availability and quality risks
- Technical complexity assumptions
- Resource and timeline constraints
- Stakeholder engagement assumptions

## Success Metrics
- Stakeholder satisfaction with insights
- Accuracy of predictions (if applicable)
- Business impact of recommendations
- Reproducibility of results`
            }
        ];
        res.json({
            templates,
            timestamp: new Date().toISOString()
        });
    }
    catch (error) {
        console.error('PRD templates error:', error);
        res.status(500).json({
            error: 'Failed to get PRD templates',
            message: error.message
        });
    }
});
/**
 * POST /api/taskmaster/apply-template/:projectName
 * Apply a PRD template to create a new PRD file
 */
router.post('/apply-template/:projectName', async (req, res) => {
    try {
        const { projectName } = req.params;
        const { templateId, fileName = 'prd.txt', customizations = {} } = req.body;
        if (!templateId) {
            return res.status(400).json({
                error: 'Missing required parameter',
                message: 'templateId is required'
            });
        }
        // Get project path
        let projectPath;
        try {
            projectPath = await extractProjectDirectory(projectName);
        }
        catch (error) {
            return res.status(404).json({
                error: 'Project not found',
                message: `Project "${projectName}" does not exist`
            });
        }
        // Get the template content (this would normally fetch from the templates list)
        const templates = await getAvailableTemplates();
        const template = templates.find(t => t.id === templateId);
        if (!template) {
            return res.status(404).json({
                error: 'Template not found',
                message: `Template "${templateId}" does not exist`
            });
        }
        // Apply customizations to template content
        let content = template.content;
        // Replace placeholders with customizations
        for (const [key, value] of Object.entries(customizations)) {
            const placeholder = `[${key}]`;
            content = content.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g'), value);
        }
        // Ensure .taskmaster/docs directory exists
        const docsDir = path.join(projectPath, '.taskmaster', 'docs');
        try {
            await fsPromises.mkdir(docsDir, { recursive: true });
        }
        catch (error) {
            console.error('Failed to create docs directory:', error);
        }
        const filePath = path.join(docsDir, fileName);
        // Write the template content to the file
        try {
            await fsPromises.writeFile(filePath, content, 'utf8');
            res.json({
                projectName,
                projectPath,
                templateId,
                templateName: template.name,
                fileName,
                filePath: filePath,
                message: 'PRD template applied successfully',
                timestamp: new Date().toISOString()
            });
        }
        catch (writeError) {
            console.error('Failed to write PRD template:', writeError);
            return res.status(500).json({
                error: 'Failed to write PRD template',
                message: writeError.message
            });
        }
    }
    catch (error) {
        console.error('Apply template error:', error);
        res.status(500).json({
            error: 'Failed to apply PRD template',
            message: error.message
        });
    }
});
// Helper function to get available templates
async function getAvailableTemplates() {
    // This could be extended to read from files or database
    return [
        {
            id: 'web-app',
            name: 'Web Application',
            description: 'Template for web application projects',
            category: 'web',
            content: `# Product Requirements Document - Web Application

## Overview
**Product Name:** [Your App Name]
**Version:** 1.0
**Date:** ${new Date().toISOString().split('T')[0]}
**Author:** [Your Name]

## Executive Summary
Brief description of what this web application will do and why it's needed.

## User Stories
1. As a user, I want [feature] so I can [benefit]
2. As a user, I want [feature] so I can [benefit]
3. As a user, I want [feature] so I can [benefit]

## Technical Requirements
- Frontend framework
- Backend services
- Database requirements
- Security considerations

## Success Metrics
- User engagement metrics
- Performance benchmarks
- Business objectives`
        },
        // Add other templates here if needed
    ];
}
export default router;
//# sourceMappingURL=taskmaster.js.map