@triedotdev/mcp 1.0.119 → 1.0.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/guardian/goal-validator.ts"],"sourcesContent":["/**\n * Goal Validator - Helpers for goal tracking\n * \n * Goal detection is handled entirely by the AI watcher in watch.ts.\n * The AI (Anthropic) checks every changed file against user-defined goals,\n * using the Trie's priority scoring for cost control.\n * \n * This module provides:\n * - getActiveGoals: loads active goals for the AI prompt\n * - recordGoalViolationCaught: tracks when a violation is detected\n * - recordGoalViolationFixed: tracks when a violation is auto-fixed\n */\n\nimport type { Goal } from './guardian-state.js';\nimport { getGuardianState } from './guardian-state.js';\n\n/**\n * Get active goals for a project (used by the AI watcher)\n */\nexport async function getActiveGoals(projectPath: string): Promise<Goal[]> {\n const guardianState = getGuardianState(projectPath);\n await guardianState.load();\n return guardianState.getAllGoals().filter(g => g.status === 'active');\n}\n\nexport async function recordGoalViolationCaught(\n goal: Goal,\n file: string,\n projectPath: string\n): Promise<void> {\n const guardianState = getGuardianState(projectPath);\n await guardianState.load();\n \n const metadata = goal.metadata || {};\n const caughtCount = (metadata.caughtCount || 0) + 1;\n \n await guardianState.updateGoal(goal.id, {\n metadata: {\n ...metadata,\n caughtCount,\n lastCaught: new Date().toISOString(),\n lastCaughtFile: file,\n },\n });\n}\n\nexport async function recordGoalViolationFixed(\n goal: Goal,\n file: string,\n projectPath: string\n): Promise<void> {\n const guardianState = getGuardianState(projectPath);\n await guardianState.load();\n \n const metadata = goal.metadata || {};\n const caughtCount = (metadata.caughtCount || 0) + 1;\n const fixedCount = (metadata.fixedCount || 0) + 1;\n \n await guardianState.updateGoal(goal.id, {\n metadata: {\n ...metadata,\n caughtCount,\n fixedCount,\n lastFixed: new Date().toISOString(),\n lastFixedFile: file,\n },\n });\n \n if (goal.type === 'reduction') {\n const newValue = Math.max(0, goal.currentValue - 1);\n await guardianState.updateGoal(goal.id, {\n currentValue: newValue,\n });\n \n if (newValue <= goal.target) {\n await guardianState.updateGoal(goal.id, {\n status: 'achieved',\n achievedAt: new Date().toISOString(),\n });\n }\n }\n}\n\n/**\n * Manually check files against goals\n * Returns violations found\n */\nexport async function checkFilesForGoalViolations(\n goals: Goal[],\n projectPath: string,\n filesToCheck?: string[]\n): Promise<Array<{ file: string; message: string; severity: 'critical' | 'warning' | 'info' }>> {\n // Import AI client\n const { isAIAvailable, runAIAnalysis } = await import('../ai/client.js');\n \n if (!isAIAvailable()) {\n throw new Error('AI not available - ANTHROPIC_API_KEY not set');\n }\n \n // Get files to check\n let files: string[] = [];\n if (filesToCheck && filesToCheck.length > 0) {\n files = filesToCheck;\n } else {\n // Find recently modified files (last 7 days)\n const { execSync } = await import('child_process');\n try {\n const gitOutput = execSync(\n 'git diff --name-only HEAD && git ls-files --modified && git ls-files --others --exclude-standard',\n { cwd: projectPath, encoding: 'utf-8' }\n ).trim();\n \n if (gitOutput) {\n const gitFiles = new Set(gitOutput.split('\\n').filter(Boolean));\n files = Array.from(gitFiles)\n .map(f => `${projectPath}/${f}`)\n .filter(f => {\n // Filter to code files only\n return /\\.(ts|tsx|js|jsx|py|go|rs|java|c|cpp|h|hpp|cs|rb|php)$/.test(f);\n })\n .slice(0, 20); // Limit to 20 files\n }\n } catch {\n // Git command failed, skip\n }\n }\n \n if (files.length === 0) {\n return [];\n }\n \n // Read file contents\n const { readFile } = await import('fs/promises');\n const { basename } = await import('path');\n const fileContents = await Promise.all(\n files.map(async (filePath) => {\n try {\n const content = await readFile(filePath, 'utf-8');\n const relativePath = filePath.replace(projectPath + '/', '');\n return {\n path: relativePath,\n content: content.slice(0, 5000), // Limit content size\n };\n } catch {\n return null;\n }\n })\n );\n \n const validFiles = fileContents.filter((f): f is { path: string; content: string } => f !== null);\n \n if (validFiles.length === 0) {\n return [];\n }\n \n // Build files block for AI\n const filesBlock = validFiles\n .map(f => `--- ${f.path} ---\\n${f.content}`)\n .join('\\n\\n');\n \n // Build goals section\n const goalsSection = `\nUSER-DEFINED GOALS (check EVERY file against ALL goals):\n${goals.map((g, i) => ` ${i + 1}. \"${g.description}\"`).join('\\n')}\n\nThis is a MANUAL CHECK requested by the user. Report ALL goal violations you find.\n`;\n \n // Run AI analysis\n const result = await runAIAnalysis({\n systemPrompt: `You are checking code for GOAL VIOLATIONS ONLY.\n${goalsSection}\nReply ONLY with a JSON array. Each element must have:\n- \"file\": relative file path\n- \"severity\": \"critical\" | \"major\" | \"minor\"\n- \"description\": 1-sentence description of the goal violation\n- \"confidence\": number 0-100, how confident you are this is a violation\n- \"isGoalViolation\": true (always true for this scan)\n- \"goalIndex\": 0-based index of the violated goal\n\nBe thorough. If a goal says \"no emojis\" and you see ANY emoji in the file, report it. If a goal says \"no console.log\" and you see console.log, report it.\n\nIf no violations found, reply with: []\nOutput ONLY the JSON array, no markdown fences, no commentary.`,\n userPrompt: `Check these files for goal violations:\\n\\n${filesBlock}`,\n maxTokens: 2048,\n temperature: 0.1,\n });\n \n // Parse response\n let issues: Array<{\n file: string;\n severity: 'critical' | 'major' | 'minor';\n description: string;\n confidence: number;\n isGoalViolation: boolean;\n goalIndex?: number;\n }> = [];\n \n try {\n const cleaned = result.content.replace(/```json?\\n?|\\n?```/g, '').trim();\n issues = JSON.parse(cleaned);\n if (!Array.isArray(issues)) issues = [];\n } catch {\n // Parse failed\n return [];\n }\n \n // Convert to violation format and record\n const violations: Array<{ file: string; message: string; severity: 'critical' | 'warning' | 'info' }> = [];\n \n for (const issue of issues) {\n if (!issue.isGoalViolation || issue.confidence < 50) continue;\n if (issue.goalIndex == null || issue.goalIndex < 0 || issue.goalIndex >= goals.length) continue;\n \n const goal = goals[issue.goalIndex]!;\n const severity = issue.severity === 'critical' ? 'critical' : 'warning';\n const message = `Goal \"${goal.description}\" violated in ${issue.file}: ${issue.description} [${issue.confidence}% confidence]`;\n \n violations.push({\n file: issue.file,\n message,\n severity,\n });\n \n // Record violation\n await recordGoalViolationCaught(goal, issue.file, projectPath);\n }\n \n return violations;\n}\n"],"mappings":"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","names":[]}