@triedotdev/mcp 1.0.44 → 1.0.45

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/project-info.ts","../src/skills/installer.ts","../src/skills/parser.ts","../src/memory/issue-store.ts","../src/memory/bm25.ts","../src/memory/compactor.ts","../src/memory/global-memory.ts","../src/utils/context-state.ts"],"sourcesContent":["/**\n * Project Info Manager\n * \n * Manages the .trie/PROJECT.md file that stores user-defined project context.\n * Unlike AGENTS.md (auto-generated), PROJECT.md is fully user-controlled.\n */\n\nimport { readFile, writeFile, mkdir } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { getWorkingDirectory } from './workspace.js';\n\nconst PROJECT_MD_PATH = '.trie/PROJECT.md';\n\n/**\n * Default PROJECT.md template\n */\nexport function getProjectTemplate(): string {\n return `# Project Information\n\n> This file stores important project context for AI assistants.\n> Edit freely - this file is yours, not auto-generated.\n> Available via MCP resource: \\`trie://project\\`\n\n---\n\n## Project Overview\n\n<!-- Describe your project's purpose and goals -->\n\n[Add project description here]\n\n---\n\n## Technology Stack\n\n<!-- List frameworks, languages, databases, cloud services, etc. -->\n\n- **Language:** \n- **Framework:** \n- **Database:** \n- **Hosting:** \n\n---\n\n## Architecture\n\n<!-- Key patterns, architectural decisions, and system design -->\n\n[Describe your architecture here]\n\n---\n\n## Coding Conventions\n\n<!-- Style guidelines, naming conventions, patterns to follow -->\n\n- \n- \n- \n\n---\n\n## Environment\n\n<!-- URLs, API endpoints, deployment info -->\n\n| Environment | URL | Notes |\n|-------------|-----|-------|\n| Development | | |\n| Staging | | |\n| Production | | |\n\n---\n\n## Team\n\n<!-- Ownership, contacts, responsibilities -->\n\n- **Owner:** \n- **Team:** \n\n---\n\n## Compliance\n\n<!-- HIPAA, SOC2, GDPR, PCI-DSS requirements if applicable -->\n\n- [ ] GDPR\n- [ ] SOC2\n- [ ] HIPAA\n- [ ] PCI-DSS\n\n---\n\n## AI Instructions\n\n<!-- Special instructions for AI assistants working on this project -->\n\nWhen working on this project, AI assistants should:\n\n1. \n2. \n3. \n\n---\n\n*This file is read by Trie agents and exposed via \\`trie://project\\` MCP resource.*\n*Edit this file to provide context to Claude Code, Cursor, GitHub Actions, and other AI tools.*\n`;\n}\n\n/**\n * Check if PROJECT.md exists\n */\nexport function projectInfoExists(workDir?: string): boolean {\n const dir = workDir || getWorkingDirectory(undefined, true);\n const projectPath = join(dir, PROJECT_MD_PATH);\n return existsSync(projectPath);\n}\n\n/**\n * Load PROJECT.md content\n */\nexport async function loadProjectInfo(workDir?: string): Promise<string | null> {\n const dir = workDir || getWorkingDirectory(undefined, true);\n const projectPath = join(dir, PROJECT_MD_PATH);\n \n try {\n if (!existsSync(projectPath)) {\n return null;\n }\n return await readFile(projectPath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Save PROJECT.md content\n */\nexport async function saveProjectInfo(content: string, workDir?: string): Promise<void> {\n const dir = workDir || getWorkingDirectory(undefined, true);\n const trieDir = join(dir, '.trie');\n const projectPath = join(dir, PROJECT_MD_PATH);\n \n // Ensure .trie directory exists\n await mkdir(trieDir, { recursive: true });\n \n await writeFile(projectPath, content, 'utf-8');\n}\n\n/**\n * Initialize PROJECT.md with template\n */\nexport async function initProjectInfo(workDir?: string): Promise<{ created: boolean; path: string }> {\n const dir = workDir || getWorkingDirectory(undefined, true);\n const projectPath = join(dir, PROJECT_MD_PATH);\n \n if (existsSync(projectPath)) {\n return { created: false, path: projectPath };\n }\n \n await saveProjectInfo(getProjectTemplate(), dir);\n return { created: true, path: projectPath };\n}\n\n/**\n * Get a specific section from PROJECT.md\n */\nexport async function getProjectSection(sectionName: string, workDir?: string): Promise<string | null> {\n const content = await loadProjectInfo(workDir);\n if (!content) return null;\n \n // Find section by header\n const sectionRegex = new RegExp(\n `## ${escapeRegex(sectionName)}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |\\\\n---\\\\s*$|$)`,\n 'i'\n );\n \n const match = content.match(sectionRegex);\n if (match) {\n return match[1].trim();\n }\n \n return null;\n}\n\n/**\n * Update a specific section in PROJECT.md\n */\nexport async function updateProjectSection(\n sectionName: string, \n newContent: string, \n workDir?: string\n): Promise<boolean> {\n let content = await loadProjectInfo(workDir);\n \n if (!content) {\n // Initialize with template first\n await initProjectInfo(workDir);\n content = await loadProjectInfo(workDir);\n if (!content) return false;\n }\n \n // Find and replace section content\n const sectionRegex = new RegExp(\n `(## ${escapeRegex(sectionName)}\\\\s*\\\\n)([\\\\s\\\\S]*?)((?=\\\\n## )|(?=\\\\n---\\\\s*$)|$)`,\n 'i'\n );\n \n if (content.match(sectionRegex)) {\n const updatedContent = content.replace(sectionRegex, `$1\\n${newContent}\\n\\n$3`);\n await saveProjectInfo(updatedContent, workDir);\n return true;\n }\n \n return false;\n}\n\n/**\n * Append content to a section\n */\nexport async function appendToSection(\n sectionName: string,\n contentToAdd: string,\n workDir?: string\n): Promise<boolean> {\n const currentContent = await getProjectSection(sectionName, workDir);\n if (currentContent === null) return false;\n \n const newContent = currentContent + '\\n' + contentToAdd;\n return updateProjectSection(sectionName, newContent, workDir);\n}\n\n/**\n * Get all section names from PROJECT.md\n */\nexport async function getProjectSections(workDir?: string): Promise<string[]> {\n const content = await loadProjectInfo(workDir);\n if (!content) return [];\n \n const sectionRegex = /^## (.+)$/gm;\n const sections: string[] = [];\n let match;\n \n while ((match = sectionRegex.exec(content)) !== null) {\n sections.push(match[1].trim());\n }\n \n return sections;\n}\n\n/**\n * Get project info as structured data (for JSON responses)\n */\nexport async function getProjectInfoStructured(workDir?: string): Promise<{\n exists: boolean;\n path: string;\n sections: Record<string, string>;\n raw: string | null;\n}> {\n const dir = workDir || getWorkingDirectory(undefined, true);\n const projectPath = join(dir, PROJECT_MD_PATH);\n const content = await loadProjectInfo(dir);\n \n if (!content) {\n return {\n exists: false,\n path: projectPath,\n sections: {},\n raw: null,\n };\n }\n \n const sectionNames = await getProjectSections(dir);\n const sections: Record<string, string> = {};\n \n for (const name of sectionNames) {\n const sectionContent = await getProjectSection(name, dir);\n if (sectionContent) {\n sections[name] = sectionContent;\n }\n }\n \n return {\n exists: true,\n path: projectPath,\n sections,\n raw: content,\n };\n}\n\n/**\n * Escape special regex characters\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","/**\n * Skill Installer\n * \n * Installs skills from GitHub repositories into .trie/skills/\n * Skills can come from any repo that follows the SKILL.md format.\n */\n\nimport { mkdir, rm, writeFile, readdir, readFile, access, cp } from 'fs/promises';\nimport { join } from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { parseSkillMd } from './parser.js';\nimport { getWorkingDirectory } from '../utils/workspace.js';\nimport type { InstalledSkill, SkillInstallResult } from '../types/external-skill.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Install a skill from a GitHub repository\n * \n * @param source - GitHub source in format \"owner/repo\" or \"owner/repo/skill-name\"\n * @param skillName - Optional skill name if repo contains multiple skills\n */\nexport async function installSkill(source: string, skillName?: string): Promise<SkillInstallResult> {\n const parts = source.split('/');\n if (parts.length < 2) {\n return { success: false, name: 'unknown', error: 'Invalid source format. Use owner/repo or owner/repo/skill-name' };\n }\n \n const owner = parts[0];\n const repo = parts[1];\n const specifiedSkill = skillName || parts[2];\n \n const skillsDir = join(getWorkingDirectory(undefined, true), '.trie', 'skills');\n const tempDir = join(skillsDir, `.temp-${Date.now()}`);\n \n try {\n await mkdir(skillsDir, { recursive: true });\n \n // Clone the repository\n const repoUrl = `https://github.com/${owner}/${repo}.git`;\n await execAsync(`git clone --depth 1 \"${repoUrl}\" \"${tempDir}\"`, { timeout: 60000 });\n \n // Find the SKILL.md file\n const sourcePath = await findSkillPath(tempDir, specifiedSkill);\n if (!sourcePath) {\n throw new Error(`SKILL.md not found in repository. Searched in: root, skills/, ${specifiedSkill || 'subdirectories'}`);\n }\n \n // Parse and validate the skill\n const parsed = await parseSkillMd(sourcePath);\n const name = parsed.frontmatter.name;\n \n // Copy to final location\n const targetPath = join(skillsDir, name);\n \n // Remove existing if present\n await rm(targetPath, { recursive: true, force: true });\n \n // Copy skill directory\n await cp(sourcePath, targetPath, { recursive: true });\n \n // Write installation metadata\n await writeFile(join(targetPath, '.installed.json'), JSON.stringify({\n installedFrom: source,\n installedAt: new Date().toISOString(),\n repository: `${owner}/${repo}`,\n }, null, 2));\n \n return { success: true, name, path: targetPath };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, name: skillName || 'unknown', error: message };\n } finally {\n // Clean up temp directory\n await rm(tempDir, { recursive: true, force: true }).catch(() => {});\n }\n}\n\n/**\n * Find the path to a SKILL.md within a cloned repository\n */\nasync function findSkillPath(repoPath: string, skillName?: string): Promise<string | null> {\n const searchPaths: string[] = [];\n \n if (skillName) {\n // Search for specific skill\n searchPaths.push(\n join(repoPath, 'skills', skillName),\n join(repoPath, skillName),\n );\n }\n \n // Also search common locations\n searchPaths.push(\n repoPath,\n join(repoPath, 'skill'),\n );\n \n // If no specific skill, try to find any skill directory\n if (!skillName) {\n try {\n const skillsSubdir = join(repoPath, 'skills');\n await access(skillsSubdir);\n const entries = await readdir(skillsSubdir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n searchPaths.push(join(skillsSubdir, entry.name));\n }\n }\n } catch {\n // skills/ directory doesn't exist\n }\n }\n \n // Check each path for SKILL.md\n for (const searchPath of searchPaths) {\n try {\n await parseSkillMd(searchPath);\n return searchPath;\n } catch {\n // Not a valid skill directory\n }\n }\n \n return null;\n}\n\n/**\n * List all installed skills\n */\nexport async function listInstalledSkills(): Promise<InstalledSkill[]> {\n const skillsDir = join(getWorkingDirectory(undefined, true), '.trie', 'skills');\n const skills: InstalledSkill[] = [];\n \n try {\n const entries = await readdir(skillsDir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith('.')) continue;\n \n const skillPath = join(skillsDir, entry.name);\n \n try {\n const parsed = await parseSkillMd(skillPath);\n const metaPath = join(skillPath, '.installed.json');\n \n let meta = { installedFrom: 'unknown', installedAt: new Date().toISOString() };\n try {\n meta = JSON.parse(await readFile(metaPath, 'utf-8'));\n } catch {\n // No metadata file\n }\n \n skills.push({\n name: parsed.frontmatter.name,\n description: parsed.frontmatter.description,\n path: skillPath,\n installedFrom: meta.installedFrom,\n installedAt: meta.installedAt,\n });\n } catch {\n // Invalid skill directory, skip\n }\n }\n } catch {\n // Skills directory doesn't exist\n }\n \n return skills;\n}\n\n/**\n * Remove an installed skill\n */\nexport async function removeSkill(skillName: string): Promise<boolean> {\n const skillsDir = join(getWorkingDirectory(undefined, true), '.trie', 'skills');\n const skillPath = join(skillsDir, skillName);\n \n try {\n await rm(skillPath, { recursive: true });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get a specific installed skill by name\n */\nexport async function getInstalledSkill(skillName: string): Promise<InstalledSkill | null> {\n const skills = await listInstalledSkills();\n return skills.find(s => s.name === skillName) || null;\n}\n","/**\n * Skill Parser\n * \n * Parses SKILL.md files to extract frontmatter and content.\n * Skills follow the Agent Skills specification from skills.sh.\n */\n\nimport { readFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { ParsedSkill, SkillFrontmatter } from '../types/external-skill.js';\n\n/**\n * Parse a SKILL.md file from a skill directory\n */\nexport async function parseSkillMd(skillPath: string): Promise<ParsedSkill> {\n const skillMdPath = join(skillPath, 'SKILL.md');\n const rawContent = await readFile(skillMdPath, 'utf-8');\n \n const frontmatterMatch = rawContent.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch || !frontmatterMatch[1]) {\n throw new Error('Invalid SKILL.md: missing YAML frontmatter');\n }\n \n const frontmatter = parseYamlFrontmatter(frontmatterMatch[1]);\n \n if (!frontmatter.name || !frontmatter.description) {\n throw new Error('Invalid SKILL.md: missing required name or description in frontmatter');\n }\n \n const content = rawContent.slice(frontmatterMatch[0].length).trim();\n \n return {\n frontmatter,\n content,\n rawContent,\n };\n}\n\n/**\n * Simple YAML frontmatter parser\n * Handles basic key: value pairs without external dependencies\n */\nfunction parseYamlFrontmatter(yaml: string): SkillFrontmatter {\n const result: Record<string, unknown> = {};\n const lines = yaml.split('\\n');\n \n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n \n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n \n const key = trimmed.slice(0, colonIndex).trim();\n let value: unknown = trimmed.slice(colonIndex + 1).trim();\n \n if (value === '') continue;\n \n // Remove quotes if present\n if (typeof value === 'string') {\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n \n // Handle arrays (simple format: [item1, item2])\n if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n value = value.slice(1, -1).split(',').map(s => s.trim().replace(/^[\"']|[\"']$/g, ''));\n }\n }\n \n result[key] = value;\n }\n \n return result as unknown as SkillFrontmatter;\n}\n\n/**\n * Extract just the name from a SKILL.md without full parsing\n */\nexport async function extractSkillName(skillPath: string): Promise<string | null> {\n try {\n const parsed = await parseSkillMd(skillPath);\n return parsed.frontmatter.name;\n } catch {\n return null;\n }\n}\n","/**\n * Issue Memory Store\n * \n * Stores issues for semantic search and pattern detection.\n * Uses BM25 ranking for search (same algorithm as Elasticsearch).\n * Local JSON storage with daily logs.\n */\n\nimport { mkdir, writeFile, readFile, readdir } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { getWorkingDirectory } from '../utils/workspace.js';\nimport type { Issue } from '../types/index.js';\nimport { BM25Index } from './bm25.js';\nimport { compactOldIssues, saveCompactedSummary, getHistoricalInsights } from './compactor.js';\n\nexport interface StoredIssue {\n id: string;\n hash: string;\n severity: string;\n issue: string;\n fix: string;\n file: string;\n line?: number;\n agent: string;\n category?: string;\n timestamp: string;\n project: string;\n resolved?: boolean;\n resolvedAt?: string;\n}\n\nexport interface IssueSearchResult {\n issue: StoredIssue;\n score: number;\n matchType: 'bm25' | 'keyword';\n}\n\nexport interface IssueMemoryStats {\n totalIssues: number;\n issuesByAgent: Record<string, number>;\n issuesBySeverity: Record<string, number>;\n oldestIssue?: string;\n newestIssue?: string;\n resolvedCount: number;\n historicalIssues: number;\n improvementTrend: 'improving' | 'stable' | 'declining' | 'unknown';\n}\n\n/**\n * Store issues from a scan\n */\nexport async function storeIssues(\n issues: Issue[],\n project: string,\n workDir?: string\n): Promise<number> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(projectDir, '.trie', 'memory');\n await mkdir(memoryDir, { recursive: true });\n \n const stored: StoredIssue[] = [];\n const now = new Date().toISOString();\n \n for (const issue of issues) {\n const hash = hashIssue(issue);\n \n stored.push({\n id: issue.id,\n hash,\n severity: issue.severity,\n issue: issue.issue,\n fix: issue.fix,\n file: issue.file,\n line: issue.line,\n agent: issue.agent,\n category: issue.category,\n timestamp: now,\n project,\n resolved: false,\n });\n }\n\n await appendToDailyLog(stored, projectDir);\n await updateIssueIndex(stored, projectDir);\n \n return stored.length;\n}\n\n/**\n * Search issues using BM25 ranking (same algorithm as Elasticsearch)\n */\nexport async function searchIssues(\n query: string,\n options: {\n workDir?: string;\n limit?: number;\n project?: string;\n severity?: string[];\n agent?: string;\n includeResolved?: boolean;\n } = {}\n): Promise<IssueSearchResult[]> {\n const projectDir = options.workDir || getWorkingDirectory(undefined, true);\n const limit = options.limit || 10;\n const allIssues = await loadIssueIndex(projectDir);\n \n if (allIssues.length === 0) {\n return [];\n }\n\n // Filter issues first\n const filteredIssues = allIssues.filter(issue => {\n if (options.project && issue.project !== options.project) return false;\n if (options.severity && !options.severity.includes(issue.severity)) return false;\n if (options.agent && issue.agent !== options.agent) return false;\n if (!options.includeResolved && issue.resolved) return false;\n return true;\n });\n\n if (filteredIssues.length === 0) {\n return [];\n }\n\n // Build BM25 index\n const bm25 = new BM25Index();\n const issueMap = new Map<string, StoredIssue>();\n \n for (const issue of filteredIssues) {\n const searchText = `${issue.issue} ${issue.fix} ${issue.file} ${issue.agent} ${issue.category || ''} ${issue.severity}`;\n bm25.addDocument({\n id: issue.id,\n text: searchText,\n });\n issueMap.set(issue.id, issue);\n }\n\n // Search with BM25\n const bm25Results = bm25.search(query, limit);\n \n return bm25Results.map(result => ({\n issue: issueMap.get(result.id)!,\n score: result.score,\n matchType: 'bm25' as const,\n }));\n}\n\n/**\n * Find similar issues using BM25 similarity\n */\nexport async function findSimilarIssues(\n issue: Issue,\n options: {\n workDir?: string;\n limit?: number;\n excludeSameFile?: boolean;\n } = {}\n): Promise<IssueSearchResult[]> {\n // Use the issue description and fix as the query for similarity\n const query = `${issue.issue} ${issue.fix} ${issue.agent}`;\n const results = await searchIssues(query, {\n workDir: options.workDir,\n limit: (options.limit || 5) + 5, // Get extra to account for filtering\n includeResolved: true,\n });\n\n let filtered = results.filter(r => r.issue.id !== issue.id);\n \n if (options.excludeSameFile) {\n filtered = filtered.filter(r => r.issue.file !== issue.file);\n }\n \n return filtered.slice(0, options.limit || 5);\n}\n\n/**\n * Mark an issue as resolved\n */\nexport async function markIssueResolved(\n issueId: string,\n workDir?: string\n): Promise<boolean> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const index = await loadIssueIndex(projectDir);\n \n const issue = index.find(i => i.id === issueId);\n if (!issue) return false;\n \n issue.resolved = true;\n issue.resolvedAt = new Date().toISOString();\n \n await saveIssueIndex(index, projectDir);\n return true;\n}\n\n/**\n * Get memory statistics including historical insights\n */\nexport async function getMemoryStats(workDir?: string): Promise<IssueMemoryStats> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const index = await loadIssueIndex(projectDir);\n const historical = await getHistoricalInsights(projectDir);\n \n const stats: IssueMemoryStats = {\n totalIssues: index.length,\n issuesByAgent: {},\n issuesBySeverity: {},\n resolvedCount: 0,\n historicalIssues: historical.totalHistoricalIssues,\n improvementTrend: historical.improvementTrend,\n };\n\n for (const issue of index) {\n stats.issuesByAgent[issue.agent] = (stats.issuesByAgent[issue.agent] || 0) + 1;\n stats.issuesBySeverity[issue.severity] = (stats.issuesBySeverity[issue.severity] || 0) + 1;\n if (issue.resolved) stats.resolvedCount++;\n }\n\n if (index.length > 0) {\n const sorted = [...index].sort((a, b) => \n new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n stats.oldestIssue = sorted[0]?.timestamp;\n stats.newestIssue = sorted[sorted.length - 1]?.timestamp;\n }\n\n return stats;\n}\n\n/**\n * Get recent issues\n */\nexport async function getRecentIssues(\n options: {\n workDir?: string;\n limit?: number;\n daysBack?: number;\n } = {}\n): Promise<StoredIssue[]> {\n const projectDir = options.workDir || getWorkingDirectory(undefined, true);\n const index = await loadIssueIndex(projectDir);\n const limit = options.limit || 20;\n const daysBack = options.daysBack || 7;\n \n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - daysBack);\n \n return index\n .filter(i => new Date(i.timestamp) >= cutoff)\n .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())\n .slice(0, limit);\n}\n\n/**\n * Get daily log files\n */\nexport async function getDailyLogs(workDir?: string): Promise<string[]> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(projectDir, '.trie', 'memory');\n \n try {\n if (!existsSync(memoryDir)) return [];\n const files = await readdir(memoryDir);\n return files\n .filter(f => /^\\d{4}-\\d{2}-\\d{2}\\.md$/.test(f))\n .sort()\n .reverse();\n } catch {\n return [];\n }\n}\n\n// Private helpers\n\nasync function appendToDailyLog(issues: StoredIssue[], projectDir: string): Promise<void> {\n const memoryDir = join(projectDir, '.trie', 'memory');\n const today = new Date().toISOString().split('T')[0];\n const logPath = join(memoryDir, `${today}.md`);\n\n let content = '';\n \n try {\n if (existsSync(logPath)) {\n content = await readFile(logPath, 'utf-8');\n } else {\n content = `# Issue Log: ${today}\\n\\n`;\n }\n } catch {\n content = `# Issue Log: ${today}\\n\\n`;\n }\n\n const time = new Date().toTimeString().split(' ')[0];\n \n const newEntries = issues.map(i => \n `## [${time}] ${i.severity.toUpperCase()}: ${i.issue.slice(0, 80)}${i.issue.length > 80 ? '...' : ''}\\n` +\n `- **File:** \\`${i.file}\\`${i.line ? `:${i.line}` : ''}\\n` +\n `- **Agent:** ${i.agent}\\n` +\n `- **Fix:** ${i.fix.slice(0, 200)}${i.fix.length > 200 ? '...' : ''}\\n`\n ).join('\\n');\n\n content += newEntries + '\\n';\n \n await writeFile(logPath, content);\n}\n\nasync function loadIssueIndex(projectDir: string): Promise<StoredIssue[]> {\n const indexPath = join(projectDir, '.trie', 'memory', 'issues.json');\n \n try {\n if (existsSync(indexPath)) {\n const content = await readFile(indexPath, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // Index doesn't exist or is corrupted\n }\n \n return [];\n}\n\nasync function updateIssueIndex(newIssues: StoredIssue[], projectDir: string): Promise<void> {\n const memoryDir = join(projectDir, '.trie', 'memory');\n const indexPath = join(memoryDir, 'issues.json');\n \n await mkdir(memoryDir, { recursive: true });\n \n let existing = await loadIssueIndex(projectDir);\n \n const hashSet = new Set(existing.map(i => i.hash));\n const toAdd = newIssues.filter(i => !hashSet.has(i.hash));\n \n existing = [...existing, ...toAdd];\n \n // Intelligent compaction: summarize old issues instead of deleting\n if (existing.length > 500) {\n const { summary, remaining } = await compactOldIssues(existing, {\n keepDays: 30,\n minIssuesToCompact: 100,\n });\n \n if (summary) {\n await saveCompactedSummary(summary, projectDir);\n existing = remaining;\n }\n }\n \n // Fallback: prune to 1000 if still too large\n if (existing.length > 1000) {\n existing = existing\n .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())\n .slice(0, 1000);\n }\n \n await saveIssueIndex(existing, projectDir);\n}\n\nasync function saveIssueIndex(issues: StoredIssue[], projectDir: string): Promise<void> {\n const indexPath = join(projectDir, '.trie', 'memory', 'issues.json');\n await writeFile(indexPath, JSON.stringify(issues, null, 2));\n}\n\nfunction hashIssue(issue: Issue): string {\n const content = `${issue.issue}|${issue.file}|${issue.severity}|${issue.agent}`;\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n const char = content.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","/**\n * BM25 Search Implementation\n * \n * BM25 (Best Match 25) is a ranking function used by search engines.\n * It's more sophisticated than TF-IDF and handles term frequency saturation.\n * \n * This is the same algorithm used by Elasticsearch.\n */\n\nexport interface BM25Document {\n id: string;\n text: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface BM25Result {\n id: string;\n score: number;\n metadata?: Record<string, unknown>;\n}\n\nexport class BM25Index {\n private documents: Map<string, BM25Document> = new Map();\n private termFrequencies: Map<string, Map<string, number>> = new Map();\n private documentFrequencies: Map<string, number> = new Map();\n private documentLengths: Map<string, number> = new Map();\n private avgDocLength: number = 0;\n private k1: number = 1.5;\n private b: number = 0.75;\n\n /**\n * Add a document to the index\n */\n addDocument(doc: BM25Document): void {\n const tokens = this.tokenize(doc.text);\n this.documents.set(doc.id, doc);\n this.documentLengths.set(doc.id, tokens.length);\n\n const termFreq = new Map<string, number>();\n const seenTerms = new Set<string>();\n\n for (const token of tokens) {\n termFreq.set(token, (termFreq.get(token) || 0) + 1);\n \n if (!seenTerms.has(token)) {\n seenTerms.add(token);\n this.documentFrequencies.set(token, (this.documentFrequencies.get(token) || 0) + 1);\n }\n }\n\n this.termFrequencies.set(doc.id, termFreq);\n this.updateAvgDocLength();\n }\n\n /**\n * Add multiple documents\n */\n addDocuments(docs: BM25Document[]): void {\n for (const doc of docs) {\n this.addDocument(doc);\n }\n }\n\n /**\n * Search the index\n */\n search(query: string, limit: number = 10): BM25Result[] {\n const queryTokens = this.tokenize(query);\n const scores: Map<string, number> = new Map();\n const N = this.documents.size;\n\n for (const [docId] of this.documents) {\n let score = 0;\n const docLength = this.documentLengths.get(docId) || 0;\n const termFreqs = this.termFrequencies.get(docId);\n\n if (!termFreqs) continue;\n\n for (const term of queryTokens) {\n const tf = termFreqs.get(term) || 0;\n if (tf === 0) continue;\n\n const df = this.documentFrequencies.get(term) || 0;\n const idf = Math.log((N - df + 0.5) / (df + 0.5) + 1);\n\n const numerator = tf * (this.k1 + 1);\n const denominator = tf + this.k1 * (1 - this.b + this.b * (docLength / this.avgDocLength));\n \n score += idf * (numerator / denominator);\n }\n\n if (score > 0) {\n scores.set(docId, score);\n }\n }\n\n return Array.from(scores.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, limit)\n .map(([id, score]) => ({\n id,\n score,\n metadata: this.documents.get(id)?.metadata,\n }));\n }\n\n /**\n * Get document count\n */\n get size(): number {\n return this.documents.size;\n }\n\n /**\n * Clear the index\n */\n clear(): void {\n this.documents.clear();\n this.termFrequencies.clear();\n this.documentFrequencies.clear();\n this.documentLengths.clear();\n this.avgDocLength = 0;\n }\n\n /**\n * Serialize the index to JSON\n */\n serialize(): string {\n return JSON.stringify({\n documents: Array.from(this.documents.entries()),\n termFrequencies: Array.from(this.termFrequencies.entries()).map(([k, v]) => [k, Array.from(v.entries())]),\n documentFrequencies: Array.from(this.documentFrequencies.entries()),\n documentLengths: Array.from(this.documentLengths.entries()),\n avgDocLength: this.avgDocLength,\n });\n }\n\n /**\n * Load from serialized JSON\n */\n static deserialize(json: string): BM25Index {\n const data = JSON.parse(json);\n const index = new BM25Index();\n \n index.documents = new Map(data.documents);\n index.termFrequencies = new Map(data.termFrequencies.map(([k, v]: [string, [string, number][]]) => [k, new Map(v)]));\n index.documentFrequencies = new Map(data.documentFrequencies);\n index.documentLengths = new Map(data.documentLengths);\n index.avgDocLength = data.avgDocLength;\n \n return index;\n }\n\n private tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s]/g, ' ')\n .split(/\\s+/)\n .filter(token => token.length > 2 && !this.isStopWord(token));\n }\n\n private isStopWord(word: string): boolean {\n const stopWords = new Set([\n 'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have', 'i',\n 'it', 'for', 'not', 'on', 'with', 'he', 'as', 'you', 'do', 'at',\n 'this', 'but', 'his', 'by', 'from', 'they', 'we', 'say', 'her', 'she',\n 'or', 'an', 'will', 'my', 'one', 'all', 'would', 'there', 'their', 'what',\n 'so', 'up', 'out', 'if', 'about', 'who', 'get', 'which', 'go', 'me',\n 'when', 'make', 'can', 'like', 'time', 'no', 'just', 'him', 'know', 'take',\n 'into', 'year', 'your', 'some', 'could', 'them', 'see', 'other', 'than', 'then',\n 'now', 'look', 'only', 'come', 'its', 'over', 'also', 'back', 'after', 'use',\n 'two', 'how', 'our', 'first', 'way', 'even', 'new', 'want', 'because', 'any',\n 'these', 'give', 'day', 'most', 'us', 'should', 'been', 'has', 'was', 'are',\n ]);\n return stopWords.has(word);\n }\n\n private updateAvgDocLength(): void {\n if (this.documentLengths.size === 0) {\n this.avgDocLength = 0;\n return;\n }\n const total = Array.from(this.documentLengths.values()).reduce((a, b) => a + b, 0);\n this.avgDocLength = total / this.documentLengths.size;\n }\n}\n","/**\n * Memory Compactor\n * \n * Intelligently compacts old issues into summaries instead of deleting them.\n * Preserves patterns and insights while reducing storage.\n */\n\nimport { mkdir, writeFile, readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { StoredIssue } from './issue-store.js';\n\nexport interface CompactedSummary {\n period: string;\n startDate: string;\n endDate: string;\n totalIssues: number;\n resolvedCount: number;\n bySeverity: Record<string, number>;\n byAgent: Record<string, number>;\n topPatterns: PatternSummary[];\n hotFiles: { file: string; count: number }[];\n compactedAt: string;\n}\n\nexport interface PatternSummary {\n pattern: string;\n count: number;\n severity: string;\n agent: string;\n exampleFix: string;\n}\n\n/**\n * Compact old issues into summaries\n * Returns the compacted summary and the remaining (recent) issues\n */\nexport async function compactOldIssues(\n issues: StoredIssue[],\n options: {\n keepDays?: number;\n minIssuesToCompact?: number;\n } = {}\n): Promise<{ summary: CompactedSummary | null; remaining: StoredIssue[] }> {\n const keepDays = options.keepDays ?? 30;\n const minIssues = options.minIssuesToCompact ?? 100;\n \n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - keepDays);\n \n const oldIssues = issues.filter(i => new Date(i.timestamp) < cutoffDate);\n const recentIssues = issues.filter(i => new Date(i.timestamp) >= cutoffDate);\n \n // Only compact if we have enough old issues\n if (oldIssues.length < minIssues) {\n return { summary: null, remaining: issues };\n }\n \n // Build summary\n const summary = buildSummary(oldIssues);\n \n return { summary, remaining: recentIssues };\n}\n\n/**\n * Build a summary from a set of issues\n */\nfunction buildSummary(issues: StoredIssue[]): CompactedSummary {\n const sorted = issues.sort((a, b) => \n new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n \n const bySeverity: Record<string, number> = {};\n const byAgent: Record<string, number> = {};\n const patternMap: Map<string, { count: number; issue: StoredIssue }> = new Map();\n const fileCount: Map<string, number> = new Map();\n \n for (const issue of issues) {\n // Count by severity\n bySeverity[issue.severity] = (bySeverity[issue.severity] || 0) + 1;\n \n // Count by agent\n byAgent[issue.agent] = (byAgent[issue.agent] || 0) + 1;\n \n // Track patterns (normalized issue text)\n const patternKey = normalizePattern(issue.issue);\n const existing = patternMap.get(patternKey);\n if (existing) {\n existing.count++;\n } else {\n patternMap.set(patternKey, { count: 1, issue });\n }\n \n // Count files\n const fileName = issue.file.split('/').pop() || issue.file;\n fileCount.set(fileName, (fileCount.get(fileName) || 0) + 1);\n }\n \n // Get top patterns\n const topPatterns = Array.from(patternMap.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, 10)\n .map(([pattern, data]) => ({\n pattern: pattern.slice(0, 100),\n count: data.count,\n severity: data.issue.severity,\n agent: data.issue.agent,\n exampleFix: data.issue.fix.slice(0, 200),\n }));\n \n // Get hot files\n const hotFiles = Array.from(fileCount.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([file, count]) => ({ file, count }));\n \n return {\n period: `${sorted[0]?.timestamp.split('T')[0]} to ${sorted[sorted.length - 1]?.timestamp.split('T')[0]}`,\n startDate: sorted[0]?.timestamp || '',\n endDate: sorted[sorted.length - 1]?.timestamp || '',\n totalIssues: issues.length,\n resolvedCount: issues.filter(i => i.resolved).length,\n bySeverity,\n byAgent,\n topPatterns,\n hotFiles,\n compactedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Normalize issue text for pattern matching\n */\nfunction normalizePattern(text: string): string {\n return text\n .toLowerCase()\n .replace(/`[^`]+`/g, 'CODE')\n .replace(/\\b\\d+\\b/g, 'N')\n .replace(/[\"']/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 150);\n}\n\n/**\n * Save compacted summary to disk\n */\nexport async function saveCompactedSummary(\n summary: CompactedSummary,\n projectDir: string\n): Promise<void> {\n const memoryDir = join(projectDir, '.trie', 'memory');\n await mkdir(memoryDir, { recursive: true });\n \n const summaryPath = join(memoryDir, 'compacted-summaries.json');\n \n let summaries: CompactedSummary[] = [];\n try {\n if (existsSync(summaryPath)) {\n summaries = JSON.parse(await readFile(summaryPath, 'utf-8'));\n }\n } catch {\n summaries = [];\n }\n \n summaries.push(summary);\n \n // Keep only last 12 summaries (1 year of monthly summaries)\n if (summaries.length > 12) {\n summaries = summaries.slice(-12);\n }\n \n await writeFile(summaryPath, JSON.stringify(summaries, null, 2));\n}\n\n/**\n * Load compacted summaries\n */\nexport async function loadCompactedSummaries(projectDir: string): Promise<CompactedSummary[]> {\n const summaryPath = join(projectDir, '.trie', 'memory', 'compacted-summaries.json');\n \n try {\n if (existsSync(summaryPath)) {\n return JSON.parse(await readFile(summaryPath, 'utf-8'));\n }\n } catch {\n // File doesn't exist or is corrupted\n }\n \n return [];\n}\n\n/**\n * Generate a markdown summary of compacted history\n */\nexport function formatCompactedSummary(summary: CompactedSummary): string {\n const lines: string[] = [\n `## Compacted Summary: ${summary.period}`,\n '',\n `**Total Issues:** ${summary.totalIssues} (${summary.resolvedCount} resolved)`,\n '',\n '### By Severity',\n ...Object.entries(summary.bySeverity).map(([s, c]) => `- ${s}: ${c}`),\n '',\n '### Top Patterns',\n ...summary.topPatterns.slice(0, 5).map(p => \n `- **${p.pattern.slice(0, 50)}...** (${p.count}x, ${p.severity})`\n ),\n '',\n '### Hot Files',\n ...summary.hotFiles.slice(0, 5).map(f => `- ${f.file}: ${f.count} issues`),\n ];\n \n return lines.join('\\n');\n}\n\n/**\n * Get insights from compacted history\n */\nexport async function getHistoricalInsights(projectDir: string): Promise<{\n totalHistoricalIssues: number;\n recurringPatterns: PatternSummary[];\n improvementTrend: 'improving' | 'stable' | 'declining' | 'unknown';\n}> {\n const summaries = await loadCompactedSummaries(projectDir);\n \n if (summaries.length === 0) {\n return {\n totalHistoricalIssues: 0,\n recurringPatterns: [],\n improvementTrend: 'unknown',\n };\n }\n \n const totalHistoricalIssues = summaries.reduce((sum, s) => sum + s.totalIssues, 0);\n \n // Find patterns that appear across multiple summaries\n const patternCounts: Map<string, PatternSummary & { appearances: number }> = new Map();\n \n for (const summary of summaries) {\n for (const pattern of summary.topPatterns) {\n const key = pattern.pattern;\n const existing = patternCounts.get(key);\n if (existing) {\n existing.count += pattern.count;\n existing.appearances++;\n } else {\n patternCounts.set(key, { ...pattern, appearances: 1 });\n }\n }\n }\n \n const recurringPatterns = Array.from(patternCounts.values())\n .filter(p => p.appearances >= 2)\n .sort((a, b) => b.count - a.count)\n .slice(0, 5);\n \n // Calculate improvement trend\n let improvementTrend: 'improving' | 'stable' | 'declining' | 'unknown' = 'unknown';\n \n if (summaries.length >= 2) {\n const recent = summaries.slice(-2);\n const olderCount = recent[0]?.totalIssues || 0;\n const newerCount = recent[1]?.totalIssues || 0;\n \n if (newerCount < olderCount * 0.8) {\n improvementTrend = 'improving';\n } else if (newerCount > olderCount * 1.2) {\n improvementTrend = 'declining';\n } else {\n improvementTrend = 'stable';\n }\n }\n \n return {\n totalHistoricalIssues,\n recurringPatterns,\n improvementTrend,\n };\n}\n","/**\n * Cross-Project Memory\n * \n * Stores and retrieves patterns across all projects.\n * Location: ~/.trie/memory/\n */\n\nimport { mkdir, writeFile, readFile, readdir } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport type { Issue } from '../types/index.js';\n\nconst GLOBAL_TRIE_DIR = join(homedir(), '.trie');\nconst GLOBAL_MEMORY_DIR = join(GLOBAL_TRIE_DIR, 'memory');\n\nexport interface GlobalPattern {\n id: string;\n pattern: string;\n description: string;\n severity: string;\n agent: string;\n occurrences: number;\n projects: string[];\n firstSeen: string;\n lastSeen: string;\n fixApplied?: {\n project: string;\n timestamp: string;\n fix: string;\n };\n}\n\nexport interface ProjectSummary {\n name: string;\n path: string;\n lastScan: string;\n healthScore: number;\n totalIssues: number;\n patterns: string[];\n}\n\n/**\n * Record issues to global memory\n */\nexport async function recordToGlobalMemory(\n issues: Issue[],\n projectName: string,\n projectPath: string,\n healthScore: number = 0\n): Promise<void> {\n await mkdir(GLOBAL_MEMORY_DIR, { recursive: true });\n await mkdir(join(GLOBAL_MEMORY_DIR, 'projects'), { recursive: true });\n\n const patterns = await loadGlobalPatterns();\n const now = new Date().toISOString();\n\n for (const issue of issues) {\n const patternId = extractPatternId(issue);\n const existing = patterns.find(p => p.id === patternId);\n\n if (existing) {\n existing.occurrences++;\n existing.lastSeen = now;\n if (!existing.projects.includes(projectName)) {\n existing.projects.push(projectName);\n }\n } else {\n patterns.push({\n id: patternId,\n pattern: issue.issue.slice(0, 200),\n description: issue.fix.slice(0, 200),\n severity: issue.severity,\n agent: issue.agent,\n occurrences: 1,\n projects: [projectName],\n firstSeen: now,\n lastSeen: now,\n });\n }\n }\n\n await saveGlobalPatterns(patterns);\n\n const summaryPath = join(GLOBAL_MEMORY_DIR, 'projects', `${sanitizeName(projectName)}.json`);\n const summary: ProjectSummary = {\n name: projectName,\n path: projectPath,\n lastScan: now,\n healthScore,\n totalIssues: issues.length,\n patterns: [...new Set(issues.map(i => extractPatternId(i)))],\n };\n await writeFile(summaryPath, JSON.stringify(summary, null, 2));\n}\n\n/**\n * Find patterns that appear across multiple projects\n */\nexport async function findCrossProjectPatterns(\n minOccurrences: number = 2\n): Promise<GlobalPattern[]> {\n const patterns = await loadGlobalPatterns();\n return patterns\n .filter(p => p.projects.length >= minOccurrences)\n .sort((a, b) => b.occurrences - a.occurrences);\n}\n\n/**\n * Check if an issue has been fixed in another project\n */\nexport async function findFixFromOtherProjects(\n issue: Issue\n): Promise<GlobalPattern | null> {\n const patterns = await loadGlobalPatterns();\n const patternId = extractPatternId(issue);\n const pattern = patterns.find(p => p.id === patternId);\n\n if (pattern?.fixApplied) {\n return pattern;\n }\n\n return null;\n}\n\n/**\n * Record that a pattern was fixed\n */\nexport async function recordPatternFix(\n issue: Issue,\n projectName: string,\n fix: string\n): Promise<void> {\n const patterns = await loadGlobalPatterns();\n const patternId = extractPatternId(issue);\n const pattern = patterns.find(p => p.id === patternId);\n\n if (pattern && !pattern.fixApplied) {\n pattern.fixApplied = {\n project: projectName,\n timestamp: new Date().toISOString(),\n fix: fix.slice(0, 500),\n };\n await saveGlobalPatterns(patterns);\n }\n}\n\n/**\n * Get all tracked projects\n */\nexport async function listTrackedProjects(): Promise<ProjectSummary[]> {\n const projectsDir = join(GLOBAL_MEMORY_DIR, 'projects');\n \n try {\n if (!existsSync(projectsDir)) return [];\n \n const files = await readdir(projectsDir);\n const summaries: ProjectSummary[] = [];\n \n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const content = await readFile(join(projectsDir, file), 'utf-8');\n summaries.push(JSON.parse(content));\n } catch {\n // Skip invalid files\n }\n }\n \n return summaries.sort((a, b) => \n new Date(b.lastScan).getTime() - new Date(a.lastScan).getTime()\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Get global memory statistics\n */\nexport async function getGlobalMemoryStats(): Promise<{\n totalPatterns: number;\n crossProjectPatterns: number;\n trackedProjects: number;\n totalOccurrences: number;\n fixedPatterns: number;\n patternsByAgent: Record<string, number>;\n}> {\n const patterns = await loadGlobalPatterns();\n const projects = await listTrackedProjects();\n \n // Count patterns by agent type\n const patternsByAgent: Record<string, number> = {};\n for (const pattern of patterns) {\n patternsByAgent[pattern.agent] = (patternsByAgent[pattern.agent] || 0) + 1;\n }\n \n return {\n totalPatterns: patterns.length,\n crossProjectPatterns: patterns.filter(p => p.projects.length >= 2).length,\n trackedProjects: projects.length,\n totalOccurrences: patterns.reduce((sum, p) => sum + p.occurrences, 0),\n fixedPatterns: patterns.filter(p => p.fixApplied).length,\n patternsByAgent,\n };\n}\n\n/**\n * Update GLOBAL_MEMORY.md with current patterns\n */\nexport async function updateGlobalMemoryMd(): Promise<void> {\n const patterns = await loadGlobalPatterns();\n const crossProject = patterns.filter(p => p.projects.length >= 2);\n const projects = await listTrackedProjects();\n\n const lines: string[] = [\n '# Global Trie Memory',\n '',\n '> Auto-generated file tracking patterns across all your projects.',\n `> Last updated: ${new Date().toISOString()}`,\n '',\n '## Summary',\n '',\n `- **Projects tracked:** ${projects.length}`,\n `- **Total patterns:** ${patterns.length}`,\n `- **Cross-project patterns:** ${crossProject.length}`,\n '',\n '## Cross-Project Patterns',\n '',\n 'These issues appear in multiple projects:',\n '',\n ];\n \n for (const p of crossProject.slice(0, 20)) {\n lines.push(\n `### ${p.pattern.slice(0, 60)}${p.pattern.length > 60 ? '...' : ''}`,\n '',\n `- **Severity:** ${p.severity}`,\n `- **Agent:** ${p.agent}`,\n `- **Occurrences:** ${p.occurrences} across ${p.projects.length} projects`,\n `- **Projects:** ${p.projects.slice(0, 5).join(', ')}${p.projects.length > 5 ? '...' : ''}`,\n );\n if (p.fixApplied) {\n lines.push(`- **Fixed in:** ${p.fixApplied.project} on ${p.fixApplied.timestamp.split('T')[0]}`);\n } else {\n lines.push('- **Status:** Not fixed');\n }\n lines.push('');\n }\n\n lines.push(\n '## Tracked Projects',\n '',\n '| Project | Last Scan | Health | Issues |',\n '|---------|-----------|--------|--------|',\n );\n \n for (const p of projects.slice(0, 20)) {\n lines.push(`| ${p.name} | ${p.lastScan.split('T')[0]} | ${p.healthScore}% | ${p.totalIssues} |`);\n }\n\n lines.push('', '---', '', '*This file is auto-generated by Trie. Do not edit manually.*');\n\n await mkdir(GLOBAL_MEMORY_DIR, { recursive: true });\n await writeFile(join(GLOBAL_MEMORY_DIR, 'GLOBAL_MEMORY.md'), lines.join('\\n'));\n}\n\n/**\n * Search global patterns\n */\nexport async function searchGlobalPatterns(\n query: string,\n options: {\n limit?: number;\n severity?: string[];\n agent?: string;\n } = {}\n): Promise<GlobalPattern[]> {\n const patterns = await loadGlobalPatterns();\n const limit = options.limit || 10;\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(t => t.length > 2);\n \n const scored = patterns\n .filter(p => {\n if (options.severity && !options.severity.includes(p.severity)) return false;\n if (options.agent && p.agent !== options.agent) return false;\n return true;\n })\n .map(p => {\n const text = `${p.pattern} ${p.description} ${p.agent}`.toLowerCase();\n let score = 0;\n for (const term of queryTerms) {\n if (text.includes(term)) score++;\n }\n return { pattern: p, score };\n })\n .filter(s => s.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n \n return scored.map(s => s.pattern);\n}\n\n// Private helpers\n\nasync function loadGlobalPatterns(): Promise<GlobalPattern[]> {\n const patternsPath = join(GLOBAL_MEMORY_DIR, 'global-patterns.json');\n \n try {\n if (existsSync(patternsPath)) {\n const content = await readFile(patternsPath, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // File doesn't exist or is corrupted\n }\n \n return [];\n}\n\nasync function saveGlobalPatterns(patterns: GlobalPattern[]): Promise<void> {\n await mkdir(GLOBAL_MEMORY_DIR, { recursive: true });\n const patternsPath = join(GLOBAL_MEMORY_DIR, 'global-patterns.json');\n \n const pruned = patterns\n .sort((a, b) => new Date(b.lastSeen).getTime() - new Date(a.lastSeen).getTime())\n .slice(0, 500);\n \n await writeFile(patternsPath, JSON.stringify(pruned, null, 2));\n}\n\nfunction extractPatternId(issue: Issue): string {\n const normalized = issue.issue\n .toLowerCase()\n .replace(/`[^`]+`/g, 'CODE')\n .replace(/\\b\\d+\\b/g, 'N')\n .replace(/['\"]/g, '')\n .slice(0, 100);\n \n let hash = 0;\n for (let i = 0; i < normalized.length; i++) {\n const char = normalized.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n \n return `${issue.agent}-${issue.severity}-${Math.abs(hash).toString(36)}`;\n}\n\nfunction sanitizeName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase();\n}\n","/**\n * Context State Manager\n * \n * Manages the .trie/AGENTS.md file that provides context to AI coding assistants.\n * Updates automatically when agents run to keep context current.\n * Also integrates with issue memory and cross-project tracking.\n */\n\nimport { readFile, writeFile, mkdir } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join, basename } from 'path';\nimport { getWorkingDirectory } from './workspace.js';\nimport type { AgentResult } from '../types/index.js';\nimport type { SkillRecord } from '../types/external-skill.js';\nimport { loadProjectInfo, projectInfoExists } from './project-info.js';\nimport { storeIssues } from '../memory/issue-store.js';\nimport { recordToGlobalMemory, updateGlobalMemoryMd } from '../memory/global-memory.js';\n\nexport interface ScanSummary {\n timestamp: string;\n agents: string[];\n filesScanned: number;\n issues: {\n critical: number;\n serious: number;\n moderate: number;\n low: number;\n total: number;\n };\n duration: number;\n hotFiles: Array<{ file: string; issueCount: number }>;\n}\n\nexport interface ContextState {\n lastScan: ScanSummary | null;\n healthScore: number;\n activePriorities: string[];\n contextSignals: Record<string, boolean>;\n agentStatus: Record<string, {\n lastRun: string | null;\n issuesFound: number;\n skillsApplied?: string[];\n }>;\n scanHistory: ScanSummary[];\n customAgents: string[];\n skills: Record<string, SkillRecord>;\n environment?: string;\n}\n\nconst AGENTS_MD_PATH = '.trie/AGENTS.md';\nconst STATE_JSON_PATH = '.trie/state.json';\n\n/**\n * Load current context state\n */\nexport async function loadContextState(): Promise<ContextState> {\n const workDir = getWorkingDirectory(undefined, true);\n const statePath = join(workDir, STATE_JSON_PATH);\n const defaults = getDefaultState();\n \n try {\n if (existsSync(statePath)) {\n const content = await readFile(statePath, 'utf-8');\n const loaded = JSON.parse(content);\n // Merge with defaults to ensure new fields exist\n return {\n ...defaults,\n ...loaded,\n skills: loaded.skills || defaults.skills,\n };\n }\n } catch {\n // Return default state\n }\n \n return defaults;\n}\n\n/**\n * Save context state\n */\nexport async function saveContextState(state: ContextState): Promise<void> {\n const workDir = getWorkingDirectory(undefined, true);\n const trieDir = join(workDir, '.trie');\n const statePath = join(workDir, STATE_JSON_PATH);\n \n // Ensure directory exists\n await mkdir(trieDir, { recursive: true });\n \n await writeFile(statePath, JSON.stringify(state, null, 2));\n}\n\n/**\n * Update context state after a scan\n */\nexport async function updateContextAfterScan(\n results: AgentResult[],\n filesScanned: number,\n contextSignals: Record<string, boolean>,\n duration: number\n): Promise<void> {\n const state = await loadContextState();\n const workDir = getWorkingDirectory(undefined, true);\n const now = new Date().toISOString();\n \n // Calculate issue counts\n const allIssues = results.flatMap(r => r.issues);\n const issueCounts = {\n critical: allIssues.filter(i => i.severity === 'critical').length,\n serious: allIssues.filter(i => i.severity === 'serious').length,\n moderate: allIssues.filter(i => i.severity === 'moderate').length,\n low: allIssues.filter(i => i.severity === 'low').length,\n total: allIssues.length,\n };\n \n // Find hot files\n const fileIssueMap = new Map<string, number>();\n for (const issue of allIssues) {\n const count = fileIssueMap.get(issue.file) || 0;\n fileIssueMap.set(issue.file, count + 1);\n }\n const hotFiles = Array.from(fileIssueMap.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([file, issueCount]) => ({ file, issueCount }));\n \n // Create scan summary\n const scanSummary: ScanSummary = {\n timestamp: now,\n agents: results.map(r => r.agent),\n filesScanned,\n issues: issueCounts,\n duration,\n hotFiles,\n };\n \n // Update agent status\n for (const result of results) {\n state.agentStatus[result.agent] = {\n lastRun: now,\n issuesFound: result.issues.length,\n };\n }\n \n // Calculate health score (0-100)\n // Penalize critical issues heavily, serious issues moderately\n const criticalPenalty = issueCounts.critical * 25;\n const seriousPenalty = issueCounts.serious * 10;\n const moderatePenalty = issueCounts.moderate * 3;\n const lowPenalty = issueCounts.low * 1;\n const totalPenalty = Math.min(100, criticalPenalty + seriousPenalty + moderatePenalty + lowPenalty);\n state.healthScore = Math.max(0, 100 - totalPenalty);\n \n // Update priorities based on issues\n state.activePriorities = generatePriorities(issueCounts, contextSignals);\n \n // Update context signals\n state.contextSignals = { ...state.contextSignals, ...contextSignals };\n \n // Update scan history (keep last 20)\n state.scanHistory = [scanSummary, ...state.scanHistory.slice(0, 19)];\n state.lastScan = scanSummary;\n \n // Save state\n await saveContextState(state);\n \n // Update AGENTS.md\n await updateAgentsMd(state);\n \n // Store issues to memory\n if (allIssues.length > 0) {\n const projectName = basename(workDir);\n try {\n await storeIssues(allIssues, projectName, workDir);\n await recordToGlobalMemory(allIssues, projectName, workDir, state.healthScore);\n await updateGlobalMemoryMd();\n } catch {\n // Memory storage is non-critical, don't fail the scan\n }\n }\n}\n\n/**\n * Update the AGENTS.md file with current state\n */\nasync function updateAgentsMd(state: ContextState): Promise<void> {\n const workDir = getWorkingDirectory(undefined, true);\n const mdPath = join(workDir, AGENTS_MD_PATH);\n \n let content: string;\n try {\n content = await readFile(mdPath, 'utf-8');\n } catch {\n // Use template if file doesn't exist\n content = getAgentsMdTemplate();\n }\n \n // Update sections\n content = updateSection(content, 'Project State', generateProjectStateTable(state));\n content = updateSection(content, 'Active Priorities', generatePrioritiesList(state));\n content = updateSection(content, 'Agent Status', generateAgentStatusTable(state));\n content = updateSection(content, 'Recent Scan History', generateScanHistoryTable(state));\n content = updateSection(content, 'Context Signals Detected', generateContextSignals(state));\n content = updateSection(content, 'Risk Assessment', generateRiskAssessment(state));\n content = updateSection(content, 'Hot Files', generateHotFilesSection(state));\n \n // Update last updated timestamp\n content = content.replace(\n /Last updated:.*$/m,\n `Last updated: ${new Date().toISOString()}`\n );\n \n await writeFile(mdPath, content);\n}\n\n/**\n * Update a specific section in the markdown\n */\nfunction updateSection(content: string, sectionName: string, newContent: string): string {\n // Look for the section header and replace content until the next section\n const sectionRegex = new RegExp(\n `(### ${sectionName}[\\\\s\\\\S]*?)(?=###|---|\\n## |$)`,\n 'g'\n );\n \n const replacement = `### ${sectionName}\\n${newContent}\\n\\n`;\n \n if (content.match(sectionRegex)) {\n return content.replace(sectionRegex, replacement);\n }\n \n // Section doesn't exist, don't add it\n return content;\n}\n\n/**\n * Generate the project state table\n */\nfunction generateProjectStateTable(state: ContextState): string {\n const lastScan = state.lastScan;\n const lastScanDate = lastScan ? new Date(lastScan.timestamp).toLocaleString() : 'Never';\n const criticalCount = lastScan?.issues.critical ?? 0;\n const totalTasks = lastScan?.issues.total ?? 0;\n \n return `| Metric | Value | Updated |\n|--------|-------|---------|\n| Last Scan | ${lastScanDate} | ${lastScan ? 'Auto' : '-'} |\n| Critical Issues | ${criticalCount} | ${lastScan ? 'Auto' : '-'} |\n| Open Tasks | ${totalTasks} | ${lastScan ? 'Auto' : '-'} |\n| Health Score | ${state.healthScore}% | ${lastScan ? 'Auto' : '-'} |`;\n}\n\n/**\n * Generate priorities list\n */\nfunction generatePrioritiesList(state: ContextState): string {\n if (state.activePriorities.length === 0) {\n return '_No active priorities. Run a scan to identify issues._';\n }\n \n return state.activePriorities\n .map((p, i) => `${i + 1}. ${p}`)\n .join('\\n');\n}\n\n/**\n * Generate priorities based on scan results\n */\nfunction generatePriorities(\n issues: { critical: number; serious: number; moderate: number; low: number },\n contextSignals: Record<string, boolean>\n): string[] {\n const priorities: string[] = [];\n \n if (issues.critical > 0) {\n priorities.push(`🚨 Fix ${issues.critical} critical security issue${issues.critical > 1 ? 's' : ''} immediately`);\n }\n \n if (issues.serious > 0) {\n priorities.push(`⚠️ Address ${issues.serious} serious issue${issues.serious > 1 ? 's' : ''} before deployment`);\n }\n \n if (contextSignals.touchesAuth && issues.critical === 0) {\n priorities.push('✅ Auth code reviewed - continue monitoring');\n }\n \n if (contextSignals.touchesPayments) {\n priorities.push('💳 Payment code detected - ensure PCI compliance');\n }\n \n if (contextSignals.touchesUserData) {\n priorities.push('🔐 User data handling detected - verify privacy compliance');\n }\n \n if (issues.moderate > 5) {\n priorities.push(`📋 Schedule time to address ${issues.moderate} moderate issues`);\n }\n \n if (priorities.length === 0) {\n priorities.push('✨ No critical issues - focus on feature development');\n }\n \n return priorities.slice(0, 5);\n}\n\n/**\n * Generate agent status table\n */\nfunction generateAgentStatusTable(state: ContextState): string {\n const builtInAgents = [\n 'security', 'privacy', 'legal', 'accessibility', 'bugs',\n 'design', 'architecture', 'performance', 'devops', 'soc2',\n 'e2e', 'typecheck', 'visual-qa', 'data-flow'\n ];\n \n let table = `| Agent | Status | Last Run | Issues Found |\n|-------|--------|----------|--------------|`;\n \n for (const agent of builtInAgents) {\n const status = state.agentStatus[agent];\n const lastRun = status?.lastRun \n ? new Date(status.lastRun).toLocaleDateString()\n : 'Never';\n const issues = status?.issuesFound ?? '-';\n const statusEmoji = status ? '✅' : '⏸️';\n \n table += `\\n| ${agent} | ${statusEmoji} Ready | ${lastRun} | ${issues} |`;\n }\n \n return table;\n}\n\n/**\n * Generate scan history table\n */\nfunction generateScanHistoryTable(state: ContextState): string {\n if (state.scanHistory.length === 0) {\n return `| Date | Agents | Files | Issues | Duration |\n|------|--------|-------|--------|----------|\n| - | - | - | - | - |`;\n }\n \n let table = `| Date | Agents | Files | Issues | Duration |\n|------|--------|-------|--------|----------|`;\n \n for (const scan of state.scanHistory.slice(0, 10)) {\n const date = new Date(scan.timestamp).toLocaleDateString();\n const agents = scan.agents.slice(0, 3).join(', ') + (scan.agents.length > 3 ? '...' : '');\n const duration = `${(scan.duration / 1000).toFixed(1)}s`;\n \n table += `\\n| ${date} | ${agents} | ${scan.filesScanned} | ${scan.issues.total} | ${duration} |`;\n }\n \n return table;\n}\n\n/**\n * Generate context signals section\n */\nfunction generateContextSignals(state: ContextState): string {\n const signals = [\n 'touchesAuth',\n 'touchesPayments', \n 'touchesUserData',\n 'touchesAPI',\n 'touchesDatabase',\n 'touchesCrypto'\n ];\n \n return signals\n .map(s => {\n const value = state.contextSignals[s];\n const emoji = value === true ? '✅' : value === false ? '❌' : '❓';\n return `- \\`${s}\\`: ${emoji} ${value === undefined ? 'Unknown' : value ? 'Yes' : 'No'}`;\n })\n .join('\\n');\n}\n\n/**\n * Generate risk assessment section\n */\nfunction generateRiskAssessment(state: ContextState): string {\n const score = state.healthScore;\n let riskLevel: string;\n let confidence: number;\n \n if (state.lastScan === null) {\n return `- Overall Risk: Unknown\n- Confidence: 0%`;\n }\n \n if (score >= 90) {\n riskLevel = '🟢 Low';\n confidence = 95;\n } else if (score >= 70) {\n riskLevel = '🟡 Medium';\n confidence = 85;\n } else if (score >= 50) {\n riskLevel = '🟠 High';\n confidence = 80;\n } else {\n riskLevel = '🔴 Critical';\n confidence = 90;\n }\n \n return `- Overall Risk: ${riskLevel}\n- Health Score: ${score}%\n- Confidence: ${confidence}%`;\n}\n\n/**\n * Generate hot files section\n */\nfunction generateHotFilesSection(state: ContextState): string {\n if (!state.lastScan || state.lastScan.hotFiles.length === 0) {\n return '_Run a scan to identify hot files._';\n }\n \n return state.lastScan.hotFiles\n .map(f => `- \\`${f.file}\\` - ${f.issueCount} issue${f.issueCount > 1 ? 's' : ''}`)\n .join('\\n');\n}\n\n/**\n * Get default state\n */\nfunction getDefaultState(): ContextState {\n return {\n lastScan: null,\n healthScore: 0,\n activePriorities: [\n 'Initial setup required - run first scan with `trie scan`',\n 'Configure agents in `.trie/config.json`',\n 'Set up CI/CD integration'\n ],\n contextSignals: {},\n agentStatus: {},\n scanHistory: [],\n customAgents: [],\n skills: {},\n environment: detectEnvironment(),\n };\n}\n\n/**\n * Detect the current execution environment\n */\nexport function detectEnvironment(): string {\n if (process.env.GITHUB_ACTIONS) return 'github-actions';\n if (process.env.GITLAB_CI) return 'gitlab-ci';\n if (process.env.CI) return 'ci';\n const parent = process.env._ || '';\n if (parent.includes('cursor')) return 'cursor';\n if (parent.includes('claude')) return 'claude-code';\n return 'cli';\n}\n\n/**\n * Record skill installation in context state\n */\nexport async function recordSkillInstalled(params: {\n name: string;\n source: string;\n}): Promise<void> {\n const state = await loadContextState();\n state.skills[params.name] = {\n source: params.source,\n installedAt: new Date().toISOString(),\n timesApplied: 0,\n appliedBy: [],\n };\n await saveContextState(state);\n}\n\n/**\n * Record skill usage by an agent\n */\nexport async function recordSkillUsage(params: {\n skillNames: string[];\n agentName: string;\n}): Promise<void> {\n const state = await loadContextState();\n const now = new Date().toISOString();\n \n for (const skillName of params.skillNames) {\n const skillRecord = state.skills[skillName];\n if (skillRecord) {\n skillRecord.timesApplied++;\n skillRecord.lastApplied = now;\n if (!skillRecord.appliedBy.includes(params.agentName)) {\n skillRecord.appliedBy.push(params.agentName);\n }\n }\n }\n \n const agentStatus = state.agentStatus[params.agentName];\n if (agentStatus) {\n agentStatus.skillsApplied = params.skillNames;\n }\n \n await saveContextState(state);\n}\n\n/**\n * Get the AGENTS.md template\n */\nfunction getAgentsMdTemplate(): string {\n return `# Trie Agent Context\n\n> **Auto-generated file** - Updated automatically when agents run.\n> Last updated: Never (initial state)\n\nThis file provides prioritized context for all AI coding assistants working with this codebase.\nAgents should read this file first and update it after completing scans.\n\n---\n\n## Quick Context (Read First)\n\n### Project State\n| Metric | Value | Updated |\n|--------|-------|---------|\n| Last Scan | Never | - |\n| Critical Issues | 0 | - |\n| Open Tasks | 0 | - |\n| Health Score | Unknown | - |\n\n### Active Priorities\n1. Initial setup required - run first scan with \\`trie scan\\`\n2. Configure agents in \\`.trie/config.json\\`\n3. Set up CI/CD integration\n\n### Hot Files\n_Run a scan to identify hot files._\n\n---\n\n## Agent Status\n\n### Agent Status\n| Agent | Status | Last Run | Issues Found |\n|-------|--------|----------|--------------|\n| security | Ready | Never | - |\n| privacy | Ready | Never | - |\n| bugs | Ready | Never | - |\n\n### Recent Scan History\n| Date | Agents | Files | Issues | Duration |\n|------|--------|-------|--------|----------|\n| - | - | - | - | - |\n\n---\n\n## Context Analysis\n\n### Context Signals Detected\n- \\`touchesAuth\\`: Unknown\n- \\`touchesPayments\\`: Unknown\n- \\`touchesUserData\\`: Unknown\n- \\`touchesAPI\\`: Unknown\n- \\`touchesDatabase\\`: Unknown\n- \\`touchesCrypto\\`: Unknown\n\n### Risk Assessment\n- Overall Risk: Unknown\n- Confidence: 0%\n\n---\n\n*This file is maintained by Trie agents. Manual edits will be preserved in non-auto sections.*\n`;\n}\n\n/**\n * Add custom skill to context state\n */\nexport async function addCustomAgentToContext(agentName: string): Promise<void> {\n const state = await loadContextState();\n \n if (!state.customAgents.includes(agentName)) {\n state.customAgents.push(agentName);\n await saveContextState(state);\n }\n}\n\n/**\n * Get context state for AI assistants (formatted summary)\n */\nexport async function getContextForAI(): Promise<string> {\n const state = await loadContextState();\n const workDir = getWorkingDirectory(undefined, true);\n \n const lines: string[] = [];\n \n // Include PROJECT.md content first (user-defined context takes priority)\n if (projectInfoExists(workDir)) {\n const projectInfo = await loadProjectInfo(workDir);\n if (projectInfo) {\n lines.push(projectInfo);\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n }\n \n // Add Trie scan context\n lines.push(\n '## Trie Scan Context',\n '',\n `**Health Score:** ${state.healthScore}%`,\n `**Last Scan:** ${state.lastScan ? new Date(state.lastScan.timestamp).toLocaleString() : 'Never'}`,\n '',\n '**Active Priorities:**',\n ...state.activePriorities.map(p => `- ${p}`),\n ''\n );\n \n if (state.lastScan) {\n lines.push(\n '**Recent Issues:**',\n `- Critical: ${state.lastScan.issues.critical}`,\n `- Serious: ${state.lastScan.issues.serious}`,\n `- Moderate: ${state.lastScan.issues.moderate}`,\n `- Low: ${state.lastScan.issues.low}`,\n ''\n );\n \n if (state.lastScan.hotFiles.length > 0) {\n lines.push(\n '**Hot Files (most issues):**',\n ...state.lastScan.hotFiles.slice(0, 5).map(f => `- ${f.file}: ${f.issueCount} issues`),\n ''\n );\n }\n }\n \n return lines.join('\\n');\n}\n"],"mappings":"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","names":["mkdir","writeFile","readFile","join","readFile","join","join","mkdir","writeFile","readFile","mkdir","writeFile","readFile","readdir","existsSync","join","mkdir","writeFile","readFile","existsSync","join","join","mkdir","existsSync","readdir","readFile","writeFile","mkdir","writeFile","readFile","readdir","existsSync","join","join","existsSync","readdir","readFile","mkdir","writeFile","readFile","writeFile","mkdir","existsSync","join","join","existsSync","readFile","mkdir","writeFile"]}
@@ -2,7 +2,7 @@ import {
2
2
  listInstalledSkills,
3
3
  parseSkillMd,
4
4
  recordSkillUsage
5
- } from "./chunk-52SSNKXS.js";
5
+ } from "./chunk-PZDQIFKO.js";
6
6
  import {
7
7
  checkFileLevelIssues,
8
8
  getVibeCodeTrie,
@@ -8491,6 +8491,118 @@ Output STRICT JSON:
8491
8491
  }
8492
8492
  };
8493
8493
 
8494
+ // src/skills/gating.ts
8495
+ import { existsSync as existsSync2 } from "fs";
8496
+ import { readFile } from "fs/promises";
8497
+ import { join } from "path";
8498
+ import { execSync } from "child_process";
8499
+ async function checkSkillRequirements(frontmatter, projectDir) {
8500
+ const result = { allowed: true };
8501
+ if (frontmatter.requires && frontmatter.requires.length > 0) {
8502
+ const projectDeps = await getProjectDependencies(projectDir);
8503
+ const missing = frontmatter.requires.filter((dep) => !projectDeps.has(dep));
8504
+ if (missing.length > 0) {
8505
+ result.allowed = false;
8506
+ result.missingDeps = missing;
8507
+ result.reason = `Missing dependencies: ${missing.join(", ")}`;
8508
+ return result;
8509
+ }
8510
+ }
8511
+ const reqs = frontmatter.requirements;
8512
+ if (!reqs) {
8513
+ return result;
8514
+ }
8515
+ if (reqs.deps && reqs.deps.length > 0) {
8516
+ const projectDeps = await getProjectDependencies(projectDir);
8517
+ const missing = reqs.deps.filter((dep) => !projectDeps.has(dep));
8518
+ if (missing.length > 0) {
8519
+ result.allowed = false;
8520
+ result.missingDeps = missing;
8521
+ result.reason = `Missing dependencies: ${missing.join(", ")}`;
8522
+ return result;
8523
+ }
8524
+ }
8525
+ if (reqs.anyDeps && reqs.anyDeps.length > 0) {
8526
+ const projectDeps = await getProjectDependencies(projectDir);
8527
+ const hasAny = reqs.anyDeps.some((dep) => projectDeps.has(dep));
8528
+ if (!hasAny) {
8529
+ result.allowed = false;
8530
+ result.missingDeps = reqs.anyDeps;
8531
+ result.reason = `Requires at least one of: ${reqs.anyDeps.join(", ")}`;
8532
+ return result;
8533
+ }
8534
+ }
8535
+ if (reqs.env && reqs.env.length > 0) {
8536
+ const missing = reqs.env.filter((envVar) => !process.env[envVar]);
8537
+ if (missing.length > 0) {
8538
+ result.allowed = false;
8539
+ result.missingEnv = missing;
8540
+ result.reason = `Missing environment variables: ${missing.join(", ")}`;
8541
+ return result;
8542
+ }
8543
+ }
8544
+ if (reqs.bins && reqs.bins.length > 0) {
8545
+ const missing = reqs.bins.filter((bin) => !isBinaryAvailable(bin));
8546
+ if (missing.length > 0) {
8547
+ result.allowed = false;
8548
+ result.missingBins = missing;
8549
+ result.reason = `Missing binaries: ${missing.join(", ")}`;
8550
+ return result;
8551
+ }
8552
+ }
8553
+ if (reqs.configFiles && reqs.configFiles.length > 0) {
8554
+ const missing = reqs.configFiles.filter((file) => !existsSync2(join(projectDir, file)));
8555
+ if (missing.length > 0) {
8556
+ result.allowed = false;
8557
+ result.missingConfigs = missing;
8558
+ result.reason = `Missing config files: ${missing.join(", ")}`;
8559
+ return result;
8560
+ }
8561
+ }
8562
+ return result;
8563
+ }
8564
+ async function getProjectDependencies(projectDir) {
8565
+ try {
8566
+ const pkgPath = join(projectDir, "package.json");
8567
+ if (!existsSync2(pkgPath)) {
8568
+ return /* @__PURE__ */ new Set();
8569
+ }
8570
+ const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
8571
+ return /* @__PURE__ */ new Set([
8572
+ ...Object.keys(pkg.dependencies || {}),
8573
+ ...Object.keys(pkg.devDependencies || {})
8574
+ ]);
8575
+ } catch {
8576
+ return /* @__PURE__ */ new Set();
8577
+ }
8578
+ }
8579
+ function isBinaryAvailable(binary) {
8580
+ try {
8581
+ const command = process.platform === "win32" ? `where ${binary}` : `which ${binary}`;
8582
+ execSync(command, { stdio: "ignore" });
8583
+ return true;
8584
+ } catch {
8585
+ return false;
8586
+ }
8587
+ }
8588
+ function formatGatingReason(result) {
8589
+ if (result.allowed) return "Allowed";
8590
+ const parts = [];
8591
+ if (result.missingDeps?.length) {
8592
+ parts.push(`deps: ${result.missingDeps.join(", ")}`);
8593
+ }
8594
+ if (result.missingEnv?.length) {
8595
+ parts.push(`env: ${result.missingEnv.join(", ")}`);
8596
+ }
8597
+ if (result.missingBins?.length) {
8598
+ parts.push(`bins: ${result.missingBins.join(", ")}`);
8599
+ }
8600
+ if (result.missingConfigs?.length) {
8601
+ parts.push(`configs: ${result.missingConfigs.join(", ")}`);
8602
+ }
8603
+ return `Missing: ${parts.join("; ")}`;
8604
+ }
8605
+
8494
8606
  // src/agents/skill-review.ts
8495
8607
  var SkillReviewAgent = class extends BaseAgent {
8496
8608
  name = "skill-review";
@@ -8498,6 +8610,7 @@ var SkillReviewAgent = class extends BaseAgent {
8498
8610
  version = "1.0.0";
8499
8611
  skills = [];
8500
8612
  loadedSkillContent = /* @__PURE__ */ new Map();
8613
+ filteredSkills = /* @__PURE__ */ new Map();
8501
8614
  get priority() {
8502
8615
  return {
8503
8616
  name: this.name,
@@ -8523,19 +8636,49 @@ var SkillReviewAgent = class extends BaseAgent {
8523
8636
  return Math.min(1, confidence);
8524
8637
  }
8525
8638
  /**
8526
- * Load installed skills before scanning
8639
+ * Load installed skills with gating based on requirements
8640
+ * Checks: dependencies, env vars, binaries, and config files
8527
8641
  */
8528
8642
  async loadSkills() {
8529
- this.skills = await listInstalledSkills();
8643
+ const allSkills = await listInstalledSkills();
8644
+ const workDir = getWorkingDirectory(void 0, true);
8645
+ this.skills = [];
8530
8646
  this.loadedSkillContent.clear();
8531
- for (const skill of this.skills) {
8647
+ this.filteredSkills.clear();
8648
+ for (const skill of allSkills) {
8532
8649
  try {
8533
8650
  const parsed = await parseSkillMd(skill.path);
8534
- this.loadedSkillContent.set(skill.name, parsed);
8651
+ const gatingResult = await checkSkillRequirements(parsed.frontmatter, workDir);
8652
+ if (gatingResult.allowed) {
8653
+ this.skills.push(skill);
8654
+ this.loadedSkillContent.set(skill.name, parsed);
8655
+ } else {
8656
+ this.filteredSkills.set(skill.name, gatingResult);
8657
+ }
8535
8658
  } catch {
8536
8659
  }
8537
8660
  }
8538
8661
  }
8662
+ /**
8663
+ * Get skills that were filtered out with reasons
8664
+ */
8665
+ getFilteredSkills() {
8666
+ return this.filteredSkills;
8667
+ }
8668
+ /**
8669
+ * Get filtered skill names (for backwards compatibility)
8670
+ */
8671
+ getFilteredSkillNames() {
8672
+ return Array.from(this.filteredSkills.keys());
8673
+ }
8674
+ /**
8675
+ * Get a summary of why skills were filtered
8676
+ */
8677
+ getFilteredSkillsSummary() {
8678
+ return Array.from(this.filteredSkills.entries()).map(
8679
+ ([name, result]) => `${name}: ${formatGatingReason(result)}`
8680
+ );
8681
+ }
8539
8682
  /**
8540
8683
  * Get names of skills this agent will apply
8541
8684
  */
@@ -8667,8 +8810,8 @@ ${parsed.rawContent}`);
8667
8810
  }
8668
8811
  };
8669
8812
 
8670
- // src/agents/custom-agent.ts
8671
- var CustomAgent = class extends BaseAgent {
8813
+ // src/agents/custom-skill.ts
8814
+ var CustomSkill = class extends BaseAgent {
8672
8815
  name;
8673
8816
  description;
8674
8817
  version;
@@ -8689,7 +8832,7 @@ var CustomAgent = class extends BaseAgent {
8689
8832
  };
8690
8833
  }
8691
8834
  /**
8692
- * Check if agent should activate based on code context
8835
+ * Check if skill should activate based on code context
8693
8836
  */
8694
8837
  shouldActivate(context) {
8695
8838
  const rules = this.config.activationRules;
@@ -8862,7 +9005,7 @@ var CustomAgent = class extends BaseAgent {
8862
9005
  return this.config.fixPrompt;
8863
9006
  }
8864
9007
  /**
8865
- * Get agent metadata
9008
+ * Get skill metadata
8866
9009
  */
8867
9010
  getMetadata() {
8868
9011
  return {
@@ -8875,8 +9018,8 @@ var CustomAgent = class extends BaseAgent {
8875
9018
  };
8876
9019
 
8877
9020
  // src/agents/registry.ts
8878
- import { readdir, readFile } from "fs/promises";
8879
- import { join } from "path";
9021
+ import { readdir, readFile as readFile2 } from "fs/promises";
9022
+ import { join as join2 } from "path";
8880
9023
  var AgentRegistryImpl = class {
8881
9024
  agents = /* @__PURE__ */ new Map();
8882
9025
  customAgentsLoaded = false;
@@ -8924,29 +9067,29 @@ var AgentRegistryImpl = class {
8924
9067
  }
8925
9068
  }
8926
9069
  /**
8927
- * Load custom agents from .trie/agents/ directory
9070
+ * Load custom skills from .trie/agents/ directory
8928
9071
  */
8929
- async loadCustomAgents() {
9072
+ async loadCustomSkills() {
8930
9073
  if (this.customAgentsLoaded) return;
8931
9074
  try {
8932
- const agentsDir = join(getWorkingDirectory(void 0, true), ".trie", "agents");
8933
- const files = await readdir(agentsDir);
9075
+ const skillsDir = join2(getWorkingDirectory(void 0, true), ".trie", "agents");
9076
+ const files = await readdir(skillsDir);
8934
9077
  const jsonFiles = files.filter((f) => f.endsWith(".json"));
8935
9078
  let loadedCount = 0;
8936
9079
  for (const file of jsonFiles) {
8937
9080
  try {
8938
- const configPath = join(agentsDir, file);
8939
- const content = await readFile(configPath, "utf-8");
9081
+ const configPath = join2(skillsDir, file);
9082
+ const content = await readFile2(configPath, "utf-8");
8940
9083
  const config = JSON.parse(content);
8941
- const agent = new CustomAgent(config);
8942
- this.agents.set(agent.name, agent);
9084
+ const skill = new CustomSkill(config);
9085
+ this.agents.set(skill.name, skill);
8943
9086
  loadedCount++;
8944
9087
  } catch (error) {
8945
- console.error(`Failed to load custom agent from ${file}:`, error);
9088
+ console.error(`Failed to load custom skill from ${file}:`, error);
8946
9089
  }
8947
9090
  }
8948
9091
  if (loadedCount > 0) {
8949
- console.error(`Loaded ${loadedCount} custom agent(s) from .trie/agents/`);
9092
+ console.error(`Loaded ${loadedCount} custom skill(s) from .trie/agents/`);
8950
9093
  }
8951
9094
  this.customAgentsLoaded = true;
8952
9095
  } catch (error) {
@@ -8954,6 +9097,10 @@ var AgentRegistryImpl = class {
8954
9097
  }
8955
9098
  await this.loadSkillsForAgent();
8956
9099
  }
9100
+ // Backward compatibility alias
9101
+ async loadCustomAgents() {
9102
+ return this.loadCustomSkills();
9103
+ }
8957
9104
  /**
8958
9105
  * Load installed skills for the SkillReviewAgent
8959
9106
  */
@@ -8967,16 +9114,20 @@ var AgentRegistryImpl = class {
8967
9114
  }
8968
9115
  }
8969
9116
  /**
8970
- * Reload custom agents (useful after creating new ones)
9117
+ * Reload custom skills (useful after creating new ones)
8971
9118
  */
8972
- async reloadCustomAgents() {
9119
+ async reloadCustomSkills() {
8973
9120
  for (const [name, agent] of this.agents.entries()) {
8974
- if (agent instanceof CustomAgent) {
9121
+ if (agent instanceof CustomSkill) {
8975
9122
  this.agents.delete(name);
8976
9123
  }
8977
9124
  }
8978
9125
  this.customAgentsLoaded = false;
8979
- await this.loadCustomAgents();
9126
+ await this.loadCustomSkills();
9127
+ }
9128
+ // Backward compatibility alias
9129
+ async reloadCustomAgents() {
9130
+ return this.reloadCustomSkills();
8980
9131
  }
8981
9132
  getAgent(name) {
8982
9133
  return this.agents.get(name);
@@ -8992,20 +9143,24 @@ var AgentRegistryImpl = class {
8992
9143
  */
8993
9144
  getBuiltinAgents() {
8994
9145
  return Array.from(this.agents.values()).filter(
8995
- (agent) => !(agent instanceof CustomAgent)
9146
+ (agent) => !(agent instanceof CustomSkill)
8996
9147
  );
8997
9148
  }
8998
9149
  /**
8999
- * Get only custom agents
9150
+ * Get only custom skills
9000
9151
  */
9001
- getCustomAgents() {
9152
+ getCustomSkills() {
9002
9153
  return Array.from(this.agents.values()).filter(
9003
- (agent) => agent instanceof CustomAgent
9154
+ (agent) => agent instanceof CustomSkill
9004
9155
  );
9005
9156
  }
9157
+ // Backward compatibility alias
9158
+ getCustomAgents() {
9159
+ return this.getCustomSkills();
9160
+ }
9006
9161
  registerAgent(agent) {
9007
9162
  this.agents.set(agent.name, agent);
9008
- console.error(`Registered custom agent: ${agent.name}`);
9163
+ console.error(`Registered custom skill: ${agent.name}`);
9009
9164
  }
9010
9165
  /**
9011
9166
  * Unregister an agent by name
@@ -9020,26 +9175,34 @@ var AgentRegistryImpl = class {
9020
9175
  return Array.from(this.agents.values()).map((agent) => ({
9021
9176
  name: agent.name,
9022
9177
  description: agent.description,
9023
- isCustom: agent instanceof CustomAgent
9178
+ isCustom: agent instanceof CustomSkill
9024
9179
  }));
9025
9180
  }
9026
9181
  /**
9027
- * Check if an agent is a custom agent
9182
+ * Check if an agent is a custom skill
9028
9183
  */
9029
- isCustomAgent(name) {
9184
+ isCustomSkill(name) {
9030
9185
  const agent = this.agents.get(name);
9031
- return agent instanceof CustomAgent;
9186
+ return agent instanceof CustomSkill;
9187
+ }
9188
+ // Backward compatibility alias
9189
+ isCustomAgent(name) {
9190
+ return this.isCustomSkill(name);
9032
9191
  }
9033
9192
  /**
9034
- * Get custom agent metadata
9193
+ * Get custom skill metadata
9035
9194
  */
9036
- getCustomAgentMetadata(name) {
9195
+ getCustomSkillMetadata(name) {
9037
9196
  const agent = this.agents.get(name);
9038
- if (agent instanceof CustomAgent) {
9197
+ if (agent instanceof CustomSkill) {
9039
9198
  return agent.getMetadata();
9040
9199
  }
9041
9200
  return null;
9042
9201
  }
9202
+ // Backward compatibility alias
9203
+ getCustomAgentMetadata(name) {
9204
+ return this.getCustomSkillMetadata(name);
9205
+ }
9043
9206
  };
9044
9207
  var SINGLETON_KEY = "__TRIE_AGENT_REGISTRY__";
9045
9208
  function getAgentRegistry() {
@@ -9053,7 +9216,7 @@ function getAgentRegistry() {
9053
9216
  export {
9054
9217
  SuperReviewerAgent,
9055
9218
  CRITICAL_REVIEW_CHECKLIST,
9056
- CustomAgent,
9219
+ CustomSkill,
9057
9220
  getAgentRegistry
9058
9221
  };
9059
- //# sourceMappingURL=chunk-GBGONSOR.js.map
9222
+ //# sourceMappingURL=chunk-R5HWHP5N.js.map