@hailer/mcp 1.0.29 → 1.1.2

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 +29 -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 +219 -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
@@ -0,0 +1,478 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * <hook-name>delegation-reminder</hook-name>
4
+ * <purpose>Enforces delegation pattern - orchestrator should delegate, not do directly</purpose>
5
+ * <triggers>PreToolUse</triggers>
6
+ *
7
+ * delegation-reminder.cjs
8
+ *
9
+ * HARD BLOCKS (data safety - writes only):
10
+ * - MCP write tools: create_activity, update_activity → Dmitri
11
+ * - install_workflow → Helga (use SDK)
12
+ *
13
+ * SOFT SUGGESTIONS (allows but reminds - specialists may need direct access):
14
+ * - MCP read tools: list_activities, get_workflow_schema, etc. → appropriate specialist
15
+ * - workspace/ reads → Kenji (but Helga/Viktor/Alejandro/Ingrid need access too)
16
+ * - Glob/Grep code searches → Explore agent
17
+ * - Task(giuseppe) for new app: Suggest ui-designer first
18
+ * - Task(giuseppe) for demo/mockup: Suggest marco-mockup instead
19
+ * - workspace/ writes: Suggest Helga
20
+ * - apps/ files: Suggest Giuseppe
21
+ * - .claude/agents/: Suggest Builder
22
+ * - .claude/skills/: Suggest Ada
23
+ * - git commit: Suggest Svetlana for review
24
+ * - After .ts/.tsx edits: Suggest Tanya for tests
25
+ *
26
+ * SILENTLY ALLOWS:
27
+ * - Schema/list tools used by multiple specialists (get_workflow_schema, list_workflows, etc.)
28
+ *
29
+ * SKIPS:
30
+ * - When called from within a subagent (checks agent stack + env vars)
31
+ *
32
+ * NOTE: Delegation is enforced even in yolo mode. Yolo only bypasses confirmation
33
+ * prompts (bulk-activity-guard, destructive-command-guard), not delegation pattern.
34
+ *
35
+ * Hook type: PreToolUse
36
+ */
37
+
38
+ const fs = require('fs');
39
+ const path = require('path');
40
+ const os = require('os');
41
+
42
+ // Cross-platform temp directory
43
+ const TEMP_DIR = os.tmpdir();
44
+
45
+ // Agent stack file maintained by builder-mode-manager.cjs
46
+ const AGENT_STACK_FILE = path.join(TEMP_DIR, '.claude-agent-stack.json');
47
+
48
+ /**
49
+ * Check if we're running inside a subagent.
50
+ * Uses multiple detection methods:
51
+ * 1. Agent stack file (maintained by builder-mode-manager.cjs)
52
+ * 2. CLAUDE_SUBAGENT environment variable (set by Claude Code Task tool)
53
+ * 3. CLAUDE_AGENT_* environment variables (agent identity markers)
54
+ */
55
+ function isInsideSubagent() {
56
+ // Method 1: Check agent stack file
57
+ try {
58
+ const stack = JSON.parse(fs.readFileSync(AGENT_STACK_FILE, 'utf8'));
59
+ if (stack.agents && stack.agents.length > 0) {
60
+ return true;
61
+ }
62
+ } catch (e) {
63
+ // File doesn't exist or invalid JSON - continue to other methods
64
+ }
65
+
66
+ // Method 2: Check CLAUDE_SUBAGENT env var (may be set by Task tool)
67
+ if (process.env.CLAUDE_SUBAGENT === 'true' || process.env.CLAUDE_SUBAGENT === '1') {
68
+ return true;
69
+ }
70
+
71
+ // Method 3: Check for agent identity markers in environment
72
+ // When Task tool spawns a subagent, certain env vars may be present
73
+ if (process.env.CLAUDE_AGENT_TYPE || process.env.CLAUDE_AGENT_ID) {
74
+ return true;
75
+ }
76
+
77
+ return false;
78
+ }
79
+
80
+ // Tool -> Agent mappings
81
+ const MCP_TOOL_AGENTS = {
82
+ // Kenji - data reader
83
+ 'mcp__hailer__list_activities': 'agent-kenji-data-reader',
84
+ 'mcp__hailer__count_activities': 'agent-kenji-data-reader',
85
+ 'mcp__hailer__get_activity': 'agent-kenji-data-reader',
86
+ 'mcp__hailer__list_workflows': 'agent-kenji-data-reader',
87
+ 'mcp__hailer__list_workflows_minimal': 'agent-kenji-data-reader',
88
+ 'mcp__hailer__get_workflow_schema': 'agent-kenji-data-reader',
89
+ 'mcp__hailer__list_workflow_phases': 'agent-kenji-data-reader',
90
+
91
+ // Dmitri - activity CRUD
92
+ 'mcp__hailer__create_activity': 'agent-dmitri-activity-crud',
93
+ 'mcp__hailer__update_activity': 'agent-dmitri-activity-crud',
94
+
95
+ // Viktor - insights
96
+ 'mcp__hailer__preview_insight': 'agent-viktor-sql-insights',
97
+ 'mcp__hailer__get_insight_data': 'agent-viktor-sql-insights',
98
+ 'mcp__hailer__list_insights': 'agent-viktor-sql-insights',
99
+
100
+ // Yevgeni - discussions
101
+ 'mcp__hailer__list_my_discussions': 'agent-yevgeni-discussions',
102
+ 'mcp__hailer__fetch_discussion_messages': 'agent-yevgeni-discussions',
103
+ 'mcp__hailer__add_discussion_message': 'agent-yevgeni-discussions',
104
+ 'mcp__hailer__join_discussion': 'agent-yevgeni-discussions',
105
+ 'mcp__hailer__leave_discussion': 'agent-yevgeni-discussions',
106
+ 'mcp__hailer__invite_discussion_members': 'agent-yevgeni-discussions',
107
+
108
+ // Permissions
109
+ 'mcp__hailer__list_apps': 'agent-permissions-handler',
110
+ 'mcp__hailer__add_app_member': 'agent-permissions-handler',
111
+ 'mcp__hailer__remove_app_member': 'agent-permissions-handler',
112
+ 'mcp__hailer__search_workspace_users': 'agent-permissions-handler',
113
+
114
+ // Giuseppe - app scaffold and local dev
115
+ 'mcp__hailer__scaffold_hailer_app': 'agent-giuseppe-app-builder',
116
+ 'mcp__hailer__create_app': 'agent-giuseppe-app-builder',
117
+
118
+ // Helga - workflow config (use SDK, not MCP)
119
+ 'mcp__hailer__install_workflow': 'agent-helga-workflow-config',
120
+ 'mcp__hailer__create_workflow': 'agent-helga-workflow-config',
121
+ 'mcp__hailer__update_workflow': 'agent-helga-workflow-config',
122
+ 'mcp__hailer__delete_workflow': 'agent-helga-workflow-config',
123
+ };
124
+
125
+ // File patterns that suggest delegation
126
+ const FILE_PATTERN_AGENTS = {
127
+ 'workspace/': 'agent-kenji-data-reader',
128
+ '/workspace/': 'agent-kenji-data-reader',
129
+ 'apps/': 'agent-giuseppe-app-builder',
130
+ '/apps/': 'agent-giuseppe-app-builder',
131
+ '.claude/agents/': 'agent-builder-agent-creator',
132
+ '.claude/skills/': 'agent-ada-skill-builder',
133
+ };
134
+
135
+ // Check yolo mode once at startup
136
+ let _isYolo = false;
137
+ try {
138
+ const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
139
+ const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
140
+ _isYolo = state.mode === 'yolo';
141
+ } catch {}
142
+
143
+ /**
144
+ * In normal mode: soft suggestion (allow + message)
145
+ * In yolo mode: hard block (force delegation)
146
+ *
147
+ * Yolo means "autonomous via agents", not "orchestrator does everything".
148
+ */
149
+ function suggest(message, agentHint) {
150
+ if (_isYolo) {
151
+ console.log(JSON.stringify({
152
+ decision: "block",
153
+ reason: `🚫 YOLO DELEGATION: In autonomous mode, delegate to agents.\n\n${message}${agentHint ? `\n\nDelegate to: ${agentHint}` : ''}`,
154
+ }));
155
+ } else {
156
+ console.log(JSON.stringify({
157
+ decision: "allow",
158
+ message: message,
159
+ }));
160
+ }
161
+ }
162
+
163
+ // Read stdin asynchronously for better cross-platform support
164
+ let stdinData = '';
165
+ process.stdin.setEncoding('utf8');
166
+ process.stdin.on('data', chunk => stdinData += chunk);
167
+ process.stdin.on('end', () => {
168
+ try {
169
+ const input = JSON.parse(stdinData);
170
+ processInput(input);
171
+ } catch (e) {
172
+ console.error(`[delegation-reminder] Failed to parse input: ${e.message}`);
173
+ console.log(JSON.stringify({ decision: 'allow' }));
174
+ process.exit(0);
175
+ }
176
+ });
177
+
178
+ // Check if stdin is TTY (no piped input)
179
+ if (process.stdin.isTTY) {
180
+ console.log(JSON.stringify({ decision: 'allow' }));
181
+ process.exit(0);
182
+ }
183
+
184
+ function processInput(input) {
185
+ const { tool_name, tool_input } = input;
186
+
187
+ // Skip if running inside a subagent (check agent stack, not env var)
188
+ if (isInsideSubagent()) {
189
+ console.log(JSON.stringify({ decision: "allow" }));
190
+ return;
191
+ }
192
+
193
+ // WORKFLOW SUGGESTIONS: Task tool spawning
194
+ if (tool_name === 'Task') {
195
+ const agentType = tool_input?.subagent_type || '';
196
+ // ReDoS protection: limit prompt size before regex matching
197
+ let prompt = (tool_input?.prompt || '').toLowerCase();
198
+ if (prompt.length > 10000) prompt = prompt.substring(0, 10000);
199
+
200
+ // HARD BLOCK: Built-in agent types - use specialized agents instead
201
+ // Built-in agents lack Skill tool and specialized domain knowledge
202
+ const BUILTIN_AGENTS = {
203
+ 'Plan': 'Agents should plan their own work. Give the executing agent a prompt that includes research + planning + implementation. E.g., Ingrid can load SDK-document-templates skill and plan the template herself.',
204
+ 'general-purpose': 'Use the appropriate specialized agent. Check /help:agents for the right one.',
205
+ 'Bash': 'Run bash commands directly with the Bash tool instead of spawning a Bash agent.',
206
+ };
207
+
208
+ if (BUILTIN_AGENTS[agentType]) {
209
+ console.log(JSON.stringify({
210
+ decision: "block",
211
+ reason: `🚫 BUILT-IN AGENT BLOCKED: "${agentType}" is a Claude Code built-in agent. Use specialized agents instead.\n\n${BUILTIN_AGENTS[agentType]}\n\nAgents should do their own planning+research+execution. Include research steps in the agent's prompt instead of splitting into separate Plan/Explore agents.`,
212
+ }));
213
+ return;
214
+ }
215
+
216
+ // Giuseppe for new app - suggest ui-designer first
217
+ if (agentType.includes('giuseppe')) {
218
+ // Check if it's a demo/mockup request - use word boundaries to avoid false positives
219
+ if (/\b(demo|mockup|prototype)\b/i.test(prompt) ||
220
+ ((/\b(show|present)\b/i.test(prompt)) &&
221
+ (/\b(customer|client|stakeholder)\b/i.test(prompt)))) {
222
+ console.log(JSON.stringify({
223
+ decision: "allow",
224
+ message: `💡 FOR DEMOS: Consider using agent-marco-mockup-builder instead.\n\nMarco creates interactive demos with mock data - perfect for showing customers concepts.\nGiuseppe builds production apps.\n\nUse marco for: demos, prototypes, "what if" explorations\nUse giuseppe for: real apps with SDK integration`,
225
+ }));
226
+ return;
227
+ }
228
+
229
+ // Check if design was mentioned
230
+ if (!prompt.includes('design') && !prompt.includes('spec') && !prompt.includes('following the design')) {
231
+ console.log(JSON.stringify({
232
+ decision: "allow",
233
+ message: `💡 APP WORKFLOW: Consider the full flow:\n\n1. Plan Mode → understand requirements\n2. ui-designer → create design spec\n3. Giuseppe → build the app\n\nIf you haven't created a design spec yet, consider:\nTask(subagent_type="ui-designer", prompt='{"task":"design_app","requirements":"..."}')`,
234
+ }));
235
+ return;
236
+ }
237
+ }
238
+ }
239
+
240
+ // SUGGEST: Git commit - run tests and code review first
241
+ if (tool_name === 'Bash') {
242
+ const command = tool_input?.command || '';
243
+
244
+ if (command.includes('git commit')) {
245
+ console.log(JSON.stringify({
246
+ decision: "allow",
247
+ message: `💡 BEFORE COMMIT: Consider running tests and code review.\n\n1. Task(subagent_type="agent-tanya-test-runner", prompt='{"task":"run_tests"}')\n2. Task(subagent_type="agent-svetlana-code-review", prompt='{"task":"review_changes"}')\n\nTanya runs tests, Svetlana checks for bugs and security issues.`,
248
+ }));
249
+ return;
250
+ }
251
+
252
+ // Suggest tests after build passes
253
+ if (command.includes('npm run build') && !command.includes('test')) {
254
+ console.log(JSON.stringify({
255
+ decision: "allow",
256
+ message: `💡 BUILD PASSED? Consider running tests.\n\nTask(subagent_type="agent-tanya-test-runner", prompt='{"task":"run_tests"}')\n\nTanya runs vitest/playwright and reports failures.`,
257
+ }));
258
+ return;
259
+ }
260
+ }
261
+
262
+ // SOFT SUGGEST: Glob/Grep code searches - always soft (orchestrator needs these for delegation)
263
+ // These are orchestration tools, not domain work - never block even in yolo
264
+ if (tool_name === 'Glob' || tool_name === 'Grep') {
265
+ console.log(JSON.stringify({
266
+ decision: "allow",
267
+ message: `💡 CODE SEARCH: For workspace/schema searches, delegate to Kenji.\nFor broader research, include search instructions in the appropriate agent's prompt.\n\n(Specialist agents may search within their domains - this is just a reminder.)`,
268
+ }));
269
+ return;
270
+ }
271
+
272
+ // SUGGEST: Web search - delegate to save context (always soft - orchestrator may need quick lookups)
273
+ if (tool_name === 'WebSearch' || tool_name === 'WebFetch') {
274
+ console.log(JSON.stringify({
275
+ decision: "allow",
276
+ message: `💡 SAVE CONTEXT: Consider delegating web research to agent-web-search.\n\nThe agent searches, fetches pages, and returns concise summaries instead of dumping raw content.\n\nTask(subagent_type="agent-web-search", prompt='{"query":"your question","context":"optional background"}')`,
277
+ }));
278
+ return;
279
+ }
280
+
281
+ // MCP tools - block writes, suggest for reads
282
+ if (tool_name?.startsWith('mcp__hailer__')) {
283
+ // HARD BLOCK: install_workflow should use SDK, not MCP
284
+ // Enforced even in yolo mode - delegation is about correctness, not permissions
285
+ if (tool_name === 'mcp__hailer__install_workflow') {
286
+ console.log(JSON.stringify({
287
+ decision: "block",
288
+ reason: `🚫 USE SDK, NOT MCP: For workflow creation, use agent-helga-workflow-config with the SDK approach.
289
+
290
+ Helga manages workflows via workspace/ files + npm commands, not MCP tools.
291
+
292
+ Task(subagent_type="agent-helga-workflow-config", prompt='{"task":"create_workflow","name":"MyWorkflow","description":"..."}')
293
+
294
+ The install_workflow MCP tool is for admin/dev use only.`,
295
+ }));
296
+ return;
297
+ }
298
+
299
+ // HARD BLOCK: Activity writes must go through Dmitri
300
+ // Enforced even in yolo mode - Dmitri validates field formats
301
+ if (tool_name === 'mcp__hailer__create_activity' || tool_name === 'mcp__hailer__update_activity') {
302
+ console.log(JSON.stringify({
303
+ decision: "block",
304
+ reason: `🚫 DELEGATE TO DMITRI: Activity writes must go through agent-dmitri-activity-crud.
305
+
306
+ Dmitri validates:
307
+ - Required fields are provided
308
+ - Field value formats (activitylink=string, date=timestamp)
309
+ - Real MongoDB ObjectIds (not SDK enums)
310
+
311
+ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workflow_id":"...","phase_id":"...","activities":[...]}')`,
312
+ }));
313
+ return;
314
+ }
315
+
316
+ // MCP READ TOOLS: Always allow with soft message (never block, even in yolo)
317
+ // Subagent detection is unreliable — we can't tell if Viktor or the orchestrator
318
+ // is calling preview_insight. Blocking would break agents using their own tools.
319
+ const suggestedAgent = MCP_TOOL_AGENTS[tool_name];
320
+ if (suggestedAgent) {
321
+ // Skip suggestion for tools that multiple agents legitimately use
322
+ const multiAgentTools = [
323
+ 'mcp__hailer__get_workflow_schema',
324
+ 'mcp__hailer__list_workflows',
325
+ 'mcp__hailer__list_workflows_minimal',
326
+ 'mcp__hailer__list_workflow_phases',
327
+ ];
328
+
329
+ if (multiAgentTools.includes(tool_name)) {
330
+ console.log(JSON.stringify({ decision: "allow" }));
331
+ return;
332
+ }
333
+
334
+ // Always allow — agents need their own tools
335
+ // (Viktor→preview_insight, Kenji→list_activities, etc.)
336
+ console.log(JSON.stringify({
337
+ decision: "allow",
338
+ message: `💡 MCP TOOL: If you're the orchestrator, consider delegating to ${suggestedAgent}.`,
339
+ }));
340
+ return;
341
+ }
342
+
343
+ // Unknown MCP tool - allow with reminder
344
+ console.log(JSON.stringify({
345
+ decision: "allow",
346
+ message: `💡 DELEGATE: Consider /help:agents for the right agent. Tool: ${tool_name}`,
347
+ }));
348
+ return;
349
+ }
350
+
351
+ // BLOCK: Reading workspace/ - must delegate to Kenji (with bypass option)
352
+ if (tool_name === 'Read') {
353
+ const filePath = tool_input?.file_path || '';
354
+
355
+ // workspace/ reads - SOFT SUGGESTION (not blocking)
356
+ // Multiple specialist agents (Helga, Viktor, Alejandro, Ingrid) need workspace access
357
+ // Subagent detection isn't reliable, so we suggest rather than block
358
+ if (filePath.includes('workspace/') || filePath.includes('/workspace/')) {
359
+ suggest(`💡 WORKSPACE READ: If you're the orchestrator, consider delegating to Kenji.\n\nTask(subagent_type="agent-kenji-data-reader", prompt='{"task":"read_workspace_file","path":"${filePath}"}')\n\n(Specialist agents like Helga/Viktor need direct access - this is just a reminder.)`, 'agent-kenji-data-reader');
360
+ return;
361
+ }
362
+
363
+ // Other file patterns - soft suggestions
364
+ for (const [pattern, agent] of Object.entries(FILE_PATTERN_AGENTS)) {
365
+ if (filePath.includes(pattern) && !pattern.includes('workspace')) {
366
+ const suggestions = {
367
+ 'apps/': 'Giuseppe builds and maintains apps. Consider delegating app work.',
368
+ '.claude/agents/': 'Use agent-builder-agent-creator for creating/modifying agents.',
369
+ '.claude/skills/': 'Use agent-ada-skill-builder for creating/modifying skills.',
370
+ };
371
+ const suggestion = suggestions[pattern];
372
+ if (suggestion) {
373
+ suggest(`💡 CONSIDER DELEGATING: ${suggestion}\n\nAgent: ${agent}`, agent);
374
+ return;
375
+ }
376
+ }
377
+ }
378
+ }
379
+
380
+ // SOFT REMIND: Write/Edit on various files
381
+ if (tool_name === 'Write' || tool_name === 'Edit') {
382
+ const filePath = tool_input?.file_path || '';
383
+
384
+ // WORKSPACE WRITES: Suggest appropriate specialist
385
+ if (filePath.includes('workspace/')) {
386
+ // Function field code
387
+ if (filePath.includes('/functions/')) {
388
+ suggest(`💡 FUNCTION FIELD CODE: Use agent-alejandro-function-fields.\n\nAlejandro specializes in calculated fields, functionVariables, and JavaScript formulas.`, 'agent-alejandro-function-fields');
389
+ return;
390
+ }
391
+
392
+ // fields.ts - could involve function fields
393
+ if (filePath.includes('fields.ts')) {
394
+ suggest(`💡 FIELD DEFINITIONS: Use agent-helga-workflow-config for field config.\n\n💡 FOR FUNCTION FIELDS: If adding functionEnabled/functionVariables, also use agent-alejandro-function-fields for the function code.\n\nWorkflow: Helga adds field config → Alejandro writes function code`, 'agent-helga-workflow-config');
395
+ return;
396
+ }
397
+
398
+ // Document templates
399
+ if (filePath.includes('/templates/')) {
400
+ suggest(`💡 DOCUMENT TEMPLATES: Use agent-ingrid-doc-templates.\n\nIngrid handles PDF/CSV templates, pdfmake structure, and field mappings.`, 'agent-ingrid-doc-templates');
401
+ return;
402
+ }
403
+
404
+ // Insights
405
+ if (filePath.includes('insights.ts')) {
406
+ suggest(`💡 INSIGHTS: Use agent-viktor-sql-insights.\n\nViktor creates SQL queries, data sources, and insight configurations.`, 'agent-viktor-sql-insights');
407
+ return;
408
+ }
409
+
410
+ // General workspace config
411
+ suggest(`💡 WORKSPACE CONFIG: Use agent-helga-workflow-config.\n\nHelga manages workflows, fields, phases via SDK. Knows correct field types and push/pull order.`, 'agent-helga-workflow-config');
412
+ return;
413
+ }
414
+
415
+ // Suggest delegation for agent/skill modifications
416
+ if (filePath.includes('.claude/agents/')) {
417
+ suggest(`💡 CONSIDER DELEGATING: Use agent-builder-agent-creator for agent modifications.\n\nIt follows agent structure patterns and validates format.`, 'agent-builder-agent-creator');
418
+ return;
419
+ }
420
+
421
+ if (filePath.includes('.claude/skills/')) {
422
+ suggest(`💡 CONSIDER DELEGATING: Use agent-ada-skill-builder for skill modifications.\n\nIt creates skills from patterns and failure analysis.`, 'agent-ada-skill-builder');
423
+ return;
424
+ }
425
+
426
+ // .claude/ config files - allow in yolo (orchestrator legitimately edits config)
427
+ if (filePath.includes('.claude/') && (filePath.endsWith('.json') || filePath.endsWith('.cjs'))) {
428
+ console.log(JSON.stringify({
429
+ decision: "allow",
430
+ message: `💡 CONFIG CHANGE: After editing .claude/ config, consider running audit.\n\nTask(subagent_type="agent-bjorn-config-audit", prompt='{"task":"audit_config"}')`,
431
+ }));
432
+ return;
433
+ }
434
+
435
+ if (filePath.includes('apps/') && (filePath.endsWith('.tsx') || filePath.endsWith('.ts'))) {
436
+ suggest(`💡 CONSIDER DELEGATING: Use agent-giuseppe-app-builder for app code.\n\nGiuseppe handles SDK patterns, design system, and build verification.`, 'agent-giuseppe-app-builder');
437
+ return;
438
+ }
439
+
440
+ // Integration files
441
+ if (filePath.includes('integrations/') || filePath.includes('activity-mover')) {
442
+ suggest(`💡 INTEGRATIONS: Consider the specialist:\n\n- agent-igor-activity-mover-automation: Phase cascade bots\n- agent-ivan-monolith: Webhook handlers, scheduled jobs\n- agent-zara-zapier: Zapier integrations`);
443
+ return;
444
+ }
445
+
446
+ // General .ts/.tsx code edits - don't block in yolo, just remind about tests
447
+ if ((filePath.endsWith('.ts') || filePath.endsWith('.tsx')) &&
448
+ !filePath.includes('workspace/') &&
449
+ !filePath.includes('apps/') &&
450
+ !filePath.includes('.claude/')) {
451
+ console.log(JSON.stringify({
452
+ decision: "allow",
453
+ message: `💡 CODE CHANGE: Consider running tests after editing.\n\nTask(subagent_type="agent-tanya-test-runner", prompt='{"task":"run_tests"}')`,
454
+ }));
455
+ return;
456
+ }
457
+ }
458
+
459
+ // SUGGEST: Lars for debugging when errors mentioned in prompt
460
+ if (tool_name === 'Task') {
461
+ // ReDoS protection: limit prompt size before regex matching
462
+ let prompt = (tool_input?.prompt || '').toLowerCase();
463
+ if (prompt.length > 10000) prompt = prompt.substring(0, 10000);
464
+ const agentType = tool_input?.subagent_type || '';
465
+
466
+ // If spawning general-purpose or explore for debugging, suggest lars
467
+ if ((agentType.includes('general') || agentType.includes('explore')) &&
468
+ (prompt.includes('bug') || prompt.includes('debug') || prompt.includes('error') ||
469
+ prompt.includes('not working') || prompt.includes('broken') || prompt.includes('why'))) {
470
+ suggest(`💡 FOR CODE ISSUES: Consider agent-lars-code-inspector.\n\nLars uses LSP to find:\n- Dead code and unused variables\n- Unused imports\n- Type errors\n\nTask(subagent_type="agent-lars-code-inspector", prompt='{"task":"inspect","file":"path/to/file.ts"}')`, 'agent-lars-code-inspector');
471
+ return;
472
+ }
473
+ }
474
+
475
+ // Allow the tool call
476
+ console.log(JSON.stringify({ decision: "allow" }));
477
+ process.exit(0);
478
+ }