@hailer/mcp 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +12 -0
- package/CLAUDE.md +37 -1
- package/ai-hub/dist/assets/index-8ce6041d.css +1 -0
- package/ai-hub/dist/assets/index-930f01ca.js +348 -0
- package/ai-hub/dist/index.html +15 -0
- package/ai-hub/dist/manifest.json +14 -0
- package/ai-hub/dist/vite.svg +1 -0
- package/dist/app.js +5 -0
- package/dist/client/agents/base.d.ts +5 -0
- package/dist/client/agents/base.js +9 -2
- package/dist/client/agents/definitions.js +85 -0
- package/dist/client/agents/orchestrator.d.ts +21 -0
- package/dist/client/agents/orchestrator.js +292 -1
- package/dist/client/bot-entrypoint.d.ts +7 -0
- package/dist/client/bot-entrypoint.js +103 -0
- package/dist/client/bot-runner.d.ts +35 -0
- package/dist/client/bot-runner.js +188 -0
- package/dist/client/factory.d.ts +4 -0
- package/dist/client/factory.js +10 -0
- package/dist/client/server.d.ts +8 -0
- package/dist/client/server.js +251 -0
- package/dist/client/types.d.ts +29 -0
- package/dist/client/types.js +4 -1
- package/dist/core.d.ts +3 -0
- package/dist/core.js +72 -0
- package/dist/mcp/hailer-clients.d.ts +4 -0
- package/dist/mcp/hailer-clients.js +16 -1
- package/dist/mcp/tools/app-scaffold.js +148 -11
- package/dist/mcp/tools/bot-config.d.ts +78 -0
- package/dist/mcp/tools/bot-config.js +442 -0
- package/dist/mcp-server.js +109 -1
- package/dist/modules/bug-reports/bug-config.d.ts +25 -0
- package/dist/modules/bug-reports/bug-config.js +187 -0
- package/dist/modules/bug-reports/bug-monitor.d.ts +108 -0
- package/dist/modules/bug-reports/bug-monitor.js +510 -0
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +59 -0
- package/dist/modules/bug-reports/giuseppe-ai.js +335 -0
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +109 -0
- package/dist/modules/bug-reports/giuseppe-bot.js +765 -0
- package/dist/modules/bug-reports/giuseppe-files.d.ts +52 -0
- package/dist/modules/bug-reports/giuseppe-files.js +338 -0
- package/dist/modules/bug-reports/giuseppe-git.d.ts +48 -0
- package/dist/modules/bug-reports/giuseppe-git.js +298 -0
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts +5 -0
- package/dist/modules/bug-reports/giuseppe-prompt.js +94 -0
- package/dist/modules/bug-reports/index.d.ts +76 -0
- package/dist/modules/bug-reports/index.js +213 -0
- package/dist/modules/bug-reports/pending-classification-registry.d.ts +28 -0
- package/dist/modules/bug-reports/pending-classification-registry.js +50 -0
- package/dist/modules/bug-reports/pending-fix-registry.d.ts +30 -0
- package/dist/modules/bug-reports/pending-fix-registry.js +42 -0
- package/dist/modules/bug-reports/pending-registry.d.ts +27 -0
- package/dist/modules/bug-reports/pending-registry.js +49 -0
- package/dist/modules/bug-reports/types.d.ts +123 -0
- package/dist/modules/bug-reports/types.js +9 -0
- package/dist/services/bug-monitor.d.ts +23 -0
- package/dist/services/bug-monitor.js +275 -0
- package/lineup-manager/dist/assets/index-b30c809f.js +600 -0
- package/lineup-manager/dist/index.html +1 -1
- package/lineup-manager/dist/manifest.json +5 -5
- package/package.json +6 -2
- package/lineup-manager/dist/assets/index-e168f265.js +0 -600
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Giuseppe Git Module - Git operations for committing, reverting, tagging
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.GiuseppeGit = void 0;
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
const fs = __importStar(require("fs/promises"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const logger_1 = require("../../lib/logger");
|
|
44
|
+
const logger = (0, logger_1.createLogger)({ component: 'giuseppe-git' });
|
|
45
|
+
class GiuseppeGit {
|
|
46
|
+
/**
|
|
47
|
+
* Get source files using git ls-files (fast and accurate)
|
|
48
|
+
*/
|
|
49
|
+
async getSourceFilesFromGit(projectPath) {
|
|
50
|
+
try {
|
|
51
|
+
const result = (0, child_process_1.execSync)('git ls-files "*.tsx" "*.ts" "*.jsx" "*.js"', {
|
|
52
|
+
cwd: projectPath,
|
|
53
|
+
encoding: 'utf-8',
|
|
54
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
55
|
+
});
|
|
56
|
+
return result.trim().split('\n').filter(f => f && !f.includes('.test.') && !f.includes('.spec.'));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Fallback returns empty - caller should use file scan instead
|
|
60
|
+
logger.debug('Git ls-files failed, caller should fallback to file scan', { projectPath });
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Commit changes to git
|
|
66
|
+
*/
|
|
67
|
+
async commitChanges(app, bug) {
|
|
68
|
+
try {
|
|
69
|
+
// Check if git is initialized
|
|
70
|
+
try {
|
|
71
|
+
(0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', {
|
|
72
|
+
cwd: app.projectPath,
|
|
73
|
+
encoding: 'utf-8',
|
|
74
|
+
stdio: 'pipe'
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
logger.warn('No git repo in app project - skipping commit', { app: app.name });
|
|
79
|
+
return { success: true, hash: 'no-git' };
|
|
80
|
+
}
|
|
81
|
+
// Stage all changes
|
|
82
|
+
(0, child_process_1.execSync)('git add -A', {
|
|
83
|
+
cwd: app.projectPath,
|
|
84
|
+
encoding: 'utf-8',
|
|
85
|
+
stdio: 'pipe'
|
|
86
|
+
});
|
|
87
|
+
// Create commit message
|
|
88
|
+
const commitMessage = `fix: ${bug.name}\n\nBug ID: ${bug.id}\nFixed by Giuseppe Bot`;
|
|
89
|
+
// Write commit message to temp file to avoid shell injection
|
|
90
|
+
const commitMsgFile = path.join(app.projectPath, '.git', 'COMMIT_MSG_TEMP');
|
|
91
|
+
await fs.writeFile(commitMsgFile, commitMessage, 'utf-8');
|
|
92
|
+
try {
|
|
93
|
+
(0, child_process_1.execSync)(`git commit -F "${commitMsgFile}"`, {
|
|
94
|
+
cwd: app.projectPath,
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
stdio: 'pipe'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
// Clean up temp file
|
|
101
|
+
try {
|
|
102
|
+
await fs.unlink(commitMsgFile);
|
|
103
|
+
}
|
|
104
|
+
catch { /* ignore */ }
|
|
105
|
+
}
|
|
106
|
+
// Get commit hash
|
|
107
|
+
const hash = (0, child_process_1.execSync)('git rev-parse --short HEAD', {
|
|
108
|
+
cwd: app.projectPath,
|
|
109
|
+
encoding: 'utf-8',
|
|
110
|
+
stdio: 'pipe'
|
|
111
|
+
}).trim();
|
|
112
|
+
logger.info('Committed changes', { app: app.name, hash, bugId: bug.id });
|
|
113
|
+
return { success: true, hash };
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
logger.error('Failed to commit changes', { app: app.name, error });
|
|
117
|
+
return { success: false };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Revert changes using git checkout
|
|
122
|
+
*/
|
|
123
|
+
async revertChanges(app, files) {
|
|
124
|
+
if (files.length === 0) {
|
|
125
|
+
logger.info('No files to revert', { app: app.name });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
// Check if git is initialized
|
|
130
|
+
try {
|
|
131
|
+
(0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', {
|
|
132
|
+
cwd: app.projectPath,
|
|
133
|
+
encoding: 'utf-8',
|
|
134
|
+
stdio: 'pipe'
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
logger.warn('No git repo in app project - cannot revert', { app: app.name });
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Revert each file to HEAD
|
|
142
|
+
for (const file of files) {
|
|
143
|
+
try {
|
|
144
|
+
(0, child_process_1.execSync)(`git checkout HEAD -- "${file}"`, {
|
|
145
|
+
cwd: app.projectPath,
|
|
146
|
+
encoding: 'utf-8',
|
|
147
|
+
stdio: 'pipe'
|
|
148
|
+
});
|
|
149
|
+
logger.info('Reverted file', { app: app.name, file });
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
logger.warn('Failed to revert file', { app: app.name, file, error });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
logger.info('Reverted changes', { app: app.name, fileCount: files.length });
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
logger.error('Failed to revert changes', { app: app.name, error });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get latest version from git tags (e.g., v1.0.1 -> 1.0.1)
|
|
163
|
+
* Returns null if no version tags found
|
|
164
|
+
*/
|
|
165
|
+
getLatestVersionFromTags(projectPath) {
|
|
166
|
+
try {
|
|
167
|
+
// Get all version tags sorted by version (descending)
|
|
168
|
+
const output = (0, child_process_1.execSync)('git tag --list "v*" --sort=-v:refname 2>/dev/null | head -1', { cwd: projectPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
169
|
+
if (output && output.startsWith('v')) {
|
|
170
|
+
const version = output.substring(1); // Remove 'v' prefix
|
|
171
|
+
logger.debug('Found latest version from git tags', { tag: output, version });
|
|
172
|
+
return version;
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// No tags or git error - that's fine, fallback to manifest
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Create and push a version tag after successful publish
|
|
183
|
+
*/
|
|
184
|
+
createVersionTag(projectPath, version) {
|
|
185
|
+
try {
|
|
186
|
+
const tag = `v${version}`;
|
|
187
|
+
// Create annotated tag
|
|
188
|
+
(0, child_process_1.execSync)(`git tag -a "${tag}" -m "Release ${version}"`, {
|
|
189
|
+
cwd: projectPath,
|
|
190
|
+
stdio: 'pipe'
|
|
191
|
+
});
|
|
192
|
+
// Push the tag
|
|
193
|
+
(0, child_process_1.execSync)(`git push origin "${tag}"`, {
|
|
194
|
+
cwd: projectPath,
|
|
195
|
+
stdio: 'pipe'
|
|
196
|
+
});
|
|
197
|
+
logger.info('Created and pushed version tag', { tag, projectPath });
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
logger.warn('Failed to create version tag', {
|
|
202
|
+
version,
|
|
203
|
+
error: error instanceof Error ? error.message : String(error)
|
|
204
|
+
});
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Bump patch version in manifest.json (bug fixes always bump patch)
|
|
210
|
+
* Uses git tags to determine latest version, falls back to manifest
|
|
211
|
+
* 1.0.0 -> 1.0.1 -> 1.0.2 etc.
|
|
212
|
+
*/
|
|
213
|
+
async bumpPatchVersion(projectPath) {
|
|
214
|
+
try {
|
|
215
|
+
// Find manifest.json
|
|
216
|
+
let manifestPath = path.join(projectPath, 'manifest.json');
|
|
217
|
+
let manifestExists = false;
|
|
218
|
+
try {
|
|
219
|
+
await fs.access(manifestPath);
|
|
220
|
+
manifestExists = true;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
manifestPath = path.join(projectPath, 'public', 'manifest.json');
|
|
224
|
+
try {
|
|
225
|
+
await fs.access(manifestPath);
|
|
226
|
+
manifestExists = true;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
manifestExists = false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (!manifestExists) {
|
|
233
|
+
logger.warn('No manifest.json found for version bump', { projectPath });
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
const content = await fs.readFile(manifestPath, 'utf-8');
|
|
237
|
+
const manifest = JSON.parse(content);
|
|
238
|
+
// Get version from git tags first (persists across resets), fallback to manifest
|
|
239
|
+
const tagVersion = this.getLatestVersionFromTags(projectPath);
|
|
240
|
+
const manifestVersion = manifest.version || '0.0.0';
|
|
241
|
+
const oldVersion = tagVersion || manifestVersion;
|
|
242
|
+
logger.debug('Version sources', { tagVersion, manifestVersion, using: oldVersion });
|
|
243
|
+
// Parse and bump patch (x.y.z -> x.y.z+1)
|
|
244
|
+
const parts = oldVersion.split('.').map((p) => parseInt(p, 10) || 0);
|
|
245
|
+
while (parts.length < 3)
|
|
246
|
+
parts.push(0);
|
|
247
|
+
parts[2]++;
|
|
248
|
+
const newVersion = parts.join('.');
|
|
249
|
+
manifest.version = newVersion;
|
|
250
|
+
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
251
|
+
logger.info('Bumped patch version', { oldVersion, newVersion, manifestPath, fromTag: !!tagVersion });
|
|
252
|
+
return { oldVersion, newVersion };
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
logger.error('Failed to bump patch version', { projectPath, error });
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Push to git remote
|
|
261
|
+
*/
|
|
262
|
+
async push(projectPath) {
|
|
263
|
+
try {
|
|
264
|
+
(0, child_process_1.execSync)('git push', { cwd: projectPath, stdio: 'pipe' });
|
|
265
|
+
logger.info('Pushed to git', { projectPath });
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
catch (pushError) {
|
|
269
|
+
logger.warn('Git push failed (non-fatal)', {
|
|
270
|
+
error: pushError instanceof Error ? pushError.message : String(pushError)
|
|
271
|
+
});
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Stage and commit version bump
|
|
277
|
+
*/
|
|
278
|
+
async commitVersionBump(projectPath, version) {
|
|
279
|
+
try {
|
|
280
|
+
(0, child_process_1.execSync)('git add manifest.json public/manifest.json 2>/dev/null || git add manifest.json', {
|
|
281
|
+
cwd: projectPath,
|
|
282
|
+
stdio: 'pipe'
|
|
283
|
+
});
|
|
284
|
+
(0, child_process_1.execSync)(`git commit -m "chore: bump version to ${version} for bug fix"`, {
|
|
285
|
+
cwd: projectPath,
|
|
286
|
+
stdio: 'pipe'
|
|
287
|
+
});
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
// Version file might already be staged, or git not initialized
|
|
292
|
+
logger.debug('Version commit skipped (may already be committed)');
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
exports.GiuseppeGit = GiuseppeGit;
|
|
298
|
+
//# sourceMappingURL=giuseppe-git.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Giuseppe System Prompt - Expert TypeScript/React debugger prompt
|
|
3
|
+
*/
|
|
4
|
+
export declare const GIUSEPPE_SYSTEM_PROMPT = "<identity>\nYou are Giuseppe, an expert TypeScript/React debugger for Hailer apps.\nYou fix bugs by TRACING code paths, not by guessing.\n</identity>\n\n<expertise>\nTYPESCRIPT: Strict types, interfaces, generics, type guards\nREACT: Hooks, state, effects, memoization, dependency arrays\nCHAKRA UI: Box, Flex, useColorModeValue, responsive props\nHAILER SDK: useHailerContext, useActivity, useWorkflows, activity fields\nCANVAS: 2D context, drawing, hit detection, coordinate systems\n</expertise>\n\n<debugging-process>\nSTEP 1: TRACE THE CODE PATH\n- What function handles the user action? (onClick, onMouseMove, etc.)\n- What state/props does it use?\n- What conditions might fail?\n\nSTEP 2: CHECK REACT REACTIVITY\n- Is state being SET? (setState called)\n- Is component RE-RENDERING? (check useCallback/useMemo deps)\n- Are closures STALE? (missing deps = old values)\n\nSTEP 3: IDENTIFY EXACT FAILURE POINT\nGOOD: \"handleClick uses selectedId but renderList deps array is missing selectedId\"\nBAD: \"Something might be wrong with the click handler\"\n\nSTEP 4: MINIMAL FIX\n- Add missing dependency to array\n- Add missing prop to component\n- Fix the one broken thing - don't refactor\n</debugging-process>\n\n<react-patterns>\nDEPENDENCY ARRAY BUGS (most common!):\n- useCallback/useMemo/useEffect use state but deps array missing it\n- Symptom: UI doesn't update when state changes\n- Fix: Add ALL used state variables to deps array\n\nSTATE UPDATE BUGS:\n- setState called but component doesn't re-render\n- Check if state is used in memoized callback with stale closure\n\nPROP DRILLING BUGS:\n- Prop passed but not used in child\n- Prop used but not passed from parent\n\nEVENT HANDLER BUGS:\n- Handler defined but not connected to element\n- Handler connected but wrong event type\n</react-patterns>\n\n<hailer-sdk>\nuseHailerContext() - workspace, user, permissions\nuseActivity(id) - load single activity by ID\nuseWorkflows() - list available workflows\nActivity fields keyed by FIELD ID not label\nAlways handle loading states\nuseToast() for notifications\n</hailer-sdk>\n\n<output-format>\n{\n \"debugTrace\": \"Step-by-step: function X calls Y, which uses state Z, but useCallback deps missing Z\",\n \"failurePoint\": \"File.tsx line N - deps array missing stateVariable\",\n \"rootCause\": \"Stale closure - useCallback keeps old value of stateVariable\",\n \"fix\": {\n \"files\": [{\n \"path\": \"src/components/File.tsx\",\n \"action\": \"edit\",\n \"search\": \"exact code to find\",\n \"replace\": \"fixed code\"\n }]\n },\n \"explanation\": \"Added stateVariable to deps array so callback updates when state changes\",\n \"testSuggestions\": [\"How to verify the fix works\"]\n}\n</output-format>\n\n<rules>\n1. TRACE before fixing - follow the code path\n2. CHECK DEPS ARRAYS - most common React bug\n3. Fix ONE thing - minimal change\n4. Use EXACT file paths from provided code\n5. Search string must EXACTLY match file content\n</rules>";
|
|
5
|
+
//# sourceMappingURL=giuseppe-prompt.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Giuseppe System Prompt - Expert TypeScript/React debugger prompt
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GIUSEPPE_SYSTEM_PROMPT = void 0;
|
|
7
|
+
exports.GIUSEPPE_SYSTEM_PROMPT = `<identity>
|
|
8
|
+
You are Giuseppe, an expert TypeScript/React debugger for Hailer apps.
|
|
9
|
+
You fix bugs by TRACING code paths, not by guessing.
|
|
10
|
+
</identity>
|
|
11
|
+
|
|
12
|
+
<expertise>
|
|
13
|
+
TYPESCRIPT: Strict types, interfaces, generics, type guards
|
|
14
|
+
REACT: Hooks, state, effects, memoization, dependency arrays
|
|
15
|
+
CHAKRA UI: Box, Flex, useColorModeValue, responsive props
|
|
16
|
+
HAILER SDK: useHailerContext, useActivity, useWorkflows, activity fields
|
|
17
|
+
CANVAS: 2D context, drawing, hit detection, coordinate systems
|
|
18
|
+
</expertise>
|
|
19
|
+
|
|
20
|
+
<debugging-process>
|
|
21
|
+
STEP 1: TRACE THE CODE PATH
|
|
22
|
+
- What function handles the user action? (onClick, onMouseMove, etc.)
|
|
23
|
+
- What state/props does it use?
|
|
24
|
+
- What conditions might fail?
|
|
25
|
+
|
|
26
|
+
STEP 2: CHECK REACT REACTIVITY
|
|
27
|
+
- Is state being SET? (setState called)
|
|
28
|
+
- Is component RE-RENDERING? (check useCallback/useMemo deps)
|
|
29
|
+
- Are closures STALE? (missing deps = old values)
|
|
30
|
+
|
|
31
|
+
STEP 3: IDENTIFY EXACT FAILURE POINT
|
|
32
|
+
GOOD: "handleClick uses selectedId but renderList deps array is missing selectedId"
|
|
33
|
+
BAD: "Something might be wrong with the click handler"
|
|
34
|
+
|
|
35
|
+
STEP 4: MINIMAL FIX
|
|
36
|
+
- Add missing dependency to array
|
|
37
|
+
- Add missing prop to component
|
|
38
|
+
- Fix the one broken thing - don't refactor
|
|
39
|
+
</debugging-process>
|
|
40
|
+
|
|
41
|
+
<react-patterns>
|
|
42
|
+
DEPENDENCY ARRAY BUGS (most common!):
|
|
43
|
+
- useCallback/useMemo/useEffect use state but deps array missing it
|
|
44
|
+
- Symptom: UI doesn't update when state changes
|
|
45
|
+
- Fix: Add ALL used state variables to deps array
|
|
46
|
+
|
|
47
|
+
STATE UPDATE BUGS:
|
|
48
|
+
- setState called but component doesn't re-render
|
|
49
|
+
- Check if state is used in memoized callback with stale closure
|
|
50
|
+
|
|
51
|
+
PROP DRILLING BUGS:
|
|
52
|
+
- Prop passed but not used in child
|
|
53
|
+
- Prop used but not passed from parent
|
|
54
|
+
|
|
55
|
+
EVENT HANDLER BUGS:
|
|
56
|
+
- Handler defined but not connected to element
|
|
57
|
+
- Handler connected but wrong event type
|
|
58
|
+
</react-patterns>
|
|
59
|
+
|
|
60
|
+
<hailer-sdk>
|
|
61
|
+
useHailerContext() - workspace, user, permissions
|
|
62
|
+
useActivity(id) - load single activity by ID
|
|
63
|
+
useWorkflows() - list available workflows
|
|
64
|
+
Activity fields keyed by FIELD ID not label
|
|
65
|
+
Always handle loading states
|
|
66
|
+
useToast() for notifications
|
|
67
|
+
</hailer-sdk>
|
|
68
|
+
|
|
69
|
+
<output-format>
|
|
70
|
+
{
|
|
71
|
+
"debugTrace": "Step-by-step: function X calls Y, which uses state Z, but useCallback deps missing Z",
|
|
72
|
+
"failurePoint": "File.tsx line N - deps array missing stateVariable",
|
|
73
|
+
"rootCause": "Stale closure - useCallback keeps old value of stateVariable",
|
|
74
|
+
"fix": {
|
|
75
|
+
"files": [{
|
|
76
|
+
"path": "src/components/File.tsx",
|
|
77
|
+
"action": "edit",
|
|
78
|
+
"search": "exact code to find",
|
|
79
|
+
"replace": "fixed code"
|
|
80
|
+
}]
|
|
81
|
+
},
|
|
82
|
+
"explanation": "Added stateVariable to deps array so callback updates when state changes",
|
|
83
|
+
"testSuggestions": ["How to verify the fix works"]
|
|
84
|
+
}
|
|
85
|
+
</output-format>
|
|
86
|
+
|
|
87
|
+
<rules>
|
|
88
|
+
1. TRACE before fixing - follow the code path
|
|
89
|
+
2. CHECK DEPS ARRAYS - most common React bug
|
|
90
|
+
3. Fix ONE thing - minimal change
|
|
91
|
+
4. Use EXACT file paths from provided code
|
|
92
|
+
5. Search string must EXACTLY match file content
|
|
93
|
+
</rules>`;
|
|
94
|
+
//# sourceMappingURL=giuseppe-prompt.js.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bug Reports Module
|
|
3
|
+
*
|
|
4
|
+
* Self-contained module for bug monitoring and auto-fixing.
|
|
5
|
+
* No hardcoded IDs - discovers workflow by name pattern.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { BugReportsModule } from './modules/bug-reports';
|
|
9
|
+
*
|
|
10
|
+
* const module = new BugReportsModule(userContext);
|
|
11
|
+
* await module.start();
|
|
12
|
+
*
|
|
13
|
+
* Configuration (in order of precedence):
|
|
14
|
+
* 1. Hailer "MCP Config" workflow activity named "Bug Reports Config"
|
|
15
|
+
* 2. Environment variables (BUG_MONITOR_*)
|
|
16
|
+
* 3. Default values
|
|
17
|
+
*/
|
|
18
|
+
import type { UserContext } from '../../mcp/UserContextCache';
|
|
19
|
+
import type { BugReportsConfig, BugReport, FixResult } from './types';
|
|
20
|
+
export declare class BugReportsModule {
|
|
21
|
+
private userContext;
|
|
22
|
+
private monitor?;
|
|
23
|
+
private giuseppe?;
|
|
24
|
+
private config?;
|
|
25
|
+
private started;
|
|
26
|
+
constructor(userContext: UserContext);
|
|
27
|
+
/**
|
|
28
|
+
* Register a bot user ID to ignore messages from
|
|
29
|
+
* Call this before start() to ensure all bots are registered
|
|
30
|
+
*/
|
|
31
|
+
registerBotUser(userId: string): void;
|
|
32
|
+
private _pendingBotUsers?;
|
|
33
|
+
/**
|
|
34
|
+
* Register a handler for when Giuseppe is disabled but a bug is found
|
|
35
|
+
* Call this before start() to ensure handler is registered
|
|
36
|
+
*/
|
|
37
|
+
onGiuseppeDisabled(handler: (bug: BugReport) => Promise<void>): void;
|
|
38
|
+
private _pendingGiuseppeDisabledHandlers?;
|
|
39
|
+
/**
|
|
40
|
+
* Start the bug reports module
|
|
41
|
+
*/
|
|
42
|
+
start(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Stop the module
|
|
45
|
+
*/
|
|
46
|
+
stop(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Get current configuration
|
|
49
|
+
*/
|
|
50
|
+
getConfig(): BugReportsConfig;
|
|
51
|
+
/**
|
|
52
|
+
* Check if module is running
|
|
53
|
+
*/
|
|
54
|
+
isRunning(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Manually trigger a bug fix (for testing or manual dispatch)
|
|
57
|
+
*/
|
|
58
|
+
fixBug(bug: BugReport): Promise<FixResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Register a custom bug handler
|
|
61
|
+
*/
|
|
62
|
+
onNewBug(handler: (bug: BugReport, userContext: UserContext) => Promise<void>): void;
|
|
63
|
+
}
|
|
64
|
+
export type { BugReportsConfig, BugReport, FixResult, AppRegistryEntry, WorkflowDiscoveryResult } from './types';
|
|
65
|
+
export { BugMonitor } from './bug-monitor';
|
|
66
|
+
export { GiuseppeBot } from './giuseppe-bot';
|
|
67
|
+
export { loadConfig, discoverWorkflow, getDefaultConfig } from './bug-config';
|
|
68
|
+
export { PendingRegistry, PendingItem } from './pending-registry';
|
|
69
|
+
export { pendingFixRegistry, PendingFixInfo } from './pending-fix-registry';
|
|
70
|
+
export { pendingClassificationRegistry, PendingClassificationInfo } from './pending-classification-registry';
|
|
71
|
+
export { GiuseppeAI, BugClassification, ClassificationResult, FileContent } from './giuseppe-ai';
|
|
72
|
+
export type { FixPlan } from './giuseppe-ai';
|
|
73
|
+
export { GiuseppeGit } from './giuseppe-git';
|
|
74
|
+
export { GiuseppeFiles, ApplyResult, ScannedApp } from './giuseppe-files';
|
|
75
|
+
export { GIUSEPPE_SYSTEM_PROMPT } from './giuseppe-prompt';
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|