@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.
Files changed (233) hide show
  1. package/.claude/.session-checked +1 -0
  2. package/.claude/agents/agent-ada-skill-builder.md +10 -2
  3. package/.claude/agents/agent-alejandro-function-fields.md +104 -37
  4. package/.claude/agents/agent-bjorn-config-audit.md +41 -21
  5. package/.claude/agents/agent-builder-agent-creator.md +13 -3
  6. package/.claude/agents/agent-code-simplifier.md +53 -0
  7. package/.claude/agents/agent-dmitri-activity-crud.md +126 -11
  8. package/.claude/agents/agent-giuseppe-app-builder.md +212 -22
  9. package/.claude/agents/agent-gunther-mcp-tools.md +7 -36
  10. package/.claude/agents/agent-helga-workflow-config.md +75 -10
  11. package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
  12. package/.claude/agents/agent-ingrid-doc-templates.md +164 -36
  13. package/.claude/agents/agent-ivan-monolith.md +154 -0
  14. package/.claude/agents/agent-kenji-data-reader.md +15 -8
  15. package/.claude/agents/agent-lars-code-inspector.md +56 -8
  16. package/.claude/agents/agent-marco-mockup-builder.md +110 -0
  17. package/.claude/agents/agent-marcus-api-documenter.md +323 -0
  18. package/.claude/agents/agent-marketplace-publisher.md +232 -72
  19. package/.claude/agents/agent-marketplace-reviewer.md +255 -79
  20. package/.claude/agents/agent-permissions-handler.md +208 -0
  21. package/.claude/agents/agent-simple-writer.md +48 -0
  22. package/.claude/agents/agent-svetlana-code-review.md +127 -14
  23. package/.claude/agents/agent-tanya-test-runner.md +333 -0
  24. package/.claude/agents/agent-ui-designer.md +100 -0
  25. package/.claude/agents/agent-viktor-sql-insights.md +19 -6
  26. package/.claude/agents/agent-web-search.md +55 -0
  27. package/.claude/agents/agent-yevgeni-discussions.md +7 -1
  28. package/.claude/agents/agent-zara-zapier.md +159 -0
  29. package/.claude/commands/app-squad.md +135 -0
  30. package/.claude/commands/audit-squad.md +158 -0
  31. package/.claude/commands/autoplan.md +563 -0
  32. package/.claude/commands/cleanup-squad.md +98 -0
  33. package/.claude/commands/config-squad.md +106 -0
  34. package/.claude/commands/crud-squad.md +87 -0
  35. package/.claude/commands/data-squad.md +97 -0
  36. package/.claude/commands/debug-squad.md +303 -0
  37. package/.claude/commands/doc-squad.md +65 -0
  38. package/.claude/commands/handoff.md +137 -0
  39. package/.claude/commands/health.md +49 -0
  40. package/.claude/commands/help.md +2 -1
  41. package/.claude/commands/help:agents.md +96 -16
  42. package/.claude/commands/help:commands.md +55 -11
  43. package/.claude/commands/help:faq.md +16 -1
  44. package/.claude/commands/help:skills.md +93 -0
  45. package/.claude/commands/hotfix-squad.md +112 -0
  46. package/.claude/commands/integration-squad.md +82 -0
  47. package/.claude/commands/janitor-squad.md +167 -0
  48. package/.claude/commands/learn-auto.md +120 -0
  49. package/.claude/commands/learn.md +120 -0
  50. package/.claude/commands/mcp-list.md +27 -0
  51. package/.claude/commands/onboard-squad.md +140 -0
  52. package/.claude/commands/plan-workspace.md +732 -0
  53. package/.claude/commands/prd.md +131 -0
  54. package/.claude/commands/project-status.md +82 -0
  55. package/.claude/commands/publish.md +138 -0
  56. package/.claude/commands/recap.md +69 -0
  57. package/.claude/commands/restore.md +64 -0
  58. package/.claude/commands/review-squad.md +152 -0
  59. package/.claude/commands/save.md +24 -0
  60. package/.claude/commands/stats.md +19 -0
  61. package/.claude/commands/swarm.md +210 -0
  62. package/.claude/commands/tool-builder.md +3 -1
  63. package/.claude/commands/ws-pull.md +1 -1
  64. package/.claude/commands/yolo-off.md +17 -0
  65. package/.claude/commands/yolo.md +82 -0
  66. package/.claude/hooks/_shared-memory.cjs +305 -0
  67. package/.claude/hooks/_utils.cjs +134 -0
  68. package/.claude/hooks/agent-failure-detector.cjs +164 -79
  69. package/.claude/hooks/agent-usage-logger.cjs +204 -0
  70. package/.claude/hooks/app-edit-guard.cjs +20 -4
  71. package/.claude/hooks/auto-learn.cjs +316 -0
  72. package/.claude/hooks/bash-guard.cjs +282 -0
  73. package/.claude/hooks/builder-mode-manager.cjs +183 -54
  74. package/.claude/hooks/bulk-activity-guard.cjs +283 -0
  75. package/.claude/hooks/context-watchdog.cjs +292 -0
  76. package/.claude/hooks/delegation-reminder.cjs +478 -0
  77. package/.claude/hooks/design-system-lint.cjs +283 -0
  78. package/.claude/hooks/post-scaffold-hook.cjs +16 -3
  79. package/.claude/hooks/prompt-guard.cjs +366 -0
  80. package/.claude/hooks/publish-template-guard.cjs +16 -0
  81. package/.claude/hooks/session-start.cjs +35 -0
  82. package/.claude/hooks/shared-memory-writer.cjs +147 -0
  83. package/.claude/hooks/skill-injector.cjs +140 -0
  84. package/.claude/hooks/skill-usage-logger.cjs +258 -0
  85. package/.claude/hooks/src-edit-guard.cjs +16 -1
  86. package/.claude/hooks/sync-marketplace-agents.cjs +53 -8
  87. package/.claude/scripts/yolo-toggle.cjs +142 -0
  88. package/.claude/settings.json +141 -14
  89. package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
  90. package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
  91. package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
  92. package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
  93. package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
  94. package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
  95. package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
  96. package/.claude/skills/agent-structure/SKILL.md +98 -0
  97. package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
  98. package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
  99. package/.claude/skills/delegation-routing/SKILL.md +202 -0
  100. package/.claude/skills/frontend-design/SKILL.md +254 -0
  101. package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
  102. package/.claude/skills/hailer-api-client/SKILL.md +518 -0
  103. package/.claude/skills/hailer-app-builder/SKILL.md +939 -11
  104. package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
  105. package/.claude/skills/hailer-design-system/SKILL.md +235 -0
  106. package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
  107. package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
  108. package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
  109. package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
  110. package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
  111. package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
  112. package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
  113. package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
  114. package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
  115. package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
  116. package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
  117. package/.claude/skills/insight-join-patterns/SKILL.md +3 -0
  118. package/.claude/skills/integration-patterns/SKILL.md +421 -0
  119. package/.claude/skills/json-only-output/SKILL.md +52 -12
  120. package/.claude/skills/lsp-setup/SKILL.md +160 -0
  121. package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
  122. package/.claude/skills/optional-parameters/SKILL.md +32 -23
  123. package/.claude/skills/publish-hailer-app/SKILL.md +76 -12
  124. package/.claude/skills/testing-patterns/SKILL.md +630 -0
  125. package/.claude/skills/tool-builder/SKILL.md +250 -0
  126. package/.claude/skills/tool-parameter-usage/SKILL.md +59 -45
  127. package/.claude/skills/tool-response-verification/SKILL.md +82 -48
  128. package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
  129. package/.env.example +26 -7
  130. package/CLAUDE.md +290 -224
  131. package/dist/CLAUDE.md +370 -0
  132. package/dist/app.d.ts +1 -1
  133. package/dist/app.js +101 -101
  134. package/dist/bot/bot-config.d.ts +26 -0
  135. package/dist/bot/bot-config.js +135 -0
  136. package/dist/bot/bot-manager.d.ts +40 -0
  137. package/dist/bot/bot-manager.js +137 -0
  138. package/dist/bot/bot.d.ts +127 -0
  139. package/dist/bot/bot.js +1328 -0
  140. package/dist/bot/operation-logger.d.ts +28 -0
  141. package/dist/bot/operation-logger.js +132 -0
  142. package/dist/bot/services/conversation-manager.d.ts +60 -0
  143. package/dist/bot/services/conversation-manager.js +246 -0
  144. package/dist/bot/services/index.d.ts +9 -0
  145. package/dist/bot/services/index.js +18 -0
  146. package/dist/bot/services/message-classifier.d.ts +42 -0
  147. package/dist/bot/services/message-classifier.js +228 -0
  148. package/dist/bot/services/message-formatter.d.ts +88 -0
  149. package/dist/bot/services/message-formatter.js +411 -0
  150. package/dist/bot/services/session-logger.d.ts +162 -0
  151. package/dist/bot/services/session-logger.js +724 -0
  152. package/dist/bot/services/token-billing.d.ts +78 -0
  153. package/dist/bot/services/token-billing.js +233 -0
  154. package/dist/bot/services/types.d.ts +169 -0
  155. package/dist/bot/services/types.js +12 -0
  156. package/dist/bot/services/typing-indicator.d.ts +23 -0
  157. package/dist/bot/services/typing-indicator.js +60 -0
  158. package/dist/bot/services/workspace-schema-cache.d.ts +122 -0
  159. package/dist/bot/services/workspace-schema-cache.js +506 -0
  160. package/dist/bot/tool-executor.d.ts +28 -0
  161. package/dist/bot/tool-executor.js +48 -0
  162. package/dist/bot/workspace-overview.d.ts +12 -0
  163. package/dist/bot/workspace-overview.js +94 -0
  164. package/dist/cli.d.ts +1 -8
  165. package/dist/cli.js +1 -253
  166. package/dist/config.d.ts +96 -3
  167. package/dist/config.js +148 -37
  168. package/dist/core.d.ts +5 -0
  169. package/dist/core.js +61 -8
  170. package/dist/lib/discussion-lock.d.ts +42 -0
  171. package/dist/lib/discussion-lock.js +110 -0
  172. package/dist/lib/logger.d.ts +0 -1
  173. package/dist/lib/logger.js +39 -23
  174. package/dist/lib/request-logger.d.ts +77 -0
  175. package/dist/lib/request-logger.js +147 -0
  176. package/dist/mcp/UserContextCache.js +16 -13
  177. package/dist/mcp/hailer-clients.js +18 -17
  178. package/dist/mcp/signal-handler.js +43 -13
  179. package/dist/mcp/tool-registry.d.ts +4 -15
  180. package/dist/mcp/tool-registry.js +94 -32
  181. package/dist/mcp/tools/activity.js +28 -69
  182. package/dist/mcp/tools/app-core.js +9 -4
  183. package/dist/mcp/tools/app-marketplace.js +22 -12
  184. package/dist/mcp/tools/app-member.js +5 -2
  185. package/dist/mcp/tools/app-scaffold.js +32 -18
  186. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  187. package/dist/mcp/tools/bot-config/constants.js +94 -0
  188. package/dist/mcp/tools/bot-config/core.d.ts +253 -0
  189. package/dist/mcp/tools/bot-config/core.js +2456 -0
  190. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  191. package/dist/mcp/tools/bot-config/index.js +59 -0
  192. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  193. package/dist/mcp/tools/bot-config/tools.js +15 -0
  194. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  195. package/dist/mcp/tools/bot-config/types.js +6 -0
  196. package/dist/mcp/tools/discussion.js +107 -77
  197. package/dist/mcp/tools/document.d.ts +11 -0
  198. package/dist/mcp/tools/document.js +741 -0
  199. package/dist/mcp/tools/file.js +5 -2
  200. package/dist/mcp/tools/insight.js +36 -12
  201. package/dist/mcp/tools/investigate.d.ts +9 -0
  202. package/dist/mcp/tools/investigate.js +254 -0
  203. package/dist/mcp/tools/user.d.ts +2 -4
  204. package/dist/mcp/tools/user.js +9 -50
  205. package/dist/mcp/tools/workflow.d.ts +1 -0
  206. package/dist/mcp/tools/workflow.js +164 -52
  207. package/dist/mcp/utils/hailer-api-client.js +26 -17
  208. package/dist/mcp/webhook-handler.d.ts +64 -3
  209. package/dist/mcp/webhook-handler.js +227 -9
  210. package/dist/mcp-server.d.ts +4 -0
  211. package/dist/mcp-server.js +237 -25
  212. package/dist/plugins/bug-fixer/index.d.ts +2 -0
  213. package/dist/plugins/bug-fixer/index.js +18 -0
  214. package/dist/plugins/bug-fixer/tools.d.ts +45 -0
  215. package/dist/plugins/bug-fixer/tools.js +1096 -0
  216. package/package.json +10 -10
  217. package/scripts/test-hal-tools.ts +154 -0
  218. package/.claude/agents/agent-nora-name-functions.md +0 -123
  219. package/.claude/assistant-knowledge.md +0 -23
  220. package/.claude/commands/install-plugin.md +0 -261
  221. package/.claude/commands/list-plugins.md +0 -42
  222. package/.claude/commands/marketplace-setup.md +0 -33
  223. package/.claude/commands/publish-plugin.md +0 -55
  224. package/.claude/commands/uninstall-plugin.md +0 -87
  225. package/.claude/hooks/interactive-mode.cjs +0 -87
  226. package/.claude/hooks/mcp-server-guard.cjs +0 -108
  227. package/.claude/skills/marketplace-publishing.md +0 -155
  228. package/dist/bot/chat-bot.d.ts +0 -31
  229. package/dist/bot/chat-bot.js +0 -357
  230. package/dist/mcp/tools/metrics.d.ts +0 -13
  231. package/dist/mcp/tools/metrics.js +0 -546
  232. package/dist/stdio-server.d.ts +0 -14
  233. package/dist/stdio-server.js +0 -114
@@ -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
- logger.error('Upload failed', error);
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
- logger.error('Download failed', error);
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 (workflows=tables, activities=rows, fields=columns)`;
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 (like SQL table references)"),
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
- logger.error("Error creating insight", error);
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 on sample data before creating/updating insight`;
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 (like SQL table references)"),
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
- logger.error("Error previewing insight", error);
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
- logger.error("Error getting insight data", error);
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
- logger.error("Error updating insight", error);
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
- logger.error("Error removing insight", error);
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
- logger.error("Error listing insights", error);
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
@@ -2,12 +2,10 @@
2
2
  * User Tools - Clean Architecture Implementation
3
3
  *
4
4
  * Tools for managing users in Hailer workspaces:
5
- * - List user's workspaces (READ)
6
- * - Search for users by name (READ)
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
@@ -3,62 +3,19 @@
3
3
  * User Tools - Clean Architecture Implementation
4
4
  *
5
5
  * Tools for managing users in Hailer workspaces:
6
- * - List user's workspaces (READ)
7
- * - Search for users by name (READ)
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 = exports.listMyWorkspacesTool = void 0;
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: LIST MY WORKSPACES
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
- logger.error("Error searching workspace users", error);
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
- logger.error("Error checking workspace balance", error);
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