@hailer/mcp 0.1.15 → 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.
Files changed (112) hide show
  1. package/.claude/agents/agent-giuseppe-app-builder.md +7 -6
  2. package/.claude/agents/agent-lars-code-inspector.md +26 -14
  3. package/dist/agents/bot-manager.d.ts +48 -0
  4. package/dist/agents/bot-manager.js +254 -0
  5. package/dist/agents/factory.d.ts +150 -0
  6. package/dist/agents/factory.js +650 -0
  7. package/dist/agents/giuseppe/ai.d.ts +83 -0
  8. package/dist/agents/giuseppe/ai.js +466 -0
  9. package/dist/agents/giuseppe/bot.d.ts +110 -0
  10. package/dist/agents/giuseppe/bot.js +780 -0
  11. package/dist/agents/giuseppe/config.d.ts +25 -0
  12. package/dist/agents/giuseppe/config.js +227 -0
  13. package/dist/agents/giuseppe/files.d.ts +52 -0
  14. package/dist/agents/giuseppe/files.js +338 -0
  15. package/dist/agents/giuseppe/git.d.ts +48 -0
  16. package/dist/agents/giuseppe/git.js +298 -0
  17. package/dist/agents/giuseppe/index.d.ts +97 -0
  18. package/dist/agents/giuseppe/index.js +258 -0
  19. package/dist/agents/giuseppe/lsp.d.ts +113 -0
  20. package/dist/agents/giuseppe/lsp.js +485 -0
  21. package/dist/agents/giuseppe/monitor.d.ts +118 -0
  22. package/dist/agents/giuseppe/monitor.js +621 -0
  23. package/dist/agents/giuseppe/prompt.d.ts +5 -0
  24. package/dist/agents/giuseppe/prompt.js +94 -0
  25. package/dist/agents/giuseppe/registries/pending-classification.d.ts +28 -0
  26. package/dist/agents/giuseppe/registries/pending-classification.js +50 -0
  27. package/dist/agents/giuseppe/registries/pending-fix.d.ts +30 -0
  28. package/dist/agents/giuseppe/registries/pending-fix.js +42 -0
  29. package/dist/agents/giuseppe/registries/pending.d.ts +27 -0
  30. package/dist/agents/giuseppe/registries/pending.js +49 -0
  31. package/dist/agents/giuseppe/specialist.d.ts +47 -0
  32. package/dist/agents/giuseppe/specialist.js +237 -0
  33. package/dist/agents/giuseppe/types.d.ts +123 -0
  34. package/dist/agents/giuseppe/types.js +9 -0
  35. package/dist/agents/hailer-expert/index.d.ts +8 -0
  36. package/dist/agents/hailer-expert/index.js +14 -0
  37. package/dist/agents/hal/daemon.d.ts +142 -0
  38. package/dist/agents/hal/daemon.js +1103 -0
  39. package/dist/agents/hal/definitions.d.ts +55 -0
  40. package/dist/agents/hal/definitions.js +263 -0
  41. package/dist/agents/hal/index.d.ts +3 -0
  42. package/dist/agents/hal/index.js +8 -0
  43. package/dist/agents/index.d.ts +18 -0
  44. package/dist/agents/index.js +48 -0
  45. package/dist/agents/shared/base.d.ts +216 -0
  46. package/dist/agents/shared/base.js +846 -0
  47. package/dist/agents/shared/services/agent-registry.d.ts +107 -0
  48. package/dist/agents/shared/services/agent-registry.js +629 -0
  49. package/dist/agents/shared/services/conversation-manager.d.ts +50 -0
  50. package/dist/agents/shared/services/conversation-manager.js +136 -0
  51. package/dist/agents/shared/services/mcp-client.d.ts +56 -0
  52. package/dist/agents/shared/services/mcp-client.js +124 -0
  53. package/dist/agents/shared/services/message-classifier.d.ts +37 -0
  54. package/dist/agents/shared/services/message-classifier.js +187 -0
  55. package/dist/agents/shared/services/message-formatter.d.ts +89 -0
  56. package/dist/agents/shared/services/message-formatter.js +371 -0
  57. package/dist/agents/shared/services/session-logger.d.ts +106 -0
  58. package/dist/agents/shared/services/session-logger.js +446 -0
  59. package/dist/agents/shared/services/tool-executor.d.ts +41 -0
  60. package/dist/agents/shared/services/tool-executor.js +169 -0
  61. package/dist/agents/shared/services/workspace-schema-cache.d.ts +125 -0
  62. package/dist/agents/shared/services/workspace-schema-cache.js +578 -0
  63. package/dist/agents/shared/specialist.d.ts +91 -0
  64. package/dist/agents/shared/specialist.js +399 -0
  65. package/dist/agents/shared/tool-schema-loader.d.ts +62 -0
  66. package/dist/agents/shared/tool-schema-loader.js +232 -0
  67. package/dist/agents/shared/types.d.ts +327 -0
  68. package/dist/agents/shared/types.js +121 -0
  69. package/dist/app.js +21 -4
  70. package/dist/cli.js +0 -0
  71. package/dist/client/agents/orchestrator.d.ts +1 -0
  72. package/dist/client/agents/orchestrator.js +12 -1
  73. package/dist/commands/seed-config.d.ts +9 -0
  74. package/dist/commands/seed-config.js +372 -0
  75. package/dist/config.d.ts +10 -0
  76. package/dist/config.js +61 -1
  77. package/dist/core.d.ts +8 -0
  78. package/dist/core.js +137 -6
  79. package/dist/lib/discussion-lock.d.ts +42 -0
  80. package/dist/lib/discussion-lock.js +110 -0
  81. package/dist/mcp/UserContextCache.js +2 -2
  82. package/dist/mcp/hailer-clients.d.ts +15 -0
  83. package/dist/mcp/hailer-clients.js +100 -6
  84. package/dist/mcp/signal-handler.d.ts +16 -5
  85. package/dist/mcp/signal-handler.js +173 -122
  86. package/dist/mcp/tools/activity.js +9 -1
  87. package/dist/mcp/tools/bot-config.d.ts +184 -9
  88. package/dist/mcp/tools/bot-config.js +2177 -163
  89. package/dist/mcp/tools/giuseppe-tools.d.ts +21 -0
  90. package/dist/mcp/tools/giuseppe-tools.js +525 -0
  91. package/dist/mcp/utils/hailer-api-client.d.ts +42 -1
  92. package/dist/mcp/utils/hailer-api-client.js +128 -2
  93. package/dist/mcp/webhook-handler.d.ts +87 -0
  94. package/dist/mcp/webhook-handler.js +343 -0
  95. package/dist/mcp/workspace-cache.d.ts +5 -0
  96. package/dist/mcp/workspace-cache.js +11 -0
  97. package/dist/mcp-server.js +55 -5
  98. package/dist/modules/bug-reports/giuseppe-agent.d.ts +58 -0
  99. package/dist/modules/bug-reports/giuseppe-agent.js +467 -0
  100. package/dist/modules/bug-reports/giuseppe-ai.d.ts +25 -1
  101. package/dist/modules/bug-reports/giuseppe-ai.js +133 -2
  102. package/dist/modules/bug-reports/giuseppe-bot.d.ts +2 -2
  103. package/dist/modules/bug-reports/giuseppe-bot.js +66 -42
  104. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +80 -0
  105. package/dist/modules/bug-reports/giuseppe-daemon.js +617 -0
  106. package/dist/modules/bug-reports/giuseppe-files.d.ts +12 -0
  107. package/dist/modules/bug-reports/giuseppe-files.js +37 -0
  108. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +84 -13
  109. package/dist/modules/bug-reports/giuseppe-lsp.js +403 -61
  110. package/dist/modules/bug-reports/index.d.ts +1 -0
  111. package/dist/modules/bug-reports/index.js +31 -29
  112. package/package.json +3 -2
@@ -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