@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.
- 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 +29 -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 +219 -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
|
@@ -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
|
+
}
|