@hailer/mcp 0.2.4 → 0.2.5

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.md CHANGED
@@ -34,10 +34,32 @@ NEVER forget: You delegate, agents execute, you report back.
34
34
  </identity>
35
35
 
36
36
  <orchestrator-rules>
37
- DO DIRECTLY: Answer from context, summarize agent results, run push/sync commands
38
- DELEGATE TO AGENTS: File reads, API calls, data creation/updates, complex reasoning
37
+ DO DIRECTLY:
38
+ - Run commands agents return (Bash)
39
+ - Interpret agent JSON for users
40
+ - Route tasks to agents
41
+
42
+ DELEGATE ALWAYS:
43
+ - File reads → agent-kenji-data-reader (haiku)
44
+ - Activity CRUD → agent-dmitri-activity-crud (haiku)
45
+ - Config questions → agent-bjorn-config-audit (haiku)
46
+ - Code navigation → agent-lars-code-inspector (haiku)
47
+ - Everything else → see <agents> table
48
+
49
+ BOOTSTRAP EXCEPTION:
50
+ - You may read CLAUDE.md and .claude/agents/*.md to know routing rules
51
+ - Everything else gets delegated
52
+
53
+ RATIONALE: Haiku is cheaper than Opus. Delegate aggressively.
39
54
 
40
55
  Agents return JSON. You interpret it for the user.
56
+
57
+ **FIX ROOT CAUSE, NEVER BANDAID:**
58
+ When something fails, NEVER work around it. Always:
59
+ 1. Report the error to user
60
+ 2. Identify the root cause
61
+ 3. Fix the source file/config that's broken
62
+ 4. Never wrap, bypass, or apply temporary fixes
41
63
  </orchestrator-rules>
42
64
 
43
65
  <agents>
@@ -58,6 +80,8 @@ Agents return JSON. You interpret it for the user.
58
80
  | Skills, agent improvements | `agent-ada-skill-builder` | sonnet |
59
81
  | Document templates | `agent-ingrid-doc-templates` | sonnet |
60
82
  | Name functions | `agent-nora-name-functions` | sonnet |
83
+ | Publish plugins | `agent-marketplace-publisher` | sonnet |
84
+ | Review plugin PRs | `agent-marketplace-reviewer` | haiku |
61
85
  </agents>
62
86
 
63
87
  <delegation-protocol>
@@ -108,6 +132,25 @@ YOU must:
108
132
  3. If declined: report cancellation to user
109
133
  </needs-confirmation>
110
134
 
135
+ <agent-chaining>
136
+ When agents return `trigger_review` or similar chaining directives:
137
+ ```json
138
+ {
139
+ "status": "success",
140
+ "result": { ... },
141
+ "trigger_review": {
142
+ "agent": "marketplace-reviewer:agent-marketplace-reviewer",
143
+ "input": { "task": "review", "branch": "publish/plugin-name-v1.0.0" }
144
+ }
145
+ }
146
+ ```
147
+
148
+ YOU must:
149
+ 1. Report the first agent's success to user
150
+ 2. Immediately spawn the chained agent with the provided input
151
+ 3. Report the chained agent's result to user
152
+ </agent-chaining>
153
+
111
154
  ---
112
155
 
113
156
  <local-first>
@@ -133,9 +176,14 @@ SAFE: npm run pull, npm run generate
133
176
  </safety>
134
177
 
135
178
  <lsp-setup>
136
- **New users:** Install LSP plugin for TypeScript support:
137
- 1. `/plugin install typescript-lsp@hailer-mcp-marketplace`
138
- 2. Restart: `claude -c`
179
+ **LSP for TypeScript/JavaScript:** Requires plugin setup.
180
+
181
+ `agent-lars-code-inspector` is included by default, but LSP tool requires:
182
+ ```
183
+ /marketplace-setup
184
+ /install-plugin lars-code-inspector
185
+ claude -c
186
+ ```
139
187
 
140
188
  `ENABLE_LSP_TOOL` is auto-set via `.claude/settings.json`.
141
189
  </lsp-setup>
@@ -188,60 +236,58 @@ WITHOUT AGENTS: Use MCP tools directly
188
236
  <plugin-marketplace>
189
237
  Community agents are shared via the Hailer Agent Marketplace (separate git repo).
190
238
 
191
- **Marketplace URL:** `git@gitlab.com:hailer-repos/hailer-mcp-marketplace.git`
239
+ **Marketplace URL:** `git@github.com:Bdolf/Hailer-Marketplace.git`
192
240
 
193
- **Installed marketplace agents:**
194
- No marketplace agents installed.
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
- **Use plugin agents:**
205
- ```
206
- Task(subagent_type="plugin:agent-name", prompt="...", model="haiku|sonnet")
207
- ```
208
-
209
- **Agent sources:**
210
- - Default agents: `.claude/agents/` (shipped via npm)
211
- - Community agents: Plugin marketplace (installed separately)
241
+ **Plugin commands:**
242
+ | Command | Action |
243
+ |---------|--------|
244
+ | `/marketplace-setup` | Clone/pull marketplace repo to `./hailer-marketplace` |
245
+ | `/list-plugins` | List available plugins in marketplace |
246
+ | `/install-plugin <name>` | Copy plugin to `.claude/`, add to `<agents>` table |
247
+ | `/uninstall-plugin <name>` | Remove plugin from `.claude/`, remove from `<agents>` table |
248
+ | `/publish-plugin` | Pre-flight checks, spawn publisher agent → auto-reviews |
212
249
  </plugin-marketplace>
213
250
 
214
251
  <plugin-setup>
215
- When user asks to install plugins or set up the marketplace:
252
+ When user asks to install plugins:
216
253
 
217
- 1. Tell user to run these slash commands:
254
+ 1. First, ensure marketplace is cloned:
218
255
  ```
219
- /plugin marketplace add git@gitlab.com:hailer-repos/hailer-mcp-marketplace.git
220
- /plugin install <plugin-name>
256
+ /marketplace-setup
221
257
  ```
222
258
 
223
- 2. Tell user: "Restart Claude Code to load the plugin. Use `claude -c` to keep your conversation context."
259
+ 2. Install the plugin:
260
+ ```
261
+ /install-plugin <plugin-name>
262
+ ```
224
263
 
225
- Available plugins: `permissions-handler`, `voice-notifications`, `typescript-lsp`
264
+ 3. Tell user: "Restart Claude Code to load the plugin. Run `claude -c` to keep your conversation context."
226
265
 
227
- After restart, sync hook updates this file automatically with installed agents.
266
+ **What `/install-plugin` does:**
267
+ - Copies agents to `.claude/agents/`
268
+ - Copies skills to `.claude/skills/`
269
+ - Copies hooks to `.claude/hooks/`
270
+ - Auto-installs native LSP if plugin requires it
228
271
 
229
272
  **IMPORTANT:** After installing OR uninstalling plugins, always tell the user:
230
273
  > "Restart required for changes to take effect. Run `claude -c` to restart while keeping your conversation context."
231
274
  </plugin-setup>
232
275
 
233
276
  <plugin-contributing>
234
- To contribute agents to the marketplace:
277
+ To contribute plugins to the marketplace:
235
278
 
236
- 1. Clone: `git clone git@gitlab.com:hailer-repos/hailer-mcp-marketplace.git`
237
- 2. Create plugin structure:
279
+ 1. Ensure marketplace is cloned: `/marketplace-setup`
280
+ 2. Create plugin in `./hailer-marketplace/`:
238
281
  ```
239
282
  my-plugin/
240
283
  .claude-plugin/plugin.json
241
284
  agents/agent-my-agent.md
285
+ skills/my-skill/ (optional)
286
+ hooks/my-hook.cjs (optional)
287
+ .lsp.json (optional, for LSP support)
242
288
  ```
243
289
  3. Follow agent structure from `<agent-structure>` section
244
- 4. Push to repo
290
+ 4. Publish via PR workflow: `/publish-plugin`
245
291
  </plugin-contributing>
246
292
 
247
293
  <directory>
@@ -253,5 +299,6 @@ workspace/ # Local config (check FIRST)
253
299
  skills/ # On-demand documentation
254
300
  commands/ # Slash commands
255
301
  settings.json # Permissions
302
+ hailer-marketplace/ # Local marketplace clone (run /marketplace-setup)
256
303
  ```
257
304
  </directory>
package/dist/app.js CHANGED
@@ -17,6 +17,7 @@ const core = new core_1.Core();
17
17
  logger.info('Registering tools...');
18
18
  logger.info('Nuclear tools status', { enabled: config_1.environment.ENABLE_NUCLEAR_TOOLS });
19
19
  core.addTool(file_1.uploadFilesTool);
20
+ core.addTool(file_1.downloadFileTool);
20
21
  core.addTool(activity_1.listActivitiesTool);
21
22
  core.addTool(activity_1.showActivityByIdTool);
22
23
  core.addTool(activity_1.createActivityTool);
@@ -86,7 +87,12 @@ if (config_1.environment.MCP_CLIENT_ENABLED) {
86
87
  core.addTool(disableBotTool);
87
88
  core.addTool(checkSpecialistStatusTool);
88
89
  // Dynamic import bug-fixer tools
89
- const { bugFixerFindAppTool, bugFixerListFilesTool, bugFixerReadFileTool, bugFixerWriteFileTool, bugFixerApplyFixTool, bugFixerRunBuildTool, bugFixerGitStatusTool, bugFixerGitPullTool, bugFixerGitCommitTool, bugFixerGitPushTool, bugFixerGitRevertTool, bugFixerPublishAppTool } = require('./mcp/tools/bug-fixer-tools');
90
+ const {
91
+ // Low-level tools
92
+ bugFixerFindAppTool, bugFixerListFilesTool, bugFixerReadFileTool, bugFixerWriteFileTool, bugFixerApplyFixTool, bugFixerRunBuildTool, bugFixerGitStatusTool, bugFixerGitPullTool, bugFixerGitCommitTool, bugFixerGitPushTool, bugFixerGitRevertTool, bugFixerPublishAppTool,
93
+ // High-level workflow tools (LLM-driven)
94
+ bugFixerAnalyzeBugTool, bugFixerStartFixTool, bugFixerMarkDeclinedTool, bugFixerPublishFixTool, bugFixerRetryFixTool } = require('./mcp/tools/bug-fixer-tools');
95
+ // Low-level tools
90
96
  core.addTool(bugFixerFindAppTool);
91
97
  core.addTool(bugFixerListFilesTool);
92
98
  core.addTool(bugFixerReadFileTool);
@@ -99,6 +105,12 @@ if (config_1.environment.MCP_CLIENT_ENABLED) {
99
105
  core.addTool(bugFixerGitPushTool);
100
106
  core.addTool(bugFixerGitRevertTool);
101
107
  core.addTool(bugFixerPublishAppTool);
108
+ // High-level workflow tools (LLM-driven)
109
+ core.addTool(bugFixerAnalyzeBugTool);
110
+ core.addTool(bugFixerStartFixTool);
111
+ core.addTool(bugFixerMarkDeclinedTool);
112
+ core.addTool(bugFixerPublishFixTool);
113
+ core.addTool(bugFixerRetryFixTool);
102
114
  logger.info('Bot-internal tools registered (MCP_CLIENT_ENABLED=true)');
103
115
  }
104
116
  logger.info('All tools registered successfully');
package/dist/config.d.ts CHANGED
@@ -49,6 +49,7 @@ export declare const environment: {
49
49
  CONTEXT_MAX_SUMMARIZATION_CHUNKS: number;
50
50
  WORKSPACE_CONFIG_PATH?: string | undefined;
51
51
  DEV_APPS_PATH?: string | undefined;
52
+ DEV_APPS_PATHS?: string | undefined;
52
53
  OPENAI_API_KEY?: string | undefined;
53
54
  OPENAI_API_BASE?: string | undefined;
54
55
  OPENAI_MODEL?: string | undefined;
package/dist/config.js CHANGED
@@ -105,6 +105,9 @@ const environmentSchema = zod_1.z.object({
105
105
  WORKSPACE_CONFIG_PATH: zod_1.z.string().optional(),
106
106
  // Development apps path (for scaffolding Hailer apps outside the repo)
107
107
  DEV_APPS_PATH: zod_1.z.string().optional(),
108
+ // Multiple app directories for Bug Fixer - comma-separated paths
109
+ // Example: DEV_APPS_PATHS=/path/to/apps,/path/to/other/apps
110
+ DEV_APPS_PATHS: zod_1.z.string().optional(),
108
111
  // LLM providers
109
112
  OPENAI_API_KEY: zod_1.z.string().min(1).optional(),
110
113
  OPENAI_API_BASE: zod_1.z.string().url().optional(),
package/dist/core.d.ts CHANGED
@@ -17,7 +17,6 @@ export declare class Core {
17
17
  private mcpServer?;
18
18
  private daemonManagers;
19
19
  private statusLogIntervals;
20
- private bugReportsModules;
21
20
  private daemonInitInProgress;
22
21
  private initialDaemonReady;
23
22
  constructor();
@@ -33,10 +32,10 @@ export declare class Core {
33
32
  */
34
33
  private startMCPClient;
35
34
  /**
36
- * Start Bug Monitor for all workspaces with running daemons
37
- * Each workspace gets its own bug monitor instance
35
+ * Start Bug Fixer in standalone mode (no orchestrator/AI Hub needed)
36
+ * Uses BUG_FIXER_EMAIL and BUG_FIXER_PASSWORD env vars
38
37
  */
39
- private startBugMonitor;
38
+ private startStandaloneBugFixer;
40
39
  private initBotConfig;
41
40
  /**
42
41
  * Register webhook handler for bot config updates
package/dist/core.js CHANGED
@@ -19,7 +19,6 @@ class Core {
19
19
  mcpServer;
20
20
  daemonManagers = new Map(); // workspace ID -> DaemonManager
21
21
  statusLogIntervals = new Map(); // workspace ID -> interval
22
- bugReportsModules = new Map(); // workspace ID -> BugReportsModule
23
22
  daemonInitInProgress = new Set(); // workspace IDs currently initializing
24
23
  initialDaemonReady = new Set(); // workspace IDs that have completed first init
25
24
  constructor() {
@@ -67,9 +66,8 @@ class Core {
67
66
  // Initialize bot config persistence (reads config from Hailer Agent Directory)
68
67
  await this.initBotConfig();
69
68
  // Start daemons for all workspaces with orchestrator
69
+ // Bug Fixer is now a specialist daemon (configured in AI Hub, runs per-workspace)
70
70
  await this.startMCPClient();
71
- // Start Bug Monitor service (reads config from Hailer)
72
- await this.startBugMonitor();
73
71
  }
74
72
  this.setupGracefulShutdown();
75
73
  this.logger.info('All configured services started successfully');
@@ -95,6 +93,13 @@ class Core {
95
93
  * Start MCP Client (daemons) for all workspaces with enabled orchestrators
96
94
  */
97
95
  async startMCPClient() {
96
+ // Check for standalone Bug Fixer mode (bypass AI Hub/orchestrator)
97
+ const standaloneBugFixer = process.env.BUG_MONITOR_ENABLED === 'true' && process.env.BUG_FIXER_EMAIL;
98
+ if (standaloneBugFixer) {
99
+ this.logger.info('Standalone Bug Fixer mode detected - starting Bug Fixer only');
100
+ await this.startStandaloneBugFixer();
101
+ return;
102
+ }
98
103
  this.logger.info('Starting Chat Agent Daemons for all enabled workspaces');
99
104
  // Load all workspace configs
100
105
  const { loadBotConfigs } = require('./bot-config');
@@ -143,68 +148,27 @@ class Core {
143
148
  });
144
149
  }
145
150
  /**
146
- * Start Bug Monitor for all workspaces with running daemons
147
- * Each workspace gets its own bug monitor instance
151
+ * Start Bug Fixer in standalone mode (no orchestrator/AI Hub needed)
152
+ * Uses BUG_FIXER_EMAIL and BUG_FIXER_PASSWORD env vars
148
153
  */
149
- async startBugMonitor() {
154
+ async startStandaloneBugFixer() {
155
+ const email = process.env.BUG_FIXER_EMAIL;
156
+ const password = process.env.BUG_FIXER_PASSWORD || '';
157
+ this.logger.info('Starting standalone Bug Fixer', { email: email.replace(/(.{3}).*@/, '$1***@') });
150
158
  try {
151
- // Get all configured accounts
152
- const accounts = Object.entries(this.appConfig.hailerAccounts);
153
- if (accounts.length === 0) {
154
- this.logger.info('No Hailer accounts configured - Bug Reports Module disabled');
159
+ // Dynamic import
160
+ const { createStandaloneBugFixer } = require('./agents/factory');
161
+ const daemon = await createStandaloneBugFixer(email, password);
162
+ if (!daemon) {
163
+ this.logger.error('Failed to create standalone Bug Fixer');
155
164
  return;
156
165
  }
157
- // Start bug monitor for each workspace that has a running daemon
158
- for (const [workspaceId, daemonManager] of this.daemonManagers) {
159
- try {
160
- // Find the appropriate API key for this workspace
161
- // For now, use the first account (could be enhanced to match workspace-specific accounts)
162
- const [apiKey] = accounts[0];
163
- const userContext = await UserContextCache_1.UserContextCache.getContext(apiKey);
164
- // Dynamic import - agents only needed when client is enabled
165
- const { BugReportsModule } = require('./agents/bug-fixer');
166
- const bugReportsModule = new BugReportsModule(userContext);
167
- // Register bot user IDs to ignore (so bug monitor only processes human messages)
168
- const daemonStatus = daemonManager.getStatus();
169
- for (const daemon of daemonStatus) {
170
- bugReportsModule.registerBotUser(daemon.botId);
171
- this.logger.debug('Registered bot user for bug monitor to ignore', {
172
- workspaceId,
173
- botId: daemon.botId
174
- });
175
- }
176
- // Register bug fixer disabled handler to trigger HAL response (BEFORE start!)
177
- bugReportsModule.onBugFixerDisabled(async (bug) => {
178
- if (bug.discussionId) {
179
- const context = `[System notification: A new bug report "${bug.name}" was detected, but Bug Fixer (the auto-fix bot) is currently disabled. The user may ask how to enable Bug Fixer or want to know more about this bug. Be helpful and explain they can enable Bug Fixer in the AI Hub app.]`;
180
- await daemonManager.triggerHalResponse(bug.discussionId, bug.id, context);
181
- }
182
- });
183
- await bugReportsModule.start();
184
- if (bugReportsModule.isRunning()) {
185
- this.bugReportsModules.set(workspaceId, bugReportsModule);
186
- const config = bugReportsModule.getConfig();
187
- this.logger.info('Bug Reports Module started', {
188
- workspaceId,
189
- autoFix: config.autoFix,
190
- interval: `${config.intervalMs / 1000}s`
191
- });
192
- }
193
- }
194
- catch (error) {
195
- this.logger.warn('Bug Reports Module failed to start for workspace - continuing with other workspaces', {
196
- workspaceId,
197
- error: error instanceof Error ? error.message : String(error)
198
- });
199
- }
200
- }
201
- this.logger.info('Bug Reports Module initialization complete', {
202
- successCount: this.bugReportsModules.size,
203
- totalAttempted: this.daemonManagers.size
204
- });
166
+ // Store in daemon managers using a special key
167
+ this.daemonManagers.set('standalone-bugfixer', daemon);
168
+ this.logger.info('Standalone Bug Fixer started successfully');
205
169
  }
206
170
  catch (error) {
207
- this.logger.warn('Bug Reports Module failed to start - server will continue without bug monitoring', {
171
+ this.logger.error('Standalone Bug Fixer failed to start', {
208
172
  error: error instanceof Error ? error.message : String(error)
209
173
  });
210
174
  }
@@ -447,12 +411,6 @@ class Core {
447
411
  this.logger.debug('Stopped status logging', { workspaceId });
448
412
  }
449
413
  this.statusLogIntervals.clear();
450
- // Stop all Bug Reports Modules
451
- for (const [workspaceId, module] of this.bugReportsModules) {
452
- await module.stop();
453
- this.logger.debug('Stopped Bug Reports Module', { workspaceId });
454
- }
455
- this.bugReportsModules.clear();
456
414
  // Cleanup bot config (clear timers and callbacks) - only if client was enabled
457
415
  if (this.appConfig.server.enableClient) {
458
416
  const { cleanupBotConfig } = require('./bot-config');
@@ -17,5 +17,27 @@ export declare const bugFixerGitCommitTool: Tool;
17
17
  export declare const bugFixerGitPushTool: Tool;
18
18
  export declare const bugFixerGitRevertTool: Tool;
19
19
  export declare const bugFixerPublishAppTool: Tool;
20
+ /**
21
+ * Analyze Bug Tool - Read bug report and get classification info
22
+ * The LLM uses this to understand the bug and decide next steps
23
+ */
24
+ export declare const bugFixerAnalyzeBugTool: Tool;
25
+ /**
26
+ * Start Fix Tool - Begin the bug fix process
27
+ * This triggers the full fix workflow: find app → analyze → apply fix → build
28
+ */
29
+ export declare const bugFixerStartFixTool: Tool;
30
+ /**
31
+ * Mark Declined Tool - Mark bug as not-a-bug and close it
32
+ */
33
+ export declare const bugFixerMarkDeclinedTool: Tool;
34
+ /**
35
+ * Publish Fix Tool - Publish the fix to production
36
+ */
37
+ export declare const bugFixerPublishFixTool: Tool;
38
+ /**
39
+ * Retry Fix Tool - Retry a fix with additional context/explanation
40
+ */
41
+ export declare const bugFixerRetryFixTool: Tool;
20
42
  export declare const bugFixerTools: Tool[];
21
43
  //# sourceMappingURL=bug-fixer-tools.d.ts.map