@hailer/mcp 0.1.16 → 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 (202) 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/webhook-handler.d.ts +2 -2
  37. package/dist/mcp/webhook-handler.js +5 -3
  38. package/dist/mcp-server.d.ts +2 -2
  39. package/dist/mcp-server.js +167 -140
  40. package/package.json +1 -1
  41. package/REFACTOR_STATUS.md +0 -127
  42. package/dist/agents/bot-manager.d.ts +0 -48
  43. package/dist/agents/bot-manager.js +0 -254
  44. package/dist/agents/factory.d.ts +0 -150
  45. package/dist/agents/factory.js +0 -650
  46. package/dist/agents/giuseppe/ai.d.ts +0 -83
  47. package/dist/agents/giuseppe/ai.js +0 -466
  48. package/dist/agents/giuseppe/bot.d.ts +0 -110
  49. package/dist/agents/giuseppe/bot.js +0 -780
  50. package/dist/agents/giuseppe/config.d.ts +0 -25
  51. package/dist/agents/giuseppe/config.js +0 -227
  52. package/dist/agents/giuseppe/files.d.ts +0 -52
  53. package/dist/agents/giuseppe/files.js +0 -338
  54. package/dist/agents/giuseppe/git.d.ts +0 -48
  55. package/dist/agents/giuseppe/git.js +0 -298
  56. package/dist/agents/giuseppe/index.d.ts +0 -97
  57. package/dist/agents/giuseppe/index.js +0 -258
  58. package/dist/agents/giuseppe/lsp.d.ts +0 -113
  59. package/dist/agents/giuseppe/lsp.js +0 -485
  60. package/dist/agents/giuseppe/monitor.d.ts +0 -118
  61. package/dist/agents/giuseppe/monitor.js +0 -621
  62. package/dist/agents/giuseppe/prompt.d.ts +0 -5
  63. package/dist/agents/giuseppe/prompt.js +0 -94
  64. package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
  65. package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
  66. package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
  67. package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
  68. package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
  69. package/dist/agents/giuseppe/registries/pending.js +0 -49
  70. package/dist/agents/giuseppe/specialist.d.ts +0 -47
  71. package/dist/agents/giuseppe/specialist.js +0 -237
  72. package/dist/agents/giuseppe/types.d.ts +0 -123
  73. package/dist/agents/giuseppe/types.js +0 -9
  74. package/dist/agents/hailer-expert/index.d.ts +0 -8
  75. package/dist/agents/hailer-expert/index.js +0 -14
  76. package/dist/agents/hal/daemon.d.ts +0 -142
  77. package/dist/agents/hal/daemon.js +0 -1103
  78. package/dist/agents/hal/definitions.d.ts +0 -55
  79. package/dist/agents/hal/definitions.js +0 -263
  80. package/dist/agents/hal/index.d.ts +0 -3
  81. package/dist/agents/hal/index.js +0 -8
  82. package/dist/agents/index.d.ts +0 -18
  83. package/dist/agents/index.js +0 -48
  84. package/dist/agents/shared/base.d.ts +0 -216
  85. package/dist/agents/shared/base.js +0 -846
  86. package/dist/agents/shared/services/agent-registry.d.ts +0 -107
  87. package/dist/agents/shared/services/agent-registry.js +0 -629
  88. package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
  89. package/dist/agents/shared/services/conversation-manager.js +0 -136
  90. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  91. package/dist/agents/shared/services/mcp-client.js +0 -124
  92. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  93. package/dist/agents/shared/services/message-classifier.js +0 -187
  94. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  95. package/dist/agents/shared/services/message-formatter.js +0 -371
  96. package/dist/agents/shared/services/session-logger.d.ts +0 -106
  97. package/dist/agents/shared/services/session-logger.js +0 -446
  98. package/dist/agents/shared/services/tool-executor.d.ts +0 -41
  99. package/dist/agents/shared/services/tool-executor.js +0 -169
  100. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
  101. package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
  102. package/dist/agents/shared/specialist.d.ts +0 -91
  103. package/dist/agents/shared/specialist.js +0 -399
  104. package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
  105. package/dist/agents/shared/tool-schema-loader.js +0 -232
  106. package/dist/agents/shared/types.d.ts +0 -327
  107. package/dist/agents/shared/types.js +0 -121
  108. package/dist/client/agents/base.d.ts +0 -207
  109. package/dist/client/agents/base.js +0 -744
  110. package/dist/client/agents/definitions.d.ts +0 -53
  111. package/dist/client/agents/definitions.js +0 -263
  112. package/dist/client/agents/orchestrator.d.ts +0 -141
  113. package/dist/client/agents/orchestrator.js +0 -1062
  114. package/dist/client/agents/specialist.d.ts +0 -86
  115. package/dist/client/agents/specialist.js +0 -340
  116. package/dist/client/bot-entrypoint.d.ts +0 -7
  117. package/dist/client/bot-entrypoint.js +0 -103
  118. package/dist/client/bot-manager.d.ts +0 -44
  119. package/dist/client/bot-manager.js +0 -173
  120. package/dist/client/bot-runner.d.ts +0 -35
  121. package/dist/client/bot-runner.js +0 -188
  122. package/dist/client/chat-agent-daemon.d.ts +0 -464
  123. package/dist/client/chat-agent-daemon.js +0 -1774
  124. package/dist/client/daemon-factory.d.ts +0 -106
  125. package/dist/client/daemon-factory.js +0 -301
  126. package/dist/client/factory.d.ts +0 -111
  127. package/dist/client/factory.js +0 -314
  128. package/dist/client/index.d.ts +0 -17
  129. package/dist/client/index.js +0 -38
  130. package/dist/client/multi-bot-manager.d.ts +0 -42
  131. package/dist/client/multi-bot-manager.js +0 -161
  132. package/dist/client/orchestrator-daemon.d.ts +0 -87
  133. package/dist/client/orchestrator-daemon.js +0 -444
  134. package/dist/client/server.d.ts +0 -8
  135. package/dist/client/server.js +0 -251
  136. package/dist/client/services/agent-registry.d.ts +0 -108
  137. package/dist/client/services/agent-registry.js +0 -630
  138. package/dist/client/services/conversation-manager.d.ts +0 -50
  139. package/dist/client/services/conversation-manager.js +0 -136
  140. package/dist/client/services/mcp-client.d.ts +0 -48
  141. package/dist/client/services/mcp-client.js +0 -105
  142. package/dist/client/services/message-classifier.d.ts +0 -37
  143. package/dist/client/services/message-classifier.js +0 -187
  144. package/dist/client/services/message-formatter.d.ts +0 -84
  145. package/dist/client/services/message-formatter.js +0 -353
  146. package/dist/client/services/session-logger.d.ts +0 -106
  147. package/dist/client/services/session-logger.js +0 -446
  148. package/dist/client/services/tool-executor.d.ts +0 -41
  149. package/dist/client/services/tool-executor.js +0 -169
  150. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  151. package/dist/client/services/workspace-schema-cache.js +0 -732
  152. package/dist/client/specialist-daemon.d.ts +0 -77
  153. package/dist/client/specialist-daemon.js +0 -197
  154. package/dist/client/specialists.d.ts +0 -53
  155. package/dist/client/specialists.js +0 -178
  156. package/dist/client/tool-schema-loader.d.ts +0 -62
  157. package/dist/client/tool-schema-loader.js +0 -232
  158. package/dist/client/types.d.ts +0 -327
  159. package/dist/client/types.js +0 -121
  160. package/dist/commands/seed-config.d.ts +0 -9
  161. package/dist/commands/seed-config.js +0 -372
  162. package/dist/lib/context-manager.d.ts +0 -111
  163. package/dist/lib/context-manager.js +0 -431
  164. package/dist/lib/prompt-length-manager.d.ts +0 -81
  165. package/dist/lib/prompt-length-manager.js +0 -457
  166. package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
  167. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  168. package/dist/modules/bug-reports/bug-config.js +0 -187
  169. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  170. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  171. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  172. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  173. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  174. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  175. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  176. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  177. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  178. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  179. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  180. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  181. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  182. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  183. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  184. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  185. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  186. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  187. package/dist/modules/bug-reports/index.d.ts +0 -77
  188. package/dist/modules/bug-reports/index.js +0 -215
  189. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  190. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  191. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  192. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  193. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  194. package/dist/modules/bug-reports/pending-registry.js +0 -49
  195. package/dist/modules/bug-reports/types.d.ts +0 -123
  196. package/dist/modules/bug-reports/types.js +0 -9
  197. package/dist/routes/agents.d.ts +0 -44
  198. package/dist/routes/agents.js +0 -311
  199. package/dist/services/agent-credential-store.d.ts +0 -73
  200. package/dist/services/agent-credential-store.js +0 -212
  201. package/dist/services/bug-monitor.d.ts +0 -23
  202. package/dist/services/bug-monitor.js +0 -275
@@ -1,83 +0,0 @@
1
- /**
2
- * Giuseppe AI Module - Claude API interactions for bug analysis and fix generation
3
- */
4
- import type { BugReport, AppRegistryEntry } from './types';
5
- /** Fix plan from Claude analysis */
6
- export interface FixPlan {
7
- analysis: string;
8
- debugTrace?: string;
9
- failurePoint?: string;
10
- rootCause: string;
11
- fix: {
12
- files: Array<{
13
- path: string;
14
- action: 'edit' | 'create' | 'delete';
15
- search?: string;
16
- replace?: string;
17
- content?: string;
18
- }>;
19
- };
20
- explanation: string;
21
- testSuggestions?: string[];
22
- }
23
- export type BugClassification = 'bug' | 'feature_request' | 'unclear';
24
- export interface ClassificationResult {
25
- classification: BugClassification;
26
- reason: string;
27
- }
28
- export interface FileContent {
29
- path: string;
30
- content: string;
31
- }
32
- export declare class GiuseppeAI {
33
- private anthropic?;
34
- constructor(apiKey?: string);
35
- get isAvailable(): boolean;
36
- /**
37
- * Classify a report as bug or feature request
38
- */
39
- classifyReport(bug: BugReport): Promise<ClassificationResult>;
40
- /**
41
- * Detect user intent from a message (replaces magic word detection)
42
- * Returns the intent and confidence level
43
- */
44
- detectIntent(message: string, context: 'classification' | 'approval'): Promise<{
45
- intent: string;
46
- confidence: 'high' | 'medium' | 'low';
47
- explanation: string;
48
- }>;
49
- /**
50
- * Extract keywords from bug description for LSP filtering
51
- */
52
- private extractKeywords;
53
- /**
54
- * Analyze bug and generate fix plan using Claude (two-phase approach)
55
- * Phase 1: Send file list -> Claude picks relevant files
56
- * Phase 2: Send those files -> Claude generates fix
57
- */
58
- analyzeAndPlanFix(bug: BugReport, app: AppRegistryEntry, allFiles: string[], readFiles: (paths: string[]) => Promise<FileContent[]>, runLspAnalysis?: (files: string[], keywords: string[]) => Promise<{
59
- unusedProps: {
60
- name: string;
61
- line: number;
62
- file: string;
63
- }[];
64
- issues: {
65
- file: string;
66
- line: number;
67
- message: string;
68
- }[];
69
- }>): Promise<FixPlan | null>;
70
- /**
71
- * Retry fix based on apply error (search string not found) - re-reads file and generates new fix
72
- */
73
- retryFixFromApplyError(bug: BugReport, previousFix: FixPlan, applyError: string, currentFiles: FileContent[], attempt: number): Promise<FixPlan | null>;
74
- /**
75
- * Retry fix based on build error - sends error to Claude to generate corrected fix
76
- */
77
- retryFixFromError(bug: BugReport, previousFix: FixPlan, buildError: string, currentFiles: FileContent[], attempt: number): Promise<FixPlan | null>;
78
- /**
79
- * Generate a new fix based on user feedback
80
- */
81
- retryFixWithFeedback(bug: BugReport, previousFix: FixPlan, feedback: string, allSourceFiles: string[], currentFiles: FileContent[]): Promise<FixPlan | null>;
82
- }
83
- //# sourceMappingURL=ai.d.ts.map
@@ -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 prompt_1 = require("./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: 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: 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: 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: 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=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 './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 - state machine for approval flow
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=bot.d.ts.map