@hailer/mcp 0.1.17 → 0.2.1

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 (200) hide show
  1. package/dist/app.js +24 -20
  2. package/dist/core.d.ts +33 -9
  3. package/dist/core.js +279 -147
  4. package/dist/mcp/UserContextCache.js +18 -0
  5. package/dist/mcp/hailer-clients.d.ts +9 -1
  6. package/dist/mcp/hailer-clients.js +13 -3
  7. package/dist/mcp/signal-handler.js +1 -1
  8. package/dist/mcp/tool-registry.d.ts +3 -1
  9. package/dist/mcp/tool-registry.js +4 -1
  10. package/dist/mcp/tools/activity.js +43 -34
  11. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  12. package/dist/mcp/tools/bot-config/constants.js +94 -0
  13. package/dist/mcp/tools/{bot-config.d.ts → bot-config/core.d.ts} +6 -6
  14. package/dist/mcp/tools/{bot-config.js → bot-config/core.js} +15 -15
  15. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  16. package/dist/mcp/tools/bot-config/index.js +59 -0
  17. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  18. package/dist/mcp/tools/bot-config/tools.js +15 -0
  19. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  20. package/dist/mcp/tools/bot-config/types.js +6 -0
  21. package/dist/mcp/tools/bug-fixer-tools.d.ts +21 -0
  22. package/dist/mcp/tools/{giuseppe-tools.js → bug-fixer-tools.js} +61 -61
  23. package/dist/mcp/tools/user.js +10 -29
  24. package/dist/mcp/tools/workflow.js +36 -2
  25. package/dist/mcp/utils/data-transformers.d.ts +0 -8
  26. package/dist/mcp/utils/data-transformers.js +0 -28
  27. package/dist/mcp/utils/index.d.ts +4 -1
  28. package/dist/mcp/utils/index.js +17 -3
  29. package/dist/mcp/utils/pagination.d.ts +40 -0
  30. package/dist/mcp/utils/pagination.js +55 -0
  31. package/dist/mcp/utils/response-builder.d.ts +53 -0
  32. package/dist/mcp/utils/response-builder.js +110 -0
  33. package/dist/mcp/utils/tool-helpers.d.ts +0 -8
  34. package/dist/mcp/utils/tool-helpers.js +0 -24
  35. package/dist/mcp/utils/types.d.ts +1 -33
  36. package/dist/mcp-server.d.ts +2 -2
  37. package/dist/mcp-server.js +161 -139
  38. package/package.json +1 -1
  39. package/REFACTOR_STATUS.md +0 -127
  40. package/dist/agents/bot-manager.d.ts +0 -48
  41. package/dist/agents/bot-manager.js +0 -254
  42. package/dist/agents/factory.d.ts +0 -150
  43. package/dist/agents/factory.js +0 -650
  44. package/dist/agents/giuseppe/ai.d.ts +0 -83
  45. package/dist/agents/giuseppe/ai.js +0 -466
  46. package/dist/agents/giuseppe/bot.d.ts +0 -110
  47. package/dist/agents/giuseppe/bot.js +0 -780
  48. package/dist/agents/giuseppe/config.d.ts +0 -25
  49. package/dist/agents/giuseppe/config.js +0 -227
  50. package/dist/agents/giuseppe/files.d.ts +0 -52
  51. package/dist/agents/giuseppe/files.js +0 -338
  52. package/dist/agents/giuseppe/git.d.ts +0 -48
  53. package/dist/agents/giuseppe/git.js +0 -298
  54. package/dist/agents/giuseppe/index.d.ts +0 -97
  55. package/dist/agents/giuseppe/index.js +0 -258
  56. package/dist/agents/giuseppe/lsp.d.ts +0 -113
  57. package/dist/agents/giuseppe/lsp.js +0 -485
  58. package/dist/agents/giuseppe/monitor.d.ts +0 -118
  59. package/dist/agents/giuseppe/monitor.js +0 -621
  60. package/dist/agents/giuseppe/prompt.d.ts +0 -5
  61. package/dist/agents/giuseppe/prompt.js +0 -94
  62. package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
  63. package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
  64. package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
  65. package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
  66. package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
  67. package/dist/agents/giuseppe/registries/pending.js +0 -49
  68. package/dist/agents/giuseppe/specialist.d.ts +0 -47
  69. package/dist/agents/giuseppe/specialist.js +0 -237
  70. package/dist/agents/giuseppe/types.d.ts +0 -123
  71. package/dist/agents/giuseppe/types.js +0 -9
  72. package/dist/agents/hailer-expert/index.d.ts +0 -8
  73. package/dist/agents/hailer-expert/index.js +0 -14
  74. package/dist/agents/hal/daemon.d.ts +0 -142
  75. package/dist/agents/hal/daemon.js +0 -1103
  76. package/dist/agents/hal/definitions.d.ts +0 -55
  77. package/dist/agents/hal/definitions.js +0 -263
  78. package/dist/agents/hal/index.d.ts +0 -3
  79. package/dist/agents/hal/index.js +0 -8
  80. package/dist/agents/index.d.ts +0 -18
  81. package/dist/agents/index.js +0 -48
  82. package/dist/agents/shared/base.d.ts +0 -216
  83. package/dist/agents/shared/base.js +0 -846
  84. package/dist/agents/shared/services/agent-registry.d.ts +0 -107
  85. package/dist/agents/shared/services/agent-registry.js +0 -629
  86. package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
  87. package/dist/agents/shared/services/conversation-manager.js +0 -136
  88. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  89. package/dist/agents/shared/services/mcp-client.js +0 -124
  90. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  91. package/dist/agents/shared/services/message-classifier.js +0 -187
  92. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  93. package/dist/agents/shared/services/message-formatter.js +0 -371
  94. package/dist/agents/shared/services/session-logger.d.ts +0 -106
  95. package/dist/agents/shared/services/session-logger.js +0 -446
  96. package/dist/agents/shared/services/tool-executor.d.ts +0 -41
  97. package/dist/agents/shared/services/tool-executor.js +0 -169
  98. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
  99. package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
  100. package/dist/agents/shared/specialist.d.ts +0 -91
  101. package/dist/agents/shared/specialist.js +0 -399
  102. package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
  103. package/dist/agents/shared/tool-schema-loader.js +0 -232
  104. package/dist/agents/shared/types.d.ts +0 -327
  105. package/dist/agents/shared/types.js +0 -121
  106. package/dist/client/agents/base.d.ts +0 -207
  107. package/dist/client/agents/base.js +0 -744
  108. package/dist/client/agents/definitions.d.ts +0 -53
  109. package/dist/client/agents/definitions.js +0 -263
  110. package/dist/client/agents/orchestrator.d.ts +0 -141
  111. package/dist/client/agents/orchestrator.js +0 -1062
  112. package/dist/client/agents/specialist.d.ts +0 -86
  113. package/dist/client/agents/specialist.js +0 -340
  114. package/dist/client/bot-entrypoint.d.ts +0 -7
  115. package/dist/client/bot-entrypoint.js +0 -103
  116. package/dist/client/bot-manager.d.ts +0 -44
  117. package/dist/client/bot-manager.js +0 -173
  118. package/dist/client/bot-runner.d.ts +0 -35
  119. package/dist/client/bot-runner.js +0 -188
  120. package/dist/client/chat-agent-daemon.d.ts +0 -464
  121. package/dist/client/chat-agent-daemon.js +0 -1774
  122. package/dist/client/daemon-factory.d.ts +0 -106
  123. package/dist/client/daemon-factory.js +0 -301
  124. package/dist/client/factory.d.ts +0 -111
  125. package/dist/client/factory.js +0 -314
  126. package/dist/client/index.d.ts +0 -17
  127. package/dist/client/index.js +0 -38
  128. package/dist/client/multi-bot-manager.d.ts +0 -42
  129. package/dist/client/multi-bot-manager.js +0 -161
  130. package/dist/client/orchestrator-daemon.d.ts +0 -87
  131. package/dist/client/orchestrator-daemon.js +0 -444
  132. package/dist/client/server.d.ts +0 -8
  133. package/dist/client/server.js +0 -251
  134. package/dist/client/services/agent-registry.d.ts +0 -108
  135. package/dist/client/services/agent-registry.js +0 -630
  136. package/dist/client/services/conversation-manager.d.ts +0 -50
  137. package/dist/client/services/conversation-manager.js +0 -136
  138. package/dist/client/services/mcp-client.d.ts +0 -48
  139. package/dist/client/services/mcp-client.js +0 -105
  140. package/dist/client/services/message-classifier.d.ts +0 -37
  141. package/dist/client/services/message-classifier.js +0 -187
  142. package/dist/client/services/message-formatter.d.ts +0 -84
  143. package/dist/client/services/message-formatter.js +0 -353
  144. package/dist/client/services/session-logger.d.ts +0 -106
  145. package/dist/client/services/session-logger.js +0 -446
  146. package/dist/client/services/tool-executor.d.ts +0 -41
  147. package/dist/client/services/tool-executor.js +0 -169
  148. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  149. package/dist/client/services/workspace-schema-cache.js +0 -732
  150. package/dist/client/specialist-daemon.d.ts +0 -77
  151. package/dist/client/specialist-daemon.js +0 -197
  152. package/dist/client/specialists.d.ts +0 -53
  153. package/dist/client/specialists.js +0 -178
  154. package/dist/client/tool-schema-loader.d.ts +0 -62
  155. package/dist/client/tool-schema-loader.js +0 -232
  156. package/dist/client/types.d.ts +0 -327
  157. package/dist/client/types.js +0 -121
  158. package/dist/commands/seed-config.d.ts +0 -9
  159. package/dist/commands/seed-config.js +0 -372
  160. package/dist/lib/context-manager.d.ts +0 -111
  161. package/dist/lib/context-manager.js +0 -431
  162. package/dist/lib/prompt-length-manager.d.ts +0 -81
  163. package/dist/lib/prompt-length-manager.js +0 -457
  164. package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
  165. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  166. package/dist/modules/bug-reports/bug-config.js +0 -187
  167. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  168. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  169. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  170. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  171. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  172. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  173. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  174. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  175. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  176. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  177. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  178. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  179. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  180. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  181. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  182. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  183. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  184. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  185. package/dist/modules/bug-reports/index.d.ts +0 -77
  186. package/dist/modules/bug-reports/index.js +0 -215
  187. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  188. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  189. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  190. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  191. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  192. package/dist/modules/bug-reports/pending-registry.js +0 -49
  193. package/dist/modules/bug-reports/types.d.ts +0 -123
  194. package/dist/modules/bug-reports/types.js +0 -9
  195. package/dist/routes/agents.d.ts +0 -44
  196. package/dist/routes/agents.js +0 -311
  197. package/dist/services/agent-credential-store.d.ts +0 -73
  198. package/dist/services/agent-credential-store.js +0 -212
  199. package/dist/services/bug-monitor.d.ts +0 -23
  200. package/dist/services/bug-monitor.js +0 -275
@@ -1,466 +0,0 @@
1
- "use strict";
2
- /**
3
- * Giuseppe AI Module - Claude API interactions for bug analysis and fix generation
4
- */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.GiuseppeAI = void 0;
10
- const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
11
- const logger_1 = require("../../lib/logger");
12
- const giuseppe_prompt_1 = require("./giuseppe-prompt");
13
- const logger = (0, logger_1.createLogger)({ component: 'giuseppe-ai' });
14
- class GiuseppeAI {
15
- anthropic;
16
- constructor(apiKey) {
17
- if (apiKey) {
18
- this.anthropic = new sdk_1.default({ apiKey });
19
- }
20
- }
21
- get isAvailable() {
22
- return !!this.anthropic;
23
- }
24
- /**
25
- * Classify a report as bug or feature request
26
- */
27
- async classifyReport(bug) {
28
- if (!this.anthropic) {
29
- return { classification: 'unclear', reason: 'No AI available for classification' };
30
- }
31
- try {
32
- const prompt = `Classify this report as either a BUG or a FEATURE REQUEST.
33
-
34
- **Title:** ${bug.name}
35
- **Description:** ${bug.description || 'No description'}
36
- ${bug.stepsToReproduce ? `**Steps:** ${bug.stepsToReproduce}` : ''}
37
- ${bug.expectedBehavior ? `**Expected:** ${bug.expectedBehavior}` : ''}
38
- ${bug.actualBehavior ? `**Actual:** ${bug.actualBehavior}` : ''}
39
-
40
- A BUG is something BROKEN - it was working or should work but doesn't.
41
- Examples: "button doesn't respond", "crashes when clicking", "data not saving", "display is wrong"
42
-
43
- A FEATURE REQUEST is asking for something NEW or DIFFERENT - not broken, just wanted.
44
- Examples: "change color to blue", "add dark mode", "make it bigger", "add new button"
45
-
46
- Respond with JSON only:
47
- {
48
- "classification": "bug" | "feature_request" | "unclear",
49
- "reason": "One sentence explaining why"
50
- }`;
51
- const response = await this.anthropic.messages.create({
52
- model: 'claude-haiku-4-5-20251001',
53
- max_tokens: 200,
54
- messages: [{ role: 'user', content: prompt }]
55
- });
56
- const content = response.content[0];
57
- if (content.type !== 'text') {
58
- return { classification: 'unclear', reason: 'Could not classify' };
59
- }
60
- const parsed = JSON.parse(content.text.replace(/```json\n?|\n?```/g, ''));
61
- return {
62
- classification: parsed.classification || 'unclear',
63
- reason: parsed.reason || 'No reason provided'
64
- };
65
- }
66
- catch (error) {
67
- logger.error('Classification failed', { error });
68
- return { classification: 'unclear', reason: 'Classification error' };
69
- }
70
- }
71
- /**
72
- * Detect user intent from a message (replaces magic word detection)
73
- * Returns the intent and confidence level
74
- */
75
- async detectIntent(message, context) {
76
- if (!this.anthropic) {
77
- // Fallback to simple keyword matching
78
- const lower = message.toLowerCase().trim();
79
- if (context === 'classification') {
80
- if (lower.includes('fix') && !lower.includes('don\'t') && !lower.includes('not')) {
81
- return { intent: 'fix_it', confidence: 'medium', explanation: 'Contains "fix"' };
82
- }
83
- if (lower.includes('not a bug') || lower.includes('feature')) {
84
- return { intent: 'not_a_bug', confidence: 'medium', explanation: 'Contains "not a bug" or "feature"' };
85
- }
86
- }
87
- else {
88
- if (lower === 'approved' || lower === 'yes' || lower === 'ship it' || lower === 'deploy') {
89
- return { intent: 'approved', confidence: 'medium', explanation: 'Approval keyword' };
90
- }
91
- if (lower === 'denied' || lower === 'no' || lower === 'revert' || lower === 'cancel') {
92
- return { intent: 'denied', confidence: 'medium', explanation: 'Denial keyword' };
93
- }
94
- }
95
- return { intent: 'unknown', confidence: 'low', explanation: 'No matching keywords' };
96
- }
97
- try {
98
- const contextDescription = context === 'classification'
99
- ? `Giuseppe classified a bug report and is waiting for the user to confirm:
100
- - "fix_it" = User wants Giuseppe to proceed with fixing the bug
101
- - "not_a_bug" = User says this isn't a bug, it's a feature request or not an issue
102
- - "clarify" = User is asking a question or providing more info
103
- - "unknown" = Can't determine intent`
104
- : `Giuseppe has created a fix and is waiting for approval to publish:
105
- - "approved" = User approves publishing to production
106
- - "denied" = User rejects the fix or wants changes
107
- - "retry" = User wants Giuseppe to try a different approach
108
- - "question" = User is asking about the fix
109
- - "unknown" = Can't determine intent`;
110
- const prompt = `Detect the user's intent from this message.
111
-
112
- Context: ${contextDescription}
113
-
114
- User message: "${message}"
115
-
116
- Respond with JSON only (no markdown):
117
- {"intent": "...", "confidence": "high|medium|low", "explanation": "brief reason"}`;
118
- const response = await this.anthropic.messages.create({
119
- model: 'claude-haiku-4-5-20251001',
120
- max_tokens: 150,
121
- messages: [{ role: 'user', content: prompt }]
122
- });
123
- const content = response.content[0];
124
- if (content.type !== 'text') {
125
- return { intent: 'unknown', confidence: 'low', explanation: 'AI response error' };
126
- }
127
- const parsed = JSON.parse(content.text.replace(/```json\n?|\n?```/g, '').trim());
128
- logger.info('Intent detected', {
129
- message: message.substring(0, 50),
130
- intent: parsed.intent,
131
- confidence: parsed.confidence
132
- });
133
- return {
134
- intent: parsed.intent || 'unknown',
135
- confidence: parsed.confidence || 'low',
136
- explanation: parsed.explanation || ''
137
- };
138
- }
139
- catch (error) {
140
- logger.error('Intent detection failed', { error, message: message.substring(0, 50) });
141
- return { intent: 'unknown', confidence: 'low', explanation: 'Detection error' };
142
- }
143
- }
144
- /**
145
- * Extract keywords from bug description for LSP filtering
146
- */
147
- extractKeywords(description) {
148
- // Common technical terms to look for
149
- const techTerms = [
150
- 'click', 'drag', 'drop', 'scroll', 'hover', 'focus', 'blur',
151
- 'render', 'update', 'load', 'save', 'delete', 'create',
152
- 'button', 'input', 'form', 'modal', 'menu', 'list', 'table',
153
- 'position', 'animation', 'transition', 'style', 'color',
154
- 'error', 'crash', 'freeze', 'slow', 'lag', 'broken'
155
- ];
156
- const words = description.toLowerCase()
157
- .replace(/[^\w\s]/g, ' ')
158
- .split(/\s+/)
159
- .filter(w => w.length > 2);
160
- // Find matching tech terms
161
- const matchedTerms = techTerms.filter(term => words.some(w => w.includes(term) || term.includes(w)));
162
- // Also include unique words from description (nouns/verbs likely)
163
- const uniqueWords = words.filter(w => w.length > 4 && !['the', 'and', 'but', 'for', 'not', 'with', 'this', 'that', 'when', 'have', 'from'].includes(w));
164
- return [...new Set([...matchedTerms, ...uniqueWords])].slice(0, 10);
165
- }
166
- /**
167
- * Analyze bug and generate fix plan using Claude (two-phase approach)
168
- * Phase 1: Send file list -> Claude picks relevant files
169
- * Phase 2: Send those files -> Claude generates fix
170
- */
171
- async analyzeAndPlanFix(bug, app, allFiles, readFiles, runLspAnalysis) {
172
- if (!this.anthropic) {
173
- logger.warn('Anthropic client not initialized - cannot generate fix');
174
- return null;
175
- }
176
- try {
177
- // Phase 1: Get file list and ask Claude which files to examine
178
- logger.info('Phase 1: Asking Claude which files to examine', { fileCount: allFiles.length });
179
- const phase1Prompt = `
180
- Bug Report:
181
- - Title: ${bug.name}
182
- - Description: ${bug.description}
183
- ${bug.stepsToReproduce ? `- Steps to reproduce: ${bug.stepsToReproduce}` : ''}
184
- ${bug.expectedBehavior ? `- Expected: ${bug.expectedBehavior}` : ''}
185
- ${bug.actualBehavior ? `- Actual: ${bug.actualBehavior}` : ''}
186
-
187
- App: ${app.name}
188
-
189
- Source files in this project:
190
- ${allFiles.map(f => `- ${f}`).join('\n')}
191
-
192
- Based on the bug description, which files should I examine to fix this bug?
193
- Return ONLY a JSON array of file paths, maximum 10 files. Example: ["src/App.tsx", "src/components/Player.tsx"]`;
194
- const phase1Response = await this.anthropic.messages.create({
195
- model: 'claude-sonnet-4-20250514',
196
- max_tokens: 1024,
197
- system: 'You are a code analyst. Return only a JSON array of file paths that are most relevant to the bug. No explanation.',
198
- messages: [{ role: 'user', content: phase1Prompt }]
199
- });
200
- const phase1Content = phase1Response.content[0];
201
- if (phase1Content.type !== 'text')
202
- return null;
203
- // Parse file list from response
204
- let relevantFiles = [];
205
- try {
206
- // Try to extract JSON array
207
- const jsonMatch = phase1Content.text.match(/\[[\s\S]*?\]/);
208
- if (jsonMatch) {
209
- relevantFiles = JSON.parse(jsonMatch[0]);
210
- }
211
- }
212
- catch {
213
- logger.warn('Could not parse file list from Phase 1', { response: phase1Content.text });
214
- // Fallback: take first 5 files from src/
215
- relevantFiles = allFiles.filter(f => f.startsWith('src/')).slice(0, 5);
216
- }
217
- logger.info('Phase 1 complete: Files to examine', { files: relevantFiles });
218
- // Phase 1.5: Run TARGETED LSP analysis on relevant files only
219
- // Extract keywords from bug description for filtering
220
- const bugKeywords = this.extractKeywords(bug.description);
221
- logger.info('Extracted bug keywords for LSP filtering', { keywords: bugKeywords });
222
- let lspFindings = null;
223
- if (runLspAnalysis) {
224
- lspFindings = await runLspAnalysis(relevantFiles, bugKeywords);
225
- logger.info('Targeted LSP analysis complete', {
226
- files: relevantFiles.length,
227
- unusedProps: lspFindings.unusedProps.length,
228
- issues: lspFindings.issues.length
229
- });
230
- }
231
- // Phase 2: Read selected files and generate fix
232
- const sourceFiles = await readFiles(relevantFiles);
233
- logger.info('Phase 2: Generating fix', { filesRead: sourceFiles.length });
234
- // Build LSP findings section if available
235
- let lspSection = '';
236
- if (lspFindings && (lspFindings.unusedProps.length > 0 || lspFindings.issues.length > 0)) {
237
- lspSection = '\n\n=== LSP CODE ANALYSIS (HIGH PRIORITY) ===\n';
238
- lspSection += 'IMPORTANT: These are REAL code issues detected by static analysis. Fix these FIRST.\n\n';
239
- if (lspFindings.unusedProps.length > 0) {
240
- lspSection += 'UNUSED PROPS (declared in interface but never used in component):\n';
241
- lspFindings.unusedProps.forEach(p => {
242
- lspSection += `- ${p.file}:${p.line} - prop "${p.name}" is declared but never destructured/used\n`;
243
- // Add hint if prop name matches bug keywords
244
- if (bug.description.toLowerCase().includes(p.name.toLowerCase())) {
245
- lspSection += ` ^ THIS PROP NAME MATCHES THE BUG DESCRIPTION - VERY LIKELY THE ROOT CAUSE!\n`;
246
- }
247
- });
248
- }
249
- if (lspFindings.issues.length > 0) {
250
- lspSection += '\nDEAD CODE (functions/variables declared but never called):\n';
251
- lspFindings.issues.forEach(i => {
252
- lspSection += `- ${i.file}:${i.line} - ${i.message}\n`;
253
- });
254
- }
255
- lspSection += '\nThe fix should USE these unused props/functions, not add workaround code.\n';
256
- }
257
- const phase2Prompt = `
258
- Bug Report:
259
- - Title: ${bug.name}
260
- - Description: ${bug.description}
261
- ${bug.stepsToReproduce ? `- Steps to reproduce: ${bug.stepsToReproduce}` : ''}
262
- ${bug.expectedBehavior ? `- Expected: ${bug.expectedBehavior}` : ''}
263
- ${bug.actualBehavior ? `- Actual: ${bug.actualBehavior}` : ''}
264
- - Priority: ${bug.priority || 'unknown'}
265
- ${lspSection}
266
- App: ${app.name}
267
- Project path: ${app.projectPath}
268
-
269
- Source files:
270
- ${sourceFiles.map(f => `--- ${f.path} ---\n${f.content}\n`).join('\n')}
271
-
272
- Analyze this bug and provide a fix. Output JSON only.`;
273
- const phase2Response = await this.anthropic.messages.create({
274
- model: 'claude-sonnet-4-20250514',
275
- max_tokens: 4096,
276
- system: giuseppe_prompt_1.GIUSEPPE_SYSTEM_PROMPT,
277
- messages: [{ role: 'user', content: phase2Prompt }]
278
- });
279
- // Extract JSON from response
280
- const content = phase2Response.content[0];
281
- if (content.type !== 'text')
282
- return null;
283
- const jsonMatch = content.text.match(/```json\n([\s\S]*?)\n```/);
284
- if (!jsonMatch) {
285
- // Try parsing whole response as JSON
286
- try {
287
- return JSON.parse(content.text);
288
- }
289
- catch {
290
- logger.warn('Could not parse fix plan from response');
291
- return null;
292
- }
293
- }
294
- return JSON.parse(jsonMatch[1]);
295
- }
296
- catch (error) {
297
- logger.error('Failed to analyze bug', { error });
298
- return null;
299
- }
300
- }
301
- /**
302
- * Retry fix based on apply error (search string not found) - re-reads file and generates new fix
303
- */
304
- async retryFixFromApplyError(bug, previousFix, applyError, currentFiles, attempt) {
305
- if (!this.anthropic)
306
- return null;
307
- try {
308
- logger.info('Retrying fix after apply error', { attempt, error: applyError });
309
- const retryPrompt = `
310
- The previous fix attempt FAILED to apply with this error:
311
- \`\`\`
312
- ${applyError}
313
- \`\`\`
314
-
315
- This usually means the search string didn't match the actual file content.
316
-
317
- Previous fix that was attempted:
318
- ${JSON.stringify(previousFix.fix, null, 2)}
319
-
320
- Bug Report:
321
- - Title: ${bug.name}
322
- - Description: ${bug.description}
323
-
324
- CURRENT state of the files (read just now):
325
- ${currentFiles.map(f => `--- ${f.path} ---\n${f.content}\n`).join('\n')}
326
-
327
- Please analyze the current file content and provide a CORRECTED fix.
328
- Make sure the "search" strings EXACTLY match what's in the current files.
329
- Output JSON only.`;
330
- const response = await this.anthropic.messages.create({
331
- model: 'claude-sonnet-4-20250514',
332
- max_tokens: 4096,
333
- system: giuseppe_prompt_1.GIUSEPPE_SYSTEM_PROMPT + '\n\nIMPORTANT: Your previous fix could not be applied because the search string was not found. Read the CURRENT file content carefully and make sure your search strings match EXACTLY.',
334
- messages: [{ role: 'user', content: retryPrompt }]
335
- });
336
- const content = response.content[0];
337
- if (content.type !== 'text')
338
- return null;
339
- const jsonMatch = content.text.match(/```json\n([\s\S]*?)\n```/);
340
- if (!jsonMatch) {
341
- try {
342
- return JSON.parse(content.text);
343
- }
344
- catch {
345
- return null;
346
- }
347
- }
348
- return JSON.parse(jsonMatch[1]);
349
- }
350
- catch (error) {
351
- logger.error('Failed to generate retry fix from apply error', { error });
352
- return null;
353
- }
354
- }
355
- /**
356
- * Retry fix based on build error - sends error to Claude to generate corrected fix
357
- */
358
- async retryFixFromError(bug, previousFix, buildError, currentFiles, attempt) {
359
- if (!this.anthropic)
360
- return null;
361
- try {
362
- logger.info('Retrying fix based on build error', { attempt, error: buildError.substring(0, 200) });
363
- const retryPrompt = `
364
- The previous fix attempt FAILED with this build error:
365
- \`\`\`
366
- ${buildError}
367
- \`\`\`
368
-
369
- Previous fix that was attempted:
370
- ${JSON.stringify(previousFix.fix, null, 2)}
371
-
372
- Bug Report:
373
- - Title: ${bug.name}
374
- - Description: ${bug.description}
375
-
376
- Current state of the files after the failed fix:
377
- ${currentFiles.map(f => `--- ${f.path} ---\n${f.content}\n`).join('\n')}
378
-
379
- Please analyze the build error and provide a CORRECTED fix.
380
- The fix must resolve the TypeScript/build error while still addressing the original bug.
381
- Output JSON only.`;
382
- const response = await this.anthropic.messages.create({
383
- model: 'claude-sonnet-4-20250514',
384
- max_tokens: 4096,
385
- system: giuseppe_prompt_1.GIUSEPPE_SYSTEM_PROMPT + '\n\nIMPORTANT: Your previous fix caused a build error. Analyze the error carefully and provide a corrected fix that compiles successfully.',
386
- messages: [{ role: 'user', content: retryPrompt }]
387
- });
388
- const content = response.content[0];
389
- if (content.type !== 'text')
390
- return null;
391
- const jsonMatch = content.text.match(/```json\n([\s\S]*?)\n```/);
392
- if (!jsonMatch) {
393
- try {
394
- return JSON.parse(content.text);
395
- }
396
- catch {
397
- return null;
398
- }
399
- }
400
- return JSON.parse(jsonMatch[1]);
401
- }
402
- catch (error) {
403
- logger.error('Failed to generate retry fix', { error });
404
- return null;
405
- }
406
- }
407
- /**
408
- * Generate a new fix based on user feedback
409
- */
410
- async retryFixWithFeedback(bug, previousFix, feedback, allSourceFiles, currentFiles) {
411
- if (!this.anthropic)
412
- return null;
413
- try {
414
- const prompt = `
415
- The previous fix was REJECTED by the user. Here's their feedback:
416
-
417
- **User feedback:**
418
- ${feedback}
419
-
420
- **Original bug:**
421
- - Title: ${bug.name}
422
- - Description: ${bug.description}
423
- ${bug.stepsToReproduce ? `- Steps to reproduce: ${bug.stepsToReproduce}` : ''}
424
- ${bug.expectedBehavior ? `- Expected: ${bug.expectedBehavior}` : ''}
425
- ${bug.actualBehavior ? `- Actual: ${bug.actualBehavior}` : ''}
426
-
427
- **Previous fix that was rejected:**
428
- ${JSON.stringify(previousFix.fix, null, 2)}
429
-
430
- **AVAILABLE SOURCE FILES (use ONLY these exact paths):**
431
- ${allSourceFiles.map(f => `- ${f}`).join('\n')}
432
-
433
- **Relevant source files (searched based on your feedback):**
434
- ${currentFiles.map(f => `--- ${f.path} ---\n${f.content}\n`).join('\n')}
435
-
436
- Based on the user's feedback, generate a DIFFERENT fix that addresses their concerns.
437
- IMPORTANT: Use ONLY file paths from the AVAILABLE SOURCE FILES list above.
438
- Output JSON only.`;
439
- const response = await this.anthropic.messages.create({
440
- model: 'claude-sonnet-4-20250514',
441
- max_tokens: 4096,
442
- system: giuseppe_prompt_1.GIUSEPPE_SYSTEM_PROMPT + '\n\nIMPORTANT: The user rejected the previous fix. Read their feedback carefully and try a different approach.',
443
- messages: [{ role: 'user', content: prompt }]
444
- });
445
- const content = response.content[0];
446
- if (content.type !== 'text')
447
- return null;
448
- const jsonMatch = content.text.match(/```json\n([\s\S]*?)\n```/);
449
- if (!jsonMatch) {
450
- try {
451
- return JSON.parse(content.text);
452
- }
453
- catch {
454
- return null;
455
- }
456
- }
457
- return JSON.parse(jsonMatch[1]);
458
- }
459
- catch (error) {
460
- logger.error('Failed to generate retry fix with feedback', { error });
461
- return null;
462
- }
463
- }
464
- }
465
- exports.GiuseppeAI = GiuseppeAI;
466
- //# sourceMappingURL=giuseppe-ai.js.map
@@ -1,110 +0,0 @@
1
- /**
2
- * Bug Reports Module - Giuseppe Bot
3
- *
4
- * Autonomous app fixer that:
5
- * 1. Analyzes bug reports
6
- * 2. Finds app project code
7
- * 3. Generates fixes using Claude
8
- * 4. Tests locally
9
- * 5. Publishes to production
10
- */
11
- import type { UserContext } from '../../mcp/UserContextCache';
12
- import type { BugReport, BugReportsConfig, FixResult } from './types';
13
- import type { BugMonitor } from './bug-monitor';
14
- export declare class GiuseppeBot {
15
- private userContext;
16
- private config;
17
- private monitor;
18
- private ai;
19
- private git;
20
- private files;
21
- private lsp;
22
- private appsRegistry;
23
- constructor(userContext: UserContext, config: BugReportsConfig, monitor: BugMonitor);
24
- /**
25
- * Create a session log entry in Context Log workflow
26
- * Links to the bug report for traceability
27
- */
28
- private createSessionLogEntry;
29
- /**
30
- * Check if this bug was already classified by looking for classification message in discussion
31
- */
32
- private wasAlreadyClassified;
33
- /**
34
- * Handle a new bug - main entry point
35
- */
36
- handleBug(bug: BugReport): Promise<FixResult>;
37
- /**
38
- * Continue with bug fix after user confirms
39
- */
40
- proceedWithFix(bug: BugReport): Promise<FixResult>;
41
- /**
42
- * Handle a message in a bug discussion - uses LLM to understand intent
43
- */
44
- handleDiscussionMessage(discussionId: string, message: string, _senderId: string): Promise<{
45
- approved: boolean;
46
- published: boolean;
47
- retrying?: boolean;
48
- error?: string;
49
- }>;
50
- /**
51
- * Handle "fix it" confirmation - proceed with bug fix
52
- */
53
- private handleFixItConfirmation;
54
- /**
55
- * Handle "not a bug" confirmation - close without fixing
56
- */
57
- private handleNotABugConfirmation;
58
- /**
59
- * Handle "approved" - publish to production
60
- */
61
- private handleApproval;
62
- /**
63
- * Handle "denied" - ask for explanation
64
- */
65
- private handleDenial;
66
- /**
67
- * Handle explanation after denial - retry the fix
68
- */
69
- private handleExplanationAndRetry;
70
- /**
71
- * Check if there's a pending fix for a discussion
72
- */
73
- hasPendingFix(discussionId: string): boolean;
74
- /**
75
- * Retry a pending fix with explanation from HAL
76
- * Called by HAL after gathering info through conversation
77
- */
78
- retryWithExplanation(discussionId: string, explanation: string): Promise<boolean>;
79
- /**
80
- * Initialize registry callback (call this after construction)
81
- */
82
- initializeRegistryCallback(): void;
83
- /**
84
- * Initialize classification registry callbacks for HAL coordination
85
- * This allows HAL to trigger "fix it" or "not a bug" via natural conversation
86
- */
87
- initializeClassificationCallbacks(): void;
88
- /**
89
- * Helper to send a message to a discussion
90
- */
91
- private sendDiscussionMessage;
92
- /**
93
- * Build and test the app
94
- */
95
- private buildAndTest;
96
- /**
97
- * Join a bug's discussion using the activity ID (not discussion ID)
98
- * For activity discussions, we must use joinActivityDiscussion
99
- */
100
- private joinBugDiscussion;
101
- /**
102
- * Publish app to production using expect script (same as MCP tool)
103
- */
104
- private publishApp;
105
- /**
106
- * Report progress to bug discussion
107
- */
108
- private reportProgress;
109
- }
110
- //# sourceMappingURL=giuseppe-bot.d.ts.map