@triedotdev/mcp 1.0.68 → 1.0.70
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.
- package/README.md +14 -0
- package/dist/{chunk-HWJJIAR7.js → chunk-BHIKY5PW.js} +13 -2
- package/dist/chunk-BHIKY5PW.js.map +1 -0
- package/dist/{chunk-O7WFJC2P.js → chunk-COXK23KW.js} +11 -6
- package/dist/chunk-COXK23KW.js.map +1 -0
- package/dist/{chunk-CMZTFDNC.js → chunk-LWT7XFDD.js} +6 -6
- package/dist/chunk-LWT7XFDD.js.map +1 -0
- package/dist/{chunk-IF2KTITI.js → chunk-OAICCSDL.js} +334 -42
- package/dist/chunk-OAICCSDL.js.map +1 -0
- package/dist/cli/main.js +14 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +4 -4
- package/dist/{goal-manager-B673YUZF.js → goal-manager-5FLR7IS2.js} +3 -3
- package/dist/{guardian-agent-FYZ5F3DA.js → guardian-agent-QFREM3AR.js} +4 -4
- package/dist/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-CMZTFDNC.js.map +0 -1
- package/dist/chunk-HWJJIAR7.js.map +0 -1
- package/dist/chunk-IF2KTITI.js.map +0 -1
- package/dist/chunk-O7WFJC2P.js.map +0 -1
- /package/dist/{goal-manager-B673YUZF.js.map → goal-manager-5FLR7IS2.js.map} +0 -0
- /package/dist/{guardian-agent-FYZ5F3DA.js.map → guardian-agent-QFREM3AR.js.map} +0 -0
package/README.md
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
Download the Trie workspace: https://www.trie.dev
|
|
6
6
|
Follow me on X: https://x.com/louiskishfy
|
|
7
7
|
|
|
8
|
+
## More Info
|
|
9
|
+
|
|
10
|
+
Long article I wrote here about this emerging space in AI tooling, this project, and the problems I'm working on solving: https://www.linkedin.com/pulse/your-new-ai-tool-probably-prompt-pack-lou-kishfy-gxjac/?trackingId=Dcuh2kGsRaigIt06UTUw5Q%3D%3D
|
|
11
|
+
|
|
8
12
|
## Why Trie Exists
|
|
9
13
|
|
|
10
14
|
I shipped consumer apps that gained traction quickly with Cursor and Claude Code—real users, paying customers. AI-generated code helped me move fast, but it became a nightmare to maintain as one person. I'd fix something and forget why. The same bugs came back. My codebase grew faster than my memory of it. I burned through tokens like no tomorrow.
|
|
@@ -60,6 +64,16 @@ Trie's memory is a tree. The more incidents you report, the smarter the tree get
|
|
|
60
64
|
|
|
61
65
|
## What's New (January 2026)
|
|
62
66
|
|
|
67
|
+
### Hypothesis & Goals Improvements (Latest)
|
|
68
|
+
|
|
69
|
+
**Bug Fixes**
|
|
70
|
+
- **Goal progress calculation**: Reduction goals now display correctly. Previously "Reduce from 20 → 10, currently at 15" showed 150% instead of 50%. Fixed with proper reduction formula.
|
|
71
|
+
- **Hypothesis status transitions**: Auto-generated hypotheses now properly transition from `proposed` → `testing` when first evidence is gathered.
|
|
72
|
+
|
|
73
|
+
**Enhancements**
|
|
74
|
+
- **Path-aware goal tracking**: Goals like "Improve code quality in the auth module" now correctly filter issues by directory path. Matches patterns like "in the auth module", "in src/", "in components folder".
|
|
75
|
+
- **Progress bar clamping**: Progress bars now clamp to 0-100% to prevent display overflow for edge cases.
|
|
76
|
+
|
|
63
77
|
### Guardian Agency
|
|
64
78
|
|
|
65
79
|
**Persistent Memory**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGuardianState
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-COXK23KW.js";
|
|
4
4
|
import {
|
|
5
5
|
BackupManager,
|
|
6
6
|
atomicWriteJSON,
|
|
@@ -722,6 +722,17 @@ var GoalManager = class {
|
|
|
722
722
|
return issues.filter((r) => r.issue.severity === "critical").length;
|
|
723
723
|
}
|
|
724
724
|
const desc = goal.description.toLowerCase();
|
|
725
|
+
const dirMatch = goal.description.match(/in\s+(?:the\s+)?(\S+?)(?:\s+(?:module|folder|directory|dir))?(?:\s|$)/i);
|
|
726
|
+
if (dirMatch && dirMatch[1]) {
|
|
727
|
+
const dirName = dirMatch[1].toLowerCase().replace(/[/\\]$/, "");
|
|
728
|
+
const matchingIssues = issues.filter((r) => {
|
|
729
|
+
const filePath = r.issue.file.toLowerCase();
|
|
730
|
+
return filePath.includes(`/${dirName}/`) || filePath.includes(`\\${dirName}\\`) || filePath.startsWith(`${dirName}/`) || filePath.startsWith(`${dirName}\\`);
|
|
731
|
+
});
|
|
732
|
+
if (matchingIssues.length > 0 || desc.includes(dirName)) {
|
|
733
|
+
return matchingIssues.length;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
725
736
|
if (desc.includes("dead code") || desc.includes("unused") || desc.includes("remove unused")) {
|
|
726
737
|
const deadCodeIssues = issues.filter((r) => {
|
|
727
738
|
const msg = r.issue.issue.toLowerCase();
|
|
@@ -1028,4 +1039,4 @@ export {
|
|
|
1028
1039
|
getGoalManager,
|
|
1029
1040
|
clearGoalManagers
|
|
1030
1041
|
};
|
|
1031
|
-
//# sourceMappingURL=chunk-
|
|
1042
|
+
//# sourceMappingURL=chunk-BHIKY5PW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/guardian/insight-store.ts","../src/guardian/goal-manager.ts"],"sourcesContent":["/**\n * Insight Store - Persistent storage for Guardian insights\n * \n * Phase 1 of Guardian Agency Plan: Fix critical persistence gaps\n * \n * Persists to: .trie/memory/guardian-insights.json\n * \n * Features:\n * - Insight persistence across restarts\n * - Cooldown state persistence (prevents duplicate insights)\n * - Dismissed insight tracking\n * - Atomic writes with backup rotation\n * - Zod validation for data integrity\n */\n\nimport { mkdir, readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { safeParseAndValidate } from '../memory/validation.js';\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\n/**\n * Schema for insight details\n */\nexport const InsightDetailsSchema = z.object({\n affectedFiles: z.array(z.string()).optional(),\n issueBreakdown: z.record(z.string(), z.number()).optional(),\n examples: z.array(z.string()).optional(),\n trend: z.enum(['improving', 'stable', 'worsening']).optional(),\n comparison: z.string().optional(),\n resolvedCount: z.number().optional(),\n resolvedIssues: z.array(z.object({\n file: z.string(),\n line: z.number().optional(),\n issue: z.string(),\n agent: z.string(),\n resolvedAt: z.string().optional(),\n })).optional(),\n summary: z.string().optional(),\n});\n\n/**\n * Schema for a Guardian insight\n */\nexport const GuardianInsightSchema = z.object({\n id: z.string(),\n type: z.enum(['observation', 'warning', 'suggestion', 'celebration', 'question']),\n message: z.string(),\n context: z.string().optional(),\n suggestedAction: z.string().optional(),\n actionCommand: z.string().optional(),\n relatedIssues: z.array(z.string()),\n priority: z.number().min(1).max(10),\n timestamp: z.number(),\n dismissed: z.boolean(),\n category: z.enum(['security', 'quality', 'performance', 'pattern', 'progress', 'general']),\n details: InsightDetailsSchema.optional(),\n});\n\nexport type GuardianInsight = z.infer<typeof GuardianInsightSchema>;\n\n/**\n * Schema for the entire insight store file\n */\nexport const InsightStoreDataSchema = z.object({\n version: z.literal(1),\n insights: z.array(GuardianInsightSchema),\n cooldowns: z.record(z.string(), z.number()), // insightKey -> timestamp\n dismissedIds: z.array(z.string()), // Track dismissed insight IDs permanently\n lastUpdated: z.string(),\n});\n\nexport type InsightStoreData = z.infer<typeof InsightStoreDataSchema>;\n\n// ============================================================================\n// InsightStore Class\n// ============================================================================\n\n/**\n * Persistent store for Guardian insights\n * \n * Usage:\n * ```typescript\n * const store = new InsightStore(projectPath);\n * await store.load();\n * \n * await store.addInsight(insight);\n * const active = store.getActiveInsights();\n * await store.dismissInsight(insightId);\n * ```\n */\nexport class InsightStore {\n private projectPath: string;\n private data: InsightStoreData;\n private loaded: boolean = false;\n private dirty: boolean = false;\n \n // Default cooldown periods (in ms)\n static readonly COOLDOWNS: Record<string, number> = {\n 'pre-push-warning': 60000, // 1 min between pre-push warnings\n 'security-warning': 30000, // 30s between security warnings\n 'new-issues': 30000, // 30s between new issue observations\n 'celebration': 60000, // 1 min between celebrations\n 'pattern-suggestion': 120000, // 2 min between pattern suggestions\n 'accessibility-visual-qa': 300000, // 5 min between visual QA suggestions\n 'goal-suggestion': 300000, // 5 min between goal suggestions\n 'risk-prediction': 180000, // 3 min between risk predictions\n 'hypothesis-update': 600000, // 10 min between hypothesis updates\n 'auto-escalation': 300000, // 5 min between auto-escalations\n };\n \n constructor(projectPath: string) {\n this.projectPath = projectPath;\n this.data = this.createEmptyData();\n }\n \n /**\n * Get the storage file path\n */\n private getStorePath(): string {\n return join(this.projectPath, '.trie', 'memory', 'guardian-insights.json');\n }\n \n /**\n * Create empty data structure\n */\n private createEmptyData(): InsightStoreData {\n return {\n version: 1,\n insights: [],\n cooldowns: {},\n dismissedIds: [],\n lastUpdated: new Date().toISOString(),\n };\n }\n \n /**\n * Load insights from disk\n * \n * If the file is corrupted, attempts recovery from backup.\n * Returns empty data if no valid file/backup exists.\n */\n async load(): Promise<InsightStoreData> {\n if (this.loaded) {\n return this.data;\n }\n \n const storePath = this.getStorePath();\n \n try {\n if (existsSync(storePath)) {\n const content = await readFile(storePath, 'utf-8');\n const result = safeParseAndValidate(content, InsightStoreDataSchema);\n \n if (result.success) {\n this.data = result.data;\n this.loaded = true;\n // Deduplicate any existing duplicate insights\n this.deduplicateInsights();\n return this.data;\n }\n \n // Validation failed - attempt recovery from backup\n console.error(` Insight store corrupted: ${result.error}`);\n const backupManager = new BackupManager(storePath);\n \n if (await backupManager.recoverFromBackup()) {\n console.error(' Recovered from backup');\n const recovered = await readFile(storePath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, InsightStoreDataSchema);\n if (recoveredResult.success) {\n this.data = recoveredResult.data;\n this.loaded = true;\n // Deduplicate any existing duplicate insights\n this.deduplicateInsights();\n return this.data;\n }\n }\n \n console.error(' No valid backup found, starting fresh');\n }\n } catch (error) {\n // File doesn't exist or recovery failed - start fresh\n console.error(` Could not load insight store: ${error}`);\n }\n \n this.data = this.createEmptyData();\n this.loaded = true;\n return this.data;\n }\n \n /**\n * Deduplicate existing insights on load\n * Keeps the most recent instance of each unique insight\n */\n private deduplicateInsights(): void {\n const seen = new Map<string, number>(); // contentKey -> index of first occurrence\n const toRemove: number[] = [];\n \n // Process from newest to oldest (insights are sorted by recency)\n for (let i = 0; i < this.data.insights.length; i++) {\n const insight = this.data.insights[i];\n if (!insight) continue;\n \n const contentKey = this.getContentKey(insight);\n \n if (seen.has(contentKey)) {\n // This is a duplicate - mark for removal\n toRemove.push(i);\n } else {\n seen.set(contentKey, i);\n }\n }\n \n // Remove duplicates (reverse order to preserve indices)\n if (toRemove.length > 0) {\n for (let i = toRemove.length - 1; i >= 0; i--) {\n const idx = toRemove[i];\n if (idx !== undefined) {\n this.data.insights.splice(idx, 1);\n }\n }\n this.dirty = true;\n }\n }\n \n /**\n * Save insights to disk\n * \n * Creates backup before writing, uses atomic write.\n */\n async save(): Promise<void> {\n if (!this.dirty && this.loaded) {\n return; // No changes to save\n }\n \n const storePath = this.getStorePath();\n const memoryDir = join(this.projectPath, '.trie', 'memory');\n \n // Ensure directory exists\n await mkdir(memoryDir, { recursive: true });\n \n // Create backup before writing\n const backupManager = new BackupManager(storePath);\n await backupManager.createBackup();\n \n // Update timestamp\n this.data.lastUpdated = new Date().toISOString();\n \n // Atomic write\n await atomicWriteJSON(storePath, this.data);\n \n this.dirty = false;\n }\n \n /**\n * Generate a content-based key for deduplication\n * Insights with the same content key are considered duplicates\n */\n private getContentKey(insight: GuardianInsight): string {\n // Normalize the message by removing specific numbers/counts that might vary slightly\n // e.g., \"Found 30 security issues\" and \"Found 31 security issues\" are the same insight\n const normalizedMessage = insight.message\n .replace(/\\d+/g, 'N') // Replace all numbers with N\n .toLowerCase()\n .trim();\n \n return `${insight.type}:${insight.category}:${normalizedMessage}`;\n }\n \n /**\n * Add an insight to the store\n * \n * Checks for duplicates using both insight ID and content similarity.\n * If a similar insight already exists (same type, category, and normalized message),\n * updates its timestamp instead of creating a duplicate.\n * Respects cooldowns to prevent insight spam.\n */\n async addInsight(insight: GuardianInsight): Promise<boolean> {\n await this.load();\n \n // Check if already exists by ID\n if (this.data.insights.some(i => i.id === insight.id)) {\n return false;\n }\n \n // Check if ID was previously dismissed (don't re-add)\n if (this.data.dismissedIds.includes(insight.id)) {\n return false;\n }\n \n // Check for content-based duplicates (same type, category, similar message)\n const contentKey = this.getContentKey(insight);\n const existingIndex = this.data.insights.findIndex(i => \n !i.dismissed && this.getContentKey(i) === contentKey\n );\n \n if (existingIndex >= 0) {\n // Update existing insight instead of adding duplicate\n const existing = this.data.insights[existingIndex];\n if (existing) {\n // Update with new data but keep the original ID\n existing.timestamp = insight.timestamp;\n existing.message = insight.message; // Update with current counts\n existing.details = insight.details; // Update details\n existing.relatedIssues = insight.relatedIssues;\n existing.suggestedAction = insight.suggestedAction;\n \n // Move to front of list\n this.data.insights.splice(existingIndex, 1);\n this.data.insights.unshift(existing);\n \n this.dirty = true;\n await this.save();\n }\n return false; // Return false to indicate no new insight was created\n }\n \n // Add to front of list\n this.data.insights.unshift(insight);\n \n // Keep only last 100 insights\n if (this.data.insights.length > 100) {\n this.data.insights = this.data.insights.slice(0, 100);\n }\n \n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Check if a cooldown has expired for an insight type\n */\n canCreateInsight(insightKey: string): boolean {\n const lastTime = this.data.cooldowns[insightKey];\n const cooldown = InsightStore.COOLDOWNS[insightKey] || 30000;\n \n if (!lastTime) return true;\n return Date.now() - lastTime > cooldown;\n }\n \n /**\n * Mark that an insight type was created (set cooldown)\n */\n async markInsightCreated(insightKey: string): Promise<void> {\n await this.load();\n this.data.cooldowns[insightKey] = Date.now();\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get active (non-dismissed) insights\n * \n * Returns insights sorted by priority (highest first),\n * limited to the specified count.\n */\n getActiveInsights(limit: number = 5): GuardianInsight[] {\n return this.data.insights\n .filter(i => !i.dismissed)\n .sort((a, b) => b.priority - a.priority)\n .slice(0, limit);\n }\n \n /**\n * Get all insights (including dismissed)\n */\n getAllInsights(): GuardianInsight[] {\n return [...this.data.insights];\n }\n \n /**\n * Dismiss an insight by ID\n */\n async dismissInsight(insightId: string): Promise<boolean> {\n await this.load();\n \n const insight = this.data.insights.find(i => i.id === insightId);\n if (!insight) {\n return false;\n }\n \n insight.dismissed = true;\n \n // Track permanently dismissed IDs\n if (!this.data.dismissedIds.includes(insightId)) {\n this.data.dismissedIds.push(insightId);\n \n // Keep only last 500 dismissed IDs\n if (this.data.dismissedIds.length > 500) {\n this.data.dismissedIds = this.data.dismissedIds.slice(-500);\n }\n }\n \n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Remove an insight entirely\n */\n async removeInsight(insightId: string): Promise<boolean> {\n await this.load();\n \n const index = this.data.insights.findIndex(i => i.id === insightId);\n if (index === -1) {\n return false;\n }\n \n this.data.insights.splice(index, 1);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Clear all cooldowns\n */\n async clearCooldowns(): Promise<void> {\n await this.load();\n this.data.cooldowns = {};\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get insight by ID\n */\n getInsight(insightId: string): GuardianInsight | undefined {\n return this.data.insights.find(i => i.id === insightId);\n }\n \n /**\n * Update an existing insight\n */\n async updateInsight(insightId: string, updates: Partial<GuardianInsight>): Promise<boolean> {\n await this.load();\n \n const insight = this.data.insights.find(i => i.id === insightId);\n if (!insight) {\n return false;\n }\n \n Object.assign(insight, updates);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Get insights by category\n */\n getInsightsByCategory(category: GuardianInsight['category']): GuardianInsight[] {\n return this.data.insights.filter(i => i.category === category && !i.dismissed);\n }\n \n /**\n * Get insights by type\n */\n getInsightsByType(type: GuardianInsight['type']): GuardianInsight[] {\n return this.data.insights.filter(i => i.type === type && !i.dismissed);\n }\n \n /**\n * Get insights from the last N hours\n */\n getRecentInsights(hours: number = 24): GuardianInsight[] {\n const cutoff = Date.now() - (hours * 60 * 60 * 1000);\n return this.data.insights.filter(i => i.timestamp >= cutoff);\n }\n \n /**\n * Get statistics about insights\n */\n getStats(): {\n total: number;\n active: number;\n dismissed: number;\n byCategory: Record<string, number>;\n byType: Record<string, number>;\n } {\n const stats = {\n total: this.data.insights.length,\n active: 0,\n dismissed: 0,\n byCategory: {} as Record<string, number>,\n byType: {} as Record<string, number>,\n };\n \n for (const insight of this.data.insights) {\n if (insight.dismissed) {\n stats.dismissed++;\n } else {\n stats.active++;\n }\n \n stats.byCategory[insight.category] = (stats.byCategory[insight.category] || 0) + 1;\n stats.byType[insight.type] = (stats.byType[insight.type] || 0) + 1;\n }\n \n return stats;\n }\n \n /**\n * Prune old insights (older than N days)\n */\n async pruneOldInsights(daysToKeep: number = 30): Promise<number> {\n await this.load();\n \n const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);\n const originalCount = this.data.insights.length;\n \n this.data.insights = this.data.insights.filter(i => i.timestamp >= cutoff);\n \n const pruned = originalCount - this.data.insights.length;\n if (pruned > 0) {\n this.dirty = true;\n await this.save();\n }\n \n return pruned;\n }\n \n /**\n * Check if the store has been loaded\n */\n isLoaded(): boolean {\n return this.loaded;\n }\n \n /**\n * Force reload from disk\n */\n async reload(): Promise<InsightStoreData> {\n this.loaded = false;\n this.dirty = false;\n return this.load();\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst insightStores: Map<string, InsightStore> = new Map();\n\n/**\n * Get the InsightStore for a project (singleton per project)\n */\nexport function getInsightStore(projectPath: string): InsightStore {\n let store = insightStores.get(projectPath);\n if (!store) {\n store = new InsightStore(projectPath);\n insightStores.set(projectPath, store);\n }\n return store;\n}\n\n/**\n * Clear all InsightStore instances (for testing)\n */\nexport function clearInsightStores(): void {\n insightStores.clear();\n}\n","/**\n * Goal Manager - Autonomous goal generation and tracking\n * \n * Phase 2 of Guardian Agency Plan: Autonomous Goals\n * \n * Features:\n * - Auto-generates goals from incident patterns\n * - Tracks goal progress over time\n * - Presents goals to users for acceptance/rejection\n * - Adaptive goal difficulty based on team velocity\n * - Goal achievement celebrations\n */\n\nimport type { Goal } from './guardian-state.js';\nimport { getGuardianState } from './guardian-state.js';\nimport { getInsightStore, type GuardianInsight } from './insight-store.js';\nimport { searchIssues, getMemoryStats } from '../memory/issue-store.js';\nimport { basename } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A pattern detected from incident history\n */\nexport interface IncidentPattern {\n type: 'file-cluster' | 'severity-trend' | 'agent-concentration' | 'time-pattern';\n description: string;\n metric: string;\n currentValue: number;\n suggestedTarget: number;\n confidence: number; // 0-1\n evidence: string[];\n category?: 'security' | 'quality' | 'performance' | 'coverage' | 'general';\n}\n\n/**\n * Goal opportunity - a potential goal before user acceptance\n */\nexport interface GoalOpportunity {\n pattern: IncidentPattern;\n goal: Omit<Goal, 'id' | 'createdAt' | 'updatedAt'>;\n reasoning: string;\n}\n\n/**\n * Configuration for goal generation\n */\nexport interface GoalGenerationConfig {\n minConfidence: number; // Minimum confidence to suggest goal (0-1)\n maxActiveGoals: number; // Maximum concurrent active goals\n goalDurationDays: number; // Default goal duration in days\n reductionTargetPercent: number; // Target reduction percentage\n}\n\nconst DEFAULT_CONFIG: GoalGenerationConfig = {\n minConfidence: 0.6,\n maxActiveGoals: 3,\n goalDurationDays: 14,\n reductionTargetPercent: 50,\n};\n\n// ============================================================================\n// GoalManager Class\n// ============================================================================\n\n/**\n * Manages autonomous goal generation and tracking\n */\nexport class GoalManager {\n private projectPath: string;\n private config: GoalGenerationConfig;\n private guardianState;\n private insightStore;\n \n constructor(projectPath: string, config: Partial<GoalGenerationConfig> = {}) {\n this.projectPath = projectPath;\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.guardianState = getGuardianState(projectPath);\n this.insightStore = getInsightStore(projectPath);\n }\n \n /**\n * Analyze incident patterns from memory\n */\n async analyzeIncidentPatterns(): Promise<IncidentPattern[]> {\n const patterns: IncidentPattern[] = [];\n \n try {\n // Get recent issues for analysis\n const stats = await getMemoryStats(this.projectPath);\n const recentIssues = await searchIssues('', {\n workDir: this.projectPath,\n limit: 500,\n includeResolved: true,\n });\n \n if (recentIssues.length < 5) {\n return patterns; // Not enough data for pattern detection\n }\n \n // 1. Analyze file clusters (files with most issues)\n const fileIssueCount = new Map<string, number>();\n for (const { issue } of recentIssues) {\n const file = issue.file;\n fileIssueCount.set(file, (fileIssueCount.get(file) || 0) + 1);\n }\n \n const sortedFiles = [...fileIssueCount.entries()]\n .sort((a, b) => b[1] - a[1]);\n \n // Detect hot directories\n const dirIssueCount = new Map<string, number>();\n for (const [file, count] of sortedFiles) {\n const parts = file.split('/');\n if (parts.length > 1) {\n const dir = parts.slice(0, -1).join('/');\n dirIssueCount.set(dir, (dirIssueCount.get(dir) || 0) + count);\n }\n }\n \n const sortedDirs = [...dirIssueCount.entries()]\n .sort((a, b) => b[1] - a[1]);\n \n if (sortedDirs.length > 0) {\n const [topDir, topDirCount] = sortedDirs[0]!;\n const totalIssues = recentIssues.length;\n const percentage = (topDirCount / totalIssues) * 100;\n \n if (percentage >= 30) {\n patterns.push({\n type: 'file-cluster',\n description: `${basename(topDir)}/ has ${percentage.toFixed(0)}% of issues`,\n metric: `${topDir}_issues`,\n currentValue: topDirCount,\n suggestedTarget: Math.floor(topDirCount * (1 - this.config.reductionTargetPercent / 100)),\n confidence: Math.min(0.9, percentage / 100 + 0.3),\n evidence: [\n `${topDirCount} issues in ${topDir}/`,\n `${percentage.toFixed(0)}% of total issues`,\n `Top files: ${sortedFiles.filter(([f]) => f.startsWith(topDir)).slice(0, 3).map(([f]) => basename(f)).join(', ')}`,\n ],\n category: 'quality',\n });\n }\n }\n \n // 2. Analyze severity trends\n const criticalCount = recentIssues.filter(r => r.issue.severity === 'critical').length;\n const seriousCount = recentIssues.filter(r => r.issue.severity === 'serious').length;\n \n if (criticalCount >= 3) {\n patterns.push({\n type: 'severity-trend',\n description: `${criticalCount} critical issues need attention`,\n metric: 'critical_issues',\n currentValue: criticalCount,\n suggestedTarget: 0,\n confidence: Math.min(0.95, 0.5 + criticalCount * 0.1),\n evidence: [\n `${criticalCount} critical severity issues`,\n `${seriousCount} serious severity issues`,\n 'Critical issues should be zero for production safety',\n ],\n category: 'security',\n });\n }\n \n // 3. Analyze agent concentration (skill-specific issues)\n const agentIssueCount = new Map<string, number>();\n for (const { issue } of recentIssues) {\n agentIssueCount.set(issue.agent, (agentIssueCount.get(issue.agent) || 0) + 1);\n }\n \n const sortedAgents = [...agentIssueCount.entries()]\n .sort((a, b) => b[1] - a[1]);\n \n if (sortedAgents.length > 0) {\n const [topAgent, topAgentCount] = sortedAgents[0]!;\n const percentage = (topAgentCount / recentIssues.length) * 100;\n \n if (percentage >= 40 && topAgentCount >= 5) {\n const category = this.agentToCategory(topAgent);\n patterns.push({\n type: 'agent-concentration',\n description: `${topAgent} skill finds ${percentage.toFixed(0)}% of issues`,\n metric: `${topAgent}_issues`,\n currentValue: topAgentCount,\n suggestedTarget: Math.floor(topAgentCount * 0.5),\n confidence: Math.min(0.85, percentage / 100 + 0.2),\n evidence: [\n `${topAgentCount} issues from ${topAgent}`,\n `${percentage.toFixed(0)}% of all issues`,\n `Suggests focused improvement in ${category} area`,\n ],\n category,\n });\n }\n }\n \n // 4. Detect improvement trends (for streak goals)\n if (stats.improvementTrend === 'improving') {\n patterns.push({\n type: 'time-pattern',\n description: 'Quality is improving - maintain the streak',\n metric: 'clean_scans',\n currentValue: 0,\n suggestedTarget: 5,\n confidence: 0.7,\n evidence: [\n 'Historical trend shows improvement',\n 'Momentum is positive',\n 'Streak goal can maintain motivation',\n ],\n category: 'quality',\n });\n }\n \n } catch (error) {\n console.error('Failed to analyze incident patterns:', error);\n }\n \n return patterns;\n }\n \n /**\n * Convert agent name to category\n */\n private agentToCategory(agent: string): 'security' | 'quality' | 'performance' | 'coverage' | 'general' {\n const categoryMap: Record<string, 'security' | 'quality' | 'performance' | 'coverage' | 'general'> = {\n 'security': 'security',\n 'privacy': 'security',\n 'soc2': 'security',\n 'performance': 'performance',\n 'accessibility': 'quality',\n 'test': 'coverage',\n 'typecheck': 'quality',\n 'bug-finding': 'quality',\n };\n return categoryMap[agent] || 'general';\n }\n \n /**\n * Generate goal opportunities from patterns\n */\n async generateGoalOpportunities(): Promise<GoalOpportunity[]> {\n const patterns = await this.analyzeIncidentPatterns();\n const opportunities: GoalOpportunity[] = [];\n \n // Filter by confidence threshold\n const validPatterns = patterns.filter(p => p.confidence >= this.config.minConfidence);\n \n // Check current active goals\n await this.guardianState.load();\n const activeGoals = this.guardianState.getActiveGoals();\n \n // Don't suggest too many goals\n const slotsAvailable = this.config.maxActiveGoals - activeGoals.length;\n if (slotsAvailable <= 0) {\n return opportunities;\n }\n \n // Convert patterns to goal opportunities\n for (const pattern of validPatterns.slice(0, slotsAvailable)) {\n const goalType = pattern.type === 'time-pattern' ? 'streak' : 'reduction';\n const deadline = new Date();\n deadline.setDate(deadline.getDate() + this.config.goalDurationDays);\n \n opportunities.push({\n pattern,\n goal: {\n description: this.generateGoalDescription(pattern),\n type: goalType,\n metric: pattern.metric,\n target: pattern.suggestedTarget,\n currentValue: pattern.currentValue,\n startValue: pattern.currentValue,\n status: 'active',\n autoGenerated: true,\n confidence: pattern.confidence,\n deadline: deadline.toISOString(),\n category: pattern.category,\n evidence: pattern.evidence,\n },\n reasoning: this.generateGoalReasoning(pattern),\n });\n }\n \n return opportunities;\n }\n \n /**\n * Generate a human-readable goal description\n */\n private generateGoalDescription(pattern: IncidentPattern): string {\n switch (pattern.type) {\n case 'file-cluster':\n return `Reduce issues in ${pattern.description.split(' ')[0]} by ${this.config.reductionTargetPercent}%`;\n case 'severity-trend':\n return 'Eliminate all critical issues';\n case 'agent-concentration':\n return `Reduce ${pattern.description.split(' ')[0]} issues by 50%`;\n case 'time-pattern':\n return 'Achieve 5 consecutive clean scans';\n default:\n return pattern.description;\n }\n }\n \n /**\n * Generate reasoning for why this goal was suggested\n */\n private generateGoalReasoning(pattern: IncidentPattern): string {\n const evidence = pattern.evidence.join('. ');\n return `Based on analysis: ${evidence}. Confidence: ${(pattern.confidence * 100).toFixed(0)}%`;\n }\n \n /**\n * Auto-generate goals and create them (with auto-generated status)\n * \n * Returns goals that need user acceptance.\n */\n async autoGenerateGoals(): Promise<Goal[]> {\n const opportunities = await this.generateGoalOpportunities();\n const createdGoals: Goal[] = [];\n \n for (const opportunity of opportunities) {\n const goal: Goal = {\n id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n ...opportunity.goal,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n \n await this.guardianState.addGoal(goal);\n createdGoals.push(goal);\n \n // Create insight about the new goal\n if (this.insightStore.canCreateInsight('goal-suggestion')) {\n const insight: GuardianInsight = {\n id: `insight-goal-${goal.id}`,\n type: 'suggestion',\n message: `New goal suggested: ${goal.description}`,\n context: opportunity.reasoning,\n suggestedAction: 'Review and accept/reject this goal',\n relatedIssues: [],\n priority: 6,\n timestamp: Date.now(),\n dismissed: false,\n category: 'progress',\n details: {\n examples: opportunity.pattern.evidence,\n },\n };\n await this.insightStore.addInsight(insight);\n await this.insightStore.markInsightCreated('goal-suggestion');\n }\n }\n \n return createdGoals;\n }\n \n /**\n * Update goal progress based on current state\n */\n async updateGoalProgress(): Promise<void> {\n await this.guardianState.load();\n const activeGoals = this.guardianState.getActiveGoals();\n \n for (const goal of activeGoals) {\n const currentValue = await this.measureGoalMetric(goal);\n \n // Update current value\n await this.guardianState.updateGoal(goal.id, { currentValue });\n \n // Check if goal achieved\n if (this.isGoalAchieved(goal, currentValue)) {\n await this.guardianState.updateGoal(goal.id, {\n status: 'achieved',\n achievedAt: new Date().toISOString(),\n currentValue,\n });\n \n // Celebrate!\n await this.celebrateGoalAchievement(goal);\n }\n \n // Check if goal failed (past deadline and not achieved)\n if (goal.deadline) {\n const deadline = new Date(goal.deadline);\n if (Date.now() > deadline.getTime() && !this.isGoalAchieved(goal, currentValue)) {\n await this.guardianState.updateGoal(goal.id, {\n status: 'failed',\n currentValue,\n });\n }\n }\n }\n }\n \n /**\n * Measure the current value of a goal's metric\n * \n * Supports both structured metrics and semantic/natural language goals\n */\n private async measureGoalMetric(goal: Goal): Promise<number> {\n try {\n const issues = await searchIssues('', {\n workDir: this.projectPath,\n limit: 1000,\n includeResolved: false,\n });\n \n // Structured metrics (auto-generated goals)\n if (goal.metric.endsWith('_issues')) {\n const prefix = goal.metric.replace('_issues', '');\n \n // Check if it's a directory metric\n if (prefix.includes('/')) {\n return issues.filter(r => r.issue.file.startsWith(prefix)).length;\n }\n \n // Check if it's an agent metric\n return issues.filter(r => r.issue.agent === prefix).length;\n }\n \n if (goal.metric === 'critical_issues') {\n return issues.filter(r => r.issue.severity === 'critical').length;\n }\n \n // Semantic goal tracking - match description to issue types\n const desc = goal.description.toLowerCase();\n \n // Path-aware matching for directory/module-specific goals\n // Matches patterns like \"in the auth module\", \"in src/\", \"in components folder\"\n const dirMatch = goal.description.match(/in\\s+(?:the\\s+)?(\\S+?)(?:\\s+(?:module|folder|directory|dir))?(?:\\s|$)/i);\n if (dirMatch && dirMatch[1]) {\n const dirName = dirMatch[1].toLowerCase().replace(/[/\\\\]$/, ''); // Normalize trailing slashes\n const matchingIssues = issues.filter(r => {\n const filePath = r.issue.file.toLowerCase();\n // Match directory name anywhere in path (e.g., \"auth\" matches \"src/auth/login.ts\")\n return filePath.includes(`/${dirName}/`) || \n filePath.includes(`\\\\${dirName}\\\\`) ||\n filePath.startsWith(`${dirName}/`) ||\n filePath.startsWith(`${dirName}\\\\`);\n });\n if (matchingIssues.length > 0 || desc.includes(dirName)) {\n return matchingIssues.length;\n }\n }\n \n // Dead code / unused code goals\n if (desc.includes('dead code') || desc.includes('unused') || desc.includes('remove unused')) {\n const deadCodeIssues = issues.filter(r => {\n const msg = r.issue.issue.toLowerCase();\n return msg.includes('unused') || msg.includes('dead code') || \n msg.includes('never used') || msg.includes('unreachable') ||\n msg.includes('no-unused') || msg.includes('defined but never');\n });\n return deadCodeIssues.length;\n }\n \n // Security goals\n if (desc.includes('security') || desc.includes('vulnerab') || desc.includes('fix security')) {\n const securityIssues = issues.filter(r => \n r.issue.agent === 'security' || r.issue.agent === 'privacy' ||\n r.issue.severity === 'critical'\n );\n return securityIssues.length;\n }\n \n // Type safety goals\n if (desc.includes('type') || desc.includes('typescript') || desc.includes('any type')) {\n const typeIssues = issues.filter(r => \n r.issue.agent === 'typecheck' ||\n r.issue.issue.toLowerCase().includes('type') ||\n r.issue.issue.toLowerCase().includes('any')\n );\n return typeIssues.length;\n }\n \n // Test coverage goals\n if (desc.includes('test') || desc.includes('coverage')) {\n const testIssues = issues.filter(r => \n r.issue.agent === 'test' ||\n r.issue.issue.toLowerCase().includes('test') ||\n r.issue.issue.toLowerCase().includes('coverage')\n );\n return testIssues.length;\n }\n \n // Performance goals\n if (desc.includes('performance') || desc.includes('slow') || desc.includes('optimize')) {\n const perfIssues = issues.filter(r => \n r.issue.agent === 'performance' ||\n r.issue.issue.toLowerCase().includes('performance') ||\n r.issue.issue.toLowerCase().includes('slow')\n );\n return perfIssues.length;\n }\n \n // Accessibility goals\n if (desc.includes('accessibility') || desc.includes('a11y') || desc.includes('accessible')) {\n const a11yIssues = issues.filter(r => \n r.issue.agent === 'accessibility' ||\n r.issue.issue.toLowerCase().includes('accessibility')\n );\n return a11yIssues.length;\n }\n \n // Bug-related goals\n if (desc.includes('bug') || desc.includes('fix') || desc.includes('error')) {\n const bugIssues = issues.filter(r => \n r.issue.agent === 'bug-finding' ||\n r.issue.severity === 'critical' ||\n r.issue.severity === 'serious'\n );\n return bugIssues.length;\n }\n \n // Quality goals (general)\n if (desc.includes('quality') || desc.includes('clean') || desc.includes('improve')) {\n // Count all issues as baseline for quality\n return issues.length;\n }\n \n // Default: total issues\n return issues.length;\n } catch {\n return goal.currentValue; // Return existing value on error\n }\n }\n \n /**\n * Check if a goal has been achieved\n */\n private isGoalAchieved(goal: Goal, currentValue: number): boolean {\n switch (goal.type) {\n case 'reduction':\n return currentValue <= goal.target;\n case 'score':\n return currentValue >= goal.target;\n case 'streak':\n return currentValue >= goal.target;\n default:\n return currentValue <= goal.target;\n }\n }\n \n /**\n * Create a celebration insight for goal achievement\n */\n private async celebrateGoalAchievement(goal: Goal): Promise<void> {\n // Find resolved issues that match this goal's metric\n const resolvedDetails = await this.getResolvedIssuesForGoal(goal);\n \n // Validate required fields\n if (goal.startValue === undefined || goal.startValue === null) {\n throw new Error(`Goal ${goal.id} missing startValue`);\n }\n if (goal.currentValue === undefined || goal.currentValue === null) {\n throw new Error(`Goal ${goal.id} missing currentValue`);\n }\n if (goal.target === undefined || goal.target === null) {\n throw new Error(`Goal ${goal.id} missing target`);\n }\n \n // Validate resolvedDetails structure\n for (let i = 0; i < resolvedDetails.length; i++) {\n const issue = resolvedDetails[i];\n if (!issue) {\n throw new Error(`Resolved issue at index ${i} is null/undefined`);\n }\n if (!issue.file) {\n throw new Error(`Resolved issue at index ${i} missing file field`);\n }\n if (!issue.issue) {\n throw new Error(`Resolved issue at index ${i} missing issue description`);\n }\n if (!issue.agent) {\n throw new Error(`Resolved issue at index ${i} missing agent field`);\n }\n }\n \n const insight: GuardianInsight = {\n id: `insight-achieved-${goal.id}`,\n type: 'celebration',\n message: `Goal achieved: ${goal.description}!`,\n context: `Started at ${goal.startValue}, now at ${goal.currentValue}. Target was ${goal.target}.`,\n relatedIssues: [],\n priority: 8,\n timestamp: Date.now(),\n dismissed: false,\n category: 'progress',\n details: {\n resolvedCount: resolvedDetails.length,\n resolvedIssues: resolvedDetails.slice(0, 20).map(issue => ({\n file: issue.file,\n line: issue.line,\n issue: issue.issue,\n agent: issue.agent,\n resolvedAt: issue.resolvedAt,\n })),\n summary: resolvedDetails.length > 0 \n ? `Resolved ${resolvedDetails.length} issue${resolvedDetails.length > 1 ? 's' : ''} matching this goal`\n : 'Progress tracked via metric reduction',\n },\n };\n \n // Validate insight structure before saving\n if (!insight.details) {\n throw new Error('Failed to create details object for goal achievement insight');\n }\n if (insight.details.resolvedCount === undefined) {\n throw new Error('resolvedCount is undefined in goal achievement insight');\n }\n if (insight.details.resolvedCount > 0 && (!insight.details.resolvedIssues || insight.details.resolvedIssues.length === 0)) {\n throw new Error(`resolvedCount is ${insight.details.resolvedCount} but resolvedIssues array is empty`);\n }\n if (insight.details.resolvedCount !== insight.details.resolvedIssues?.length) {\n throw new Error(`resolvedCount (${insight.details.resolvedCount}) doesn't match resolvedIssues length (${insight.details.resolvedIssues?.length})`);\n }\n \n await this.insightStore.addInsight(insight);\n }\n\n /**\n * Get resolved issues that match a goal's metric pattern\n */\n private async getResolvedIssuesForGoal(goal: Goal): Promise<Array<{ file: string; line: number | undefined; issue: string; agent: string; resolvedAt: string | undefined }>> {\n try {\n // Get all resolved issues\n const allResolved = await searchIssues('', {\n workDir: this.projectPath,\n limit: 1000,\n includeResolved: true,\n });\n \n // Filter to only resolved issues\n const resolved = allResolved\n .map(r => r.issue)\n .filter(issue => issue.resolved === true);\n \n // Filter by goal's metric pattern (same logic as measureGoalMetric)\n const desc = goal.description.toLowerCase();\n const metric = goal.metric.toLowerCase();\n \n let matchingResolved = resolved;\n \n // Match by metric pattern\n if (metric.endsWith('_issues')) {\n const prefix = metric.replace('_issues', '');\n if (prefix.includes('/')) {\n matchingResolved = resolved.filter(i => i.file.startsWith(prefix));\n } else {\n matchingResolved = resolved.filter(i => i.agent === prefix);\n }\n } else if (metric === 'critical_issues') {\n matchingResolved = resolved.filter(i => i.severity === 'critical');\n } else {\n // Semantic matching (same as measureGoalMetric)\n if (desc.includes('dead code') || desc.includes('unused') || desc.includes('remove unused')) {\n matchingResolved = resolved.filter(i => {\n const msg = i.issue.toLowerCase();\n return msg.includes('unused') || msg.includes('dead code') || \n msg.includes('never used') || msg.includes('unreachable') ||\n msg.includes('no-unused') || msg.includes('defined but never');\n });\n } else if (desc.includes('security') || desc.includes('vulnerab') || desc.includes('fix security')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'security' || i.agent === 'privacy' || i.severity === 'critical'\n );\n } else if (desc.includes('type') || desc.includes('typescript') || desc.includes('any type')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'typecheck' ||\n i.issue.toLowerCase().includes('type') ||\n i.issue.toLowerCase().includes('any')\n );\n } else if (desc.includes('test') || desc.includes('coverage')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'test' ||\n i.issue.toLowerCase().includes('test') ||\n i.issue.toLowerCase().includes('coverage')\n );\n } else if (desc.includes('performance') || desc.includes('slow') || desc.includes('optimize')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'performance' ||\n i.issue.toLowerCase().includes('performance') ||\n i.issue.toLowerCase().includes('slow')\n );\n } else if (desc.includes('accessibility') || desc.includes('a11y') || desc.includes('accessible')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'accessibility' ||\n i.issue.toLowerCase().includes('accessibility')\n );\n } else if (desc.includes('bug') || desc.includes('fix') || desc.includes('error')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'bug-finding' ||\n i.severity === 'critical' ||\n i.severity === 'serious'\n );\n }\n }\n \n // Filter by resolvedAt timestamp (only include issues resolved during goal's lifetime)\n const goalCreatedAt = new Date(goal.createdAt).getTime();\n const goalAchievedAt = goal.achievedAt ? new Date(goal.achievedAt).getTime() : Date.now();\n \n return matchingResolved\n .filter(issue => {\n if (!issue.resolvedAt) return false;\n const resolvedAt = new Date(issue.resolvedAt).getTime();\n return resolvedAt >= goalCreatedAt && resolvedAt <= goalAchievedAt;\n })\n .sort((a, b) => {\n // Sort by resolvedAt, most recent first\n const aTime = a.resolvedAt ? new Date(a.resolvedAt).getTime() : 0;\n const bTime = b.resolvedAt ? new Date(b.resolvedAt).getTime() : 0;\n return bTime - aTime;\n });\n } catch {\n return [];\n }\n }\n \n /**\n * Accept an auto-generated goal\n */\n async acceptGoal(goalId: string): Promise<boolean> {\n return this.guardianState.respondToGoal(goalId, true);\n }\n \n /**\n * Reject an auto-generated goal\n */\n async rejectGoal(goalId: string): Promise<boolean> {\n return this.guardianState.respondToGoal(goalId, false);\n }\n \n /**\n * Get pending auto-generated goals (awaiting acceptance)\n */\n getPendingGoals(): Goal[] {\n return this.guardianState.getAutoGeneratedGoals()\n .filter(g => g.status === 'active');\n }\n \n /**\n * Get goal progress summary\n */\n getGoalProgressSummary(): {\n active: number;\n achieved: number;\n failed: number;\n pending: number;\n } {\n const goals = this.guardianState.getAllGoals();\n return {\n active: goals.filter(g => g.status === 'active').length,\n achieved: goals.filter(g => g.status === 'achieved').length,\n failed: goals.filter(g => g.status === 'failed').length,\n pending: goals.filter(g => g.autoGenerated && g.status === 'active').length,\n };\n }\n}\n\n// ============================================================================\n// Adaptive Scan Frequency\n// ============================================================================\n\n/**\n * Calculate optimal scan frequency based on current risk level\n */\nexport async function calculateAdaptiveScanFrequency(projectPath: string): Promise<{\n frequencyMs: number;\n reason: string;\n}> {\n const guardianState = getGuardianState(projectPath);\n await guardianState.load();\n \n try {\n const stats = await getMemoryStats(projectPath);\n const issues = await searchIssues('', {\n workDir: projectPath,\n limit: 100,\n includeResolved: false,\n });\n \n const criticalCount = issues.filter(r => r.issue.severity === 'critical').length;\n const seriousCount = issues.filter(r => r.issue.severity === 'serious').length;\n \n // High risk: scan every minute\n if (criticalCount >= 3) {\n return {\n frequencyMs: 60000,\n reason: `${criticalCount} critical issues detected - scanning frequently`,\n };\n }\n \n // Medium-high risk: scan every 2 minutes\n if (criticalCount > 0 || seriousCount >= 5) {\n return {\n frequencyMs: 120000,\n reason: `Critical or many serious issues - elevated scan frequency`,\n };\n }\n \n // Medium risk: scan every 3 minutes\n if (seriousCount > 0) {\n return {\n frequencyMs: 180000,\n reason: `${seriousCount} serious issues - moderate scan frequency`,\n };\n }\n \n // Low risk: scan every 5 minutes (default)\n if (stats.totalIssues > 10) {\n return {\n frequencyMs: 300000,\n reason: 'Some issues present - standard scan frequency',\n };\n }\n \n // Very low risk: scan every 10 minutes\n return {\n frequencyMs: 600000,\n reason: 'Code looks good - relaxed scan frequency',\n };\n \n } catch {\n // Default on error\n return {\n frequencyMs: 300000,\n reason: 'Default scan frequency (5 min)',\n };\n }\n}\n\n/**\n * Apply adaptive scan frequency\n */\nexport async function adaptScanFrequency(projectPath: string): Promise<number> {\n const guardianState = getGuardianState(projectPath);\n const { frequencyMs } = await calculateAdaptiveScanFrequency(projectPath);\n \n await guardianState.setScanFrequency(frequencyMs);\n \n return frequencyMs;\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst goalManagers: Map<string, GoalManager> = new Map();\n\n/**\n * Get the GoalManager for a project (singleton per project)\n */\nexport function getGoalManager(projectPath: string): GoalManager {\n let manager = goalManagers.get(projectPath);\n if (!manager) {\n manager = new GoalManager(projectPath);\n goalManagers.set(projectPath, manager);\n }\n return manager;\n}\n\n/**\n * Clear all GoalManager instances (for testing)\n */\nexport function clearGoalManagers(): void {\n goalManagers.clear();\n}\n"],"mappings":";;;;;;;;;;;;AAeA,SAAS,OAAO,gBAAgB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,SAAS;AAYX,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC5C,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC1D,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,OAAO,EAAE,KAAK,CAAC,aAAa,UAAU,WAAW,CAAC,EAAE,SAAS;AAAA,EAC7D,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,gBAAgB,EAAE,MAAM,EAAE,OAAO;AAAA,IAC/B,MAAM,EAAE,OAAO;AAAA,IACf,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,OAAO,EAAE,OAAO;AAAA,IAChB,OAAO,EAAE,OAAO;AAAA,IAChB,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,SAAS,EAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAKM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,KAAK,CAAC,eAAe,WAAW,cAAc,eAAe,UAAU,CAAC;AAAA,EAChF,SAAS,EAAE,OAAO;AAAA,EAClB,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EACjC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAClC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,QAAQ;AAAA,EACrB,UAAU,EAAE,KAAK,CAAC,YAAY,WAAW,eAAe,WAAW,YAAY,SAAS,CAAC;AAAA,EACzF,SAAS,qBAAqB,SAAS;AACzC,CAAC;AAOM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,SAAS,EAAE,QAAQ,CAAC;AAAA,EACpB,UAAU,EAAE,MAAM,qBAAqB;AAAA,EACvC,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AAAA;AAAA,EAC1C,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA;AAAA,EAChC,aAAa,EAAE,OAAO;AACxB,CAAC;AAqBM,IAAM,eAAN,MAAM,cAAa;AAAA,EAChB;AAAA,EACA;AAAA,EACA,SAAkB;AAAA,EAClB,QAAiB;AAAA;AAAA,EAGzB,OAAgB,YAAoC;AAAA,IAClD,oBAAoB;AAAA;AAAA,IACpB,oBAAoB;AAAA;AAAA,IACpB,cAAc;AAAA;AAAA,IACd,eAAe;AAAA;AAAA,IACf,sBAAsB;AAAA;AAAA,IACtB,2BAA2B;AAAA;AAAA,IAC3B,mBAAmB;AAAA;AAAA,IACnB,mBAAmB;AAAA;AAAA,IACnB,qBAAqB;AAAA;AAAA,IACrB,mBAAmB;AAAA;AAAA,EACrB;AAAA,EAEA,YAAY,aAAqB;AAC/B,SAAK,cAAc;AACnB,SAAK,OAAO,KAAK,gBAAgB;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAuB;AAC7B,WAAO,KAAK,KAAK,aAAa,SAAS,UAAU,wBAAwB;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAoC;AAC1C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,MACZ,cAAc,CAAC;AAAA,MACf,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAkC;AACtC,QAAI,KAAK,QAAQ;AACf,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,YAAY,KAAK,aAAa;AAEpC,QAAI;AACF,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,UAAU,MAAM,SAAS,WAAW,OAAO;AACjD,cAAM,SAAS,qBAAqB,SAAS,sBAAsB;AAEnE,YAAI,OAAO,SAAS;AAClB,eAAK,OAAO,OAAO;AACnB,eAAK,SAAS;AAEd,eAAK,oBAAoB;AACzB,iBAAO,KAAK;AAAA,QACd;AAGA,gBAAQ,MAAM,+BAA+B,OAAO,KAAK,EAAE;AAC3D,cAAM,gBAAgB,IAAI,cAAc,SAAS;AAEjD,YAAI,MAAM,cAAc,kBAAkB,GAAG;AAC3C,kBAAQ,MAAM,0BAA0B;AACxC,gBAAM,YAAY,MAAM,SAAS,WAAW,OAAO;AACnD,gBAAM,kBAAkB,qBAAqB,WAAW,sBAAsB;AAC9E,cAAI,gBAAgB,SAAS;AAC3B,iBAAK,OAAO,gBAAgB;AAC5B,iBAAK,SAAS;AAEd,iBAAK,oBAAoB;AACzB,mBAAO,KAAK;AAAA,UACd;AAAA,QACF;AAEA,gBAAQ,MAAM,0CAA0C;AAAA,MAC1D;AAAA,IACF,SAAS,OAAO;AAEd,cAAQ,MAAM,oCAAoC,KAAK,EAAE;AAAA,IAC3D;AAEA,SAAK,OAAO,KAAK,gBAAgB;AACjC,SAAK,SAAS;AACd,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,sBAA4B;AAClC,UAAM,OAAO,oBAAI,IAAoB;AACrC,UAAM,WAAqB,CAAC;AAG5B,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK,SAAS,QAAQ,KAAK;AAClD,YAAM,UAAU,KAAK,KAAK,SAAS,CAAC;AACpC,UAAI,CAAC,QAAS;AAEd,YAAM,aAAa,KAAK,cAAc,OAAO;AAE7C,UAAI,KAAK,IAAI,UAAU,GAAG;AAExB,iBAAS,KAAK,CAAC;AAAA,MACjB,OAAO;AACL,aAAK,IAAI,YAAY,CAAC;AAAA,MACxB;AAAA,IACF;AAGA,QAAI,SAAS,SAAS,GAAG;AACvB,eAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,cAAM,MAAM,SAAS,CAAC;AACtB,YAAI,QAAQ,QAAW;AACrB,eAAK,KAAK,SAAS,OAAO,KAAK,CAAC;AAAA,QAClC;AAAA,MACF;AACA,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,SAAS,KAAK,QAAQ;AAC9B;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,YAAY,KAAK,KAAK,aAAa,SAAS,QAAQ;AAG1D,UAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAG1C,UAAM,gBAAgB,IAAI,cAAc,SAAS;AACjD,UAAM,cAAc,aAAa;AAGjC,SAAK,KAAK,eAAc,oBAAI,KAAK,GAAE,YAAY;AAG/C,UAAM,gBAAgB,WAAW,KAAK,IAAI;AAE1C,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,SAAkC;AAGtD,UAAM,oBAAoB,QAAQ,QAC/B,QAAQ,QAAQ,GAAG,EACnB,YAAY,EACZ,KAAK;AAER,WAAO,GAAG,QAAQ,IAAI,IAAI,QAAQ,QAAQ,IAAI,iBAAiB;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAW,SAA4C;AAC3D,UAAM,KAAK,KAAK;AAGhB,QAAI,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,QAAQ,EAAE,GAAG;AACrD,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,KAAK,aAAa,SAAS,QAAQ,EAAE,GAAG;AAC/C,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,KAAK,cAAc,OAAO;AAC7C,UAAM,gBAAgB,KAAK,KAAK,SAAS;AAAA,MAAU,OACjD,CAAC,EAAE,aAAa,KAAK,cAAc,CAAC,MAAM;AAAA,IAC5C;AAEA,QAAI,iBAAiB,GAAG;AAEtB,YAAM,WAAW,KAAK,KAAK,SAAS,aAAa;AACjD,UAAI,UAAU;AAEZ,iBAAS,YAAY,QAAQ;AAC7B,iBAAS,UAAU,QAAQ;AAC3B,iBAAS,UAAU,QAAQ;AAC3B,iBAAS,gBAAgB,QAAQ;AACjC,iBAAS,kBAAkB,QAAQ;AAGnC,aAAK,KAAK,SAAS,OAAO,eAAe,CAAC;AAC1C,aAAK,KAAK,SAAS,QAAQ,QAAQ;AAEnC,aAAK,QAAQ;AACb,cAAM,KAAK,KAAK;AAAA,MAClB;AACA,aAAO;AAAA,IACT;AAGA,SAAK,KAAK,SAAS,QAAQ,OAAO;AAGlC,QAAI,KAAK,KAAK,SAAS,SAAS,KAAK;AACnC,WAAK,KAAK,WAAW,KAAK,KAAK,SAAS,MAAM,GAAG,GAAG;AAAA,IACtD;AAEA,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,YAA6B;AAC5C,UAAM,WAAW,KAAK,KAAK,UAAU,UAAU;AAC/C,UAAM,WAAW,cAAa,UAAU,UAAU,KAAK;AAEvD,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,KAAK,IAAI,IAAI,WAAW;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,YAAmC;AAC1D,UAAM,KAAK,KAAK;AAChB,SAAK,KAAK,UAAU,UAAU,IAAI,KAAK,IAAI;AAC3C,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB,QAAgB,GAAsB;AACtD,WAAO,KAAK,KAAK,SACd,OAAO,OAAK,CAAC,EAAE,SAAS,EACxB,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EACtC,MAAM,GAAG,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAoC;AAClC,WAAO,CAAC,GAAG,KAAK,KAAK,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,WAAqC;AACxD,UAAM,KAAK,KAAK;AAEhB,UAAM,UAAU,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAC/D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,YAAQ,YAAY;AAGpB,QAAI,CAAC,KAAK,KAAK,aAAa,SAAS,SAAS,GAAG;AAC/C,WAAK,KAAK,aAAa,KAAK,SAAS;AAGrC,UAAI,KAAK,KAAK,aAAa,SAAS,KAAK;AACvC,aAAK,KAAK,eAAe,KAAK,KAAK,aAAa,MAAM,IAAI;AAAA,MAC5D;AAAA,IACF;AAEA,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAqC;AACvD,UAAM,KAAK,KAAK;AAEhB,UAAM,QAAQ,KAAK,KAAK,SAAS,UAAU,OAAK,EAAE,OAAO,SAAS;AAClE,QAAI,UAAU,IAAI;AAChB,aAAO;AAAA,IACT;AAEA,SAAK,KAAK,SAAS,OAAO,OAAO,CAAC;AAClC,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAgC;AACpC,UAAM,KAAK,KAAK;AAChB,SAAK,KAAK,YAAY,CAAC;AACvB,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,WAAgD;AACzD,WAAO,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAmB,SAAqD;AAC1F,UAAM,KAAK,KAAK;AAEhB,UAAM,UAAU,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAC/D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,SAAS,OAAO;AAC9B,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,UAA0D;AAC9E,WAAO,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,aAAa,YAAY,CAAC,EAAE,SAAS;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,MAAkD;AAClE,WAAO,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,SAAS,QAAQ,CAAC,EAAE,SAAS;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,QAAgB,IAAuB;AACvD,UAAM,SAAS,KAAK,IAAI,IAAK,QAAQ,KAAK,KAAK;AAC/C,WAAO,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,aAAa,MAAM;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,WAME;AACA,UAAM,QAAQ;AAAA,MACZ,OAAO,KAAK,KAAK,SAAS;AAAA,MAC1B,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY,CAAC;AAAA,MACb,QAAQ,CAAC;AAAA,IACX;AAEA,eAAW,WAAW,KAAK,KAAK,UAAU;AACxC,UAAI,QAAQ,WAAW;AACrB,cAAM;AAAA,MACR,OAAO;AACL,cAAM;AAAA,MACR;AAEA,YAAM,WAAW,QAAQ,QAAQ,KAAK,MAAM,WAAW,QAAQ,QAAQ,KAAK,KAAK;AACjF,YAAM,OAAO,QAAQ,IAAI,KAAK,MAAM,OAAO,QAAQ,IAAI,KAAK,KAAK;AAAA,IACnE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,aAAqB,IAAqB;AAC/D,UAAM,KAAK,KAAK;AAEhB,UAAM,SAAS,KAAK,IAAI,IAAK,aAAa,KAAK,KAAK,KAAK;AACzD,UAAM,gBAAgB,KAAK,KAAK,SAAS;AAEzC,SAAK,KAAK,WAAW,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,aAAa,MAAM;AAEzE,UAAM,SAAS,gBAAgB,KAAK,KAAK,SAAS;AAClD,QAAI,SAAS,GAAG;AACd,WAAK,QAAQ;AACb,YAAM,KAAK,KAAK;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAoC;AACxC,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;AAMA,IAAM,gBAA2C,oBAAI,IAAI;AAKlD,SAAS,gBAAgB,aAAmC;AACjE,MAAI,QAAQ,cAAc,IAAI,WAAW;AACzC,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,aAAa,WAAW;AACpC,kBAAc,IAAI,aAAa,KAAK;AAAA,EACtC;AACA,SAAO;AACT;;;ACviBA,SAAS,gBAAgB;AAuCzB,IAAM,iBAAuC;AAAA,EAC3C,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,wBAAwB;AAC1B;AASO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,aAAqB,SAAwC,CAAC,GAAG;AAC3E,SAAK,cAAc;AACnB,SAAK,SAAS,EAAE,GAAG,gBAAgB,GAAG,OAAO;AAC7C,SAAK,gBAAgB,iBAAiB,WAAW;AACjD,SAAK,eAAe,gBAAgB,WAAW;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,0BAAsD;AAC1D,UAAM,WAA8B,CAAC;AAErC,QAAI;AAEF,YAAM,QAAQ,MAAM,eAAe,KAAK,WAAW;AACnD,YAAM,eAAe,MAAM,aAAa,IAAI;AAAA,QAC1C,SAAS,KAAK;AAAA,QACd,OAAO;AAAA,QACP,iBAAiB;AAAA,MACnB,CAAC;AAED,UAAI,aAAa,SAAS,GAAG;AAC3B,eAAO;AAAA,MACT;AAGA,YAAM,iBAAiB,oBAAI,IAAoB;AAC/C,iBAAW,EAAE,MAAM,KAAK,cAAc;AACpC,cAAM,OAAO,MAAM;AACnB,uBAAe,IAAI,OAAO,eAAe,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MAC9D;AAEA,YAAM,cAAc,CAAC,GAAG,eAAe,QAAQ,CAAC,EAC7C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAG7B,YAAM,gBAAgB,oBAAI,IAAoB;AAC9C,iBAAW,CAAC,MAAM,KAAK,KAAK,aAAa;AACvC,cAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,YAAI,MAAM,SAAS,GAAG;AACpB,gBAAM,MAAM,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AACvC,wBAAc,IAAI,MAAM,cAAc,IAAI,GAAG,KAAK,KAAK,KAAK;AAAA,QAC9D;AAAA,MACF;AAEA,YAAM,aAAa,CAAC,GAAG,cAAc,QAAQ,CAAC,EAC3C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAE7B,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,CAAC,QAAQ,WAAW,IAAI,WAAW,CAAC;AAC1C,cAAM,cAAc,aAAa;AACjC,cAAM,aAAc,cAAc,cAAe;AAEjD,YAAI,cAAc,IAAI;AACpB,mBAAS,KAAK;AAAA,YACZ,MAAM;AAAA,YACN,aAAa,GAAG,SAAS,MAAM,CAAC,SAAS,WAAW,QAAQ,CAAC,CAAC;AAAA,YAC9D,QAAQ,GAAG,MAAM;AAAA,YACjB,cAAc;AAAA,YACd,iBAAiB,KAAK,MAAM,eAAe,IAAI,KAAK,OAAO,yBAAyB,IAAI;AAAA,YACxF,YAAY,KAAK,IAAI,KAAK,aAAa,MAAM,GAAG;AAAA,YAChD,UAAU;AAAA,cACR,GAAG,WAAW,cAAc,MAAM;AAAA,cAClC,GAAG,WAAW,QAAQ,CAAC,CAAC;AAAA,cACxB,cAAc,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,YAClH;AAAA,YACA,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF;AAGA,YAAM,gBAAgB,aAAa,OAAO,OAAK,EAAE,MAAM,aAAa,UAAU,EAAE;AAChF,YAAM,eAAe,aAAa,OAAO,OAAK,EAAE,MAAM,aAAa,SAAS,EAAE;AAE9E,UAAI,iBAAiB,GAAG;AACtB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,aAAa,GAAG,aAAa;AAAA,UAC7B,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,YAAY,KAAK,IAAI,MAAM,MAAM,gBAAgB,GAAG;AAAA,UACpD,UAAU;AAAA,YACR,GAAG,aAAa;AAAA,YAChB,GAAG,YAAY;AAAA,YACf;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAGA,YAAM,kBAAkB,oBAAI,IAAoB;AAChD,iBAAW,EAAE,MAAM,KAAK,cAAc;AACpC,wBAAgB,IAAI,MAAM,QAAQ,gBAAgB,IAAI,MAAM,KAAK,KAAK,KAAK,CAAC;AAAA,MAC9E;AAEA,YAAM,eAAe,CAAC,GAAG,gBAAgB,QAAQ,CAAC,EAC/C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAE7B,UAAI,aAAa,SAAS,GAAG;AAC3B,cAAM,CAAC,UAAU,aAAa,IAAI,aAAa,CAAC;AAChD,cAAM,aAAc,gBAAgB,aAAa,SAAU;AAE3D,YAAI,cAAc,MAAM,iBAAiB,GAAG;AAC1C,gBAAM,WAAW,KAAK,gBAAgB,QAAQ;AAC9C,mBAAS,KAAK;AAAA,YACZ,MAAM;AAAA,YACN,aAAa,GAAG,QAAQ,gBAAgB,WAAW,QAAQ,CAAC,CAAC;AAAA,YAC7D,QAAQ,GAAG,QAAQ;AAAA,YACnB,cAAc;AAAA,YACd,iBAAiB,KAAK,MAAM,gBAAgB,GAAG;AAAA,YAC/C,YAAY,KAAK,IAAI,MAAM,aAAa,MAAM,GAAG;AAAA,YACjD,UAAU;AAAA,cACR,GAAG,aAAa,gBAAgB,QAAQ;AAAA,cACxC,GAAG,WAAW,QAAQ,CAAC,CAAC;AAAA,cACxB,mCAAmC,QAAQ;AAAA,YAC7C;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,MAAM,qBAAqB,aAAa;AAC1C,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,YAAY;AAAA,UACZ,UAAU;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IAEF,SAAS,OAAO;AACd,cAAQ,MAAM,wCAAwC,KAAK;AAAA,IAC7D;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,OAAgF;AACtG,UAAM,cAA+F;AAAA,MACnG,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,eAAe;AAAA,IACjB;AACA,WAAO,YAAY,KAAK,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,4BAAwD;AAC5D,UAAM,WAAW,MAAM,KAAK,wBAAwB;AACpD,UAAM,gBAAmC,CAAC;AAG1C,UAAM,gBAAgB,SAAS,OAAO,OAAK,EAAE,cAAc,KAAK,OAAO,aAAa;AAGpF,UAAM,KAAK,cAAc,KAAK;AAC9B,UAAM,cAAc,KAAK,cAAc,eAAe;AAGtD,UAAM,iBAAiB,KAAK,OAAO,iBAAiB,YAAY;AAChE,QAAI,kBAAkB,GAAG;AACvB,aAAO;AAAA,IACT;AAGA,eAAW,WAAW,cAAc,MAAM,GAAG,cAAc,GAAG;AAC5D,YAAM,WAAW,QAAQ,SAAS,iBAAiB,WAAW;AAC9D,YAAM,WAAW,oBAAI,KAAK;AAC1B,eAAS,QAAQ,SAAS,QAAQ,IAAI,KAAK,OAAO,gBAAgB;AAElE,oBAAc,KAAK;AAAA,QACjB;AAAA,QACA,MAAM;AAAA,UACJ,aAAa,KAAK,wBAAwB,OAAO;AAAA,UACjD,MAAM;AAAA,UACN,QAAQ,QAAQ;AAAA,UAChB,QAAQ,QAAQ;AAAA,UAChB,cAAc,QAAQ;AAAA,UACtB,YAAY,QAAQ;AAAA,UACpB,QAAQ;AAAA,UACR,eAAe;AAAA,UACf,YAAY,QAAQ;AAAA,UACpB,UAAU,SAAS,YAAY;AAAA,UAC/B,UAAU,QAAQ;AAAA,UAClB,UAAU,QAAQ;AAAA,QACpB;AAAA,QACA,WAAW,KAAK,sBAAsB,OAAO;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAAwB,SAAkC;AAChE,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK;AACH,eAAO,oBAAoB,QAAQ,YAAY,MAAM,GAAG,EAAE,CAAC,CAAC,OAAO,KAAK,OAAO,sBAAsB;AAAA,MACvG,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO,UAAU,QAAQ,YAAY,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,MACpD,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO,QAAQ;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,SAAkC;AAC9D,UAAM,WAAW,QAAQ,SAAS,KAAK,IAAI;AAC3C,WAAO,sBAAsB,QAAQ,kBAAkB,QAAQ,aAAa,KAAK,QAAQ,CAAC,CAAC;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAqC;AACzC,UAAM,gBAAgB,MAAM,KAAK,0BAA0B;AAC3D,UAAM,eAAuB,CAAC;AAE9B,eAAW,eAAe,eAAe;AACvC,YAAM,OAAa;AAAA,QACjB,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,QAChE,GAAG,YAAY;AAAA,QACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AAEA,YAAM,KAAK,cAAc,QAAQ,IAAI;AACrC,mBAAa,KAAK,IAAI;AAGtB,UAAI,KAAK,aAAa,iBAAiB,iBAAiB,GAAG;AACzD,cAAM,UAA2B;AAAA,UAC/B,IAAI,gBAAgB,KAAK,EAAE;AAAA,UAC3B,MAAM;AAAA,UACN,SAAS,uBAAuB,KAAK,WAAW;AAAA,UAChD,SAAS,YAAY;AAAA,UACrB,iBAAiB;AAAA,UACjB,eAAe,CAAC;AAAA,UAChB,UAAU;AAAA,UACV,WAAW,KAAK,IAAI;AAAA,UACpB,WAAW;AAAA,UACX,UAAU;AAAA,UACV,SAAS;AAAA,YACP,UAAU,YAAY,QAAQ;AAAA,UAChC;AAAA,QACF;AACA,cAAM,KAAK,aAAa,WAAW,OAAO;AAC1C,cAAM,KAAK,aAAa,mBAAmB,iBAAiB;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAoC;AACxC,UAAM,KAAK,cAAc,KAAK;AAC9B,UAAM,cAAc,KAAK,cAAc,eAAe;AAEtD,eAAW,QAAQ,aAAa;AAC9B,YAAM,eAAe,MAAM,KAAK,kBAAkB,IAAI;AAGtD,YAAM,KAAK,cAAc,WAAW,KAAK,IAAI,EAAE,aAAa,CAAC;AAG7D,UAAI,KAAK,eAAe,MAAM,YAAY,GAAG;AAC3C,cAAM,KAAK,cAAc,WAAW,KAAK,IAAI;AAAA,UAC3C,QAAQ;AAAA,UACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,UACnC;AAAA,QACF,CAAC;AAGD,cAAM,KAAK,yBAAyB,IAAI;AAAA,MAC1C;AAGA,UAAI,KAAK,UAAU;AACjB,cAAM,WAAW,IAAI,KAAK,KAAK,QAAQ;AACvC,YAAI,KAAK,IAAI,IAAI,SAAS,QAAQ,KAAK,CAAC,KAAK,eAAe,MAAM,YAAY,GAAG;AAC/E,gBAAM,KAAK,cAAc,WAAW,KAAK,IAAI;AAAA,YAC3C,QAAQ;AAAA,YACR;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,kBAAkB,MAA6B;AAC3D,QAAI;AACF,YAAM,SAAS,MAAM,aAAa,IAAI;AAAA,QACpC,SAAS,KAAK;AAAA,QACd,OAAO;AAAA,QACP,iBAAiB;AAAA,MACnB,CAAC;AAGD,UAAI,KAAK,OAAO,SAAS,SAAS,GAAG;AACnC,cAAM,SAAS,KAAK,OAAO,QAAQ,WAAW,EAAE;AAGhD,YAAI,OAAO,SAAS,GAAG,GAAG;AACxB,iBAAO,OAAO,OAAO,OAAK,EAAE,MAAM,KAAK,WAAW,MAAM,CAAC,EAAE;AAAA,QAC7D;AAGA,eAAO,OAAO,OAAO,OAAK,EAAE,MAAM,UAAU,MAAM,EAAE;AAAA,MACtD;AAEA,UAAI,KAAK,WAAW,mBAAmB;AACrC,eAAO,OAAO,OAAO,OAAK,EAAE,MAAM,aAAa,UAAU,EAAE;AAAA,MAC7D;AAGA,YAAM,OAAO,KAAK,YAAY,YAAY;AAI1C,YAAM,WAAW,KAAK,YAAY,MAAM,wEAAwE;AAChH,UAAI,YAAY,SAAS,CAAC,GAAG;AAC3B,cAAM,UAAU,SAAS,CAAC,EAAE,YAAY,EAAE,QAAQ,UAAU,EAAE;AAC9D,cAAM,iBAAiB,OAAO,OAAO,OAAK;AACxC,gBAAM,WAAW,EAAE,MAAM,KAAK,YAAY;AAE1C,iBAAO,SAAS,SAAS,IAAI,OAAO,GAAG,KAChC,SAAS,SAAS,KAAK,OAAO,IAAI,KAClC,SAAS,WAAW,GAAG,OAAO,GAAG,KACjC,SAAS,WAAW,GAAG,OAAO,IAAI;AAAA,QAC3C,CAAC;AACD,YAAI,eAAe,SAAS,KAAK,KAAK,SAAS,OAAO,GAAG;AACvD,iBAAO,eAAe;AAAA,QACxB;AAAA,MACF;AAGA,UAAI,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,eAAe,GAAG;AAC3F,cAAM,iBAAiB,OAAO,OAAO,OAAK;AACxC,gBAAM,MAAM,EAAE,MAAM,MAAM,YAAY;AACtC,iBAAO,IAAI,SAAS,QAAQ,KAAK,IAAI,SAAS,WAAW,KAClD,IAAI,SAAS,YAAY,KAAK,IAAI,SAAS,aAAa,KACxD,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,mBAAmB;AAAA,QACtE,CAAC;AACD,eAAO,eAAe;AAAA,MACxB;AAGA,UAAI,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,cAAc,GAAG;AAC3F,cAAM,iBAAiB,OAAO;AAAA,UAAO,OACnC,EAAE,MAAM,UAAU,cAAc,EAAE,MAAM,UAAU,aAClD,EAAE,MAAM,aAAa;AAAA,QACvB;AACA,eAAO,eAAe;AAAA,MACxB;AAGA,UAAI,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,UAAU,GAAG;AACrF,cAAM,aAAa,OAAO;AAAA,UAAO,OAC/B,EAAE,MAAM,UAAU,eAClB,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,MAAM,KAC3C,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,KAAK;AAAA,QAC5C;AACA,eAAO,WAAW;AAAA,MACpB;AAGA,UAAI,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,UAAU,GAAG;AACtD,cAAM,aAAa,OAAO;AAAA,UAAO,OAC/B,EAAE,MAAM,UAAU,UAClB,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,MAAM,KAC3C,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,UAAU;AAAA,QACjD;AACA,eAAO,WAAW;AAAA,MACpB;AAGA,UAAI,KAAK,SAAS,aAAa,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,UAAU,GAAG;AACtF,cAAM,aAAa,OAAO;AAAA,UAAO,OAC/B,EAAE,MAAM,UAAU,iBAClB,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,aAAa,KAClD,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,MAAM;AAAA,QAC7C;AACA,eAAO,WAAW;AAAA,MACpB;AAGA,UAAI,KAAK,SAAS,eAAe,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,YAAY,GAAG;AAC1F,cAAM,aAAa,OAAO;AAAA,UAAO,OAC/B,EAAE,MAAM,UAAU,mBAClB,EAAE,MAAM,MAAM,YAAY,EAAE,SAAS,eAAe;AAAA,QACtD;AACA,eAAO,WAAW;AAAA,MACpB;AAGA,UAAI,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,OAAO,GAAG;AAC1E,cAAM,YAAY,OAAO;AAAA,UAAO,OAC9B,EAAE,MAAM,UAAU,iBAClB,EAAE,MAAM,aAAa,cACrB,EAAE,MAAM,aAAa;AAAA,QACvB;AACA,eAAO,UAAU;AAAA,MACnB;AAGA,UAAI,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,SAAS,GAAG;AAElF,eAAO,OAAO;AAAA,MAChB;AAGA,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,MAAY,cAA+B;AAChE,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,eAAO,gBAAgB,KAAK;AAAA,MAC9B,KAAK;AACH,eAAO,gBAAgB,KAAK;AAAA,MAC9B,KAAK;AACH,eAAO,gBAAgB,KAAK;AAAA,MAC9B;AACE,eAAO,gBAAgB,KAAK;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,yBAAyB,MAA2B;AAEhE,UAAM,kBAAkB,MAAM,KAAK,yBAAyB,IAAI;AAGhE,QAAI,KAAK,eAAe,UAAa,KAAK,eAAe,MAAM;AAC7D,YAAM,IAAI,MAAM,QAAQ,KAAK,EAAE,qBAAqB;AAAA,IACtD;AACA,QAAI,KAAK,iBAAiB,UAAa,KAAK,iBAAiB,MAAM;AACjE,YAAM,IAAI,MAAM,QAAQ,KAAK,EAAE,uBAAuB;AAAA,IACxD;AACA,QAAI,KAAK,WAAW,UAAa,KAAK,WAAW,MAAM;AACrD,YAAM,IAAI,MAAM,QAAQ,KAAK,EAAE,iBAAiB;AAAA,IAClD;AAGA,aAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;AAC/C,YAAM,QAAQ,gBAAgB,CAAC;AAC/B,UAAI,CAAC,OAAO;AACV,cAAM,IAAI,MAAM,2BAA2B,CAAC,oBAAoB;AAAA,MAClE;AACA,UAAI,CAAC,MAAM,MAAM;AACf,cAAM,IAAI,MAAM,2BAA2B,CAAC,qBAAqB;AAAA,MACnE;AACA,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,2BAA2B,CAAC,4BAA4B;AAAA,MAC1E;AACA,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,2BAA2B,CAAC,sBAAsB;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,UAA2B;AAAA,MAC/B,IAAI,oBAAoB,KAAK,EAAE;AAAA,MAC/B,MAAM;AAAA,MACN,SAAS,kBAAkB,KAAK,WAAW;AAAA,MAC3C,SAAS,cAAc,KAAK,UAAU,YAAY,KAAK,YAAY,gBAAgB,KAAK,MAAM;AAAA,MAC9F,eAAe,CAAC;AAAA,MAChB,UAAU;AAAA,MACV,WAAW,KAAK,IAAI;AAAA,MACpB,WAAW;AAAA,MACX,UAAU;AAAA,MACV,SAAS;AAAA,QACP,eAAe,gBAAgB;AAAA,QAC/B,gBAAgB,gBAAgB,MAAM,GAAG,EAAE,EAAE,IAAI,YAAU;AAAA,UACzD,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,OAAO,MAAM;AAAA,UACb,OAAO,MAAM;AAAA,UACb,YAAY,MAAM;AAAA,QACpB,EAAE;AAAA,QACF,SAAS,gBAAgB,SAAS,IAC9B,YAAY,gBAAgB,MAAM,SAAS,gBAAgB,SAAS,IAAI,MAAM,EAAE,wBAChF;AAAA,MACN;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AACA,QAAI,QAAQ,QAAQ,kBAAkB,QAAW;AAC/C,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AACA,QAAI,QAAQ,QAAQ,gBAAgB,MAAM,CAAC,QAAQ,QAAQ,kBAAkB,QAAQ,QAAQ,eAAe,WAAW,IAAI;AACzH,YAAM,IAAI,MAAM,oBAAoB,QAAQ,QAAQ,aAAa,oCAAoC;AAAA,IACvG;AACA,QAAI,QAAQ,QAAQ,kBAAkB,QAAQ,QAAQ,gBAAgB,QAAQ;AAC5E,YAAM,IAAI,MAAM,kBAAkB,QAAQ,QAAQ,aAAa,0CAA0C,QAAQ,QAAQ,gBAAgB,MAAM,GAAG;AAAA,IACpJ;AAEA,UAAM,KAAK,aAAa,WAAW,OAAO;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,yBAAyB,MAAsI;AAC3K,QAAI;AAEF,YAAM,cAAc,MAAM,aAAa,IAAI;AAAA,QACzC,SAAS,KAAK;AAAA,QACd,OAAO;AAAA,QACP,iBAAiB;AAAA,MACnB,CAAC;AAGD,YAAM,WAAW,YACd,IAAI,OAAK,EAAE,KAAK,EAChB,OAAO,WAAS,MAAM,aAAa,IAAI;AAG1C,YAAM,OAAO,KAAK,YAAY,YAAY;AAC1C,YAAM,SAAS,KAAK,OAAO,YAAY;AAEvC,UAAI,mBAAmB;AAGvB,UAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,cAAM,SAAS,OAAO,QAAQ,WAAW,EAAE;AAC3C,YAAI,OAAO,SAAS,GAAG,GAAG;AACxB,6BAAmB,SAAS,OAAO,OAAK,EAAE,KAAK,WAAW,MAAM,CAAC;AAAA,QACnE,OAAO;AACL,6BAAmB,SAAS,OAAO,OAAK,EAAE,UAAU,MAAM;AAAA,QAC5D;AAAA,MACF,WAAW,WAAW,mBAAmB;AACvC,2BAAmB,SAAS,OAAO,OAAK,EAAE,aAAa,UAAU;AAAA,MACnE,OAAO;AAEL,YAAI,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,eAAe,GAAG;AAC3F,6BAAmB,SAAS,OAAO,OAAK;AACtC,kBAAM,MAAM,EAAE,MAAM,YAAY;AAChC,mBAAO,IAAI,SAAS,QAAQ,KAAK,IAAI,SAAS,WAAW,KAClD,IAAI,SAAS,YAAY,KAAK,IAAI,SAAS,aAAa,KACxD,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,mBAAmB;AAAA,UACtE,CAAC;AAAA,QACH,WAAW,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,cAAc,GAAG;AAClG,6BAAmB,SAAS;AAAA,YAAO,OACjC,EAAE,UAAU,cAAc,EAAE,UAAU,aAAa,EAAE,aAAa;AAAA,UACpE;AAAA,QACF,WAAW,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,UAAU,GAAG;AAC5F,6BAAmB,SAAS;AAAA,YAAO,OACjC,EAAE,UAAU,eACZ,EAAE,MAAM,YAAY,EAAE,SAAS,MAAM,KACrC,EAAE,MAAM,YAAY,EAAE,SAAS,KAAK;AAAA,UACtC;AAAA,QACF,WAAW,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,UAAU,GAAG;AAC7D,6BAAmB,SAAS;AAAA,YAAO,OACjC,EAAE,UAAU,UACZ,EAAE,MAAM,YAAY,EAAE,SAAS,MAAM,KACrC,EAAE,MAAM,YAAY,EAAE,SAAS,UAAU;AAAA,UAC3C;AAAA,QACF,WAAW,KAAK,SAAS,aAAa,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,UAAU,GAAG;AAC7F,6BAAmB,SAAS;AAAA,YAAO,OACjC,EAAE,UAAU,iBACZ,EAAE,MAAM,YAAY,EAAE,SAAS,aAAa,KAC5C,EAAE,MAAM,YAAY,EAAE,SAAS,MAAM;AAAA,UACvC;AAAA,QACF,WAAW,KAAK,SAAS,eAAe,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,YAAY,GAAG;AACjG,6BAAmB,SAAS;AAAA,YAAO,OACjC,EAAE,UAAU,mBACZ,EAAE,MAAM,YAAY,EAAE,SAAS,eAAe;AAAA,UAChD;AAAA,QACF,WAAW,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,OAAO,GAAG;AACjF,6BAAmB,SAAS;AAAA,YAAO,OACjC,EAAE,UAAU,iBACZ,EAAE,aAAa,cACf,EAAE,aAAa;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAGA,YAAM,gBAAgB,IAAI,KAAK,KAAK,SAAS,EAAE,QAAQ;AACvD,YAAM,iBAAiB,KAAK,aAAa,IAAI,KAAK,KAAK,UAAU,EAAE,QAAQ,IAAI,KAAK,IAAI;AAExF,aAAO,iBACJ,OAAO,WAAS;AACf,YAAI,CAAC,MAAM,WAAY,QAAO;AAC9B,cAAM,aAAa,IAAI,KAAK,MAAM,UAAU,EAAE,QAAQ;AACtD,eAAO,cAAc,iBAAiB,cAAc;AAAA,MACtD,CAAC,EACA,KAAK,CAAC,GAAG,MAAM;AAEd,cAAM,QAAQ,EAAE,aAAa,IAAI,KAAK,EAAE,UAAU,EAAE,QAAQ,IAAI;AAChE,cAAM,QAAQ,EAAE,aAAa,IAAI,KAAK,EAAE,UAAU,EAAE,QAAQ,IAAI;AAChE,eAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACL,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,QAAkC;AACjD,WAAO,KAAK,cAAc,cAAc,QAAQ,IAAI;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,QAAkC;AACjD,WAAO,KAAK,cAAc,cAAc,QAAQ,KAAK;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,kBAA0B;AACxB,WAAO,KAAK,cAAc,sBAAsB,EAC7C,OAAO,OAAK,EAAE,WAAW,QAAQ;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,yBAKE;AACA,UAAM,QAAQ,KAAK,cAAc,YAAY;AAC7C,WAAO;AAAA,MACL,QAAQ,MAAM,OAAO,OAAK,EAAE,WAAW,QAAQ,EAAE;AAAA,MACjD,UAAU,MAAM,OAAO,OAAK,EAAE,WAAW,UAAU,EAAE;AAAA,MACrD,QAAQ,MAAM,OAAO,OAAK,EAAE,WAAW,QAAQ,EAAE;AAAA,MACjD,SAAS,MAAM,OAAO,OAAK,EAAE,iBAAiB,EAAE,WAAW,QAAQ,EAAE;AAAA,IACvE;AAAA,EACF;AACF;AASA,eAAsB,+BAA+B,aAGlD;AACD,QAAM,gBAAgB,iBAAiB,WAAW;AAClD,QAAM,cAAc,KAAK;AAEzB,MAAI;AACF,UAAM,QAAQ,MAAM,eAAe,WAAW;AAC9C,UAAM,SAAS,MAAM,aAAa,IAAI;AAAA,MACpC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,iBAAiB;AAAA,IACnB,CAAC;AAED,UAAM,gBAAgB,OAAO,OAAO,OAAK,EAAE,MAAM,aAAa,UAAU,EAAE;AAC1E,UAAM,eAAe,OAAO,OAAO,OAAK,EAAE,MAAM,aAAa,SAAS,EAAE;AAGxE,QAAI,iBAAiB,GAAG;AACtB,aAAO;AAAA,QACL,aAAa;AAAA,QACb,QAAQ,GAAG,aAAa;AAAA,MAC1B;AAAA,IACF;AAGA,QAAI,gBAAgB,KAAK,gBAAgB,GAAG;AAC1C,aAAO;AAAA,QACL,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,QAAI,eAAe,GAAG;AACpB,aAAO;AAAA,QACL,aAAa;AAAA,QACb,QAAQ,GAAG,YAAY;AAAA,MACzB;AAAA,IACF;AAGA,QAAI,MAAM,cAAc,IAAI;AAC1B,aAAO;AAAA,QACL,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,WAAO;AAAA,MACL,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EAEF,QAAQ;AAEN,WAAO;AAAA,MACL,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKA,eAAsB,mBAAmB,aAAsC;AAC7E,QAAM,gBAAgB,iBAAiB,WAAW;AAClD,QAAM,EAAE,YAAY,IAAI,MAAM,+BAA+B,WAAW;AAExE,QAAM,cAAc,iBAAiB,WAAW;AAEhD,SAAO;AACT;AAMA,IAAM,eAAyC,oBAAI,IAAI;AAKhD,SAAS,eAAe,aAAkC;AAC/D,MAAI,UAAU,aAAa,IAAI,WAAW;AAC1C,MAAI,CAAC,SAAS;AACZ,cAAU,IAAI,YAAY,WAAW;AACrC,iBAAa,IAAI,aAAa,OAAO;AAAA,EACvC;AACA,SAAO;AACT;AAKO,SAAS,oBAA0B;AACxC,eAAa,MAAM;AACrB;","names":[]}
|
|
@@ -365,16 +365,21 @@ var GuardianState = class {
|
|
|
365
365
|
...evidence,
|
|
366
366
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
367
367
|
});
|
|
368
|
+
if (hypothesis.status === "proposed" && hypothesis.evidence.length === 1) {
|
|
369
|
+
hypothesis.status = "testing";
|
|
370
|
+
}
|
|
368
371
|
const supportingCount = hypothesis.evidence.filter((e) => e.type === "supporting").length;
|
|
369
372
|
const contradictingCount = hypothesis.evidence.filter((e) => e.type === "contradicting").length;
|
|
370
373
|
const total = supportingCount + contradictingCount;
|
|
371
374
|
if (total > 0) {
|
|
372
375
|
hypothesis.confidence = supportingCount / total;
|
|
373
|
-
if (hypothesis.
|
|
374
|
-
hypothesis.
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
hypothesis.
|
|
376
|
+
if (hypothesis.status === "testing") {
|
|
377
|
+
if (hypothesis.confidence > 0.8 && supportingCount >= 3) {
|
|
378
|
+
hypothesis.status = "validated";
|
|
379
|
+
hypothesis.validatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
380
|
+
} else if (hypothesis.confidence < 0.2 && contradictingCount >= 3) {
|
|
381
|
+
hypothesis.status = "invalidated";
|
|
382
|
+
}
|
|
378
383
|
}
|
|
379
384
|
}
|
|
380
385
|
hypothesis.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -671,4 +676,4 @@ function getGuardianState(projectPath) {
|
|
|
671
676
|
export {
|
|
672
677
|
getGuardianState
|
|
673
678
|
};
|
|
674
|
-
//# sourceMappingURL=chunk-
|
|
679
|
+
//# sourceMappingURL=chunk-COXK23KW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/guardian/guardian-state.ts"],"sourcesContent":["/**\n * Guardian State - Persistent state management for Guardian Agent\n * \n * Phase 1 of Guardian Agency Plan: State persistence\n * \n * Persists to: .trie/memory/guardian-state.json\n * \n * Features:\n * - Goal storage (manual and auto-generated)\n * - Risk budget tracking\n * - Hypothesis storage\n * - Agent metrics\n * - Contextual timing state (quiet hours, etc.)\n * - Atomic writes with backup rotation\n */\n\nimport { mkdir, readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { safeParseAndValidate } from '../memory/validation.js';\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\n/**\n * Schema for a Goal\n */\nexport const GoalSchema = z.object({\n id: z.string(),\n description: z.string(),\n type: z.enum(['streak', 'reduction', 'score', 'custom']),\n metric: z.string(),\n target: z.number(),\n currentValue: z.number(),\n startValue: z.number().optional(),\n status: z.enum(['active', 'achieved', 'failed', 'paused', 'rejected']),\n autoGenerated: z.boolean(),\n confidence: z.number().min(0).max(1).optional(), // For auto-generated goals\n createdAt: z.string(),\n updatedAt: z.string(),\n achievedAt: z.string().optional(),\n deadline: z.string().optional(),\n category: z.enum(['security', 'quality', 'performance', 'coverage', 'general']).optional(),\n evidence: z.array(z.string()).optional(), // Why this goal was generated\n});\n\nexport type Goal = z.infer<typeof GoalSchema>;\n\n/**\n * Schema for a Hypothesis\n */\nexport const HypothesisSchema = z.object({\n id: z.string(),\n statement: z.string(),\n confidence: z.number().min(0).max(1), // 0-1, adjusts based on validation\n status: z.enum(['proposed', 'testing', 'validated', 'invalidated', 'retired']),\n evidence: z.array(z.object({\n type: z.enum(['supporting', 'contradicting']),\n description: z.string(),\n timestamp: z.string(),\n weight: z.number().min(0).max(1).optional(),\n })),\n createdAt: z.string(),\n updatedAt: z.string(),\n validatedAt: z.string().optional(),\n testCriteria: z.string().optional(),\n category: z.enum(['timing', 'pattern', 'team', 'code', 'general']).optional(),\n});\n\nexport type Hypothesis = z.infer<typeof HypothesisSchema>;\n\n/**\n * Schema for Risk Budget\n */\nexport const RiskBudgetSchema = z.object({\n daily: z.number(),\n weekly: z.number(),\n usedToday: z.number(),\n usedThisWeek: z.number(),\n lastResetDay: z.string(), // ISO date (YYYY-MM-DD)\n lastResetWeek: z.string(), // ISO week (YYYY-WNN)\n});\n\nexport type RiskBudget = z.infer<typeof RiskBudgetSchema>;\n\n/**\n * Schema for Agent Metrics (Meta-Learning)\n */\nexport const AgentMetricsSchema = z.object({\n predictiveAccuracy: z.number().min(0).max(1),\n falsePositiveRate: z.number().min(0).max(1),\n userSatisfaction: z.number().min(0).max(1),\n hypothesisAccuracy: z.number().min(0).max(1),\n totalPredictions: z.number(),\n correctPredictions: z.number(),\n totalInsights: z.number(),\n helpfulInsights: z.number(),\n dismissedInsights: z.number(),\n actedOnInsights: z.number(),\n});\n\nexport type AgentMetrics = z.infer<typeof AgentMetricsSchema>;\n\n/**\n * Schema for Timing Context\n */\nexport const TimingContextSchema = z.object({\n quietHoursStart: z.number().min(0).max(23), // Hour of day (0-23)\n quietHoursEnd: z.number().min(0).max(23),\n quietHoursEnabled: z.boolean(),\n workDays: z.array(z.number().min(0).max(6)), // 0 = Sunday\n lastActiveTimestamp: z.number(),\n timezone: z.string().optional(),\n crunchMode: z.boolean(), // During crunch, defer low-priority items\n crunchModeUntil: z.string().optional(),\n});\n\nexport type TimingContext = z.infer<typeof TimingContextSchema>;\n\n/**\n * Schema for the entire Guardian state file\n */\nexport const GuardianStateDataSchema = z.object({\n version: z.literal(1),\n goals: z.array(GoalSchema),\n hypotheses: z.array(HypothesisSchema),\n riskBudget: RiskBudgetSchema,\n metrics: AgentMetricsSchema,\n timing: TimingContextSchema,\n scanFrequencyMs: z.number(), // Current scan frequency\n lastScanTimestamp: z.number().optional(),\n lastUpdated: z.string(),\n});\n\nexport type GuardianStateData = z.infer<typeof GuardianStateDataSchema>;\n\n// ============================================================================\n// GuardianState Class\n// ============================================================================\n\n/**\n * Persistent state manager for Guardian Agent\n * \n * Manages goals, hypotheses, risk budget, metrics, and timing context.\n */\nexport class GuardianState {\n private projectPath: string;\n private data: GuardianStateData;\n private loaded: boolean = false;\n private dirty: boolean = false;\n \n constructor(projectPath: string) {\n this.projectPath = projectPath;\n this.data = this.createDefaultState();\n }\n \n /**\n * Get the storage file path\n */\n private getStorePath(): string {\n return join(this.projectPath, '.trie', 'memory', 'guardian-state.json');\n }\n \n /**\n * Create default state\n */\n private createDefaultState(): GuardianStateData {\n const now = new Date();\n const today = now.toISOString().split('T')[0]!;\n const week = this.getISOWeek(now);\n \n return {\n version: 1,\n goals: [],\n hypotheses: [],\n riskBudget: {\n daily: 10,\n weekly: 50,\n usedToday: 0,\n usedThisWeek: 0,\n lastResetDay: today,\n lastResetWeek: week,\n },\n metrics: {\n predictiveAccuracy: 0.5, // Start neutral\n falsePositiveRate: 0.5,\n userSatisfaction: 0.5,\n hypothesisAccuracy: 0.5,\n totalPredictions: 0,\n correctPredictions: 0,\n totalInsights: 0,\n helpfulInsights: 0,\n dismissedInsights: 0,\n actedOnInsights: 0,\n },\n timing: {\n quietHoursStart: 21, // 9 PM\n quietHoursEnd: 8, // 8 AM\n quietHoursEnabled: true,\n workDays: [1, 2, 3, 4, 5], // Mon-Fri\n lastActiveTimestamp: Date.now(),\n crunchMode: false,\n },\n scanFrequencyMs: 300000, // 5 minutes default\n lastUpdated: new Date().toISOString(),\n };\n }\n \n /**\n * Get ISO week string (YYYY-WNN)\n */\n private getISOWeek(date: Date): string {\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n const dayNum = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n const weekNo = Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);\n return `${d.getUTCFullYear()}-W${weekNo.toString().padStart(2, '0')}`;\n }\n \n /**\n * Load state from disk\n */\n async load(): Promise<GuardianStateData> {\n if (this.loaded) {\n return this.data;\n }\n \n const storePath = this.getStorePath();\n \n try {\n if (existsSync(storePath)) {\n const content = await readFile(storePath, 'utf-8');\n const result = safeParseAndValidate(content, GuardianStateDataSchema);\n \n if (result.success) {\n this.data = result.data;\n this.loaded = true;\n \n // Check for day/week reset\n await this.checkAndResetBudgets();\n \n return this.data;\n }\n \n // Validation failed - attempt recovery\n console.error(` Guardian state corrupted: ${result.error}`);\n const backupManager = new BackupManager(storePath);\n \n if (await backupManager.recoverFromBackup()) {\n console.error(' ✅ Recovered from backup');\n const recovered = await readFile(storePath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, GuardianStateDataSchema);\n if (recoveredResult.success) {\n this.data = recoveredResult.data;\n this.loaded = true;\n return this.data;\n }\n }\n \n console.error(' No valid backup found, starting fresh');\n }\n } catch (error) {\n console.error(` Could not load guardian state: ${error}`);\n }\n \n this.data = this.createDefaultState();\n this.loaded = true;\n return this.data;\n }\n \n /**\n * Save state to disk\n */\n async save(): Promise<void> {\n if (!this.dirty && this.loaded) {\n return;\n }\n \n const storePath = this.getStorePath();\n const memoryDir = join(this.projectPath, '.trie', 'memory');\n \n await mkdir(memoryDir, { recursive: true });\n \n const backupManager = new BackupManager(storePath);\n await backupManager.createBackup();\n \n this.data.lastUpdated = new Date().toISOString();\n \n await atomicWriteJSON(storePath, this.data);\n \n this.dirty = false;\n }\n \n /**\n * Check and reset daily/weekly budgets if needed\n */\n private async checkAndResetBudgets(): Promise<void> {\n const now = new Date();\n const today = now.toISOString().split('T')[0]!;\n const week = this.getISOWeek(now);\n \n let needsSave = false;\n \n if (this.data.riskBudget.lastResetDay !== today) {\n this.data.riskBudget.usedToday = 0;\n this.data.riskBudget.lastResetDay = today;\n needsSave = true;\n }\n \n if (this.data.riskBudget.lastResetWeek !== week) {\n this.data.riskBudget.usedThisWeek = 0;\n this.data.riskBudget.lastResetWeek = week;\n needsSave = true;\n }\n \n if (needsSave) {\n this.dirty = true;\n await this.save();\n }\n }\n \n // ========================================================================\n // Goals\n // ========================================================================\n \n /**\n * Add a goal\n */\n async addGoal(goal: Goal): Promise<boolean> {\n await this.load();\n \n if (this.data.goals.some(g => g.id === goal.id)) {\n return false;\n }\n \n this.data.goals.push(goal);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Update a goal\n */\n async updateGoal(goalId: string, updates: Partial<Goal>): Promise<boolean> {\n await this.load();\n \n const goal = this.data.goals.find(g => g.id === goalId);\n if (!goal) {\n return false;\n }\n \n Object.assign(goal, updates, { updatedAt: new Date().toISOString() });\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Get active goals\n */\n getActiveGoals(): Goal[] {\n return this.data.goals.filter(g => g.status === 'active');\n }\n \n /**\n * Get all goals\n */\n getAllGoals(): Goal[] {\n return [...this.data.goals];\n }\n \n /**\n * Get goal by ID\n */\n getGoal(goalId: string): Goal | undefined {\n return this.data.goals.find(g => g.id === goalId);\n }\n \n /**\n * Remove a goal\n */\n async removeGoal(goalId: string): Promise<boolean> {\n await this.load();\n \n const index = this.data.goals.findIndex(g => g.id === goalId);\n if (index === -1) {\n return false;\n }\n \n this.data.goals.splice(index, 1);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Get auto-generated goals\n */\n getAutoGeneratedGoals(): Goal[] {\n return this.data.goals.filter(g => g.autoGenerated);\n }\n \n /**\n * Accept or reject an auto-generated goal\n */\n async respondToGoal(goalId: string, accept: boolean): Promise<boolean> {\n return this.updateGoal(goalId, {\n status: accept ? 'active' : 'rejected',\n });\n }\n \n // ========================================================================\n // Hypotheses\n // ========================================================================\n \n /**\n * Add a hypothesis\n */\n async addHypothesis(hypothesis: Hypothesis): Promise<boolean> {\n await this.load();\n \n if (this.data.hypotheses.some(h => h.id === hypothesis.id)) {\n return false;\n }\n \n this.data.hypotheses.push(hypothesis);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Update a hypothesis\n */\n async updateHypothesis(hypothesisId: string, updates: Partial<Hypothesis>): Promise<boolean> {\n await this.load();\n \n const hypothesis = this.data.hypotheses.find(h => h.id === hypothesisId);\n if (!hypothesis) {\n return false;\n }\n \n Object.assign(hypothesis, updates, { updatedAt: new Date().toISOString() });\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Add evidence to a hypothesis\n */\n async addEvidence(\n hypothesisId: string,\n evidence: { type: 'supporting' | 'contradicting'; description: string; weight?: number }\n ): Promise<boolean> {\n await this.load();\n \n const hypothesis = this.data.hypotheses.find(h => h.id === hypothesisId);\n if (!hypothesis) {\n return false;\n }\n \n hypothesis.evidence.push({\n ...evidence,\n timestamp: new Date().toISOString(),\n });\n \n // Transition from proposed to testing when first evidence is gathered\n if (hypothesis.status === 'proposed' && hypothesis.evidence.length === 1) {\n hypothesis.status = 'testing';\n }\n \n // Adjust confidence based on evidence\n const supportingCount = hypothesis.evidence.filter(e => e.type === 'supporting').length;\n const contradictingCount = hypothesis.evidence.filter(e => e.type === 'contradicting').length;\n const total = supportingCount + contradictingCount;\n \n if (total > 0) {\n hypothesis.confidence = supportingCount / total;\n \n // Update status based on confidence (only if already testing)\n if (hypothesis.status === 'testing') {\n if (hypothesis.confidence > 0.8 && supportingCount >= 3) {\n hypothesis.status = 'validated';\n hypothesis.validatedAt = new Date().toISOString();\n } else if (hypothesis.confidence < 0.2 && contradictingCount >= 3) {\n hypothesis.status = 'invalidated';\n }\n }\n }\n \n hypothesis.updatedAt = new Date().toISOString();\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Get active hypotheses\n */\n getActiveHypotheses(): Hypothesis[] {\n return this.data.hypotheses.filter(h => \n h.status === 'proposed' || h.status === 'testing'\n );\n }\n \n /**\n * Get validated hypotheses\n */\n getValidatedHypotheses(): Hypothesis[] {\n return this.data.hypotheses.filter(h => h.status === 'validated');\n }\n \n /**\n * Get all hypotheses\n */\n getAllHypotheses(): Hypothesis[] {\n return [...this.data.hypotheses];\n }\n \n /**\n * Get hypothesis by ID\n */\n getHypothesis(hypothesisId: string): Hypothesis | undefined {\n return this.data.hypotheses.find(h => h.id === hypothesisId);\n }\n \n // ========================================================================\n // Risk Budget\n // ========================================================================\n \n /**\n * Get current risk budget\n */\n getRiskBudget(): RiskBudget {\n return { ...this.data.riskBudget };\n }\n \n /**\n * Use risk budget\n */\n async useRiskBudget(amount: number): Promise<boolean> {\n await this.load();\n await this.checkAndResetBudgets();\n \n if (this.data.riskBudget.usedToday + amount > this.data.riskBudget.daily) {\n return false; // Would exceed daily budget\n }\n \n if (this.data.riskBudget.usedThisWeek + amount > this.data.riskBudget.weekly) {\n return false; // Would exceed weekly budget\n }\n \n this.data.riskBudget.usedToday += amount;\n this.data.riskBudget.usedThisWeek += amount;\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Check if risk budget is available\n */\n hasRiskBudget(amount: number = 1): boolean {\n return (\n this.data.riskBudget.usedToday + amount <= this.data.riskBudget.daily &&\n this.data.riskBudget.usedThisWeek + amount <= this.data.riskBudget.weekly\n );\n }\n \n /**\n * Update risk budget limits\n */\n async setRiskBudget(daily: number, weekly: number): Promise<void> {\n await this.load();\n this.data.riskBudget.daily = daily;\n this.data.riskBudget.weekly = weekly;\n this.dirty = true;\n await this.save();\n }\n \n // ========================================================================\n // Metrics\n // ========================================================================\n \n /**\n * Get agent metrics\n */\n getMetrics(): AgentMetrics {\n return { ...this.data.metrics };\n }\n \n /**\n * Record a prediction outcome\n */\n async recordPrediction(correct: boolean): Promise<void> {\n await this.load();\n \n this.data.metrics.totalPredictions++;\n if (correct) {\n this.data.metrics.correctPredictions++;\n }\n \n // Recalculate accuracy\n this.data.metrics.predictiveAccuracy = \n this.data.metrics.correctPredictions / this.data.metrics.totalPredictions;\n \n this.dirty = true;\n await this.save();\n }\n \n /**\n * Record user feedback on an insight\n */\n async recordInsightFeedback(feedback: 'helpful' | 'dismissed' | 'acted'): Promise<void> {\n await this.load();\n \n this.data.metrics.totalInsights++;\n \n switch (feedback) {\n case 'helpful':\n this.data.metrics.helpfulInsights++;\n break;\n case 'dismissed':\n this.data.metrics.dismissedInsights++;\n break;\n case 'acted':\n this.data.metrics.actedOnInsights++;\n this.data.metrics.helpfulInsights++; // Acted on is also helpful\n break;\n }\n \n // Recalculate satisfaction\n if (this.data.metrics.totalInsights > 0) {\n this.data.metrics.userSatisfaction = \n this.data.metrics.helpfulInsights / this.data.metrics.totalInsights;\n this.data.metrics.falsePositiveRate = \n this.data.metrics.dismissedInsights / this.data.metrics.totalInsights;\n }\n \n this.dirty = true;\n await this.save();\n }\n \n /**\n * Update hypothesis accuracy\n */\n async updateHypothesisAccuracy(): Promise<void> {\n await this.load();\n \n const validated = this.data.hypotheses.filter(h => h.status === 'validated').length;\n const invalidated = this.data.hypotheses.filter(h => h.status === 'invalidated').length;\n const total = validated + invalidated;\n \n if (total > 0) {\n this.data.metrics.hypothesisAccuracy = validated / total;\n this.dirty = true;\n await this.save();\n }\n }\n \n // ========================================================================\n // Timing Context\n // ========================================================================\n \n /**\n * Get timing context\n */\n getTimingContext(): TimingContext {\n return { ...this.data.timing };\n }\n \n /**\n * Check if currently in quiet hours\n */\n isQuietHours(): boolean {\n if (!this.data.timing.quietHoursEnabled) {\n return false;\n }\n \n const now = new Date();\n const hour = now.getHours();\n const start = this.data.timing.quietHoursStart;\n const end = this.data.timing.quietHoursEnd;\n \n // Handle overnight quiet hours (e.g., 21:00 - 08:00)\n if (start > end) {\n return hour >= start || hour < end;\n }\n \n // Same-day quiet hours (e.g., 12:00 - 14:00)\n return hour >= start && hour < end;\n }\n \n /**\n * Check if today is a work day\n */\n isWorkDay(): boolean {\n const dayOfWeek = new Date().getDay();\n return this.data.timing.workDays.includes(dayOfWeek);\n }\n \n /**\n * Check if in crunch mode\n */\n isInCrunchMode(): boolean {\n if (!this.data.timing.crunchMode) {\n return false;\n }\n \n if (this.data.timing.crunchModeUntil) {\n const until = new Date(this.data.timing.crunchModeUntil);\n if (Date.now() > until.getTime()) {\n // Crunch mode expired\n this.data.timing.crunchMode = false;\n this.data.timing.crunchModeUntil = undefined;\n this.dirty = true;\n return false;\n }\n }\n \n return true;\n }\n \n /**\n * Enable crunch mode\n */\n async setCrunchMode(enabled: boolean, until?: Date): Promise<void> {\n await this.load();\n this.data.timing.crunchMode = enabled;\n this.data.timing.crunchModeUntil = until?.toISOString();\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Update quiet hours settings\n */\n async setQuietHours(start: number, end: number, enabled: boolean = true): Promise<void> {\n await this.load();\n this.data.timing.quietHoursStart = start;\n this.data.timing.quietHoursEnd = end;\n this.data.timing.quietHoursEnabled = enabled;\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Update work days\n */\n async setWorkDays(days: number[]): Promise<void> {\n await this.load();\n this.data.timing.workDays = days;\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Update last active timestamp\n */\n async touchActive(): Promise<void> {\n await this.load();\n this.data.timing.lastActiveTimestamp = Date.now();\n this.dirty = true;\n await this.save();\n }\n \n // ========================================================================\n // Scan Frequency\n // ========================================================================\n \n /**\n * Get current scan frequency in milliseconds\n */\n getScanFrequencyMs(): number {\n return this.data.scanFrequencyMs;\n }\n \n /**\n * Set scan frequency\n */\n async setScanFrequency(ms: number): Promise<void> {\n await this.load();\n this.data.scanFrequencyMs = Math.max(10000, ms); // Min 10 seconds\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Record a scan timestamp\n */\n async recordScan(): Promise<void> {\n await this.load();\n this.data.lastScanTimestamp = Date.now();\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get last scan timestamp\n */\n getLastScanTimestamp(): number | undefined {\n return this.data.lastScanTimestamp;\n }\n \n // ========================================================================\n // Utility\n // ========================================================================\n \n /**\n * Get full state data\n */\n getData(): GuardianStateData {\n return { ...this.data };\n }\n \n /**\n * Force reload from disk\n */\n async reload(): Promise<GuardianStateData> {\n this.loaded = false;\n this.dirty = false;\n return this.load();\n }\n \n /**\n * Check if loaded\n */\n isLoaded(): boolean {\n return this.loaded;\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst guardianStates: Map<string, GuardianState> = new Map();\n\n/**\n * Get the GuardianState for a project (singleton per project)\n */\nexport function getGuardianState(projectPath: string): GuardianState {\n let state = guardianStates.get(projectPath);\n if (!state) {\n state = new GuardianState(projectPath);\n guardianStates.set(projectPath, state);\n }\n return state;\n}\n\n/**\n * Clear all GuardianState instances (for testing)\n */\nexport function clearGuardianStates(): void {\n guardianStates.clear();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGoalManager,
|
|
3
3
|
getInsightStore
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BHIKY5PW.js";
|
|
5
5
|
import {
|
|
6
6
|
getGuardianState
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-COXK23KW.js";
|
|
8
8
|
import {
|
|
9
9
|
findCrossProjectPatterns,
|
|
10
10
|
recordToGlobalMemory
|
|
@@ -899,14 +899,14 @@ var SlackIntegration = class {
|
|
|
899
899
|
*/
|
|
900
900
|
async sendScanNotification(_issues, priorityReport, repositoryName, branch = "main") {
|
|
901
901
|
const { urgent, high, medium, low } = priorityReport;
|
|
902
|
-
const
|
|
902
|
+
const statusEmoji = urgent.length > 0 ? "[URGENT]" : high.length > 0 ? "[HIGH]" : "[OK]";
|
|
903
903
|
const message = {
|
|
904
904
|
blocks: [
|
|
905
905
|
{
|
|
906
906
|
type: "section",
|
|
907
907
|
text: {
|
|
908
908
|
type: "mrkdwn",
|
|
909
|
-
text:
|
|
909
|
+
text: `${statusEmoji} *Trie Security Scan Complete*
|
|
910
910
|
*Repository:* ${repositoryName} (${branch})`
|
|
911
911
|
}
|
|
912
912
|
},
|
|
@@ -2329,7 +2329,7 @@ var GuardianAgent = class {
|
|
|
2329
2329
|
await this.guardianState.recordScan();
|
|
2330
2330
|
try {
|
|
2331
2331
|
const riskLevel = issues.filter((i) => i.severity === "critical").length > 0 ? "critical" : issues.filter((i) => i.severity === "serious").length >= 3 ? "high" : issues.length > 10 ? "medium" : "low";
|
|
2332
|
-
const { calculateAdaptiveScanFrequency } = await import("./goal-manager-
|
|
2332
|
+
const { calculateAdaptiveScanFrequency } = await import("./goal-manager-5FLR7IS2.js");
|
|
2333
2333
|
const result = await calculateAdaptiveScanFrequency(riskLevel);
|
|
2334
2334
|
await this.guardianState.setScanFrequency(result.frequencyMs);
|
|
2335
2335
|
} catch {
|
|
@@ -2563,4 +2563,4 @@ export {
|
|
|
2563
2563
|
GuardianAgent,
|
|
2564
2564
|
getGuardian
|
|
2565
2565
|
};
|
|
2566
|
-
//# sourceMappingURL=chunk-
|
|
2566
|
+
//# sourceMappingURL=chunk-LWT7XFDD.js.map
|