@hailer/mcp 0.1.14 → 0.1.16
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/agents/agent-giuseppe-app-builder.md +7 -6
- package/.claude/agents/agent-lars-code-inspector.md +26 -14
- package/dist/agents/bot-manager.d.ts +48 -0
- package/dist/agents/bot-manager.js +254 -0
- package/dist/agents/factory.d.ts +150 -0
- package/dist/agents/factory.js +650 -0
- package/dist/agents/giuseppe/ai.d.ts +83 -0
- package/dist/agents/giuseppe/ai.js +466 -0
- package/dist/agents/giuseppe/bot.d.ts +110 -0
- package/dist/agents/giuseppe/bot.js +780 -0
- package/dist/agents/giuseppe/config.d.ts +25 -0
- package/dist/agents/giuseppe/config.js +227 -0
- package/dist/agents/giuseppe/files.d.ts +52 -0
- package/dist/agents/giuseppe/files.js +338 -0
- package/dist/agents/giuseppe/git.d.ts +48 -0
- package/dist/agents/giuseppe/git.js +298 -0
- package/dist/agents/giuseppe/index.d.ts +97 -0
- package/dist/agents/giuseppe/index.js +258 -0
- package/dist/agents/giuseppe/lsp.d.ts +113 -0
- package/dist/agents/giuseppe/lsp.js +485 -0
- package/dist/agents/giuseppe/monitor.d.ts +118 -0
- package/dist/agents/giuseppe/monitor.js +621 -0
- package/dist/agents/giuseppe/prompt.d.ts +5 -0
- package/dist/agents/giuseppe/prompt.js +94 -0
- package/dist/agents/giuseppe/registries/pending-classification.d.ts +28 -0
- package/dist/agents/giuseppe/registries/pending-classification.js +50 -0
- package/dist/agents/giuseppe/registries/pending-fix.d.ts +30 -0
- package/dist/agents/giuseppe/registries/pending-fix.js +42 -0
- package/dist/agents/giuseppe/registries/pending.d.ts +27 -0
- package/dist/agents/giuseppe/registries/pending.js +49 -0
- package/dist/agents/giuseppe/specialist.d.ts +47 -0
- package/dist/agents/giuseppe/specialist.js +237 -0
- package/dist/agents/giuseppe/types.d.ts +123 -0
- package/dist/agents/giuseppe/types.js +9 -0
- package/dist/agents/hailer-expert/index.d.ts +8 -0
- package/dist/agents/hailer-expert/index.js +14 -0
- package/dist/agents/hal/daemon.d.ts +142 -0
- package/dist/agents/hal/daemon.js +1103 -0
- package/dist/agents/hal/definitions.d.ts +55 -0
- package/dist/agents/hal/definitions.js +263 -0
- package/dist/agents/hal/index.d.ts +3 -0
- package/dist/agents/hal/index.js +8 -0
- package/dist/agents/index.d.ts +18 -0
- package/dist/agents/index.js +48 -0
- package/dist/agents/shared/base.d.ts +216 -0
- package/dist/agents/shared/base.js +846 -0
- package/dist/agents/shared/services/agent-registry.d.ts +107 -0
- package/dist/agents/shared/services/agent-registry.js +629 -0
- package/dist/agents/shared/services/conversation-manager.d.ts +50 -0
- package/dist/agents/shared/services/conversation-manager.js +136 -0
- package/dist/agents/shared/services/mcp-client.d.ts +56 -0
- package/dist/agents/shared/services/mcp-client.js +124 -0
- package/dist/agents/shared/services/message-classifier.d.ts +37 -0
- package/dist/agents/shared/services/message-classifier.js +187 -0
- package/dist/agents/shared/services/message-formatter.d.ts +89 -0
- package/dist/agents/shared/services/message-formatter.js +371 -0
- package/dist/agents/shared/services/session-logger.d.ts +106 -0
- package/dist/agents/shared/services/session-logger.js +446 -0
- package/dist/agents/shared/services/tool-executor.d.ts +41 -0
- package/dist/agents/shared/services/tool-executor.js +169 -0
- package/dist/agents/shared/services/workspace-schema-cache.d.ts +125 -0
- package/dist/agents/shared/services/workspace-schema-cache.js +578 -0
- package/dist/agents/shared/specialist.d.ts +91 -0
- package/dist/agents/shared/specialist.js +399 -0
- package/dist/agents/shared/tool-schema-loader.d.ts +62 -0
- package/dist/agents/shared/tool-schema-loader.js +232 -0
- package/dist/agents/shared/types.d.ts +327 -0
- package/dist/agents/shared/types.js +121 -0
- package/dist/app.js +21 -4
- package/dist/cli.js +0 -0
- package/dist/client/agents/orchestrator.d.ts +1 -0
- package/dist/client/agents/orchestrator.js +12 -1
- package/dist/commands/seed-config.d.ts +9 -0
- package/dist/commands/seed-config.js +372 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +61 -1
- package/dist/core.d.ts +8 -0
- package/dist/core.js +137 -6
- package/dist/lib/discussion-lock.d.ts +42 -0
- package/dist/lib/discussion-lock.js +110 -0
- package/dist/mcp/UserContextCache.js +2 -2
- package/dist/mcp/hailer-clients.d.ts +15 -0
- package/dist/mcp/hailer-clients.js +100 -6
- package/dist/mcp/signal-handler.d.ts +16 -5
- package/dist/mcp/signal-handler.js +173 -122
- package/dist/mcp/tools/activity.js +9 -1
- package/dist/mcp/tools/bot-config.d.ts +184 -9
- package/dist/mcp/tools/bot-config.js +2177 -163
- package/dist/mcp/tools/giuseppe-tools.d.ts +21 -0
- package/dist/mcp/tools/giuseppe-tools.js +525 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +42 -1
- package/dist/mcp/utils/hailer-api-client.js +128 -2
- package/dist/mcp/webhook-handler.d.ts +87 -0
- package/dist/mcp/webhook-handler.js +343 -0
- package/dist/mcp/workspace-cache.d.ts +5 -0
- package/dist/mcp/workspace-cache.js +11 -0
- package/dist/mcp-server.js +55 -5
- package/dist/modules/bug-reports/giuseppe-agent.d.ts +58 -0
- package/dist/modules/bug-reports/giuseppe-agent.js +467 -0
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +25 -1
- package/dist/modules/bug-reports/giuseppe-ai.js +133 -2
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +3 -2
- package/dist/modules/bug-reports/giuseppe-bot.js +75 -36
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts +80 -0
- package/dist/modules/bug-reports/giuseppe-daemon.js +617 -0
- package/dist/modules/bug-reports/giuseppe-files.d.ts +12 -0
- package/dist/modules/bug-reports/giuseppe-files.js +37 -0
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts +113 -0
- package/dist/modules/bug-reports/giuseppe-lsp.js +485 -0
- package/dist/modules/bug-reports/index.d.ts +1 -0
- package/dist/modules/bug-reports/index.js +31 -29
- package/package.json +5 -4
|
@@ -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=git.js.map
|
|
@@ -0,0 +1,97 @@
|
|
|
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 { GiuseppeModule } from './agents/giuseppe';
|
|
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 { GiuseppeBot } from './bot';
|
|
20
|
+
import type { BugReportsConfig, BugReport, FixResult } from './types';
|
|
21
|
+
export declare class BugReportsModule {
|
|
22
|
+
private userContext;
|
|
23
|
+
private monitor?;
|
|
24
|
+
private giuseppe?;
|
|
25
|
+
private config?;
|
|
26
|
+
private started;
|
|
27
|
+
constructor(userContext: UserContext);
|
|
28
|
+
/**
|
|
29
|
+
* Register a bot user ID to ignore messages from
|
|
30
|
+
* Call this before start() to ensure all bots are registered
|
|
31
|
+
*/
|
|
32
|
+
registerBotUser(userId: string): void;
|
|
33
|
+
private _pendingBotUsers?;
|
|
34
|
+
/**
|
|
35
|
+
* Register a handler for when Giuseppe is disabled but a bug is found
|
|
36
|
+
* Call this before start() to ensure handler is registered
|
|
37
|
+
*/
|
|
38
|
+
onGiuseppeDisabled(handler: (bug: BugReport) => Promise<void>): void;
|
|
39
|
+
private _pendingGiuseppeDisabledHandlers?;
|
|
40
|
+
/**
|
|
41
|
+
* Enable conversational mode - bugs go to daemon instead of auto-fixer
|
|
42
|
+
* The daemon handler receives bugs and handles conversation with user
|
|
43
|
+
*/
|
|
44
|
+
enableConversationalMode(handler: (bug: BugReport) => Promise<void>): void;
|
|
45
|
+
private _conversationalModeHandler?;
|
|
46
|
+
/**
|
|
47
|
+
* Check if conversational mode is enabled
|
|
48
|
+
*/
|
|
49
|
+
isConversationalMode(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get the GiuseppeBot instance for daemon to invoke fixes
|
|
52
|
+
*/
|
|
53
|
+
getGiuseppeBot(): GiuseppeBot | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Start the bug reports module
|
|
56
|
+
*/
|
|
57
|
+
start(): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Stop the module
|
|
60
|
+
*/
|
|
61
|
+
stop(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Get current configuration
|
|
64
|
+
*/
|
|
65
|
+
getConfig(): BugReportsConfig;
|
|
66
|
+
/**
|
|
67
|
+
* Check if module is running
|
|
68
|
+
*/
|
|
69
|
+
isRunning(): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Get discovered phase IDs for the Bug Reports workflow
|
|
72
|
+
* Returns phase IDs for inProgress, fixed, declined, closed, new
|
|
73
|
+
*/
|
|
74
|
+
getPhaseIds(): Record<string, string | undefined>;
|
|
75
|
+
/**
|
|
76
|
+
* Manually trigger a bug fix (for testing or manual dispatch)
|
|
77
|
+
*/
|
|
78
|
+
fixBug(bug: BugReport): Promise<FixResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Register a custom bug handler
|
|
81
|
+
*/
|
|
82
|
+
onNewBug(handler: (bug: BugReport, userContext: UserContext) => Promise<void>): void;
|
|
83
|
+
}
|
|
84
|
+
export type { BugReportsConfig, BugReport, FixResult, AppRegistryEntry, WorkflowDiscoveryResult } from './types';
|
|
85
|
+
export { BugMonitor } from './monitor';
|
|
86
|
+
export { GiuseppeBot } from './bot';
|
|
87
|
+
export { loadConfig, discoverWorkflow, getDefaultConfig } from './config';
|
|
88
|
+
export { PendingRegistry, PendingItem } from './registries/pending';
|
|
89
|
+
export { pendingFixRegistry, PendingFixInfo } from './registries/pending-fix';
|
|
90
|
+
export { pendingClassificationRegistry, PendingClassificationInfo } from './registries/pending-classification';
|
|
91
|
+
export { GiuseppeAI, BugClassification, ClassificationResult, FileContent } from './ai';
|
|
92
|
+
export type { FixPlan } from './ai';
|
|
93
|
+
export { GiuseppeGit } from './git';
|
|
94
|
+
export { GiuseppeFiles, ApplyResult, ScannedApp } from './files';
|
|
95
|
+
export { GIUSEPPE_SYSTEM_PROMPT } from './prompt';
|
|
96
|
+
export { BugReportsModule as GiuseppeModule };
|
|
97
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bug Reports Module
|
|
4
|
+
*
|
|
5
|
+
* Self-contained module for bug monitoring and auto-fixing.
|
|
6
|
+
* No hardcoded IDs - discovers workflow by name pattern.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { GiuseppeModule } from './agents/giuseppe';
|
|
10
|
+
*
|
|
11
|
+
* const module = new BugReportsModule(userContext);
|
|
12
|
+
* await module.start();
|
|
13
|
+
*
|
|
14
|
+
* Configuration (in order of precedence):
|
|
15
|
+
* 1. Hailer "MCP Config" workflow activity named "Bug Reports Config"
|
|
16
|
+
* 2. Environment variables (BUG_MONITOR_*)
|
|
17
|
+
* 3. Default values
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.GiuseppeModule = exports.GIUSEPPE_SYSTEM_PROMPT = exports.GiuseppeFiles = exports.GiuseppeGit = exports.GiuseppeAI = exports.pendingClassificationRegistry = exports.pendingFixRegistry = exports.PendingRegistry = exports.getDefaultConfig = exports.discoverWorkflow = exports.loadConfig = exports.GiuseppeBot = exports.BugMonitor = exports.BugReportsModule = void 0;
|
|
21
|
+
const logger_1 = require("../../lib/logger");
|
|
22
|
+
const monitor_1 = require("./monitor");
|
|
23
|
+
const bot_1 = require("./bot");
|
|
24
|
+
const config_1 = require("./config");
|
|
25
|
+
const logger = (0, logger_1.createLogger)({ component: 'bug-reports-module' });
|
|
26
|
+
class BugReportsModule {
|
|
27
|
+
userContext;
|
|
28
|
+
monitor;
|
|
29
|
+
giuseppe;
|
|
30
|
+
config;
|
|
31
|
+
started = false;
|
|
32
|
+
constructor(userContext) {
|
|
33
|
+
this.userContext = userContext;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Register a bot user ID to ignore messages from
|
|
37
|
+
* Call this before start() to ensure all bots are registered
|
|
38
|
+
*/
|
|
39
|
+
registerBotUser(userId) {
|
|
40
|
+
if (this.monitor) {
|
|
41
|
+
this.monitor.registerBotUser(userId);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Store for later if monitor not created yet
|
|
45
|
+
this._pendingBotUsers = this._pendingBotUsers || [];
|
|
46
|
+
this._pendingBotUsers.push(userId);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
_pendingBotUsers;
|
|
50
|
+
/**
|
|
51
|
+
* Register a handler for when Giuseppe is disabled but a bug is found
|
|
52
|
+
* Call this before start() to ensure handler is registered
|
|
53
|
+
*/
|
|
54
|
+
onGiuseppeDisabled(handler) {
|
|
55
|
+
if (this.monitor) {
|
|
56
|
+
this.monitor.onGiuseppeDisabled(handler);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Store for later if monitor not created yet
|
|
60
|
+
this._pendingGiuseppeDisabledHandlers = this._pendingGiuseppeDisabledHandlers || [];
|
|
61
|
+
this._pendingGiuseppeDisabledHandlers.push(handler);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
_pendingGiuseppeDisabledHandlers;
|
|
65
|
+
/**
|
|
66
|
+
* Enable conversational mode - bugs go to daemon instead of auto-fixer
|
|
67
|
+
* The daemon handler receives bugs and handles conversation with user
|
|
68
|
+
*/
|
|
69
|
+
enableConversationalMode(handler) {
|
|
70
|
+
this._conversationalModeHandler = handler;
|
|
71
|
+
logger.info('Conversational mode enabled - bugs will be handled by daemon');
|
|
72
|
+
}
|
|
73
|
+
_conversationalModeHandler;
|
|
74
|
+
/**
|
|
75
|
+
* Check if conversational mode is enabled
|
|
76
|
+
*/
|
|
77
|
+
isConversationalMode() {
|
|
78
|
+
return !!this._conversationalModeHandler;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get the GiuseppeBot instance for daemon to invoke fixes
|
|
82
|
+
*/
|
|
83
|
+
getGiuseppeBot() {
|
|
84
|
+
return this.giuseppe;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Start the bug reports module
|
|
88
|
+
*/
|
|
89
|
+
async start() {
|
|
90
|
+
if (this.started) {
|
|
91
|
+
logger.warn('BugReportsModule already started');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
logger.info('Starting Bug Reports Module...');
|
|
95
|
+
try {
|
|
96
|
+
// Load configuration
|
|
97
|
+
this.config = await (0, config_1.loadConfig)(this.userContext);
|
|
98
|
+
if (!this.config.enabled) {
|
|
99
|
+
logger.info('Bug Reports Module is disabled');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Create monitor
|
|
103
|
+
this.monitor = new monitor_1.BugMonitor(this.userContext);
|
|
104
|
+
// Register any pending bot users
|
|
105
|
+
if (this._pendingBotUsers) {
|
|
106
|
+
for (const userId of this._pendingBotUsers) {
|
|
107
|
+
this.monitor.registerBotUser(userId);
|
|
108
|
+
}
|
|
109
|
+
this._pendingBotUsers = undefined;
|
|
110
|
+
}
|
|
111
|
+
// Register any pending giuseppe disabled handlers
|
|
112
|
+
if (this._pendingGiuseppeDisabledHandlers) {
|
|
113
|
+
for (const handler of this._pendingGiuseppeDisabledHandlers) {
|
|
114
|
+
this.monitor.onGiuseppeDisabled(handler);
|
|
115
|
+
}
|
|
116
|
+
this._pendingGiuseppeDisabledHandlers = undefined;
|
|
117
|
+
}
|
|
118
|
+
// Create Giuseppe bot (needed for both conversational and auto-fix modes)
|
|
119
|
+
if (this.config.autoFix) {
|
|
120
|
+
if (!this.config.anthropicApiKey && !process.env.ANTHROPIC_API_KEY) {
|
|
121
|
+
logger.warn('Auto-fix enabled but no ANTHROPIC_API_KEY - Giuseppe disabled');
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.giuseppe = new bot_1.GiuseppeBot(this.userContext, this.config, this.monitor);
|
|
125
|
+
// Initialize registry callback for HAL coordination
|
|
126
|
+
this.giuseppe.initializeRegistryCallback();
|
|
127
|
+
this.giuseppe.initializeClassificationCallbacks();
|
|
128
|
+
// Check if conversational mode is enabled (daemon handles bugs)
|
|
129
|
+
if (this._conversationalModeHandler) {
|
|
130
|
+
// Skip old-style notifications - daemon handles intro messages
|
|
131
|
+
this.monitor.setSkipNotifications(true);
|
|
132
|
+
// Conversational mode: bugs go to daemon, daemon invokes fixes
|
|
133
|
+
this.monitor.onNewBug(async (bug) => {
|
|
134
|
+
logger.info('New bug detected - forwarding to daemon', { bugId: bug.id, bugName: bug.name });
|
|
135
|
+
await this._conversationalModeHandler(bug);
|
|
136
|
+
});
|
|
137
|
+
// In conversational mode, daemon handles messages through LLM
|
|
138
|
+
// No need to register message handler here
|
|
139
|
+
logger.info('Giuseppe Bot enabled in CONVERSATIONAL mode - daemon handles bugs');
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// Legacy auto-fix mode: bot handles everything automatically
|
|
143
|
+
this.monitor.onNewBug(async (bug) => {
|
|
144
|
+
const result = await this.giuseppe.handleBug(bug);
|
|
145
|
+
logger.info('Giuseppe fix result', {
|
|
146
|
+
bugId: bug.id,
|
|
147
|
+
success: result.success,
|
|
148
|
+
summary: result.summary
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
// Register Giuseppe as message handler (for approval messages)
|
|
152
|
+
this.monitor.onMessage(async (discussionId, message, senderId) => {
|
|
153
|
+
const result = await this.giuseppe.handleDiscussionMessage(discussionId, message, senderId);
|
|
154
|
+
if (result.approved) {
|
|
155
|
+
logger.info('Fix approved', {
|
|
156
|
+
discussionId,
|
|
157
|
+
published: result.published,
|
|
158
|
+
error: result.error
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
logger.info('Giuseppe Bot enabled in AUTO-FIX mode');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Start monitoring
|
|
167
|
+
await this.monitor.start();
|
|
168
|
+
this.started = true;
|
|
169
|
+
logger.info('Bug Reports Module started', {
|
|
170
|
+
autoFix: !!this.giuseppe,
|
|
171
|
+
notifyOnNew: this.config.notifyOnNew,
|
|
172
|
+
intervalMs: this.config.intervalMs
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
logger.error('Failed to start Bug Reports Module', { error });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Stop the module
|
|
181
|
+
*/
|
|
182
|
+
async stop() {
|
|
183
|
+
if (this.monitor) {
|
|
184
|
+
await this.monitor.stop();
|
|
185
|
+
}
|
|
186
|
+
this.started = false;
|
|
187
|
+
logger.info('Bug Reports Module stopped');
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get current configuration
|
|
191
|
+
*/
|
|
192
|
+
getConfig() {
|
|
193
|
+
return this.config || (0, config_1.getDefaultConfig)();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Check if module is running
|
|
197
|
+
*/
|
|
198
|
+
isRunning() {
|
|
199
|
+
return this.started;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get discovered phase IDs for the Bug Reports workflow
|
|
203
|
+
* Returns phase IDs for inProgress, fixed, declined, closed, new
|
|
204
|
+
*/
|
|
205
|
+
getPhaseIds() {
|
|
206
|
+
const discovery = this.monitor?.getDiscovery();
|
|
207
|
+
return discovery?.phases || {};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Manually trigger a bug fix (for testing or manual dispatch)
|
|
211
|
+
*/
|
|
212
|
+
async fixBug(bug) {
|
|
213
|
+
if (!this.giuseppe) {
|
|
214
|
+
return {
|
|
215
|
+
success: false,
|
|
216
|
+
summary: 'Giuseppe Bot not initialized (autoFix disabled or no API key)'
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return this.giuseppe.handleBug(bug);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Register a custom bug handler
|
|
223
|
+
*/
|
|
224
|
+
onNewBug(handler) {
|
|
225
|
+
if (this.monitor) {
|
|
226
|
+
this.monitor.onNewBug(handler);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
logger.warn('Cannot register handler - monitor not initialized');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.BugReportsModule = BugReportsModule;
|
|
234
|
+
exports.GiuseppeModule = BugReportsModule;
|
|
235
|
+
var monitor_2 = require("./monitor");
|
|
236
|
+
Object.defineProperty(exports, "BugMonitor", { enumerable: true, get: function () { return monitor_2.BugMonitor; } });
|
|
237
|
+
var bot_2 = require("./bot");
|
|
238
|
+
Object.defineProperty(exports, "GiuseppeBot", { enumerable: true, get: function () { return bot_2.GiuseppeBot; } });
|
|
239
|
+
var config_2 = require("./config");
|
|
240
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_2.loadConfig; } });
|
|
241
|
+
Object.defineProperty(exports, "discoverWorkflow", { enumerable: true, get: function () { return config_2.discoverWorkflow; } });
|
|
242
|
+
Object.defineProperty(exports, "getDefaultConfig", { enumerable: true, get: function () { return config_2.getDefaultConfig; } });
|
|
243
|
+
var pending_1 = require("./registries/pending");
|
|
244
|
+
Object.defineProperty(exports, "PendingRegistry", { enumerable: true, get: function () { return pending_1.PendingRegistry; } });
|
|
245
|
+
var pending_fix_1 = require("./registries/pending-fix");
|
|
246
|
+
Object.defineProperty(exports, "pendingFixRegistry", { enumerable: true, get: function () { return pending_fix_1.pendingFixRegistry; } });
|
|
247
|
+
var pending_classification_1 = require("./registries/pending-classification");
|
|
248
|
+
Object.defineProperty(exports, "pendingClassificationRegistry", { enumerable: true, get: function () { return pending_classification_1.pendingClassificationRegistry; } });
|
|
249
|
+
// Export extracted Giuseppe modules
|
|
250
|
+
var ai_1 = require("./ai");
|
|
251
|
+
Object.defineProperty(exports, "GiuseppeAI", { enumerable: true, get: function () { return ai_1.GiuseppeAI; } });
|
|
252
|
+
var git_1 = require("./git");
|
|
253
|
+
Object.defineProperty(exports, "GiuseppeGit", { enumerable: true, get: function () { return git_1.GiuseppeGit; } });
|
|
254
|
+
var files_1 = require("./files");
|
|
255
|
+
Object.defineProperty(exports, "GiuseppeFiles", { enumerable: true, get: function () { return files_1.GiuseppeFiles; } });
|
|
256
|
+
var prompt_1 = require("./prompt");
|
|
257
|
+
Object.defineProperty(exports, "GIUSEPPE_SYSTEM_PROMPT", { enumerable: true, get: function () { return prompt_1.GIUSEPPE_SYSTEM_PROMPT; } });
|
|
258
|
+
//# sourceMappingURL=index.js.map
|