@triedotdev/mcp 1.0.123 → 1.0.124

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.
Files changed (32) hide show
  1. package/dist/{chunk-QIS2VDJL.js → chunk-7J4ZOOAD.js} +50 -13
  2. package/dist/{chunk-QIS2VDJL.js.map → chunk-7J4ZOOAD.js.map} +1 -1
  3. package/dist/{chunk-F4ZIAHTZ.js → chunk-A4EDTN6R.js} +2 -2
  4. package/dist/{chunk-B46FDUKR.js → chunk-D2CGMX7K.js} +4 -4
  5. package/dist/{chunk-CKT2A33R.js → chunk-W2DEBKZ2.js} +2 -2
  6. package/dist/{chunk-WRGSH5RT.js → chunk-WMI44VIC.js} +2 -2
  7. package/dist/{chunk-WRGSH5RT.js.map → chunk-WMI44VIC.js.map} +1 -1
  8. package/dist/cli/main.js +2 -2
  9. package/dist/cli/yolo-daemon.js +5 -5
  10. package/dist/{client-PMKE26IV.js → client-EWP4SIG3.js} +2 -2
  11. package/dist/{goal-validator-XYA364W3.js → goal-validator-CKFKJ46J.js} +2 -2
  12. package/dist/{guardian-agent-PTC6G37Q.js → guardian-agent-5QVLDPKB.js} +5 -5
  13. package/dist/{hypothesis-WWDONGPU.js → hypothesis-HFYZNIMZ.js} +2 -2
  14. package/dist/index.js +147 -27
  15. package/dist/index.js.map +1 -1
  16. package/dist/ui/chat.html +821 -0
  17. package/dist/ui/goals.html +724 -0
  18. package/dist/ui/hypotheses.html +768 -0
  19. package/dist/ui/ledger.html +711 -0
  20. package/dist/ui/nudges.html +752 -0
  21. package/package.json +1 -1
  22. package/dist/ui/memory-viewer.html +0 -773
  23. package/dist/ui/pr-review.html +0 -742
  24. package/dist/ui/scan-dashboard.html +0 -741
  25. package/dist/ui/visual-qa.html +0 -762
  26. /package/dist/{chunk-F4ZIAHTZ.js.map → chunk-A4EDTN6R.js.map} +0 -0
  27. /package/dist/{chunk-B46FDUKR.js.map → chunk-D2CGMX7K.js.map} +0 -0
  28. /package/dist/{chunk-CKT2A33R.js.map → chunk-W2DEBKZ2.js.map} +0 -0
  29. /package/dist/{client-PMKE26IV.js.map → client-EWP4SIG3.js.map} +0 -0
  30. /package/dist/{goal-validator-XYA364W3.js.map → goal-validator-CKFKJ46J.js.map} +0 -0
  31. /package/dist/{guardian-agent-PTC6G37Q.js.map → guardian-agent-5QVLDPKB.js.map} +0 -0
  32. /package/dist/{hypothesis-WWDONGPU.js.map → hypothesis-HFYZNIMZ.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tryGetClient
3
- } from "./chunk-WRGSH5RT.js";
3
+ } from "./chunk-WMI44VIC.js";
4
4
  import {
5
5
  searchIssues
6
6
  } from "./chunk-K5EXATBF.js";
@@ -801,4 +801,4 @@ export {
801
801
  getStorage,
802
802
  GotchaPredictor
803
803
  };
804
- //# sourceMappingURL=chunk-F4ZIAHTZ.js.map
804
+ //# sourceMappingURL=chunk-A4EDTN6R.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-TRIJC5MW.js";
4
4
  import {
5
5
  getHypothesisEngine
6
- } from "./chunk-CKT2A33R.js";
6
+ } from "./chunk-W2DEBKZ2.js";
7
7
  import {
8
8
  getInsightStore
9
9
  } from "./chunk-4YJ6KLGI.js";
@@ -11,11 +11,11 @@ import {
11
11
  GotchaPredictor,
12
12
  findCrossProjectPatterns,
13
13
  recordToGlobalMemory
14
- } from "./chunk-F4ZIAHTZ.js";
14
+ } from "./chunk-A4EDTN6R.js";
15
15
  import {
16
16
  isAIAvailable,
17
17
  runAIAnalysis
18
- } from "./chunk-WRGSH5RT.js";
18
+ } from "./chunk-WMI44VIC.js";
19
19
  import {
20
20
  autoResolveIssues,
21
21
  getHistoricalInsights,
@@ -2143,4 +2143,4 @@ export {
2143
2143
  GuardianAgent,
2144
2144
  getGuardian
2145
2145
  };
2146
- //# sourceMappingURL=chunk-B46FDUKR.js.map
2146
+ //# sourceMappingURL=chunk-D2CGMX7K.js.map
@@ -133,7 +133,7 @@ var HypothesisEngine = class {
133
133
  * This enables fully agentic hypothesis creation based on actual codebase observations
134
134
  */
135
135
  async generateHypothesesWithAI(context) {
136
- const { isAIAvailable, runAIAnalysis } = await import("./client-PMKE26IV.js");
136
+ const { isAIAvailable, runAIAnalysis } = await import("./client-EWP4SIG3.js");
137
137
  if (!isAIAvailable()) {
138
138
  return [];
139
139
  }
@@ -718,4 +718,4 @@ export {
718
718
  clearHypothesisEngines,
719
719
  gatherEvidenceForHypothesis
720
720
  };
721
- //# sourceMappingURL=chunk-CKT2A33R.js.map
721
+ //# sourceMappingURL=chunk-W2DEBKZ2.js.map
@@ -292,7 +292,7 @@ async function runAIWithTools(request) {
292
292
  const toolResults = [];
293
293
  for (const block of toolUseBlocks) {
294
294
  const input = block.input ?? {};
295
- allToolCalls.push({ name: block.name, input });
295
+ allToolCalls.push({ id: block.id, name: block.name, input });
296
296
  let resultText;
297
297
  let isError = false;
298
298
  try {
@@ -337,4 +337,4 @@ export {
337
337
  getAIStatusMessage,
338
338
  runAIWithTools
339
339
  };
340
- //# sourceMappingURL=chunk-WRGSH5RT.js.map
340
+ //# sourceMappingURL=chunk-WMI44VIC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ai/client.ts"],"sourcesContent":["/**\n * Centralized AI Client\n * \n * Handles API key detection, graceful fallbacks, and AI-powered analysis.\n * All agents use this for AI-enhanced analysis.\n * \n * API Key Setup:\n * 1. Set ANTHROPIC_API_KEY in your environment\n * 2. Or add it to your MCP server config (mcp.json)\n * 3. Or create .env file in your project root\n * \n * If no API key is found, agents fall back to pattern-only mode.\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { execSync } from 'node:child_process';\nimport { join } from 'path';\nimport { getWorkingDirectory, getTrieDirectory } from '../utils/workspace.js';\n\n// Cached client instance\nlet clientInstance: Anthropic | null = null;\nlet apiKeyChecked = false;\nlet apiKeyAvailable = false;\n\n/**\n * Check if AI is available (API key is set)\n */\nexport function isAIAvailable(): boolean {\n if (!apiKeyChecked) {\n checkAPIKey();\n }\n return apiKeyAvailable;\n}\n\n/**\n * Read API key from Apple Keychain (macOS only)\n */\nexport function getKeyFromKeychain(): string | null {\n if (process.platform !== 'darwin') return null;\n try {\n const result = execSync(\n 'security find-generic-password -a \"trie\" -s \"anthropic-api-key\" -w 2>/dev/null',\n { encoding: 'utf-8' }\n ).trim();\n return result.length > 10 ? result : null;\n } catch { return null; }\n}\n\n/**\n * Save API key to Apple Keychain (macOS only)\n */\nexport function saveKeyToKeychain(key: string): boolean {\n if (process.platform !== 'darwin') return false;\n try {\n try { execSync('security delete-generic-password -a \"trie\" -s \"anthropic-api-key\" 2>/dev/null'); } catch { /* not found */ }\n execSync(`security add-generic-password -a \"trie\" -s \"anthropic-api-key\" -w \"${key.replace(/\"/g, '\\\\\"')}\"`);\n return true;\n } catch { return false; }\n}\n\n/**\n * Save API key and refresh the cached state\n */\nexport function setAPIKey(key: string): { saved: boolean; method: 'keychain' | 'config' } {\n process.env.ANTHROPIC_API_KEY = key;\n clientInstance = null;\n apiKeyChecked = true;\n apiKeyAvailable = true;\n\n if (saveKeyToKeychain(key)) {\n return { saved: true, method: 'keychain' };\n }\n\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const trieDir = getTrieDirectory(workDir);\n const configPath = join(trieDir, 'config.json');\n let config: Record<string, unknown> = {};\n if (existsSync(configPath)) {\n config = JSON.parse(readFileSync(configPath, 'utf-8'));\n }\n if (!config.apiKeys || typeof config.apiKeys !== 'object') config.apiKeys = {};\n (config.apiKeys as Record<string, string>).anthropic = key;\n mkdirSync(trieDir, { recursive: true });\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n } catch { /* best effort */ }\n\n return { saved: true, method: 'config' };\n}\n\n/**\n * Check for API key in environment, keychain, config, and .env files\n */\nfunction checkAPIKey(): void {\n apiKeyChecked = true;\n \n // 1. Check standard env var first\n const envApiKey = process.env.ANTHROPIC_API_KEY;\n if (envApiKey && envApiKey.length > 10) {\n apiKeyAvailable = true;\n return;\n }\n\n // 2. Check Apple Keychain (macOS)\n const keychainKey = getKeyFromKeychain();\n if (keychainKey) {\n process.env.ANTHROPIC_API_KEY = keychainKey;\n apiKeyAvailable = true;\n return;\n }\n \n // 3. Check config file\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const configPath = join(getTrieDirectory(workDir), 'config.json');\n \n if (existsSync(configPath)) {\n const configContent = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(configContent);\n \n if (config.apiKeys?.anthropic && config.apiKeys.anthropic.length > 10) {\n process.env.ANTHROPIC_API_KEY = config.apiKeys.anthropic;\n apiKeyAvailable = true;\n return;\n }\n }\n } catch {\n // Config file doesn't exist or couldn't be read\n }\n \n // 4. Check .env files\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const envFiles = ['.env', '.env.local', '.env.production'];\n \n for (const envFile of envFiles) {\n const envPath = join(workDir, envFile);\n if (existsSync(envPath)) {\n const envContent = readFileSync(envPath, 'utf-8');\n const lines = envContent.split('\\n');\n \n for (const line of lines) {\n const match = line.match(/^\\s*ANTHROPIC_API_KEY\\s*=\\s*(.+)$/);\n if (match && match[1]) {\n const key = match[1].trim().replace(/^[\"']|[\"']$/g, '');\n if (key.length > 10) {\n process.env.ANTHROPIC_API_KEY = key;\n apiKeyAvailable = true;\n return;\n }\n }\n }\n }\n }\n } catch {\n // .env file doesn't exist or couldn't be read\n }\n \n apiKeyAvailable = false;\n}\n\n/**\n * Get the Anthropic client (lazy initialized)\n * Throws if API key is not available\n */\nexport function getClient(): Anthropic {\n if (!isAIAvailable()) {\n throw new Error(\n 'ANTHROPIC_API_KEY not found. Set it in your environment to enable AI-powered analysis.\\n' +\n 'Example: export ANTHROPIC_API_KEY=sk-ant-...'\n );\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\n/**\n * Try to get client, return null if not available\n */\nexport function tryGetClient(): Anthropic | null {\n if (!isAIAvailable()) {\n return null;\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\nexport interface AIAnalysisRequest {\n systemPrompt: string;\n userPrompt: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface AIAnalysisResult {\n success: boolean;\n content: string;\n error?: string;\n tokensUsed?: {\n input: number;\n output: number;\n };\n}\n\n/**\n * Run AI analysis with the given prompts\n */\nexport async function runAIAnalysis(request: AIAnalysisRequest): Promise<AIAnalysisResult> {\n const client = tryGetClient();\n \n if (!client) {\n return {\n success: false,\n content: '',\n error: 'AI not available - ANTHROPIC_API_KEY not set'\n };\n }\n \n try {\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: request.maxTokens || 4096,\n temperature: request.temperature ?? 0.3,\n system: request.systemPrompt,\n messages: [\n {\n role: 'user',\n content: request.userPrompt\n }\n ]\n });\n \n // Extract text content\n const textContent = response.content\n .filter((block): block is Anthropic.TextBlock => block.type === 'text')\n .map(block => block.text)\n .join('\\n');\n \n return {\n success: true,\n content: textContent,\n tokensUsed: {\n input: response.usage.input_tokens,\n output: response.usage.output_tokens\n }\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n \n // Check for specific error types\n if (errorMessage.includes('authentication') || errorMessage.includes('API key')) {\n return {\n success: false,\n content: '',\n error: 'Invalid API key. Check your ANTHROPIC_API_KEY.'\n };\n }\n \n if (errorMessage.includes('rate limit')) {\n return {\n success: false,\n content: '',\n error: 'Rate limited. Try again in a moment.'\n };\n }\n \n return {\n success: false,\n content: '',\n error: `AI analysis failed: ${errorMessage}`\n };\n }\n}\n\n/**\n * AI analysis for code issues\n */\nexport interface CodeIssueAnalysisRequest {\n issues: Array<{\n file: string;\n line?: number;\n issue: string;\n code?: string;\n }>;\n analysisType: 'validate' | 'expand' | 'fix' | 'explain';\n context?: string;\n}\n\n/**\n * Run AI analysis on code issues\n * Used by agents to validate, expand, or fix detected issues\n */\nexport async function analyzeCodeIssues(request: CodeIssueAnalysisRequest): Promise<AIAnalysisResult> {\n const systemPrompts: Record<CodeIssueAnalysisRequest['analysisType'], string> = {\n validate: `You are a senior code reviewer. Analyze the following issues detected by static analysis.\nFor each issue:\n1. Determine if it's a TRUE POSITIVE (real problem) or FALSE POSITIVE (not actually an issue)\n2. Provide a confidence score (0-100)\n3. Explain your reasoning briefly\n\nOutput format:\n### Issue 1: [file:line]\n**Verdict:** TRUE_POSITIVE / FALSE_POSITIVE\n**Confidence:** [0-100]\n**Reason:** [one line explanation]\n**Fix:** [specific fix if true positive]`,\n\n expand: `You are a security expert and senior architect. Given these detected code issues, look deeper:\n1. Are there related problems in the same code that were missed?\n2. What's the root cause of these patterns?\n3. What's the blast radius if these issues cause problems?\n4. What architectural changes would prevent these patterns?\n\nBe specific. Reference line numbers. Provide code examples.`,\n\n fix: `You are an expert programmer. For each issue, provide a specific fix:\n1. Show the exact code change needed\n2. Explain why this fix works\n3. Note any edge cases to consider\n\nUse markdown code blocks with the language specified.`,\n\n explain: `You are a patient teacher explaining code issues to a junior developer.\nFor each issue:\n1. Explain what the problem is in simple terms\n2. Explain why it's a problem (what could go wrong)\n3. Explain the fix and why it works\n4. Provide a learning resource if relevant`\n };\n\n const issuesText = request.issues.map((issue, i) => {\n let text = `### Issue ${i + 1}: ${issue.file}${issue.line ? ':' + issue.line : ''}\\n`;\n text += `**Problem:** ${issue.issue}\\n`;\n if (issue.code) {\n text += `**Code:**\\n\\`\\`\\`\\n${issue.code}\\n\\`\\`\\`\\n`;\n }\n return text;\n }).join('\\n');\n\n const userPrompt = `${request.context ? `Context: ${request.context}\\n\\n` : ''}${issuesText}`;\n\n return runAIAnalysis({\n systemPrompt: systemPrompts[request.analysisType],\n userPrompt,\n maxTokens: 4096,\n temperature: 0.2\n });\n}\n\n/**\n * Get status message about AI availability\n */\nexport function getAIStatusMessage(): string {\n if (isAIAvailable()) {\n return '[AI] AI-powered analysis enabled';\n }\n return '[!] AI not available (ANTHROPIC_API_KEY not set) - using pattern-only mode';\n}\n\nexport interface AIToolCallRecord {\n name: string;\n input: Record<string, unknown>;\n}\n\nexport interface AIToolCallResult {\n success: boolean;\n content: string;\n error?: string;\n toolCalls?: AIToolCallRecord[];\n}\n\n/**\n * Run AI analysis with tool-use support.\n * Loops until Claude returns a final text response or hits maxToolRounds.\n */\nexport async function runAIWithTools(request: {\n systemPrompt: string;\n messages: Anthropic.MessageParam[];\n tools: Anthropic.Tool[];\n executeTool: (name: string, input: Record<string, unknown>) => Promise<string>;\n maxTokens?: number;\n maxToolRounds?: number;\n}): Promise<AIToolCallResult> {\n const client = tryGetClient();\n if (!client) {\n return { success: false, content: '', error: 'AI not available - ANTHROPIC_API_KEY not set' };\n }\n\n const maxRounds = request.maxToolRounds ?? 5;\n const messages: Anthropic.MessageParam[] = [...request.messages];\n const allToolCalls: AIToolCallRecord[] = [];\n\n try {\n for (let round = 0; round < maxRounds; round++) {\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: request.maxTokens || 4096,\n temperature: 0.3,\n system: request.systemPrompt,\n messages,\n tools: request.tools,\n });\n\n const toolUseBlocks = response.content.filter(\n (b): b is Anthropic.ToolUseBlock => b.type === 'tool_use'\n );\n const textBlocks = response.content.filter(\n (b): b is Anthropic.TextBlock => b.type === 'text'\n );\n\n if (toolUseBlocks.length === 0) {\n const result: AIToolCallResult = {\n success: true,\n content: textBlocks.map(b => b.text).join('\\n'),\n };\n if (allToolCalls.length > 0) result.toolCalls = allToolCalls;\n return result;\n }\n\n // Claude wants to use tools -- execute them\n messages.push({ role: 'assistant', content: response.content });\n\n const toolResults: Anthropic.ToolResultBlockParam[] = [];\n for (const block of toolUseBlocks) {\n const input = (block.input ?? {}) as Record<string, unknown>;\n allToolCalls.push({ name: block.name, input });\n let resultText: string;\n let isError = false;\n try {\n resultText = await request.executeTool(block.name, input);\n } catch (err) {\n resultText = `Tool error: ${err instanceof Error ? err.message : String(err)}`;\n isError = true;\n }\n toolResults.push({\n type: 'tool_result',\n tool_use_id: block.id,\n content: resultText,\n is_error: isError,\n });\n }\n\n messages.push({ role: 'user', content: toolResults });\n\n if (response.stop_reason === 'end_turn') {\n const text = textBlocks.map(b => b.text).join('\\n');\n const result: AIToolCallResult = { success: true, content: text || 'Done.' };\n if (allToolCalls.length > 0) result.toolCalls = allToolCalls;\n return result;\n }\n }\n\n const result: AIToolCallResult = { success: true, content: 'Reached maximum tool rounds.' };\n if (allToolCalls.length > 0) result.toolCalls = allToolCalls;\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { success: false, content: '', error: `AI tool-use failed: ${errorMessage}` };\n }\n}\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../src/ai/client.ts"],"sourcesContent":["/**\n * Centralized AI Client\n * \n * Handles API key detection, graceful fallbacks, and AI-powered analysis.\n * All agents use this for AI-enhanced analysis.\n * \n * API Key Setup:\n * 1. Set ANTHROPIC_API_KEY in your environment\n * 2. Or add it to your MCP server config (mcp.json)\n * 3. Or create .env file in your project root\n * \n * If no API key is found, agents fall back to pattern-only mode.\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { execSync } from 'node:child_process';\nimport { join } from 'path';\nimport { getWorkingDirectory, getTrieDirectory } from '../utils/workspace.js';\n\n// Cached client instance\nlet clientInstance: Anthropic | null = null;\nlet apiKeyChecked = false;\nlet apiKeyAvailable = false;\n\n/**\n * Check if AI is available (API key is set)\n */\nexport function isAIAvailable(): boolean {\n if (!apiKeyChecked) {\n checkAPIKey();\n }\n return apiKeyAvailable;\n}\n\n/**\n * Read API key from Apple Keychain (macOS only)\n */\nexport function getKeyFromKeychain(): string | null {\n if (process.platform !== 'darwin') return null;\n try {\n const result = execSync(\n 'security find-generic-password -a \"trie\" -s \"anthropic-api-key\" -w 2>/dev/null',\n { encoding: 'utf-8' }\n ).trim();\n return result.length > 10 ? result : null;\n } catch { return null; }\n}\n\n/**\n * Save API key to Apple Keychain (macOS only)\n */\nexport function saveKeyToKeychain(key: string): boolean {\n if (process.platform !== 'darwin') return false;\n try {\n try { execSync('security delete-generic-password -a \"trie\" -s \"anthropic-api-key\" 2>/dev/null'); } catch { /* not found */ }\n execSync(`security add-generic-password -a \"trie\" -s \"anthropic-api-key\" -w \"${key.replace(/\"/g, '\\\\\"')}\"`);\n return true;\n } catch { return false; }\n}\n\n/**\n * Save API key and refresh the cached state\n */\nexport function setAPIKey(key: string): { saved: boolean; method: 'keychain' | 'config' } {\n process.env.ANTHROPIC_API_KEY = key;\n clientInstance = null;\n apiKeyChecked = true;\n apiKeyAvailable = true;\n\n if (saveKeyToKeychain(key)) {\n return { saved: true, method: 'keychain' };\n }\n\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const trieDir = getTrieDirectory(workDir);\n const configPath = join(trieDir, 'config.json');\n let config: Record<string, unknown> = {};\n if (existsSync(configPath)) {\n config = JSON.parse(readFileSync(configPath, 'utf-8'));\n }\n if (!config.apiKeys || typeof config.apiKeys !== 'object') config.apiKeys = {};\n (config.apiKeys as Record<string, string>).anthropic = key;\n mkdirSync(trieDir, { recursive: true });\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n } catch { /* best effort */ }\n\n return { saved: true, method: 'config' };\n}\n\n/**\n * Check for API key in environment, keychain, config, and .env files\n */\nfunction checkAPIKey(): void {\n apiKeyChecked = true;\n \n // 1. Check standard env var first\n const envApiKey = process.env.ANTHROPIC_API_KEY;\n if (envApiKey && envApiKey.length > 10) {\n apiKeyAvailable = true;\n return;\n }\n\n // 2. Check Apple Keychain (macOS)\n const keychainKey = getKeyFromKeychain();\n if (keychainKey) {\n process.env.ANTHROPIC_API_KEY = keychainKey;\n apiKeyAvailable = true;\n return;\n }\n \n // 3. Check config file\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const configPath = join(getTrieDirectory(workDir), 'config.json');\n \n if (existsSync(configPath)) {\n const configContent = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(configContent);\n \n if (config.apiKeys?.anthropic && config.apiKeys.anthropic.length > 10) {\n process.env.ANTHROPIC_API_KEY = config.apiKeys.anthropic;\n apiKeyAvailable = true;\n return;\n }\n }\n } catch {\n // Config file doesn't exist or couldn't be read\n }\n \n // 4. Check .env files\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const envFiles = ['.env', '.env.local', '.env.production'];\n \n for (const envFile of envFiles) {\n const envPath = join(workDir, envFile);\n if (existsSync(envPath)) {\n const envContent = readFileSync(envPath, 'utf-8');\n const lines = envContent.split('\\n');\n \n for (const line of lines) {\n const match = line.match(/^\\s*ANTHROPIC_API_KEY\\s*=\\s*(.+)$/);\n if (match && match[1]) {\n const key = match[1].trim().replace(/^[\"']|[\"']$/g, '');\n if (key.length > 10) {\n process.env.ANTHROPIC_API_KEY = key;\n apiKeyAvailable = true;\n return;\n }\n }\n }\n }\n }\n } catch {\n // .env file doesn't exist or couldn't be read\n }\n \n apiKeyAvailable = false;\n}\n\n/**\n * Get the Anthropic client (lazy initialized)\n * Throws if API key is not available\n */\nexport function getClient(): Anthropic {\n if (!isAIAvailable()) {\n throw new Error(\n 'ANTHROPIC_API_KEY not found. Set it in your environment to enable AI-powered analysis.\\n' +\n 'Example: export ANTHROPIC_API_KEY=sk-ant-...'\n );\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\n/**\n * Try to get client, return null if not available\n */\nexport function tryGetClient(): Anthropic | null {\n if (!isAIAvailable()) {\n return null;\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\nexport interface AIAnalysisRequest {\n systemPrompt: string;\n userPrompt: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface AIAnalysisResult {\n success: boolean;\n content: string;\n error?: string;\n tokensUsed?: {\n input: number;\n output: number;\n };\n}\n\n/**\n * Run AI analysis with the given prompts\n */\nexport async function runAIAnalysis(request: AIAnalysisRequest): Promise<AIAnalysisResult> {\n const client = tryGetClient();\n \n if (!client) {\n return {\n success: false,\n content: '',\n error: 'AI not available - ANTHROPIC_API_KEY not set'\n };\n }\n \n try {\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: request.maxTokens || 4096,\n temperature: request.temperature ?? 0.3,\n system: request.systemPrompt,\n messages: [\n {\n role: 'user',\n content: request.userPrompt\n }\n ]\n });\n \n // Extract text content\n const textContent = response.content\n .filter((block): block is Anthropic.TextBlock => block.type === 'text')\n .map(block => block.text)\n .join('\\n');\n \n return {\n success: true,\n content: textContent,\n tokensUsed: {\n input: response.usage.input_tokens,\n output: response.usage.output_tokens\n }\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n \n // Check for specific error types\n if (errorMessage.includes('authentication') || errorMessage.includes('API key')) {\n return {\n success: false,\n content: '',\n error: 'Invalid API key. Check your ANTHROPIC_API_KEY.'\n };\n }\n \n if (errorMessage.includes('rate limit')) {\n return {\n success: false,\n content: '',\n error: 'Rate limited. Try again in a moment.'\n };\n }\n \n return {\n success: false,\n content: '',\n error: `AI analysis failed: ${errorMessage}`\n };\n }\n}\n\n/**\n * AI analysis for code issues\n */\nexport interface CodeIssueAnalysisRequest {\n issues: Array<{\n file: string;\n line?: number;\n issue: string;\n code?: string;\n }>;\n analysisType: 'validate' | 'expand' | 'fix' | 'explain';\n context?: string;\n}\n\n/**\n * Run AI analysis on code issues\n * Used by agents to validate, expand, or fix detected issues\n */\nexport async function analyzeCodeIssues(request: CodeIssueAnalysisRequest): Promise<AIAnalysisResult> {\n const systemPrompts: Record<CodeIssueAnalysisRequest['analysisType'], string> = {\n validate: `You are a senior code reviewer. Analyze the following issues detected by static analysis.\nFor each issue:\n1. Determine if it's a TRUE POSITIVE (real problem) or FALSE POSITIVE (not actually an issue)\n2. Provide a confidence score (0-100)\n3. Explain your reasoning briefly\n\nOutput format:\n### Issue 1: [file:line]\n**Verdict:** TRUE_POSITIVE / FALSE_POSITIVE\n**Confidence:** [0-100]\n**Reason:** [one line explanation]\n**Fix:** [specific fix if true positive]`,\n\n expand: `You are a security expert and senior architect. Given these detected code issues, look deeper:\n1. Are there related problems in the same code that were missed?\n2. What's the root cause of these patterns?\n3. What's the blast radius if these issues cause problems?\n4. What architectural changes would prevent these patterns?\n\nBe specific. Reference line numbers. Provide code examples.`,\n\n fix: `You are an expert programmer. For each issue, provide a specific fix:\n1. Show the exact code change needed\n2. Explain why this fix works\n3. Note any edge cases to consider\n\nUse markdown code blocks with the language specified.`,\n\n explain: `You are a patient teacher explaining code issues to a junior developer.\nFor each issue:\n1. Explain what the problem is in simple terms\n2. Explain why it's a problem (what could go wrong)\n3. Explain the fix and why it works\n4. Provide a learning resource if relevant`\n };\n\n const issuesText = request.issues.map((issue, i) => {\n let text = `### Issue ${i + 1}: ${issue.file}${issue.line ? ':' + issue.line : ''}\\n`;\n text += `**Problem:** ${issue.issue}\\n`;\n if (issue.code) {\n text += `**Code:**\\n\\`\\`\\`\\n${issue.code}\\n\\`\\`\\`\\n`;\n }\n return text;\n }).join('\\n');\n\n const userPrompt = `${request.context ? `Context: ${request.context}\\n\\n` : ''}${issuesText}`;\n\n return runAIAnalysis({\n systemPrompt: systemPrompts[request.analysisType],\n userPrompt,\n maxTokens: 4096,\n temperature: 0.2\n });\n}\n\n/**\n * Get status message about AI availability\n */\nexport function getAIStatusMessage(): string {\n if (isAIAvailable()) {\n return '[AI] AI-powered analysis enabled';\n }\n return '[!] AI not available (ANTHROPIC_API_KEY not set) - using pattern-only mode';\n}\n\nexport interface AIToolCallRecord {\n name: string;\n input: Record<string, unknown>;\n}\n\nexport interface AIToolCallResult {\n success: boolean;\n content: string;\n error?: string;\n toolCalls?: AIToolCallRecord[];\n}\n\n/**\n * Run AI analysis with tool-use support.\n * Loops until Claude returns a final text response or hits maxToolRounds.\n */\nexport async function runAIWithTools(request: {\n systemPrompt: string;\n messages: Anthropic.MessageParam[];\n tools: Anthropic.Tool[];\n executeTool: (name: string, input: Record<string, unknown>) => Promise<string>;\n maxTokens?: number;\n maxToolRounds?: number;\n}): Promise<AIToolCallResult> {\n const client = tryGetClient();\n if (!client) {\n return { success: false, content: '', error: 'AI not available - ANTHROPIC_API_KEY not set' };\n }\n\n const maxRounds = request.maxToolRounds ?? 5;\n const messages: Anthropic.MessageParam[] = [...request.messages];\n const allToolCalls: AIToolCallRecord[] = [];\n\n try {\n for (let round = 0; round < maxRounds; round++) {\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: request.maxTokens || 4096,\n temperature: 0.3,\n system: request.systemPrompt,\n messages,\n tools: request.tools,\n });\n\n const toolUseBlocks = response.content.filter(\n (b): b is Anthropic.ToolUseBlock => b.type === 'tool_use'\n );\n const textBlocks = response.content.filter(\n (b): b is Anthropic.TextBlock => b.type === 'text'\n );\n\n if (toolUseBlocks.length === 0) {\n const result: AIToolCallResult = {\n success: true,\n content: textBlocks.map(b => b.text).join('\\n'),\n };\n if (allToolCalls.length > 0) result.toolCalls = allToolCalls;\n return result;\n }\n\n // Claude wants to use tools -- execute them\n messages.push({ role: 'assistant', content: response.content });\n\n const toolResults: Anthropic.ToolResultBlockParam[] = [];\n for (const block of toolUseBlocks) {\n const input = (block.input ?? {}) as Record<string, unknown>;\n allToolCalls.push({ id: block.id, name: block.name, input });\n let resultText: string;\n let isError = false;\n try {\n resultText = await request.executeTool(block.name, input);\n } catch (err) {\n resultText = `Tool error: ${err instanceof Error ? err.message : String(err)}`;\n isError = true;\n }\n toolResults.push({\n type: 'tool_result',\n tool_use_id: block.id,\n content: resultText,\n is_error: isError,\n });\n }\n\n messages.push({ role: 'user', content: toolResults });\n\n if (response.stop_reason === 'end_turn') {\n const text = textBlocks.map(b => b.text).join('\\n');\n const result: AIToolCallResult = { success: true, content: text || 'Done.' };\n if (allToolCalls.length > 0) result.toolCalls = allToolCalls;\n return result;\n }\n }\n\n const result: AIToolCallResult = { success: true, content: 'Reached maximum tool rounds.' };\n if (allToolCalls.length > 0) result.toolCalls = allToolCalls;\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { success: false, content: '', error: `AI tool-use failed: ${errorMessage}` };\n }\n}\n"],"mappings":"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","names":["result"]}
package/dist/cli/main.js CHANGED
@@ -43,8 +43,8 @@ import {
43
43
  listTrackedProjects,
44
44
  searchGlobalPatterns,
45
45
  updateGlobalMemoryMd
46
- } from "../chunk-F4ZIAHTZ.js";
47
- import "../chunk-WRGSH5RT.js";
46
+ } from "../chunk-A4EDTN6R.js";
47
+ import "../chunk-WMI44VIC.js";
48
48
  import {
49
49
  getDailyLogs,
50
50
  getMemoryStats,
@@ -3,18 +3,18 @@ import {
3
3
  InteractiveDashboard,
4
4
  StreamingManager,
5
5
  TrieScanTool
6
- } from "../chunk-QIS2VDJL.js";
7
- import "../chunk-B46FDUKR.js";
6
+ } from "../chunk-7J4ZOOAD.js";
7
+ import "../chunk-D2CGMX7K.js";
8
8
  import "../chunk-DFPVUMVE.js";
9
9
  import "../chunk-TRIJC5MW.js";
10
- import "../chunk-CKT2A33R.js";
10
+ import "../chunk-W2DEBKZ2.js";
11
11
  import "../chunk-4YJ6KLGI.js";
12
12
  import {
13
13
  isTrieInitialized
14
14
  } from "../chunk-6LD7OPJL.js";
15
15
  import "../chunk-ZV2K6M7T.js";
16
- import "../chunk-F4ZIAHTZ.js";
17
- import "../chunk-WRGSH5RT.js";
16
+ import "../chunk-A4EDTN6R.js";
17
+ import "../chunk-WMI44VIC.js";
18
18
  import "../chunk-K5EXATBF.js";
19
19
  import "../chunk-UHMMANC2.js";
20
20
  import "../chunk-WS6OA7H6.js";
@@ -9,7 +9,7 @@ import {
9
9
  saveKeyToKeychain,
10
10
  setAPIKey,
11
11
  tryGetClient
12
- } from "./chunk-WRGSH5RT.js";
12
+ } from "./chunk-WMI44VIC.js";
13
13
  import "./chunk-45Y5TLQZ.js";
14
14
  import "./chunk-APMV77PU.js";
15
15
  import "./chunk-DGUM43GV.js";
@@ -25,4 +25,4 @@ export {
25
25
  setAPIKey,
26
26
  tryGetClient
27
27
  };
28
- //# sourceMappingURL=client-PMKE26IV.js.map
28
+ //# sourceMappingURL=client-EWP4SIG3.js.map
@@ -56,7 +56,7 @@ async function recordGoalViolationFixed(goal, file, projectPath) {
56
56
  }
57
57
  }
58
58
  async function checkFilesForGoalViolations(goals, projectPath, filesToCheck) {
59
- const { isAIAvailable, runAIAnalysis } = await import("./client-PMKE26IV.js");
59
+ const { isAIAvailable, runAIAnalysis } = await import("./client-EWP4SIG3.js");
60
60
  if (!isAIAvailable()) {
61
61
  throw new Error("AI not available - ANTHROPIC_API_KEY not set");
62
62
  }
@@ -185,4 +185,4 @@ export {
185
185
  recordGoalViolationCaught,
186
186
  recordGoalViolationFixed
187
187
  };
188
- //# sourceMappingURL=goal-validator-XYA364W3.js.map
188
+ //# sourceMappingURL=goal-validator-CKFKJ46J.js.map
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  GuardianAgent,
3
3
  getGuardian
4
- } from "./chunk-B46FDUKR.js";
4
+ } from "./chunk-D2CGMX7K.js";
5
5
  import "./chunk-TRIJC5MW.js";
6
- import "./chunk-CKT2A33R.js";
6
+ import "./chunk-W2DEBKZ2.js";
7
7
  import "./chunk-4YJ6KLGI.js";
8
- import "./chunk-F4ZIAHTZ.js";
9
- import "./chunk-WRGSH5RT.js";
8
+ import "./chunk-A4EDTN6R.js";
9
+ import "./chunk-WMI44VIC.js";
10
10
  import "./chunk-K5EXATBF.js";
11
11
  import "./chunk-UHMMANC2.js";
12
12
  import "./chunk-WS6OA7H6.js";
@@ -23,4 +23,4 @@ export {
23
23
  GuardianAgent,
24
24
  getGuardian
25
25
  };
26
- //# sourceMappingURL=guardian-agent-PTC6G37Q.js.map
26
+ //# sourceMappingURL=guardian-agent-5QVLDPKB.js.map
@@ -3,7 +3,7 @@ import {
3
3
  clearHypothesisEngines,
4
4
  gatherEvidenceForHypothesis,
5
5
  getHypothesisEngine
6
- } from "./chunk-CKT2A33R.js";
6
+ } from "./chunk-W2DEBKZ2.js";
7
7
  import "./chunk-4YJ6KLGI.js";
8
8
  import "./chunk-K5EXATBF.js";
9
9
  import "./chunk-UHMMANC2.js";
@@ -19,4 +19,4 @@ export {
19
19
  gatherEvidenceForHypothesis,
20
20
  getHypothesisEngine
21
21
  };
22
- //# sourceMappingURL=hypothesis-WWDONGPU.js.map
22
+ //# sourceMappingURL=hypothesis-HFYZNIMZ.js.map
package/dist/index.js CHANGED
@@ -38,11 +38,11 @@ import {
38
38
  getPrompt,
39
39
  getSystemPrompt,
40
40
  handleCheckpointTool
41
- } from "./chunk-QIS2VDJL.js";
42
- import "./chunk-B46FDUKR.js";
41
+ } from "./chunk-7J4ZOOAD.js";
42
+ import "./chunk-D2CGMX7K.js";
43
43
  import "./chunk-DFPVUMVE.js";
44
44
  import "./chunk-TRIJC5MW.js";
45
- import "./chunk-CKT2A33R.js";
45
+ import "./chunk-W2DEBKZ2.js";
46
46
  import "./chunk-4YJ6KLGI.js";
47
47
  import {
48
48
  exportToJson,
@@ -59,11 +59,11 @@ import {
59
59
  getGlobalMemoryStats,
60
60
  listTrackedProjects,
61
61
  searchGlobalPatterns
62
- } from "./chunk-F4ZIAHTZ.js";
62
+ } from "./chunk-A4EDTN6R.js";
63
63
  import {
64
64
  isAIAvailable,
65
65
  runAIAnalysis
66
- } from "./chunk-WRGSH5RT.js";
66
+ } from "./chunk-WMI44VIC.js";
67
67
  import {
68
68
  findSimilarIssues,
69
69
  getMemoryStats,
@@ -1251,7 +1251,10 @@ var TrieWatchTool = class _TrieWatchTool {
1251
1251
  debounceMs
1252
1252
  });
1253
1253
  }
1254
- void this.initialGoalComplianceScan();
1254
+ setTimeout(() => {
1255
+ void this.initialGoalComplianceScan();
1256
+ void this.initialHypothesisGeneration();
1257
+ }, 1e3);
1255
1258
  return {
1256
1259
  content: [{
1257
1260
  type: "text",
@@ -1426,7 +1429,7 @@ ${f.content.slice(0, 1e3)}`
1426
1429
  async checkAndGenerateHypotheses(projectPath) {
1427
1430
  if (!isAIAvailable()) return;
1428
1431
  try {
1429
- const { getHypothesisEngine } = await import("./hypothesis-WWDONGPU.js");
1432
+ const { getHypothesisEngine } = await import("./hypothesis-HFYZNIMZ.js");
1430
1433
  const { getOutputManager: getOutputManager2 } = await import("./output-manager-BOTMXSND.js");
1431
1434
  const hypothesisEngine = getHypothesisEngine(projectPath);
1432
1435
  const recentIssues = Array.from(this.state.issueCache.values()).flat();
@@ -1635,10 +1638,16 @@ ${f.content.slice(0, 1e3)}`
1635
1638
  this.state.lastAutoScan = now;
1636
1639
  try {
1637
1640
  const graph = new ContextGraph(projectPath);
1638
- const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-XYA364W3.js");
1641
+ const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-CKFKJ46J.js");
1639
1642
  const { appendIssuesToLedger } = await import("./ledger-JMPGJGLB.js");
1643
+ console.debug("[AI Watcher] Loading active goals...");
1640
1644
  const activeGoals = await getActiveGoals(projectPath);
1641
1645
  const hasGoals = activeGoals.length > 0;
1646
+ console.debug("[AI Watcher] Goals loaded:", {
1647
+ totalGoals: activeGoals.length,
1648
+ hasGoals,
1649
+ goals: activeGoals.map((g) => ({ id: g.id, description: g.description, status: g.status }))
1650
+ });
1642
1651
  if (this.isQuiet() && !hasGoals) return;
1643
1652
  const scored = [];
1644
1653
  for (const file of files) {
@@ -1683,6 +1692,13 @@ ${activeGoals.map((g, i) => ` ${i + 1}. "${g.description}"`).join("\n")}
1683
1692
  Goal violations are HIGH PRIORITY. If a file violates any goal, you MUST report it.
1684
1693
  `;
1685
1694
  }
1695
+ console.debug("[AI Watcher] Sending files to AI analysis:", {
1696
+ fileCount: valid.length,
1697
+ hasGoals,
1698
+ goalsIncluded: hasGoals,
1699
+ filePaths: valid.map((f) => f.path),
1700
+ goalsSection: goalsSection.slice(0, 200) + (goalsSection.length > 200 ? "..." : "")
1701
+ });
1686
1702
  const result = await runAIAnalysis({
1687
1703
  systemPrompt: `You are a code quality watcher. You review code for two things:
1688
1704
 
@@ -1711,13 +1727,29 @@ ${filesBlock}`,
1711
1727
  if (result.tokensUsed) {
1712
1728
  this.recordTokenUsage(result.tokensUsed.input + result.tokensUsed.output);
1713
1729
  }
1714
- if (!result.success || !result.content.trim()) return;
1730
+ console.debug("[AI Watcher] AI analysis result:", {
1731
+ success: result.success,
1732
+ contentLength: result.content ? result.content.length : 0,
1733
+ tokensUsed: result.tokensUsed,
1734
+ contentPreview: result.content ? result.content.slice(0, 500) : "null"
1735
+ });
1736
+ if (!result.success || !result.content.trim()) {
1737
+ console.debug("[AI Watcher] AI analysis failed or returned empty content");
1738
+ return;
1739
+ }
1715
1740
  let issues = [];
1716
1741
  try {
1717
1742
  const cleaned = result.content.replace(/```json?\n?|\n?```/g, "").trim();
1743
+ console.debug("[AI Watcher] Parsing AI response:", { cleanedContent: cleaned.slice(0, 300) });
1718
1744
  issues = JSON.parse(cleaned);
1719
1745
  if (!Array.isArray(issues)) issues = [];
1720
- } catch {
1746
+ console.debug("[AI Watcher] Parsed issues:", {
1747
+ totalIssues: issues.length,
1748
+ goalViolations: issues.filter((i) => i.isGoalViolation).length,
1749
+ issueTypes: issues.map((i) => ({ file: i.file, isGoalViolation: i.isGoalViolation, goalIndex: i.goalIndex }))
1750
+ });
1751
+ } catch (error) {
1752
+ console.debug("[AI Watcher] Failed to parse AI response:", error);
1721
1753
  return;
1722
1754
  }
1723
1755
  const issuedFiles = new Set(issues.map((i) => i.file));
@@ -1733,6 +1765,14 @@ ${filesBlock}`,
1733
1765
  const goal = activeGoals[issue.goalIndex];
1734
1766
  const confidence = Math.min(100, Math.max(0, issue.confidence ?? 80));
1735
1767
  const fixId = `fix-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1768
+ console.debug("[AI Watcher] Goal violation detected:", {
1769
+ goalDescription: goal.description,
1770
+ file: issue.file,
1771
+ violation: issue.description,
1772
+ confidence,
1773
+ goalIndex: issue.goalIndex,
1774
+ totalActiveGoals: activeGoals.length
1775
+ });
1736
1776
  const ledgerIssue = {
1737
1777
  id: fixId,
1738
1778
  hash: "",
@@ -1752,6 +1792,11 @@ ${filesBlock}`,
1752
1792
  await recordGoalViolationCaught(goal, issue.file, projectPath);
1753
1793
  const confidenceStr = `${confidence}%`;
1754
1794
  const nudgeMsg = `Goal "${goal.description}" violated in ${issue.file}: ${issue.description} [${confidenceStr} confidence]`;
1795
+ console.debug("[AI Watcher] Sending nudge:", {
1796
+ message: nudgeMsg,
1797
+ file: issue.file,
1798
+ severity: "warning"
1799
+ });
1755
1800
  getOutputManager().nudge(nudgeMsg, "warning", issue.file);
1756
1801
  this.state.nudges.push({
1757
1802
  file: basename2(issue.file),
@@ -1828,6 +1873,56 @@ ${filesBlock}`,
1828
1873
  this.state.autoScanInProgress = false;
1829
1874
  }
1830
1875
  }
1876
+ /**
1877
+ * Initial hypothesis generation when watch starts.
1878
+ *
1879
+ * This generates hypotheses from existing patterns and issues to give
1880
+ * users immediate insights about their codebase.
1881
+ */
1882
+ async initialHypothesisGeneration() {
1883
+ if (!isAIAvailable()) {
1884
+ console.debug("[Initial Hypothesis] AI not available, skipping initial hypothesis generation");
1885
+ return;
1886
+ }
1887
+ const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
1888
+ console.debug("[Initial Hypothesis] Starting initial hypothesis generation", { projectPath });
1889
+ try {
1890
+ const { getHypothesisEngine } = await import("./hypothesis-HFYZNIMZ.js");
1891
+ const hypothesisEngine = getHypothesisEngine(projectPath);
1892
+ console.debug("[Initial Hypothesis] Running AI-powered hypothesis generation...");
1893
+ const generated = await hypothesisEngine.generateHypothesesWithAI({
1894
+ recentIssues: [],
1895
+ // No recent issues yet on startup
1896
+ patterns: [],
1897
+ observations: ["Initial watch session started", "Analyzing codebase for potential patterns"]
1898
+ });
1899
+ console.debug("[Initial Hypothesis] Generated hypotheses on startup:", {
1900
+ count: generated.length,
1901
+ hypotheses: generated.map((h) => ({ statement: h.statement, confidence: h.confidence }))
1902
+ });
1903
+ if (generated.length > 0) {
1904
+ const { getOutputManager: getOutputManager2 } = await import("./output-manager-BOTMXSND.js");
1905
+ const outputManager = getOutputManager2();
1906
+ for (const hypothesis of generated.slice(0, 2)) {
1907
+ const message = `[Initial Hypothesis] "${hypothesis.statement}" (${Math.round(hypothesis.confidence * 100)}% confidence)`;
1908
+ outputManager.nudge(message, "info", void 0, 1e4);
1909
+ if (!isInteractiveMode()) {
1910
+ console.error(` [?] ${message}`);
1911
+ }
1912
+ }
1913
+ if (this.streamingManager) {
1914
+ this.streamingManager.reportSignalExtraction({
1915
+ decisions: 0,
1916
+ facts: 0,
1917
+ blockers: 0,
1918
+ questions: generated.length
1919
+ });
1920
+ }
1921
+ }
1922
+ } catch (error) {
1923
+ console.debug("[Initial Hypothesis] Failed to generate initial hypotheses:", error);
1924
+ }
1925
+ }
1831
1926
  /**
1832
1927
  * Initial goal compliance scan when watch starts.
1833
1928
  *
@@ -1843,12 +1938,23 @@ ${filesBlock}`,
1843
1938
  * 5. Nudge the user about any violations found
1844
1939
  */
1845
1940
  async initialGoalComplianceScan() {
1846
- if (!isAIAvailable()) return;
1941
+ if (!isAIAvailable()) {
1942
+ console.debug("[Initial Scan] AI not available, skipping initial goal compliance scan");
1943
+ return;
1944
+ }
1847
1945
  const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
1946
+ console.debug("[Initial Scan] Starting initial goal compliance scan", { projectPath });
1848
1947
  try {
1849
- const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-XYA364W3.js");
1948
+ const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-CKFKJ46J.js");
1850
1949
  const activeGoals = await getActiveGoals(projectPath);
1851
- if (activeGoals.length === 0) return;
1950
+ console.debug("[Initial Scan] Loaded goals for initial scan:", {
1951
+ goalCount: activeGoals.length,
1952
+ goals: activeGoals.map((g) => ({ id: g.id, description: g.description }))
1953
+ });
1954
+ if (activeGoals.length === 0) {
1955
+ console.debug("[Initial Scan] No active goals found, skipping initial scan");
1956
+ return;
1957
+ }
1852
1958
  if (!isInteractiveMode()) {
1853
1959
  console.error("[*] Checking recent files against active goals...");
1854
1960
  }
@@ -1866,7 +1972,17 @@ ${filesBlock}`,
1866
1972
  const ext = extname3(file).toLowerCase();
1867
1973
  return WATCH_EXTENSIONS.has(ext) && existsSync3(file);
1868
1974
  });
1869
- if (filesToCheck.length === 0) return;
1975
+ console.debug("[Initial Scan] Files discovered for initial scan:", {
1976
+ totalRecentFiles: recentFiles.size,
1977
+ filteredFiles: filesToCheck.length,
1978
+ filePaths: filesToCheck.slice(0, 5).map((f) => f.replace(projectPath + "/", "")),
1979
+ // Show first 5
1980
+ watchedExtensions: Array.from(WATCH_EXTENSIONS)
1981
+ });
1982
+ if (filesToCheck.length === 0) {
1983
+ console.debug("[Initial Scan] No recent files found for initial scan");
1984
+ return;
1985
+ }
1870
1986
  const maxInitialFiles = 10;
1871
1987
  const filesToScan = filesToCheck.slice(0, maxInitialFiles);
1872
1988
  if (!isInteractiveMode()) {
@@ -2047,7 +2163,7 @@ Use \`trie_watch start\` to begin autonomous scanning.`
2047
2163
  ).join("\n");
2048
2164
  let agencyStatus = "";
2049
2165
  try {
2050
- const { getGuardian } = await import("./guardian-agent-PTC6G37Q.js");
2166
+ const { getGuardian } = await import("./guardian-agent-5QVLDPKB.js");
2051
2167
  const trieAgent = getGuardian(this.watchedDirectory || getWorkingDirectory(void 0, true));
2052
2168
  await trieAgent.initialize();
2053
2169
  const status = await trieAgent.getAgencyStatus();
@@ -3845,21 +3961,25 @@ async function listInstalledSkills() {
3845
3961
 
3846
3962
  // src/server/resource-manager.ts
3847
3963
  var UI_APPS = {
3848
- "scan-dashboard": {
3849
- name: "Scan Dashboard",
3850
- description: "Interactive dashboard for viewing and managing scan results"
3964
+ "ledger": {
3965
+ name: "Decision Ledger",
3966
+ description: "Track decisions, blockers, facts, and questions across your project"
3967
+ },
3968
+ "goals": {
3969
+ name: "Goals & Progress",
3970
+ description: "Monitor code quality goals and track progress with visual indicators"
3851
3971
  },
3852
- "memory-viewer": {
3853
- name: "Memory Viewer",
3854
- description: "Search and browse issue history with context preview"
3972
+ "hypotheses": {
3973
+ name: "Hypotheses",
3974
+ description: "Test and validate development theories with evidence-based reasoning"
3855
3975
  },
3856
- "pr-review": {
3857
- name: "PR Review",
3858
- description: "File-by-file diff viewer with inline actions"
3976
+ "nudges": {
3977
+ name: "Nudges & Insights",
3978
+ description: "AI-powered code quality insights, warnings, and suggestions"
3859
3979
  },
3860
- "visual-qa": {
3861
- name: "Visual QA",
3862
- description: "Screenshot gallery with viewport comparison"
3980
+ "chat": {
3981
+ name: "AI Chat",
3982
+ description: "Interactive chat with Trie assistant for code analysis and guidance"
3863
3983
  }
3864
3984
  };
3865
3985
  var ResourceManager = class {