@hailer/mcp 1.0.29 → 1.1.3
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/.session-checked +1 -0
- package/.claude/agents/agent-ada-skill-builder.md +10 -2
- package/.claude/agents/agent-alejandro-function-fields.md +104 -37
- package/.claude/agents/agent-bjorn-config-audit.md +41 -21
- package/.claude/agents/agent-builder-agent-creator.md +13 -3
- package/.claude/agents/agent-code-simplifier.md +53 -0
- package/.claude/agents/agent-dmitri-activity-crud.md +126 -11
- package/.claude/agents/agent-giuseppe-app-builder.md +212 -22
- package/.claude/agents/agent-gunther-mcp-tools.md +7 -36
- package/.claude/agents/agent-helga-workflow-config.md +75 -10
- package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
- package/.claude/agents/agent-ingrid-doc-templates.md +164 -36
- package/.claude/agents/agent-ivan-monolith.md +154 -0
- package/.claude/agents/agent-kenji-data-reader.md +15 -8
- package/.claude/agents/agent-lars-code-inspector.md +56 -8
- package/.claude/agents/agent-marco-mockup-builder.md +110 -0
- package/.claude/agents/agent-marcus-api-documenter.md +323 -0
- package/.claude/agents/agent-marketplace-publisher.md +232 -72
- package/.claude/agents/agent-marketplace-reviewer.md +255 -79
- package/.claude/agents/agent-permissions-handler.md +208 -0
- package/.claude/agents/agent-simple-writer.md +48 -0
- package/.claude/agents/agent-svetlana-code-review.md +127 -14
- package/.claude/agents/agent-tanya-test-runner.md +333 -0
- package/.claude/agents/agent-ui-designer.md +100 -0
- package/.claude/agents/agent-viktor-sql-insights.md +19 -6
- package/.claude/agents/agent-web-search.md +55 -0
- package/.claude/agents/agent-yevgeni-discussions.md +7 -1
- package/.claude/agents/agent-zara-zapier.md +159 -0
- package/.claude/commands/app-squad.md +135 -0
- package/.claude/commands/audit-squad.md +158 -0
- package/.claude/commands/autoplan.md +563 -0
- package/.claude/commands/cleanup-squad.md +98 -0
- package/.claude/commands/config-squad.md +106 -0
- package/.claude/commands/crud-squad.md +87 -0
- package/.claude/commands/data-squad.md +97 -0
- package/.claude/commands/debug-squad.md +303 -0
- package/.claude/commands/doc-squad.md +65 -0
- package/.claude/commands/handoff.md +137 -0
- package/.claude/commands/health.md +49 -0
- package/.claude/commands/help.md +2 -1
- package/.claude/commands/help:agents.md +96 -16
- package/.claude/commands/help:commands.md +55 -11
- package/.claude/commands/help:faq.md +16 -1
- package/.claude/commands/help:skills.md +93 -0
- package/.claude/commands/hotfix-squad.md +112 -0
- package/.claude/commands/integration-squad.md +82 -0
- package/.claude/commands/janitor-squad.md +167 -0
- package/.claude/commands/learn-auto.md +120 -0
- package/.claude/commands/learn.md +120 -0
- package/.claude/commands/mcp-list.md +27 -0
- package/.claude/commands/onboard-squad.md +140 -0
- package/.claude/commands/plan-workspace.md +732 -0
- package/.claude/commands/prd.md +131 -0
- package/.claude/commands/project-status.md +82 -0
- package/.claude/commands/publish.md +138 -0
- package/.claude/commands/recap.md +69 -0
- package/.claude/commands/restore.md +64 -0
- package/.claude/commands/review-squad.md +152 -0
- package/.claude/commands/save.md +24 -0
- package/.claude/commands/stats.md +19 -0
- package/.claude/commands/swarm.md +210 -0
- package/.claude/commands/tool-builder.md +3 -1
- package/.claude/commands/ws-pull.md +1 -1
- package/.claude/commands/yolo-off.md +17 -0
- package/.claude/commands/yolo.md +82 -0
- package/.claude/hooks/_shared-memory.cjs +305 -0
- package/.claude/hooks/_utils.cjs +134 -0
- package/.claude/hooks/agent-failure-detector.cjs +164 -79
- package/.claude/hooks/agent-usage-logger.cjs +204 -0
- package/.claude/hooks/app-edit-guard.cjs +20 -4
- package/.claude/hooks/auto-learn.cjs +316 -0
- package/.claude/hooks/bash-guard.cjs +282 -0
- package/.claude/hooks/builder-mode-manager.cjs +183 -54
- package/.claude/hooks/bulk-activity-guard.cjs +283 -0
- package/.claude/hooks/context-watchdog.cjs +292 -0
- package/.claude/hooks/delegation-reminder.cjs +478 -0
- package/.claude/hooks/design-system-lint.cjs +283 -0
- package/.claude/hooks/post-scaffold-hook.cjs +16 -3
- package/.claude/hooks/prompt-guard.cjs +366 -0
- package/.claude/hooks/publish-template-guard.cjs +16 -0
- package/.claude/hooks/session-start.cjs +35 -0
- package/.claude/hooks/shared-memory-writer.cjs +147 -0
- package/.claude/hooks/skill-injector.cjs +140 -0
- package/.claude/hooks/skill-usage-logger.cjs +258 -0
- package/.claude/hooks/src-edit-guard.cjs +16 -1
- package/.claude/hooks/sync-marketplace-agents.cjs +53 -8
- package/.claude/scripts/yolo-toggle.cjs +142 -0
- package/.claude/settings.json +141 -14
- package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
- package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
- package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
- package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
- package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
- package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
- package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
- package/.claude/skills/agent-structure/SKILL.md +98 -0
- package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
- package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
- package/.claude/skills/delegation-routing/SKILL.md +202 -0
- package/.claude/skills/frontend-design/SKILL.md +254 -0
- package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
- package/.claude/skills/hailer-api-client/SKILL.md +518 -0
- package/.claude/skills/hailer-app-builder/SKILL.md +939 -11
- package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
- package/.claude/skills/hailer-design-system/SKILL.md +235 -0
- package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
- package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
- package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
- package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
- package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
- package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
- package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
- package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
- package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
- package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
- package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
- package/.claude/skills/insight-join-patterns/SKILL.md +3 -0
- package/.claude/skills/integration-patterns/SKILL.md +421 -0
- package/.claude/skills/json-only-output/SKILL.md +52 -12
- package/.claude/skills/lsp-setup/SKILL.md +160 -0
- package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
- package/.claude/skills/optional-parameters/SKILL.md +32 -23
- package/.claude/skills/publish-hailer-app/SKILL.md +76 -12
- package/.claude/skills/testing-patterns/SKILL.md +630 -0
- package/.claude/skills/tool-builder/SKILL.md +250 -0
- package/.claude/skills/tool-parameter-usage/SKILL.md +59 -45
- package/.claude/skills/tool-response-verification/SKILL.md +82 -48
- package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
- package/.env.example +26 -7
- package/CLAUDE.md +290 -224
- package/dist/CLAUDE.md +370 -0
- package/dist/app.d.ts +1 -1
- package/dist/app.js +101 -101
- package/dist/bot/bot-config.d.ts +26 -0
- package/dist/bot/bot-config.js +135 -0
- package/dist/bot/bot-manager.d.ts +40 -0
- package/dist/bot/bot-manager.js +137 -0
- package/dist/bot/bot.d.ts +127 -0
- package/dist/bot/bot.js +1328 -0
- package/dist/bot/operation-logger.d.ts +28 -0
- package/dist/bot/operation-logger.js +132 -0
- package/dist/bot/services/conversation-manager.d.ts +60 -0
- package/dist/bot/services/conversation-manager.js +246 -0
- package/dist/bot/services/index.d.ts +9 -0
- package/dist/bot/services/index.js +18 -0
- package/dist/bot/services/message-classifier.d.ts +42 -0
- package/dist/bot/services/message-classifier.js +228 -0
- package/dist/bot/services/message-formatter.d.ts +88 -0
- package/dist/bot/services/message-formatter.js +411 -0
- package/dist/bot/services/session-logger.d.ts +162 -0
- package/dist/bot/services/session-logger.js +724 -0
- package/dist/bot/services/token-billing.d.ts +78 -0
- package/dist/bot/services/token-billing.js +233 -0
- package/dist/bot/services/types.d.ts +169 -0
- package/dist/bot/services/types.js +12 -0
- package/dist/bot/services/typing-indicator.d.ts +23 -0
- package/dist/bot/services/typing-indicator.js +60 -0
- package/dist/bot/services/workspace-schema-cache.d.ts +122 -0
- package/dist/bot/services/workspace-schema-cache.js +506 -0
- package/dist/bot/tool-executor.d.ts +28 -0
- package/dist/bot/tool-executor.js +48 -0
- package/dist/bot/workspace-overview.d.ts +12 -0
- package/dist/bot/workspace-overview.js +94 -0
- package/dist/cli.d.ts +1 -8
- package/dist/cli.js +1 -253
- package/dist/config.d.ts +96 -3
- package/dist/config.js +148 -37
- package/dist/core.d.ts +5 -0
- package/dist/core.js +61 -8
- package/dist/lib/discussion-lock.d.ts +42 -0
- package/dist/lib/discussion-lock.js +110 -0
- package/dist/lib/logger.d.ts +0 -1
- package/dist/lib/logger.js +39 -23
- package/dist/lib/request-logger.d.ts +77 -0
- package/dist/lib/request-logger.js +147 -0
- package/dist/mcp/UserContextCache.js +16 -13
- package/dist/mcp/hailer-clients.js +18 -17
- package/dist/mcp/signal-handler.js +43 -13
- package/dist/mcp/tool-registry.d.ts +4 -15
- package/dist/mcp/tool-registry.js +94 -32
- package/dist/mcp/tools/activity.js +28 -69
- package/dist/mcp/tools/app-core.js +9 -4
- package/dist/mcp/tools/app-marketplace.js +22 -12
- package/dist/mcp/tools/app-member.js +5 -2
- package/dist/mcp/tools/app-scaffold.js +32 -18
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/bot-config/core.d.ts +253 -0
- package/dist/mcp/tools/bot-config/core.js +2456 -0
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/discussion.js +107 -77
- package/dist/mcp/tools/document.d.ts +11 -0
- package/dist/mcp/tools/document.js +741 -0
- package/dist/mcp/tools/file.js +5 -2
- package/dist/mcp/tools/insight.js +36 -12
- package/dist/mcp/tools/investigate.d.ts +9 -0
- package/dist/mcp/tools/investigate.js +254 -0
- package/dist/mcp/tools/user.d.ts +2 -4
- package/dist/mcp/tools/user.js +9 -50
- package/dist/mcp/tools/workflow.d.ts +1 -0
- package/dist/mcp/tools/workflow.js +164 -52
- package/dist/mcp/utils/hailer-api-client.js +26 -17
- package/dist/mcp/webhook-handler.d.ts +64 -3
- package/dist/mcp/webhook-handler.js +227 -9
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.js +237 -25
- package/dist/plugins/bug-fixer/index.d.ts +2 -0
- package/dist/plugins/bug-fixer/index.js +18 -0
- package/dist/plugins/bug-fixer/tools.d.ts +45 -0
- package/dist/plugins/bug-fixer/tools.js +1096 -0
- package/package.json +10 -10
- package/scripts/test-hal-tools.ts +154 -0
- package/.claude/agents/agent-nora-name-functions.md +0 -123
- package/.claude/assistant-knowledge.md +0 -23
- package/.claude/commands/install-plugin.md +0 -261
- package/.claude/commands/list-plugins.md +0 -42
- package/.claude/commands/marketplace-setup.md +0 -33
- package/.claude/commands/publish-plugin.md +0 -55
- package/.claude/commands/uninstall-plugin.md +0 -87
- package/.claude/hooks/interactive-mode.cjs +0 -87
- package/.claude/hooks/mcp-server-guard.cjs +0 -108
- package/.claude/skills/marketplace-publishing.md +0 -155
- package/dist/bot/chat-bot.d.ts +0 -31
- package/dist/bot/chat-bot.js +0 -357
- package/dist/mcp/tools/metrics.d.ts +0 -13
- package/dist/mcp/tools/metrics.js +0 -546
- package/dist/stdio-server.d.ts +0 -14
- package/dist/stdio-server.js +0 -114
package/dist/mcp/tools/file.js
CHANGED
|
@@ -46,6 +46,7 @@ exports.downloadFileTool = exports.uploadFilesTool = void 0;
|
|
|
46
46
|
const zod_1 = require("zod");
|
|
47
47
|
const tool_registry_1 = require("../tool-registry");
|
|
48
48
|
const logger_1 = require("../../lib/logger");
|
|
49
|
+
const request_logger_1 = require("../../lib/request-logger");
|
|
49
50
|
const fs = __importStar(require("fs"));
|
|
50
51
|
const path = __importStar(require("path"));
|
|
51
52
|
const logger = (0, logger_1.createLogger)({ component: 'file-tools' });
|
|
@@ -141,7 +142,8 @@ exports.uploadFilesTool = {
|
|
|
141
142
|
return { content: [{ type: "text", text }] };
|
|
142
143
|
}
|
|
143
144
|
catch (error) {
|
|
144
|
-
|
|
145
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
146
|
+
logger.error('Upload failed', error);
|
|
145
147
|
return {
|
|
146
148
|
content: [{
|
|
147
149
|
type: "text",
|
|
@@ -224,7 +226,8 @@ exports.downloadFileTool = {
|
|
|
224
226
|
};
|
|
225
227
|
}
|
|
226
228
|
catch (error) {
|
|
227
|
-
|
|
229
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
230
|
+
logger.error('Download failed', error);
|
|
228
231
|
return {
|
|
229
232
|
content: [{
|
|
230
233
|
type: "text",
|
|
@@ -14,6 +14,7 @@ exports.listInsightsTool = exports.removeInsightTool = exports.updateInsightTool
|
|
|
14
14
|
const zod_1 = require("zod");
|
|
15
15
|
const tool_registry_1 = require("../tool-registry");
|
|
16
16
|
const logger_1 = require("../../lib/logger");
|
|
17
|
+
const request_logger_1 = require("../../lib/request-logger");
|
|
17
18
|
const tool_helpers_1 = require("../utils/tool-helpers");
|
|
18
19
|
const logger = (0, logger_1.createLogger)({ component: 'insight-tools' });
|
|
19
20
|
// ============================================================================
|
|
@@ -91,7 +92,19 @@ const sourceSchema = zod_1.z.object({
|
|
|
91
92
|
// ============================================================================
|
|
92
93
|
// CREATE INSIGHT TOOL
|
|
93
94
|
// ============================================================================
|
|
94
|
-
const createInsightDescription = `Create SQL insight over workflow data
|
|
95
|
+
const createInsightDescription = `Create SQL insight over workflow data.
|
|
96
|
+
|
|
97
|
+
**How sources map to SQL:**
|
|
98
|
+
- sources[].name → TABLE NAME in SQL (use in FROM/JOIN)
|
|
99
|
+
- sources[].workflowId → just tells Hailer which workflow, NOT used in SQL
|
|
100
|
+
- sources[].fields[].name → COLUMN NAME in SQL (use in SELECT/WHERE/ORDER BY)
|
|
101
|
+
- sources[].fields[].fieldId → just tells Hailer which field, NOT used in SQL
|
|
102
|
+
|
|
103
|
+
**Pattern:**
|
|
104
|
+
sources: [{ name: "MyTable", workflowId: "...", fields: [{ name: "myColumn", fieldId: "..." }] }]
|
|
105
|
+
query: "SELECT myColumn FROM MyTable"
|
|
106
|
+
|
|
107
|
+
**NEVER use workflowId or fieldId in the SQL query - only use name values.**`;
|
|
95
108
|
exports.createInsightTool = {
|
|
96
109
|
name: 'create_insight',
|
|
97
110
|
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
@@ -113,7 +126,7 @@ exports.createInsightTool = {
|
|
|
113
126
|
sources: zod_1.z
|
|
114
127
|
.array(sourceSchema)
|
|
115
128
|
.min(1)
|
|
116
|
-
.describe("Workflow sources
|
|
129
|
+
.describe("Workflow sources. source.name = SQL table name, field.name = SQL column name. Never use IDs in the query."),
|
|
117
130
|
query: zod_1.z
|
|
118
131
|
.string()
|
|
119
132
|
.min(1)
|
|
@@ -204,7 +217,8 @@ exports.createInsightTool = {
|
|
|
204
217
|
};
|
|
205
218
|
}
|
|
206
219
|
catch (error) {
|
|
207
|
-
|
|
220
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
221
|
+
logger.error("Error creating insight", error);
|
|
208
222
|
let errorMessage = 'Unknown error occurred';
|
|
209
223
|
let errorDetails = '';
|
|
210
224
|
if (error instanceof Error) {
|
|
@@ -254,7 +268,13 @@ exports.createInsightTool = {
|
|
|
254
268
|
// ============================================================================
|
|
255
269
|
// PREVIEW INSIGHT TOOL
|
|
256
270
|
// ============================================================================
|
|
257
|
-
const previewInsightDescription = `Test SQL query
|
|
271
|
+
const previewInsightDescription = `Test SQL query before creating insight.
|
|
272
|
+
|
|
273
|
+
**SQL naming rules:**
|
|
274
|
+
- Table names = sources[].name (NOT workflowId)
|
|
275
|
+
- Column names = fields[].name (NOT fieldId)
|
|
276
|
+
|
|
277
|
+
Always preview before create_insight.`;
|
|
258
278
|
exports.previewInsightTool = {
|
|
259
279
|
name: 'preview_insight',
|
|
260
280
|
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
@@ -267,7 +287,7 @@ exports.previewInsightTool = {
|
|
|
267
287
|
sources: zod_1.z
|
|
268
288
|
.array(sourceSchema)
|
|
269
289
|
.min(1)
|
|
270
|
-
.describe("Workflow sources
|
|
290
|
+
.describe("Workflow sources. Use source.name as table, field.name as column in SQL."),
|
|
271
291
|
query: zod_1.z
|
|
272
292
|
.string()
|
|
273
293
|
.min(1)
|
|
@@ -297,11 +317,10 @@ exports.previewInsightTool = {
|
|
|
297
317
|
});
|
|
298
318
|
// Normalize sources (convert 'id' to 'fieldId' if needed)
|
|
299
319
|
const normalizedSources = normalizeFields(args.sources);
|
|
300
|
-
// Build preview payload
|
|
320
|
+
// Build preview payload (insightId not accepted by v3.insight.preview)
|
|
301
321
|
const previewData = {
|
|
302
322
|
sources: normalizedSources,
|
|
303
323
|
query: args.query,
|
|
304
|
-
...(args.insightId && { insightId: args.insightId }),
|
|
305
324
|
};
|
|
306
325
|
// Call v3.insight.preview endpoint
|
|
307
326
|
const result = await context.hailer.request('v3.insight.preview', [workspaceId, previewData]);
|
|
@@ -343,7 +362,8 @@ exports.previewInsightTool = {
|
|
|
343
362
|
};
|
|
344
363
|
}
|
|
345
364
|
catch (error) {
|
|
346
|
-
|
|
365
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
366
|
+
logger.error("Error previewing insight", error);
|
|
347
367
|
let errorMessage = 'Unknown error occurred';
|
|
348
368
|
if (error instanceof Error) {
|
|
349
369
|
errorMessage = error.message;
|
|
@@ -439,7 +459,8 @@ exports.getInsightDataTool = {
|
|
|
439
459
|
};
|
|
440
460
|
}
|
|
441
461
|
catch (error) {
|
|
442
|
-
|
|
462
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
463
|
+
logger.error("Error getting insight data", error);
|
|
443
464
|
let errorMessage = 'Unknown error occurred';
|
|
444
465
|
if (error instanceof Error) {
|
|
445
466
|
errorMessage = error.message;
|
|
@@ -570,7 +591,8 @@ exports.updateInsightTool = {
|
|
|
570
591
|
};
|
|
571
592
|
}
|
|
572
593
|
catch (error) {
|
|
573
|
-
|
|
594
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
595
|
+
logger.error("Error updating insight", error);
|
|
574
596
|
const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
|
|
575
597
|
// Handle SQL syntax errors
|
|
576
598
|
if (errorMessage.toLowerCase().includes('sql') || errorMessage.toLowerCase().includes('syntax')) {
|
|
@@ -711,7 +733,8 @@ exports.removeInsightTool = {
|
|
|
711
733
|
};
|
|
712
734
|
}
|
|
713
735
|
catch (error) {
|
|
714
|
-
|
|
736
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
737
|
+
logger.error("Error removing insight", error);
|
|
715
738
|
let errorMessage = 'Unknown error occurred';
|
|
716
739
|
if (error instanceof Error) {
|
|
717
740
|
errorMessage = error.message;
|
|
@@ -801,7 +824,8 @@ exports.listInsightsTool = {
|
|
|
801
824
|
};
|
|
802
825
|
}
|
|
803
826
|
catch (error) {
|
|
804
|
-
|
|
827
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
828
|
+
logger.error("Error listing insights", error);
|
|
805
829
|
let errorMessage = 'Unknown error occurred';
|
|
806
830
|
if (error instanceof Error) {
|
|
807
831
|
errorMessage = error.message;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Investigation Tool - Spawn Claude Code agents to investigate local repos
|
|
3
|
+
*
|
|
4
|
+
* Uses `claude -p` (headless mode, subscription-based) to autonomously
|
|
5
|
+
* explore codebases, search for bugs, and analyze code.
|
|
6
|
+
*/
|
|
7
|
+
import { Tool } from '../tool-registry';
|
|
8
|
+
export declare const investigateRepoTool: Tool;
|
|
9
|
+
//# sourceMappingURL=investigate.d.ts.map
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Investigation Tool - Spawn Claude Code agents to investigate local repos
|
|
4
|
+
*
|
|
5
|
+
* Uses `claude -p` (headless mode, subscription-based) to autonomously
|
|
6
|
+
* explore codebases, search for bugs, and analyze code.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.investigateRepoTool = void 0;
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const tool_registry_1 = require("../tool-registry");
|
|
13
|
+
const logger_1 = require("../../lib/logger");
|
|
14
|
+
const config_1 = require("../../config");
|
|
15
|
+
const logger = (0, logger_1.createLogger)({ component: 'investigate-tool' });
|
|
16
|
+
/**
|
|
17
|
+
* Resolve claude CLI path at module load
|
|
18
|
+
*/
|
|
19
|
+
const CLAUDE_BIN = (() => {
|
|
20
|
+
try {
|
|
21
|
+
return (0, child_process_1.execSync)('which claude', { encoding: 'utf-8' }).trim();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return 'claude'; // fallback to PATH lookup
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
/**
|
|
28
|
+
* Parse DEV_AI_REPOS env var into a name->path map.
|
|
29
|
+
* Format: "name1:/path/one,name2:/path/two"
|
|
30
|
+
*/
|
|
31
|
+
function parseRepoPaths() {
|
|
32
|
+
const raw = config_1.environment.DEV_AI_REPOS;
|
|
33
|
+
const map = new Map();
|
|
34
|
+
if (!raw)
|
|
35
|
+
return map;
|
|
36
|
+
for (const entry of raw.split(',')) {
|
|
37
|
+
const colonIdx = entry.indexOf(':');
|
|
38
|
+
if (colonIdx === -1)
|
|
39
|
+
continue;
|
|
40
|
+
const name = entry.slice(0, colonIdx).trim();
|
|
41
|
+
const repoPath = entry.slice(colonIdx + 1).trim();
|
|
42
|
+
if (name && repoPath) {
|
|
43
|
+
map.set(name, repoPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return map;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve a repo name to its local filesystem path.
|
|
50
|
+
*/
|
|
51
|
+
function resolveRepoPath(repoName) {
|
|
52
|
+
const repos = parseRepoPaths();
|
|
53
|
+
return repos.get(repoName) || null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Spawn `claude -p` in a repo directory and return its output.
|
|
57
|
+
*/
|
|
58
|
+
async function spawnInvestigation(prompt, cwd, maxTurns, repoName) {
|
|
59
|
+
const timeout = config_1.environment.DEV_AI_INVESTIGATION_TIMEOUT;
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const proc = (0, child_process_1.spawn)(CLAUDE_BIN, [
|
|
62
|
+
'-p', prompt,
|
|
63
|
+
'--output-format', 'stream-json',
|
|
64
|
+
'--verbose',
|
|
65
|
+
'--allowedTools', 'Read,Glob,Grep,Bash,Task',
|
|
66
|
+
'--max-turns', String(maxTurns),
|
|
67
|
+
], {
|
|
68
|
+
cwd,
|
|
69
|
+
timeout,
|
|
70
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
71
|
+
env: {
|
|
72
|
+
...process.env,
|
|
73
|
+
// Strip MCP vars so investigation agent doesn't connect to our MCP server
|
|
74
|
+
MCP_SERVER_URL: undefined,
|
|
75
|
+
MCP_CLIENT_API_KEY: undefined,
|
|
76
|
+
MCP_CLIENT_ENABLED: undefined,
|
|
77
|
+
CLIENT_CONFIGS: undefined,
|
|
78
|
+
BOT_EMAIL: undefined,
|
|
79
|
+
BOT_PASSWORD: undefined,
|
|
80
|
+
BOT_API_BASE_URL: undefined,
|
|
81
|
+
ANTHROPIC_API_KEY: undefined,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
let lineBuffer = '';
|
|
85
|
+
let resultText = '';
|
|
86
|
+
let stderr = '';
|
|
87
|
+
proc.stdout.on('data', (data) => {
|
|
88
|
+
lineBuffer += data.toString();
|
|
89
|
+
const lines = lineBuffer.split('\n');
|
|
90
|
+
lineBuffer = lines.pop() || ''; // Keep incomplete last line in buffer
|
|
91
|
+
for (const line of lines) {
|
|
92
|
+
const trimmed = line.trim();
|
|
93
|
+
if (!trimmed)
|
|
94
|
+
continue;
|
|
95
|
+
try {
|
|
96
|
+
const event = JSON.parse(trimmed);
|
|
97
|
+
if (event.type === 'system' && event.subtype === 'init') {
|
|
98
|
+
logger.debug(`[investigation:${repoName}] Agent initialized | tools: ${(event.tools || []).length} | model: ${event.model || 'unknown'}`);
|
|
99
|
+
}
|
|
100
|
+
else if (event.type === 'assistant' && event.message?.content) {
|
|
101
|
+
for (const block of event.message.content) {
|
|
102
|
+
if (block.type === 'tool_use') {
|
|
103
|
+
const inputStr = JSON.stringify(block.input || {});
|
|
104
|
+
logger.debug(`[investigation:${repoName}] Tool: ${block.name} ${inputStr.length > 200 ? inputStr.slice(0, 200) + '...' : inputStr}`);
|
|
105
|
+
}
|
|
106
|
+
else if (block.type === 'text') {
|
|
107
|
+
const text = (block.text || '').trim();
|
|
108
|
+
if (text) {
|
|
109
|
+
logger.debug(`[investigation:${repoName}] ${text.length > 300 ? text.slice(0, 300) + '...' : text}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (event.type === 'tool') {
|
|
115
|
+
const content = typeof event.content === 'string' ? event.content : JSON.stringify(event.content || '');
|
|
116
|
+
logger.debug(`[investigation:${repoName}] Tool result (${event.tool_name}): ${content.length > 300 ? content.slice(0, 300) + '...' : content}`);
|
|
117
|
+
}
|
|
118
|
+
else if (event.type === 'result') {
|
|
119
|
+
resultText = event.result || '';
|
|
120
|
+
const cost = event.total_cost_usd ? `$${event.total_cost_usd.toFixed(4)}` : 'unknown';
|
|
121
|
+
const duration = event.duration_ms ? `${(event.duration_ms / 1000).toFixed(1)}s` : 'unknown';
|
|
122
|
+
logger.info(`[investigation:${repoName}] Complete | ${resultText.length} chars | ${duration} | cost: ${cost}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Non-JSON line
|
|
127
|
+
if (trimmed.length > 0) {
|
|
128
|
+
logger.debug(`[investigation:${repoName}] ${trimmed.length > 300 ? trimmed.slice(0, 300) + '...' : trimmed}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
proc.stderr.on('data', (data) => {
|
|
134
|
+
const chunk = data.toString();
|
|
135
|
+
stderr += chunk;
|
|
136
|
+
const trimmed = chunk.trim();
|
|
137
|
+
if (trimmed) {
|
|
138
|
+
logger.warn(`[investigation:${repoName}] ${trimmed.length > 500 ? trimmed.slice(0, 500) + '...' : trimmed}`);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
proc.on('error', (err) => {
|
|
142
|
+
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
143
|
+
});
|
|
144
|
+
proc.on('close', (code) => {
|
|
145
|
+
// Process any remaining data in lineBuffer
|
|
146
|
+
if (lineBuffer.trim()) {
|
|
147
|
+
try {
|
|
148
|
+
const event = JSON.parse(lineBuffer.trim());
|
|
149
|
+
if (event.type === 'result') {
|
|
150
|
+
resultText = event.result || '';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// ignore
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (code === 0) {
|
|
158
|
+
resolve(resultText || 'Investigation completed but returned no structured result.');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const errDetail = stderr.trim() || `exit code ${code}`;
|
|
162
|
+
reject(new Error(`Investigation failed: ${errDetail}`));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const investigateRepoSchema = zod_1.z.object({
|
|
168
|
+
repoName: zod_1.z.string().describe('Target repo name (must match a configured repo). Available repos depend on DEV_AI_REPOS config.'),
|
|
169
|
+
prompt: zod_1.z.string().describe('What to investigate - bug description, search query, code question, etc.'),
|
|
170
|
+
maxTurns: zod_1.z.number().optional().default(30).describe('Max investigation depth (number of agentic turns). Default: 30.'),
|
|
171
|
+
});
|
|
172
|
+
exports.investigateRepoTool = {
|
|
173
|
+
name: 'investigate_repo',
|
|
174
|
+
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
175
|
+
description: 'Spawn a Claude Code agent to investigate code in a local repo. ' +
|
|
176
|
+
'Uses claude -p (headless mode, subscription-based). ' +
|
|
177
|
+
'The agent can explore files, search code, analyze the codebase autonomously, ' +
|
|
178
|
+
'and spawn investigation teams for parallel exploration of complex issues. ' +
|
|
179
|
+
'Returns the investigation findings as text.',
|
|
180
|
+
schema: investigateRepoSchema,
|
|
181
|
+
async execute(args, _context) {
|
|
182
|
+
const repos = parseRepoPaths();
|
|
183
|
+
// If no repos configured, return helpful error
|
|
184
|
+
if (repos.size === 0) {
|
|
185
|
+
return {
|
|
186
|
+
content: [{
|
|
187
|
+
type: 'text',
|
|
188
|
+
text: 'No repos configured. Set DEV_AI_REPOS in .env.local (format: "name:/path,name2:/path2").',
|
|
189
|
+
}],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const repoPath = resolveRepoPath(args.repoName);
|
|
193
|
+
if (!repoPath) {
|
|
194
|
+
const available = Array.from(repos.keys()).join(', ');
|
|
195
|
+
return {
|
|
196
|
+
content: [{
|
|
197
|
+
type: 'text',
|
|
198
|
+
text: `Unknown repo: "${args.repoName}". Available repos: ${available}`,
|
|
199
|
+
}],
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const enhancedPrompt = `You are a lead investigator. Use parallel agents to explore the codebase efficiently.
|
|
203
|
+
|
|
204
|
+
HOW TO USE PARALLEL AGENTS:
|
|
205
|
+
- Call multiple Task tools in a SINGLE response to run them in parallel
|
|
206
|
+
- Each Task call blocks until that agent finishes and returns its findings directly to you
|
|
207
|
+
- Use subagent_type: "Explore" with model: "haiku" — these are fast, read-only codebase search agents
|
|
208
|
+
- Do NOT use TeamCreate, SendMessage, or TaskCreate — just call Task directly
|
|
209
|
+
|
|
210
|
+
APPROACH:
|
|
211
|
+
1. In your FIRST response, call 2-3 Task tools simultaneously, each with a focused search prompt
|
|
212
|
+
2. You will receive all their findings in the next turn
|
|
213
|
+
3. If needed, do additional targeted searches yourself with Grep/Read
|
|
214
|
+
4. Write your FINAL REPORT
|
|
215
|
+
|
|
216
|
+
REPORT FORMAT:
|
|
217
|
+
- Root cause of the issue
|
|
218
|
+
- Affected files with paths and line numbers
|
|
219
|
+
- Suggested fix with specific code changes
|
|
220
|
+
|
|
221
|
+
INVESTIGATION TASK:
|
|
222
|
+
${args.prompt}`;
|
|
223
|
+
logger.info('Starting investigation', {
|
|
224
|
+
repo: args.repoName,
|
|
225
|
+
repoPath,
|
|
226
|
+
maxTurns: args.maxTurns,
|
|
227
|
+
promptLength: enhancedPrompt.length,
|
|
228
|
+
});
|
|
229
|
+
try {
|
|
230
|
+
const result = await spawnInvestigation(enhancedPrompt, repoPath, args.maxTurns, args.repoName);
|
|
231
|
+
logger.info('Investigation completed', {
|
|
232
|
+
repo: args.repoName,
|
|
233
|
+
resultLength: result.length,
|
|
234
|
+
});
|
|
235
|
+
return {
|
|
236
|
+
content: [{
|
|
237
|
+
type: 'text',
|
|
238
|
+
text: result || 'Investigation completed but returned no output.',
|
|
239
|
+
}],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
244
|
+
logger.error('Investigation failed', { repo: args.repoName, error: errMsg });
|
|
245
|
+
return {
|
|
246
|
+
content: [{
|
|
247
|
+
type: 'text',
|
|
248
|
+
text: `Investigation failed: ${errMsg}`,
|
|
249
|
+
}],
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
//# sourceMappingURL=investigate.js.map
|
package/dist/mcp/tools/user.d.ts
CHANGED
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
* User Tools - Clean Architecture Implementation
|
|
3
3
|
*
|
|
4
4
|
* Tools for managing users in Hailer workspaces:
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
7
|
-
* - Get workspace balance (READ)
|
|
5
|
+
* - Search for users by name (WRITE)
|
|
6
|
+
* - Get initialization data (READ) - currently disabled
|
|
8
7
|
*/
|
|
9
8
|
import { Tool } from '../tool-registry';
|
|
10
|
-
export declare const listMyWorkspacesTool: Tool;
|
|
11
9
|
export declare const searchWorkspaceUsersTool: Tool;
|
|
12
10
|
export declare const getWorkspaceBalanceTool: Tool;
|
|
13
11
|
//# sourceMappingURL=user.d.ts.map
|
package/dist/mcp/tools/user.js
CHANGED
|
@@ -3,62 +3,19 @@
|
|
|
3
3
|
* User Tools - Clean Architecture Implementation
|
|
4
4
|
*
|
|
5
5
|
* Tools for managing users in Hailer workspaces:
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* - Get workspace balance (READ)
|
|
6
|
+
* - Search for users by name (WRITE)
|
|
7
|
+
* - Get initialization data (READ) - currently disabled
|
|
9
8
|
*/
|
|
10
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.getWorkspaceBalanceTool = exports.searchWorkspaceUsersTool =
|
|
10
|
+
exports.getWorkspaceBalanceTool = exports.searchWorkspaceUsersTool = void 0;
|
|
12
11
|
const zod_1 = require("zod");
|
|
13
12
|
const tool_registry_1 = require("../tool-registry");
|
|
14
13
|
const index_1 = require("../utils/index");
|
|
15
14
|
const tool_helpers_1 = require("../utils/tool-helpers");
|
|
15
|
+
const request_logger_1 = require("../../lib/request-logger");
|
|
16
16
|
const logger = (0, index_1.createLogger)({ component: 'user-tools' });
|
|
17
17
|
// ============================================================================
|
|
18
|
-
// TOOL 1:
|
|
19
|
-
// ============================================================================
|
|
20
|
-
const listMyWorkspacesDescription = `List all workspaces the current user has access to. Use this when user needs to see their workspaces or switch between them. Returns workspace IDs that can be used in other tools.`;
|
|
21
|
-
exports.listMyWorkspacesTool = {
|
|
22
|
-
name: 'list_my_workspaces',
|
|
23
|
-
group: tool_registry_1.ToolGroup.READ,
|
|
24
|
-
description: listMyWorkspacesDescription,
|
|
25
|
-
schema: zod_1.z.object({}),
|
|
26
|
-
async execute(_args, context) {
|
|
27
|
-
logger.debug('Listing user workspaces', {
|
|
28
|
-
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
29
|
-
});
|
|
30
|
-
try {
|
|
31
|
-
if (!context.workspaceCache) {
|
|
32
|
-
return (0, tool_helpers_1.missingWorkspaceCacheResponse)();
|
|
33
|
-
}
|
|
34
|
-
const workspaces = context.workspaceCache.allWorkspaces;
|
|
35
|
-
const currentWorkspaceId = context.workspaceCache.currentWorkspace?._id;
|
|
36
|
-
const workspaceList = Object.entries(workspaces);
|
|
37
|
-
if (workspaceList.length === 0) {
|
|
38
|
-
return (0, index_1.textResponse)('❌ No workspaces found for this user.');
|
|
39
|
-
}
|
|
40
|
-
const formattedWorkspaces = workspaceList
|
|
41
|
-
.map(([id, ws]) => {
|
|
42
|
-
const isCurrent = id === currentWorkspaceId;
|
|
43
|
-
const marker = isCurrent ? ' ← current' : '';
|
|
44
|
-
return `• **${ws.name}**${marker}\n - ID: \`${id}\``;
|
|
45
|
-
})
|
|
46
|
-
.join('\n\n');
|
|
47
|
-
const hint = workspaceList.length > 1
|
|
48
|
-
? `\n\n💡 **Tip:** To work with a specific workspace, pass the \`workspaceId\` parameter to tools like \`list_activities\`, \`create_activity\`, etc.`
|
|
49
|
-
: '';
|
|
50
|
-
return (0, index_1.textResponse)(`📋 **Your Workspaces** (${workspaceList.length} total)\n\n` +
|
|
51
|
-
formattedWorkspaces +
|
|
52
|
-
hint);
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
logger.error('Error listing workspaces', error);
|
|
56
|
-
return (0, index_1.errorResponse)(`Error listing workspaces: ${(0, index_1.getErrorMessage)(error)}`);
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
// ============================================================================
|
|
61
|
-
// TOOL 2: SEARCH WORKSPACE USERS
|
|
18
|
+
// TOOL 1: SEARCH WORKSPACE USERS
|
|
62
19
|
// ============================================================================
|
|
63
20
|
const searchWorkspaceUsersDescription = `Search for users in the current workspace by name - Returns valid user IDs for assignment`;
|
|
64
21
|
exports.searchWorkspaceUsersTool = {
|
|
@@ -119,7 +76,8 @@ exports.searchWorkspaceUsersTool = {
|
|
|
119
76
|
`\n\n💡 Use these IDs in create_activity fields or followerIds parameters.`);
|
|
120
77
|
}
|
|
121
78
|
catch (error) {
|
|
122
|
-
|
|
79
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
80
|
+
logger.error("Error searching workspace users", error);
|
|
123
81
|
return (0, index_1.errorResponse)(`Error searching users: ${(0, index_1.getErrorMessage)(error)}`);
|
|
124
82
|
}
|
|
125
83
|
},
|
|
@@ -212,7 +170,8 @@ exports.getWorkspaceBalanceTool = {
|
|
|
212
170
|
`${message}`);
|
|
213
171
|
}
|
|
214
172
|
catch (error) {
|
|
215
|
-
|
|
173
|
+
if (!request_logger_1.RequestLogger.getCurrent())
|
|
174
|
+
logger.error("Error checking workspace balance", error);
|
|
216
175
|
return (0, index_1.errorResponse)(`Error checking workspace balance: ${(0, index_1.getErrorMessage)(error)}`);
|
|
217
176
|
}
|
|
218
177
|
},
|
|
@@ -14,5 +14,6 @@ export declare const updateWorkflowFieldTool: Tool;
|
|
|
14
14
|
export declare const testFunctionFieldTool: Tool;
|
|
15
15
|
export declare const listWorkflowsMinimalTool: Tool;
|
|
16
16
|
export declare const countActivitiesTool: Tool;
|
|
17
|
+
export declare const coreInitTool: Tool;
|
|
17
18
|
export declare const updateWorkflowPhaseTool: Tool;
|
|
18
19
|
//# sourceMappingURL=workflow.d.ts.map
|