@triedotdev/mcp 1.0.122 → 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 (51) hide show
  1. package/dist/{chat-store-R46BCMBW.js → chat-store-HFOOWZYN.js} +2 -2
  2. package/dist/{chunk-JG7XVS53.js → chunk-4YJ6KLGI.js} +9 -2
  3. package/dist/{chunk-JG7XVS53.js.map → chunk-4YJ6KLGI.js.map} +1 -1
  4. package/dist/{chunk-ANQPXOT2.js → chunk-7J4ZOOAD.js} +333 -304
  5. package/dist/chunk-7J4ZOOAD.js.map +1 -0
  6. package/dist/{chunk-F4ZIAHTZ.js → chunk-A4EDTN6R.js} +2 -2
  7. package/dist/{chunk-7A5RLKZY.js → chunk-D2CGMX7K.js} +7 -7
  8. package/dist/{chunk-HWXZ3E7B.js → chunk-DFPVUMVE.js} +1 -1
  9. package/dist/chunk-DFPVUMVE.js.map +1 -0
  10. package/dist/{chunk-EOLHWFDG.js → chunk-TRIJC5MW.js} +2 -2
  11. package/dist/{chunk-3BVNB3GY.js → chunk-W2DEBKZ2.js} +4 -5
  12. package/dist/chunk-W2DEBKZ2.js.map +1 -0
  13. package/dist/{chunk-WRGSH5RT.js → chunk-WMI44VIC.js} +2 -2
  14. package/dist/{chunk-WRGSH5RT.js.map → chunk-WMI44VIC.js.map} +1 -1
  15. package/dist/cli/main.js +2 -2
  16. package/dist/cli/main.js.map +1 -1
  17. package/dist/cli/yolo-daemon.js +8 -8
  18. package/dist/{client-PMKE26IV.js → client-EWP4SIG3.js} +2 -2
  19. package/dist/{goal-manager-O446DRJI.js → goal-manager-RREOIX6U.js} +3 -3
  20. package/dist/{goal-validator-XYA364W3.js → goal-validator-CKFKJ46J.js} +2 -2
  21. package/dist/{guardian-agent-KVLNECZ5.js → guardian-agent-5QVLDPKB.js} +7 -7
  22. package/dist/{hypothesis-QFGZ5ITT.js → hypothesis-HFYZNIMZ.js} +3 -3
  23. package/dist/index.js +150 -30
  24. package/dist/index.js.map +1 -1
  25. package/dist/{insight-store-DZ5C3RFM.js → insight-store-F5KDBY5Y.js} +2 -2
  26. package/dist/{terminal-spawn-2GU5KLPS.js → terminal-spawn-P5M5PHAV.js} +28 -6
  27. package/dist/terminal-spawn-P5M5PHAV.js.map +1 -0
  28. package/dist/ui/chat.html +821 -0
  29. package/dist/ui/goals.html +724 -0
  30. package/dist/ui/hypotheses.html +768 -0
  31. package/dist/ui/ledger.html +711 -0
  32. package/dist/ui/nudges.html +752 -0
  33. package/package.json +1 -1
  34. package/dist/chunk-3BVNB3GY.js.map +0 -1
  35. package/dist/chunk-ANQPXOT2.js.map +0 -1
  36. package/dist/chunk-HWXZ3E7B.js.map +0 -1
  37. package/dist/terminal-spawn-2GU5KLPS.js.map +0 -1
  38. package/dist/ui/memory-viewer.html +0 -773
  39. package/dist/ui/pr-review.html +0 -742
  40. package/dist/ui/scan-dashboard.html +0 -741
  41. package/dist/ui/visual-qa.html +0 -762
  42. /package/dist/{chat-store-R46BCMBW.js.map → chat-store-HFOOWZYN.js.map} +0 -0
  43. /package/dist/{chunk-F4ZIAHTZ.js.map → chunk-A4EDTN6R.js.map} +0 -0
  44. /package/dist/{chunk-7A5RLKZY.js.map → chunk-D2CGMX7K.js.map} +0 -0
  45. /package/dist/{chunk-EOLHWFDG.js.map → chunk-TRIJC5MW.js.map} +0 -0
  46. /package/dist/{client-PMKE26IV.js.map → client-EWP4SIG3.js.map} +0 -0
  47. /package/dist/{goal-manager-O446DRJI.js.map → goal-manager-RREOIX6U.js.map} +0 -0
  48. /package/dist/{goal-validator-XYA364W3.js.map → goal-validator-CKFKJ46J.js.map} +0 -0
  49. /package/dist/{guardian-agent-KVLNECZ5.js.map → guardian-agent-5QVLDPKB.js.map} +0 -0
  50. /package/dist/{hypothesis-QFGZ5ITT.js.map → hypothesis-HFYZNIMZ.js.map} +0 -0
  51. /package/dist/{insight-store-DZ5C3RFM.js.map → insight-store-F5KDBY5Y.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/dashboard/chat-store.ts"],"sourcesContent":["/**\n * Chat Store - Persistent storage for chat history\n * \n * Features:\n * - Save and load chat sessions\n * - List all chat sessions\n * - Archive management (rename, delete, export)\n * - Atomic writes with backup rotation\n * - Zod validation for data integrity\n * \n * Persists to: .trie/memory/chats/\n */\n\nimport { mkdir, readFile, readdir, unlink, rename as fsRename } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join, basename } from 'path';\nimport { getTrieDirectory } from '../../utils/workspace.js';\nimport { z } from 'zod';\nimport { atomicWriteJSON } from '../../utils/atomic-write.js';\nimport type { ChatMessage } from './types.js';\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\nconst ChatMessageSchema = z.object({\n role: z.enum(['user', 'assistant']),\n content: z.string(),\n timestamp: z.number(),\n toolCalls: z.array(z.object({\n id: z.string(),\n name: z.string(),\n input: z.record(z.any()),\n })).optional(),\n pendingFix: z.object({\n id: z.string(),\n file: z.string(),\n goal: z.string(),\n violation: z.string(),\n suggestedFix: z.string().optional(),\n }).optional(),\n});\n\nconst ChatSessionSchema = z.object({\n id: z.string(),\n title: z.string(),\n messages: z.array(ChatMessageSchema),\n createdAt: z.number(),\n updatedAt: z.number(),\n archived: z.boolean(),\n});\n\nexport type ChatSession = z.infer<typeof ChatSessionSchema>;\n\nconst ChatStoreIndexSchema = z.object({\n version: z.literal(1),\n sessions: z.array(z.object({\n id: z.string(),\n title: z.string(),\n createdAt: z.number(),\n updatedAt: z.number(),\n archived: z.boolean(),\n messageCount: z.number(),\n })),\n lastUpdated: z.string(),\n});\n\ntype ChatStoreIndex = z.infer<typeof ChatStoreIndexSchema>;\n\n// ============================================================================\n// ChatStore Class\n// ============================================================================\n\nexport class ChatStore {\n private projectPath: string;\n private index: ChatStoreIndex | null = null;\n \n constructor(projectPath: string) {\n this.projectPath = projectPath;\n }\n \n /**\n * Get the chats directory path\n */\n private getChatsDir(): string {\n return join(getTrieDirectory(this.projectPath), 'memory', 'chats');\n }\n \n /**\n * Get the index file path\n */\n private getIndexPath(): string {\n return join(this.getChatsDir(), 'index.json');\n }\n \n /**\n * Get the path for a specific session file\n */\n private getSessionPath(sessionId: string): string {\n return join(this.getChatsDir(), `${sessionId}.json`);\n }\n \n /**\n * Load the index file\n */\n private async loadIndex(): Promise<ChatStoreIndex> {\n if (this.index) {\n return this.index;\n }\n \n const indexPath = this.getIndexPath();\n \n if (existsSync(indexPath)) {\n try {\n const content = await readFile(indexPath, 'utf-8');\n const parsed = JSON.parse(content);\n const result = ChatStoreIndexSchema.safeParse(parsed);\n \n if (result.success) {\n this.index = result.data;\n return this.index;\n }\n } catch (error) {\n console.error('Failed to load chat index:', error);\n }\n }\n \n // Create empty index\n this.index = {\n version: 1,\n sessions: [],\n lastUpdated: new Date().toISOString(),\n };\n \n return this.index;\n }\n \n /**\n * Save the index file\n */\n private async saveIndex(): Promise<void> {\n if (!this.index) return;\n \n const indexPath = this.getIndexPath();\n const chatsDir = this.getChatsDir();\n \n // Ensure directory exists\n await mkdir(chatsDir, { recursive: true });\n \n // Update timestamp\n this.index.lastUpdated = new Date().toISOString();\n \n // Atomic write\n await atomicWriteJSON(indexPath, this.index);\n }\n \n /**\n * Generate a unique session ID\n */\n private generateSessionId(): string {\n return `chat-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n }\n \n /**\n * Generate a default title from the first user message\n */\n private generateTitle(messages: ChatMessage[]): string {\n const firstUser = messages.find(m => m.role === 'user');\n if (firstUser) {\n const text = firstUser.content.trim();\n const maxLen = 50;\n if (text.length > maxLen) {\n return text.slice(0, maxLen) + '...';\n }\n return text;\n }\n return 'New Chat';\n }\n \n /**\n * Save a chat session\n */\n async saveSession(messages: ChatMessage[], sessionId?: string, title?: string): Promise<string> {\n await this.loadIndex();\n \n const id = sessionId || this.generateSessionId();\n const now = Date.now();\n \n // Load existing session if updating\n let createdAt = now;\n if (sessionId) {\n const existing = this.index!.sessions.find(s => s.id === sessionId);\n if (existing) {\n createdAt = existing.createdAt;\n }\n }\n \n const session: ChatSession = {\n id,\n title: title || this.generateTitle(messages),\n messages,\n createdAt,\n updatedAt: now,\n archived: false,\n };\n \n // Validate\n const result = ChatSessionSchema.safeParse(session);\n if (!result.success) {\n throw new Error(`Invalid chat session: ${result.error.message}`);\n }\n \n // Save session file\n const sessionPath = this.getSessionPath(id);\n await mkdir(this.getChatsDir(), { recursive: true });\n await atomicWriteJSON(sessionPath, session);\n \n // Update index\n const existingIndex = this.index!.sessions.findIndex(s => s.id === id);\n const indexEntry = {\n id,\n title: session.title,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt,\n archived: session.archived,\n messageCount: messages.length,\n };\n \n if (existingIndex >= 0) {\n this.index!.sessions[existingIndex] = indexEntry;\n } else {\n this.index!.sessions.unshift(indexEntry);\n }\n \n await this.saveIndex();\n \n return id;\n }\n \n /**\n * Load a chat session\n */\n async loadSession(sessionId: string): Promise<ChatSession | null> {\n const sessionPath = this.getSessionPath(sessionId);\n \n if (!existsSync(sessionPath)) {\n return null;\n }\n \n try {\n const content = await readFile(sessionPath, 'utf-8');\n const parsed = JSON.parse(content);\n const result = ChatSessionSchema.safeParse(parsed);\n \n if (result.success) {\n return result.data;\n }\n \n console.error('Invalid chat session:', result.error.message);\n return null;\n } catch (error) {\n console.error('Failed to load chat session:', error);\n return null;\n }\n }\n \n /**\n * List all chat sessions\n */\n async listSessions(includeArchived: boolean = false): Promise<ChatStoreIndex['sessions']> {\n await this.loadIndex();\n \n let sessions = this.index!.sessions;\n \n if (!includeArchived) {\n sessions = sessions.filter(s => !s.archived);\n }\n \n // Sort by most recent first\n return sessions.sort((a, b) => b.updatedAt - a.updatedAt);\n }\n \n /**\n * Delete a chat session\n */\n async deleteSession(sessionId: string): Promise<boolean> {\n await this.loadIndex();\n \n const sessionPath = this.getSessionPath(sessionId);\n \n if (!existsSync(sessionPath)) {\n return false;\n }\n \n try {\n await unlink(sessionPath);\n \n // Remove from index\n this.index!.sessions = this.index!.sessions.filter(s => s.id !== sessionId);\n await this.saveIndex();\n \n return true;\n } catch (error) {\n console.error('Failed to delete chat session:', error);\n return false;\n }\n }\n \n /**\n * Rename a chat session\n */\n async renameSession(sessionId: string, newTitle: string): Promise<boolean> {\n await this.loadIndex();\n \n const session = await this.loadSession(sessionId);\n if (!session) {\n return false;\n }\n \n session.title = newTitle;\n session.updatedAt = Date.now();\n \n // Save updated session\n const sessionPath = this.getSessionPath(sessionId);\n await atomicWriteJSON(sessionPath, session);\n \n // Update index\n const indexEntry = this.index!.sessions.find(s => s.id === sessionId);\n if (indexEntry) {\n indexEntry.title = newTitle;\n indexEntry.updatedAt = session.updatedAt;\n await this.saveIndex();\n }\n \n return true;\n }\n \n /**\n * Archive a chat session\n */\n async archiveSession(sessionId: string): Promise<boolean> {\n await this.loadIndex();\n \n const session = await this.loadSession(sessionId);\n if (!session) {\n return false;\n }\n \n session.archived = true;\n session.updatedAt = Date.now();\n \n // Save updated session\n const sessionPath = this.getSessionPath(sessionId);\n await atomicWriteJSON(sessionPath, session);\n \n // Update index\n const indexEntry = this.index!.sessions.find(s => s.id === sessionId);\n if (indexEntry) {\n indexEntry.archived = true;\n indexEntry.updatedAt = session.updatedAt;\n await this.saveIndex();\n }\n \n return true;\n }\n \n /**\n * Unarchive a chat session\n */\n async unarchiveSession(sessionId: string): Promise<boolean> {\n await this.loadIndex();\n \n const session = await this.loadSession(sessionId);\n if (!session) {\n return false;\n }\n \n session.archived = false;\n session.updatedAt = Date.now();\n \n // Save updated session\n const sessionPath = this.getSessionPath(sessionId);\n await atomicWriteJSON(sessionPath, session);\n \n // Update index\n const indexEntry = this.index!.sessions.find(s => s.id === sessionId);\n if (indexEntry) {\n indexEntry.archived = false;\n indexEntry.updatedAt = session.updatedAt;\n await this.saveIndex();\n }\n \n return true;\n }\n \n /**\n * Export a chat session as JSON\n */\n async exportSession(sessionId: string): Promise<string | null> {\n const session = await this.loadSession(sessionId);\n if (!session) {\n return null;\n }\n \n return JSON.stringify(session, null, 2);\n }\n \n /**\n * Get statistics about chat sessions\n */\n async getStats(): Promise<{\n total: number;\n active: number;\n archived: number;\n totalMessages: number;\n }> {\n await this.loadIndex();\n \n const total = this.index!.sessions.length;\n const archived = this.index!.sessions.filter(s => s.archived).length;\n const active = total - archived;\n const totalMessages = this.index!.sessions.reduce((sum, s) => sum + s.messageCount, 0);\n \n return { total, active, archived, totalMessages };\n }\n \n /**\n * Prune old sessions (older than N days)\n */\n async pruneOldSessions(daysToKeep: number = 90): Promise<number> {\n await this.loadIndex();\n \n const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);\n const toDelete = this.index!.sessions.filter(s => s.updatedAt < cutoff);\n \n for (const session of toDelete) {\n await this.deleteSession(session.id);\n }\n \n return toDelete.length;\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst chatStores: Map<string, ChatStore> = new Map();\n\n/**\n * Get the ChatStore for a project (singleton per project)\n */\nexport function getChatStore(projectPath: string): ChatStore {\n let store = chatStores.get(projectPath);\n if (!store) {\n store = new ChatStore(projectPath);\n chatStores.set(projectPath, store);\n }\n return store;\n}\n\n/**\n * Clear all ChatStore instances (for testing)\n */\nexport function clearChatStores(): void {\n chatStores.clear();\n}\n"],"mappings":";;;;;;;;AAaA,SAAS,OAAO,UAAmB,cAAkC;AACrE,SAAS,kBAAkB;AAC3B,SAAS,YAAsB;AAE/B,SAAS,SAAS;AAQlB,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACjC,MAAM,EAAE,KAAK,CAAC,QAAQ,WAAW,CAAC;AAAA,EAClC,SAAS,EAAE,OAAO;AAAA,EAClB,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,MAAM,EAAE,OAAO;AAAA,IAC1B,IAAI,EAAE,OAAO;AAAA,IACb,MAAM,EAAE,OAAO;AAAA,IACf,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,YAAY,EAAE,OAAO;AAAA,IACnB,IAAI,EAAE,OAAO;AAAA,IACb,MAAM,EAAE,OAAO;AAAA,IACf,MAAM,EAAE,OAAO;AAAA,IACf,WAAW,EAAE,OAAO;AAAA,IACpB,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EACpC,CAAC,EAAE,SAAS;AACd,CAAC;AAED,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO;AAAA,EAChB,UAAU,EAAE,MAAM,iBAAiB;AAAA,EACnC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO;AAAA,EACpB,UAAU,EAAE,QAAQ;AACtB,CAAC;AAID,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,SAAS,EAAE,QAAQ,CAAC;AAAA,EACpB,UAAU,EAAE,MAAM,EAAE,OAAO;AAAA,IACzB,IAAI,EAAE,OAAO;AAAA,IACb,OAAO,EAAE,OAAO;AAAA,IAChB,WAAW,EAAE,OAAO;AAAA,IACpB,WAAW,EAAE,OAAO;AAAA,IACpB,UAAU,EAAE,QAAQ;AAAA,IACpB,cAAc,EAAE,OAAO;AAAA,EACzB,CAAC,CAAC;AAAA,EACF,aAAa,EAAE,OAAO;AACxB,CAAC;AAQM,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACA,QAA+B;AAAA,EAEvC,YAAY,aAAqB;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAsB;AAC5B,WAAO,KAAK,iBAAiB,KAAK,WAAW,GAAG,UAAU,OAAO;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAuB;AAC7B,WAAO,KAAK,KAAK,YAAY,GAAG,YAAY;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,WAA2B;AAChD,WAAO,KAAK,KAAK,YAAY,GAAG,GAAG,SAAS,OAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YAAqC;AACjD,QAAI,KAAK,OAAO;AACd,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,YAAY,KAAK,aAAa;AAEpC,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI;AACF,cAAM,UAAU,MAAM,SAAS,WAAW,OAAO;AACjD,cAAM,SAAS,KAAK,MAAM,OAAO;AACjC,cAAM,SAAS,qBAAqB,UAAU,MAAM;AAEpD,YAAI,OAAO,SAAS;AAClB,eAAK,QAAQ,OAAO;AACpB,iBAAO,KAAK;AAAA,QACd;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,8BAA8B,KAAK;AAAA,MACnD;AAAA,IACF;AAGA,SAAK,QAAQ;AAAA,MACX,SAAS;AAAA,MACT,UAAU,CAAC;AAAA,MACX,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YAA2B;AACvC,QAAI,CAAC,KAAK,MAAO;AAEjB,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,WAAW,KAAK,YAAY;AAGlC,UAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAGzC,SAAK,MAAM,eAAc,oBAAI,KAAK,GAAE,YAAY;AAGhD,UAAM,gBAAgB,WAAW,KAAK,KAAK;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAA4B;AAClC,WAAO,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,UAAiC;AACrD,UAAM,YAAY,SAAS,KAAK,OAAK,EAAE,SAAS,MAAM;AACtD,QAAI,WAAW;AACb,YAAM,OAAO,UAAU,QAAQ,KAAK;AACpC,YAAM,SAAS;AACf,UAAI,KAAK,SAAS,QAAQ;AACxB,eAAO,KAAK,MAAM,GAAG,MAAM,IAAI;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,UAAyB,WAAoB,OAAiC;AAC9F,UAAM,KAAK,UAAU;AAErB,UAAM,KAAK,aAAa,KAAK,kBAAkB;AAC/C,UAAM,MAAM,KAAK,IAAI;AAGrB,QAAI,YAAY;AAChB,QAAI,WAAW;AACb,YAAM,WAAW,KAAK,MAAO,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAClE,UAAI,UAAU;AACZ,oBAAY,SAAS;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,UAAuB;AAAA,MAC3B;AAAA,MACA,OAAO,SAAS,KAAK,cAAc,QAAQ;AAAA,MAC3C;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAGA,UAAM,SAAS,kBAAkB,UAAU,OAAO;AAClD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,MAAM,yBAAyB,OAAO,MAAM,OAAO,EAAE;AAAA,IACjE;AAGA,UAAM,cAAc,KAAK,eAAe,EAAE;AAC1C,UAAM,MAAM,KAAK,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,UAAM,gBAAgB,aAAa,OAAO;AAG1C,UAAM,gBAAgB,KAAK,MAAO,SAAS,UAAU,OAAK,EAAE,OAAO,EAAE;AACrE,UAAM,aAAa;AAAA,MACjB;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB,UAAU,QAAQ;AAAA,MAClB,cAAc,SAAS;AAAA,IACzB;AAEA,QAAI,iBAAiB,GAAG;AACtB,WAAK,MAAO,SAAS,aAAa,IAAI;AAAA,IACxC,OAAO;AACL,WAAK,MAAO,SAAS,QAAQ,UAAU;AAAA,IACzC;AAEA,UAAM,KAAK,UAAU;AAErB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,WAAgD;AAChE,UAAM,cAAc,KAAK,eAAe,SAAS;AAEjD,QAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,SAAS,aAAa,OAAO;AACnD,YAAM,SAAS,KAAK,MAAM,OAAO;AACjC,YAAM,SAAS,kBAAkB,UAAU,MAAM;AAEjD,UAAI,OAAO,SAAS;AAClB,eAAO,OAAO;AAAA,MAChB;AAEA,cAAQ,MAAM,yBAAyB,OAAO,MAAM,OAAO;AAC3D,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,gCAAgC,KAAK;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,kBAA2B,OAA4C;AACxF,UAAM,KAAK,UAAU;AAErB,QAAI,WAAW,KAAK,MAAO;AAE3B,QAAI,CAAC,iBAAiB;AACpB,iBAAW,SAAS,OAAO,OAAK,CAAC,EAAE,QAAQ;AAAA,IAC7C;AAGA,WAAO,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAqC;AACvD,UAAM,KAAK,UAAU;AAErB,UAAM,cAAc,KAAK,eAAe,SAAS;AAEjD,QAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,OAAO,WAAW;AAGxB,WAAK,MAAO,WAAW,KAAK,MAAO,SAAS,OAAO,OAAK,EAAE,OAAO,SAAS;AAC1E,YAAM,KAAK,UAAU;AAErB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AACrD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAmB,UAAoC;AACzE,UAAM,KAAK,UAAU;AAErB,UAAM,UAAU,MAAM,KAAK,YAAY,SAAS;AAChD,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,YAAQ,QAAQ;AAChB,YAAQ,YAAY,KAAK,IAAI;AAG7B,UAAM,cAAc,KAAK,eAAe,SAAS;AACjD,UAAM,gBAAgB,aAAa,OAAO;AAG1C,UAAM,aAAa,KAAK,MAAO,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AACpE,QAAI,YAAY;AACd,iBAAW,QAAQ;AACnB,iBAAW,YAAY,QAAQ;AAC/B,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,WAAqC;AACxD,UAAM,KAAK,UAAU;AAErB,UAAM,UAAU,MAAM,KAAK,YAAY,SAAS;AAChD,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,YAAQ,WAAW;AACnB,YAAQ,YAAY,KAAK,IAAI;AAG7B,UAAM,cAAc,KAAK,eAAe,SAAS;AACjD,UAAM,gBAAgB,aAAa,OAAO;AAG1C,UAAM,aAAa,KAAK,MAAO,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AACpE,QAAI,YAAY;AACd,iBAAW,WAAW;AACtB,iBAAW,YAAY,QAAQ;AAC/B,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,WAAqC;AAC1D,UAAM,KAAK,UAAU;AAErB,UAAM,UAAU,MAAM,KAAK,YAAY,SAAS;AAChD,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,YAAQ,WAAW;AACnB,YAAQ,YAAY,KAAK,IAAI;AAG7B,UAAM,cAAc,KAAK,eAAe,SAAS;AACjD,UAAM,gBAAgB,aAAa,OAAO;AAG1C,UAAM,aAAa,KAAK,MAAO,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AACpE,QAAI,YAAY;AACd,iBAAW,WAAW;AACtB,iBAAW,YAAY,QAAQ;AAC/B,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAA2C;AAC7D,UAAM,UAAU,MAAM,KAAK,YAAY,SAAS;AAChD,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAKH;AACD,UAAM,KAAK,UAAU;AAErB,UAAM,QAAQ,KAAK,MAAO,SAAS;AACnC,UAAM,WAAW,KAAK,MAAO,SAAS,OAAO,OAAK,EAAE,QAAQ,EAAE;AAC9D,UAAM,SAAS,QAAQ;AACvB,UAAM,gBAAgB,KAAK,MAAO,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,cAAc,CAAC;AAErF,WAAO,EAAE,OAAO,QAAQ,UAAU,cAAc;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,aAAqB,IAAqB;AAC/D,UAAM,KAAK,UAAU;AAErB,UAAM,SAAS,KAAK,IAAI,IAAK,aAAa,KAAK,KAAK,KAAK;AACzD,UAAM,WAAW,KAAK,MAAO,SAAS,OAAO,OAAK,EAAE,YAAY,MAAM;AAEtE,eAAW,WAAW,UAAU;AAC9B,YAAM,KAAK,cAAc,QAAQ,EAAE;AAAA,IACrC;AAEA,WAAO,SAAS;AAAA,EAClB;AACF;AAMA,IAAM,aAAqC,oBAAI,IAAI;AAK5C,SAAS,aAAa,aAAgC;AAC3D,MAAI,QAAQ,WAAW,IAAI,WAAW;AACtC,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,UAAU,WAAW;AACjC,eAAW,IAAI,aAAa,KAAK;AAAA,EACnC;AACA,SAAO;AACT;AAKO,SAAS,kBAAwB;AACtC,aAAW,MAAM;AACnB;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/terminal-spawn.ts"],"sourcesContent":["/**\n * Terminal Spawning Utility\n * \n * Spawns a new terminal window with a command to execute.\n * Supports macOS (Terminal.app, iTerm2) and Linux (gnome-terminal, konsole, xterm).\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { platform } from 'os';\n\nconst execAsync = promisify(exec);\n\nexport interface SpawnTerminalOptions {\n /** Command to execute in the new terminal */\n command: string;\n /** Working directory for the command */\n cwd?: string;\n /** Terminal title */\n title?: string;\n /** Keep terminal open after command completes */\n keepOpen?: boolean;\n}\n\n/**\n * Spawn a new terminal window with a command\n */\nexport async function spawnTerminal(options: SpawnTerminalOptions): Promise<void> {\n const { command, cwd, title, keepOpen = true } = options;\n const os = platform();\n\n if (os === 'darwin') {\n await spawnMacOSTerminal(command, cwd, title, keepOpen);\n } else if (os === 'linux') {\n await spawnLinuxTerminal(command, cwd, title, keepOpen);\n } else {\n throw new Error(`Terminal spawning not supported on ${os}`);\n }\n}\n\n/**\n * Spawn terminal on macOS using AppleScript\n * Tries Terminal.app first, falls back to open if Terminal.app fails\n */\nasync function spawnMacOSTerminal(\n command: string,\n cwd?: string,\n title?: string,\n keepOpen?: boolean\n): Promise<void> {\n // Escape single quotes in command\n const escapedCommand = command.replace(/'/g, \"'\\\"'\\\"'\");\n const escapedCwd = cwd?.replace(/'/g, \"'\\\"'\\\"'\") || process.cwd();\n const escapedTitle = title?.replace(/'/g, \"'\\\"'\\\"'\") || 'Trie Agent';\n\n // Build the full command with cd if cwd provided\n const fullCommand = cwd ? `cd '${escapedCwd}' && ${command}` : command;\n const escapedFullCommand = fullCommand.replace(/'/g, \"'\\\"'\\\"'\");\n\n // AppleScript to open Terminal.app with the command\n const script = `\ntell application \"Terminal\"\n activate\n set newTab to do script \"${escapedFullCommand}\"\n set custom title of newTab to \"${escapedTitle}\"\nend tell\n`.trim();\n\n try {\n await execAsync(`osascript -e '${script.replace(/'/g, \"'\\\"'\\\"'\")}'`);\n } catch (error) {\n // Fallback: use open command\n console.error('Terminal.app spawn failed, trying fallback...');\n const shellCmd = keepOpen \n ? `${fullCommand}; exec bash`\n : fullCommand;\n await execAsync(`open -a Terminal \"${escapedCwd}\" --args -e \"${shellCmd}\"`);\n }\n}\n\n/**\n * Spawn terminal on Linux\n * Tries common terminal emulators in order\n */\nasync function spawnLinuxTerminal(\n command: string,\n cwd?: string,\n title?: string,\n keepOpen?: boolean\n): Promise<void> {\n const workDir = cwd || process.cwd();\n const termTitle = title || 'Trie Agent';\n const shellCmd = keepOpen ? `${command}; exec bash` : command;\n\n // Try terminal emulators in order of preference\n const terminals = [\n // GNOME Terminal\n {\n command: 'gnome-terminal',\n args: `--working-directory=\"${workDir}\" --title=\"${termTitle}\" -- bash -c \"${shellCmd}\"`,\n },\n // Konsole (KDE)\n {\n command: 'konsole',\n args: `--workdir \"${workDir}\" --title \"${termTitle}\" -e bash -c \"${shellCmd}\"`,\n },\n // xterm (fallback)\n {\n command: 'xterm',\n args: `-T \"${termTitle}\" -e \"cd '${workDir}' && ${shellCmd}\"`,\n },\n ];\n\n for (const term of terminals) {\n try {\n await execAsync(`which ${term.command}`);\n await execAsync(`${term.command} ${term.args} &`);\n return;\n } catch {\n // Terminal not available, try next\n continue;\n }\n }\n\n throw new Error('No supported terminal emulator found (tried: gnome-terminal, konsole, xterm)');\n}\n\n/**\n * Spawn Claude Code in a new terminal to fix a file\n */\nexport async function spawnClaudeCodeFix(options: {\n file: string;\n goal: string;\n violation: string;\n suggestedFix?: string;\n cwd: string;\n}): Promise<void> {\n const { file, goal, violation, suggestedFix, cwd } = options;\n\n // Build a prompt for Claude CLI\n const promptLines = [\n 'Fix this file to satisfy the goal.',\n '',\n `File: ${file}`,\n `Goal: ${goal}`,\n `Violation: ${violation}`,\n ];\n \n if (suggestedFix) {\n promptLines.push(`Suggested fix: ${suggestedFix}`);\n }\n \n promptLines.push(\n '',\n 'Please fix the violation while:',\n '1. Preserving all functionality',\n '2. Maintaining code style',\n '3. Not breaking anything',\n '4. Following the goal exactly',\n );\n\n const prompt = promptLines.join('\\n');\n\n // Spawn terminal that runs: claude <prompt>\n // This will start claude in interactive mode with the prompt pre-filled\n await spawnTerminal({\n command: `claude \"${prompt.replace(/\"/g, '\\\\\"')}\"`,\n cwd,\n title: `Fixing: ${file}`,\n keepOpen: true,\n });\n}\n"],"mappings":";;;AAOA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AAEzB,IAAM,YAAY,UAAU,IAAI;AAgBhC,eAAsB,cAAc,SAA8C;AAChF,QAAM,EAAE,SAAS,KAAK,OAAO,WAAW,KAAK,IAAI;AACjD,QAAM,KAAK,SAAS;AAEpB,MAAI,OAAO,UAAU;AACnB,UAAM,mBAAmB,SAAS,KAAK,OAAO,QAAQ;AAAA,EACxD,WAAW,OAAO,SAAS;AACzB,UAAM,mBAAmB,SAAS,KAAK,OAAO,QAAQ;AAAA,EACxD,OAAO;AACL,UAAM,IAAI,MAAM,sCAAsC,EAAE,EAAE;AAAA,EAC5D;AACF;AAMA,eAAe,mBACb,SACA,KACA,OACA,UACe;AAEf,QAAM,iBAAiB,QAAQ,QAAQ,MAAM,OAAS;AACtD,QAAM,aAAa,KAAK,QAAQ,MAAM,OAAS,KAAK,QAAQ,IAAI;AAChE,QAAM,eAAe,OAAO,QAAQ,MAAM,OAAS,KAAK;AAGxD,QAAM,cAAc,MAAM,OAAO,UAAU,QAAQ,OAAO,KAAK;AAC/D,QAAM,qBAAqB,YAAY,QAAQ,MAAM,OAAS;AAG9D,QAAM,SAAS;AAAA;AAAA;AAAA,6BAGY,kBAAkB;AAAA,mCACZ,YAAY;AAAA;AAAA,EAE7C,KAAK;AAEL,MAAI;AACF,UAAM,UAAU,iBAAiB,OAAO,QAAQ,MAAM,OAAS,CAAC,GAAG;AAAA,EACrE,SAAS,OAAO;AAEd,YAAQ,MAAM,+CAA+C;AAC7D,UAAM,WAAW,WACb,GAAG,WAAW,gBACd;AACJ,UAAM,UAAU,qBAAqB,UAAU,gBAAgB,QAAQ,GAAG;AAAA,EAC5E;AACF;AAMA,eAAe,mBACb,SACA,KACA,OACA,UACe;AACf,QAAM,UAAU,OAAO,QAAQ,IAAI;AACnC,QAAM,YAAY,SAAS;AAC3B,QAAM,WAAW,WAAW,GAAG,OAAO,gBAAgB;AAGtD,QAAM,YAAY;AAAA;AAAA,IAEhB;AAAA,MACE,SAAS;AAAA,MACT,MAAM,wBAAwB,OAAO,cAAc,SAAS,iBAAiB,QAAQ;AAAA,IACvF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS;AAAA,MACT,MAAM,cAAc,OAAO,cAAc,SAAS,iBAAiB,QAAQ;AAAA,IAC7E;AAAA;AAAA,IAEA;AAAA,MACE,SAAS;AAAA,MACT,MAAM,OAAO,SAAS,aAAa,OAAO,QAAQ,QAAQ;AAAA,IAC5D;AAAA,EACF;AAEA,aAAW,QAAQ,WAAW;AAC5B,QAAI;AACF,YAAM,UAAU,SAAS,KAAK,OAAO,EAAE;AACvC,YAAM,UAAU,GAAG,KAAK,OAAO,IAAI,KAAK,IAAI,IAAI;AAChD;AAAA,IACF,QAAQ;AAEN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,8EAA8E;AAChG;AAKA,eAAsB,mBAAmB,SAMvB;AAChB,QAAM,EAAE,MAAM,MAAM,WAAW,cAAc,IAAI,IAAI;AAGrD,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA,SAAS,IAAI;AAAA,IACb,SAAS,IAAI;AAAA,IACb,cAAc,SAAS;AAAA,EACzB;AAEA,MAAI,cAAc;AAChB,gBAAY,KAAK,kBAAkB,YAAY,EAAE;AAAA,EACnD;AAEA,cAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAS,YAAY,KAAK,IAAI;AAIpC,QAAM,cAAc;AAAA,IAClB,SAAS,WAAW,OAAO,QAAQ,MAAM,KAAK,CAAC;AAAA,IAC/C;AAAA,IACA,OAAO,WAAW,IAAI;AAAA,IACtB,UAAU;AAAA,EACZ,CAAC;AACH;","names":[]}