create-merlin-brain 3.4.8 → 3.5.0

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.
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Agents Index MCP Tools
3
+ * Browse and discover AI agents from the intelligence scanner catalog.
4
+ * These agents are discovered from skills.sh, GitHub, npm, community sources,
5
+ * then graded and indexed by the intelligence-scanner worker.
6
+ */
7
+ import { z } from 'zod';
8
+ /** Grade badge mapping */
9
+ function gradeBadge(grade) {
10
+ if (!grade)
11
+ return '';
12
+ const g = grade.toUpperCase();
13
+ if (g === 'A++' || g === 'A+')
14
+ return `🟢 ${g}`;
15
+ if (g === 'A')
16
+ return `🔵 ${g}`;
17
+ if (g.startsWith('B'))
18
+ return `⚪ ${g}`;
19
+ return g;
20
+ }
21
+ /**
22
+ * Register agents index tools with the MCP server
23
+ */
24
+ export function registerAgentsIndexTools(ctx) {
25
+ const { server, client } = ctx;
26
+ // ============================================================
27
+ // Tool: merlin_discover_agents
28
+ // ============================================================
29
+ server.tool('merlin_discover_agents', 'Search the public catalog of AI agents discovered and graded by Merlin\'s intelligence scanner. Use when looking for pre-built agents for a specific task, technology, or domain.', {
30
+ query: z.string().describe('Search query (e.g., "authentication", "testing", "Stripe")'),
31
+ category: z.string().optional().describe('Filter by category (e.g., "development", "testing", "devops")'),
32
+ limit: z.number().optional().describe('Maximum results (1-20, default: 5)'),
33
+ }, async ({ query, category, limit }) => {
34
+ try {
35
+ const searchLimit = Math.min(Math.max(limit || 5, 1), 20);
36
+ const agents = await client.searchAgentsIndex(query, { category, limit: searchLimit });
37
+ if (agents.length === 0) {
38
+ return {
39
+ content: [{
40
+ type: 'text',
41
+ text: `🔍 No agents found matching "${query}"${category ? ` in category "${category}"` : ''}\n\nTry:\n- Broader search terms\n- Technology names (e.g., "typescript", "react")\n- Task descriptions (e.g., "code review", "testing")\n\nAgents are discovered from skills.sh, GitHub, npm, and community sources.`,
42
+ }],
43
+ };
44
+ }
45
+ let response = `# 🤖 Agents: ${query}\n\n`;
46
+ response += `Found ${agents.length} agent${agents.length === 1 ? '' : 's'}:\n\n`;
47
+ agents.forEach((agent, idx) => {
48
+ const badge = gradeBadge(agent.grade);
49
+ response += `## ${idx + 1}. ${agent.name} ${badge}\n`;
50
+ if (agent.description) {
51
+ response += `${agent.description}\n\n`;
52
+ }
53
+ if (agent.installCommand) {
54
+ response += `**Install:** \`${agent.installCommand}\`\n`;
55
+ }
56
+ if (agent.sourceType) {
57
+ response += `**Source:** ${agent.sourceType}`;
58
+ if (agent.sourceUrl)
59
+ response += ` — [view](${agent.sourceUrl})`;
60
+ response += '\n';
61
+ }
62
+ if (agent.keywords.length > 0) {
63
+ response += `**Keywords:** ${agent.keywords.slice(0, 8).join(', ')}\n`;
64
+ }
65
+ if (agent.rating > 0 || agent.userThumbsUp > 0) {
66
+ response += `**Rating:** ${agent.rating.toFixed(1)} (👍 ${agent.userThumbsUp})\n`;
67
+ }
68
+ response += `\n**Detail:** Use \`merlin_get_agent_detail("${agent.slug}")\`\n\n---\n\n`;
69
+ });
70
+ response += `💡 **Tip:** Use \`merlin_get_agent_detail("slug")\` to see the full system prompt and install instructions.\n`;
71
+ response += `📋 **Note:** These are community-discovered agents. Review before installing.\n`;
72
+ return { content: [{ type: 'text', text: response }] };
73
+ }
74
+ catch (error) {
75
+ return {
76
+ content: [{
77
+ type: 'text',
78
+ text: `Error searching agents: ${error instanceof Error ? error.message : 'Unknown error'}`,
79
+ }],
80
+ isError: true,
81
+ };
82
+ }
83
+ });
84
+ // ============================================================
85
+ // Tool: merlin_get_agent_detail
86
+ // ============================================================
87
+ server.tool('merlin_get_agent_detail', 'Get full details of a specific agent from the catalog by its slug. Shows system prompt, install command, grade, compatibility, and ratings.', {
88
+ slug: z.string().describe('Agent slug identifier (e.g., "stripe-integration", "vitest-config")'),
89
+ }, async ({ slug }) => {
90
+ try {
91
+ const agent = await client.getAgentIndexDetail(slug);
92
+ if (!agent) {
93
+ return {
94
+ content: [{
95
+ type: 'text',
96
+ text: `Agent "${slug}" not found in the catalog.\n\nUse \`merlin_discover_agents("query")\` to search for agents.`,
97
+ }],
98
+ isError: true,
99
+ };
100
+ }
101
+ const badge = gradeBadge(agent.grade);
102
+ let response = `# ${agent.name} ${badge}\n\n`;
103
+ if (agent.description) {
104
+ response += `${agent.description}\n\n`;
105
+ }
106
+ if (agent.category) {
107
+ response += `**Category:** ${agent.category}\n`;
108
+ }
109
+ if (agent.installCommand) {
110
+ response += `**Install:** \`${agent.installCommand}\`\n`;
111
+ }
112
+ if (agent.sourceUrl) {
113
+ response += `**Source:** [${agent.sourceType || 'link'}](${agent.sourceUrl})\n`;
114
+ }
115
+ if (agent.compatibleWith.length > 0) {
116
+ response += `**Compatible with:** ${agent.compatibleWith.join(', ')}\n`;
117
+ }
118
+ if (agent.keywords.length > 0) {
119
+ response += `**Keywords:** ${agent.keywords.join(', ')}\n`;
120
+ }
121
+ response += '\n';
122
+ // Stats
123
+ const stats = [];
124
+ if (agent.rating > 0)
125
+ stats.push(`Rating: ${agent.rating.toFixed(1)}`);
126
+ if (agent.userThumbsUp > 0)
127
+ stats.push(`👍 ${agent.userThumbsUp}`);
128
+ if (agent.userThumbsDown > 0)
129
+ stats.push(`👎 ${agent.userThumbsDown}`);
130
+ if (agent.skillsShInstalls > 0)
131
+ stats.push(`${agent.skillsShInstalls.toLocaleString()} installs`);
132
+ if (agent.usageCount > 0)
133
+ stats.push(`${agent.usageCount} uses`);
134
+ if (agent.isFeatured)
135
+ stats.push('⭐ Featured');
136
+ if (stats.length > 0) {
137
+ response += `**Stats:** ${stats.join(' | ')}\n\n`;
138
+ }
139
+ // System prompt excerpt
140
+ if (agent.systemPrompt) {
141
+ const excerpt = agent.systemPrompt.length > 500
142
+ ? agent.systemPrompt.slice(0, 500) + '...'
143
+ : agent.systemPrompt;
144
+ response += `## System Prompt\n\n\`\`\`\n${excerpt}\n\`\`\`\n\n`;
145
+ }
146
+ response += `---\n📋 **Note:** Review the system prompt before installing. Community-discovered agents are graded but not audited.\n`;
147
+ return { content: [{ type: 'text', text: response }] };
148
+ }
149
+ catch (error) {
150
+ return {
151
+ content: [{
152
+ type: 'text',
153
+ text: `Error getting agent detail: ${error instanceof Error ? error.message : 'Unknown error'}`,
154
+ }],
155
+ isError: true,
156
+ };
157
+ }
158
+ });
159
+ // ============================================================
160
+ // Tool: merlin_recommend_for_task
161
+ // ============================================================
162
+ server.tool('merlin_recommend_for_task', 'Get combined recommendations: pre-built agents AND reference codebases for a task. Use when starting a new task type to check if existing tools or examples can help. Recommend only — never auto-install.', {
163
+ task: z.string().describe('Task description (e.g., "add Stripe payments", "set up authentication", "write E2E tests")'),
164
+ limit: z.number().optional().describe('Max results per category (1-10, default: 3)'),
165
+ }, async ({ task, limit }) => {
166
+ try {
167
+ const searchLimit = Math.min(Math.max(limit || 3, 1), 10);
168
+ // Fetch agents and sights in parallel
169
+ const [agents, sights] = await Promise.all([
170
+ client.searchAgentsIndex(task, { limit: searchLimit }).catch(() => []),
171
+ client.searchPublicSights(task, searchLimit).catch(() => []),
172
+ ]);
173
+ const hasAgents = agents.length > 0;
174
+ const hasSights = sights.length > 0;
175
+ if (!hasAgents && !hasSights) {
176
+ return {
177
+ content: [{
178
+ type: 'text',
179
+ text: `🔍 No recommendations found for: "${task}"\n\nNo pre-built agents or reference codebases matched. You'll need to build from scratch.\n\nTry:\n- Broader terms (e.g., "auth" instead of "OAuth2 PKCE flow")\n- Technology names (e.g., "stripe", "prisma")`,
180
+ }],
181
+ };
182
+ }
183
+ let response = `# 💡 Recommendations for: ${task}\n\n`;
184
+ // Agents section
185
+ if (hasAgents) {
186
+ response += `## 🤖 Relevant Agents (${agents.length})\n\n`;
187
+ agents.forEach((agent, idx) => {
188
+ const badge = gradeBadge(agent.grade);
189
+ response += `${idx + 1}. **${agent.name}** ${badge}`;
190
+ if (agent.description)
191
+ response += ` — ${agent.description}`;
192
+ response += '\n';
193
+ if (agent.installCommand) {
194
+ response += ` Install: \`${agent.installCommand}\`\n`;
195
+ }
196
+ });
197
+ response += '\n';
198
+ }
199
+ // Sights section
200
+ if (hasSights) {
201
+ response += `## 📚 Reference Codebases (${sights.length})\n\n`;
202
+ sights.forEach((sight, idx) => {
203
+ response += `${idx + 1}. **${sight.owner}/${sight.repo}** ⭐ ${sight.stars.toLocaleString()}`;
204
+ if (sight.description)
205
+ response += ` — ${sight.description}`;
206
+ response += '\n';
207
+ response += ` Explore: \`merlin_get_public_sight_context("${sight.owner}", "${sight.repo}")\`\n`;
208
+ });
209
+ response += '\n';
210
+ }
211
+ response += `---\n`;
212
+ response += `💡 **Tip:** Install an agent or explore a reference codebase before coding from scratch.\n`;
213
+ response += `📋 **Note:** Recommendations only — user decides what to use.\n`;
214
+ return { content: [{ type: 'text', text: response }] };
215
+ }
216
+ catch (error) {
217
+ return {
218
+ content: [{
219
+ type: 'text',
220
+ text: `Error getting recommendations: ${error instanceof Error ? error.message : 'Unknown error'}`,
221
+ }],
222
+ isError: true,
223
+ };
224
+ }
225
+ });
226
+ }
227
+ //# sourceMappingURL=agents-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-index.js","sourceRoot":"","sources":["../../../src/server/tools/agents-index.ts"],"names":[],"mappings":"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"}
@@ -13,4 +13,5 @@ export { registerAgentTools } from './agents.js';
13
13
  export { registerDiscoveryTools } from './discoveries.js';
14
14
  export { registerRouteTools } from './route.js';
15
15
  export { registerSightsIndexTools } from './sights-index.js';
16
+ export { registerAgentsIndexTools } from './agents-index.js';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -12,4 +12,5 @@ export { registerAgentTools } from './agents.js';
12
12
  export { registerDiscoveryTools } from './discoveries.js';
13
13
  export { registerRouteTools } from './route.js';
14
14
  export { registerSightsIndexTools } from './sights-index.js';
15
+ export { registerAgentsIndexTools } from './agents-index.js';
15
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
package/files/CLAUDE.md CHANGED
@@ -1082,49 +1082,29 @@ When you successfully apply a behavior pattern, the system tracks it. Confidence
1082
1082
 
1083
1083
  You don't need to manually call `merlin_apply_behavior` for every use — the system learns from context.
1084
1084
 
1085
- ### AUTO-SKILL: Install Capabilities On Demand
1085
+ ### AUTO-DISCOVER: Agent & Sights Recommendations
1086
1086
 
1087
- **When the user needs specialized capabilities, automatically check the skills index and install relevant tools.**
1087
+ When starting work on a new task type this session, automatically check if pre-built agents or reference codebases exist:
1088
1088
 
1089
- **How it works:**
1090
- 1. Detect task needs specialized capability (UI design, data viz, API testing, etc.)
1091
- 2. Query the live skills index: `curl -s https://merlin.build/api/skills/recommend -X POST -H "Content-Type: application/json" -d '{"task":"user's task"}'`
1092
- 3. If a skill matches with high confidence (score ≥ 3), install it automatically
1093
- 4. Show a brief confirmation: `"🔧 Installing [skill name] for this task..."`
1094
-
1095
- **Trigger keywords to watch for:**
1089
+ **Trigger:** First encounter of a task domain this session (auth, payments, testing, etc.)
1090
+ **Action:** Call merlin_recommend_for_task("task description")
1091
+ **Behavior:** RECOMMEND only, never auto-install. Show results and let user decide.
1096
1092
 
1097
- | Task Keywords | Likely Skill |
1098
- |--------------|--------------|
1099
- | UI, design, wireframe, prototype, mockup, layout | canvas-design |
1100
- | chart, graph, visualization, dashboard, analytics | data-visualization |
1101
- | API test, endpoint test, HTTP test | api-testing |
1102
- | schema, ERD, migration, database design | database-design |
1093
+ | Trigger | Tool to Call |
1094
+ |---------|-------------|
1095
+ | New task domain (auth, payments, testing, etc.) | merlin_recommend_for_task("task description") |
1096
+ | User asks "find an agent for X" | merlin_discover_agents("X") |
1097
+ | User asks "how does X work in other projects" | merlin_browse_sights("X") |
1098
+ | During /merlin:plan-phase | Include merlin_recommend_for_task in planner context |
1103
1099
 
1104
- **When detected, query and install:**
1105
- ```bash
1106
- # Query the skills index
1107
- curl -s "https://merlin.build/api/skills/search?q=ui+design"
1108
-
1109
- # If shouldAutoInstall is true, run the install command
1110
- npx claude-code-templates@latest --skill creative-design/canvas-design
1100
+ **Example:**
1111
1101
  ```
1112
-
1113
- **Do NOT ask** "Would you like me to install this?" — just install it when the match is strong. The user doesn't need to know the capability wasn't built-in.
1114
-
1115
- **After installation, confirm briefly:**
1116
- ```
1117
- 🔧 Installed canvas-design skill for UI work.
1102
+ User: "I need to add authentication"
1103
+ Call: merlin_recommend_for_task("authentication")
1104
+ → Show: Pre-built agents + reference codebases
1105
+ Let user decide: Install agent, explore codebase, or code from scratch
1118
1106
  ```
1119
1107
 
1120
- Then proceed with the task using the new capability.
1121
-
1122
- **Skills Index API:**
1123
- - `GET /api/skills` - List all available skills
1124
- - `GET /api/skills/search?q=...` - Search by keywords
1125
- - `POST /api/skills/recommend` - Get recommendations for a task
1126
- - `GET /api/skills/:id` - Get specific skill details
1127
-
1128
1108
  ---
1129
1109
 
1130
1110
  ## Summary: What's Automatic vs Manual
@@ -2,19 +2,19 @@
2
2
  # Merlin Hook: Agent Sync (SessionStart, background)
3
3
  # Checks installed agents freshness and updates from cloud. Max once/hour.
4
4
  set -euo pipefail
5
- trap 'exit 0' ERR
5
+ trap 'echo "{}"; exit 0' ERR
6
6
 
7
7
  AGENTS_DIR="${HOME}/.claude/agents"
8
8
  MERLIN_DIR="${HOME}/.claude/merlin"
9
9
  LAST_SYNC="${MERLIN_DIR}/.last-agent-sync"
10
10
  API_URL="${MERLIN_API_URL:-https://api.merlin.build}"
11
11
 
12
- [ -d "${AGENTS_DIR}" ] || exit 0
12
+ [ -d "${AGENTS_DIR}" ] || { echo '{}'; exit 0; }
13
13
 
14
14
  # Skip if synced within the last hour
15
15
  if [ -f "${LAST_SYNC}" ]; then
16
16
  last=$(cat "${LAST_SYNC}" 2>/dev/null || echo "0")
17
- [ $(($(date +%s) - last)) -lt 3600 ] && exit 0
17
+ [ $(($(date +%s) - last)) -lt 3600 ] && { echo '{}'; exit 0; }
18
18
  fi
19
19
 
20
20
  sync_agents() {
@@ -41,4 +41,7 @@ sync_agents() {
41
41
  }
42
42
 
43
43
  sync_agents &
44
+
45
+ # Claude Code command hooks must output valid JSON to stdout
46
+ echo '{}'
44
47
  exit 0
@@ -5,7 +5,7 @@
5
5
  # Always exits 0 — never blocks Claude Code.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -30,4 +30,6 @@ fi
30
30
  # Log file change event
31
31
  log_event "file_changed" "$(printf '{"file":"%s","tool":"%s"}' "${file_path:-unknown}" "${tool_name:-unknown}")"
32
32
 
33
+ # Claude Code command hooks must output valid JSON to stdout
34
+ echo '{}'
33
35
  exit 0
@@ -5,7 +5,7 @@
5
5
  # Advisory only — always exits 0, never blocks edits.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -35,4 +35,6 @@ fi
35
35
  # Log the pre-edit event
36
36
  log_event "pre_edit" "$(printf '{"file":"%s"}' "${file_path:-unknown}")"
37
37
 
38
+ # Claude Code command hooks must output valid JSON to stdout
39
+ echo '{}'
38
40
  exit 0
@@ -1,25 +1,12 @@
1
- # Merlin Sights Enforcement Before Every Edit
1
+ You are evaluating whether a file edit should proceed. Context: $ARGUMENTS
2
2
 
3
- STOP. You are about to modify a file. Merlin requires a Sights check first.
3
+ Check: Has the assistant recently called merlin_get_context, merlin_find_files, or merlin_search for this file's area in the current conversation? Look at recent tool calls in the transcript.
4
4
 
5
- ## Required: Context Check
6
- If you have NOT called `merlin_get_context` for this file's area in the last 2 minutes:
7
- 1. Call `merlin_get_context("brief description of what you're changing and why")`
8
- 2. Review what Sights returns existing patterns, related files, conventions
9
- 3. Check if similar code already exists (don't duplicate)
10
- 4. THEN proceed with the edit
5
+ Rules:
6
+ - If Sights was consulted recently (within the last few messages) for this area: allow the edit
7
+ - If this is a minor/trivial edit (formatting, typo fix, small change): allow the edit
8
+ - If this is a significant edit and Sights was NOT consulted: suggest checking first
11
9
 
12
- ## Required: Convention Check
13
- Follow ALL rules from Sights:
14
- - Max file size (usually 400 lines) if approaching, split the file
15
- - Naming conventions — match existing patterns
16
- - Testing requirements — note if tests are needed
17
-
18
- ## Required: Show Your Work
19
- After the Sights check, show a brief line so the user sees Merlin is involved:
20
- ```
21
- Merlin | Checked [area] | [what you found or "clear to edit"]
22
- ```
23
-
24
- ## Never Skip This
25
- Every edit should be informed by codebase knowledge. This is what makes Merlin sessions better than raw Claude sessions. The user chose Merlin for a reason — deliver on it.
10
+ Respond with ONLY valid JSON, no other text:
11
+ - Allow the edit: {"ok": true}
12
+ - Suggest Sights check first: {"ok": false, "reason": "Call merlin_get_context before editing this file to check for existing patterns and conventions"}
@@ -5,7 +5,7 @@
5
5
  # Always exits 0 — never blocks Claude Code shutdown.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -24,4 +24,6 @@ if command -v merlin >/dev/null 2>&1; then
24
24
  merlin save-checkpoint "Session ended" >/dev/null 2>&1 &
25
25
  fi
26
26
 
27
+ # Claude Code command hooks must output valid JSON to stdout
28
+ echo '{}'
27
29
  exit 0
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Merlin Hook: SessionStart (context injection)
4
+ # Injects Merlin identity context into the session via additionalContext.
5
+ # Uses the SessionStart command hook JSON output format.
6
+ # Always exits 0 — never blocks Claude Code startup.
7
+ #
8
+ set -euo pipefail
9
+ trap 'echo "{}"; exit 0' ERR
10
+
11
+ # Output additionalContext JSON for Claude to see at session start.
12
+ # This reminds Claude it's a Merlin-powered session.
13
+ # Full boot instructions are in CLAUDE.md — this is a lightweight nudge.
14
+ cat <<'CONTEXT_JSON'
15
+ {
16
+ "hookSpecificOutput": {
17
+ "hookEventName": "SessionStart",
18
+ "additionalContext": "You are a Merlin-powered session. Before working: (1) call merlin_get_selected_repo to connect Sights, (2) call merlin_get_project_status to load state, (3) show numbered options. Check Sights before every edit. Route complex tasks to specialists via /merlin:route. Save checkpoints before stopping."
19
+ }
20
+ }
21
+ CONTEXT_JSON
22
+
23
+ exit 0
@@ -5,7 +5,7 @@
5
5
  # Always exits 0 — never blocks Claude Code startup.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -28,4 +28,6 @@ if command -v merlin >/dev/null 2>&1; then
28
28
  record_sights_call
29
29
  fi
30
30
 
31
+ # Claude Code command hooks must output valid JSON to stdout
32
+ echo '{}'
31
33
  exit 0
@@ -1,36 +1,13 @@
1
- # Merlin Session End Protocol Before Stopping
1
+ You are evaluating whether Claude should stop working. Analyze the conversation context: $ARGUMENTS
2
2
 
3
- Before this session ends, complete this checklist:
3
+ Check these criteria:
4
+ 1. Did the user's most recent request get fully addressed?
5
+ 2. Are there any obvious errors or broken code that should be fixed before stopping?
6
+ 3. Did Claude mention follow-up tasks it intended to complete but hasn't done yet?
4
7
 
5
- ## 1. Uncommitted Work
6
- Check `git status`. If there are uncommitted changes:
7
- - Stage and commit with a clear message
8
- - Run `merlin_run_verification` before committing
8
+ IMPORTANT: This is NOT about saving checkpoints or showing summaries — those are handled elsewhere.
9
+ Only evaluate whether the core work is done.
9
10
 
10
- ## 2. Save Checkpoint
11
- Call `merlin_save_checkpoint` with:
12
- - What was accomplished this session
13
- - What's left to do
14
- - Any blockers or decisions made
15
- This lets the next session (or another agent) pick up exactly where you left off.
16
-
17
- ## 3. Session Summary
18
- Show the user a brief summary:
19
- ```
20
- Merlin | Session Complete
21
- - [X] files changed
22
- - [Y] Sights queries made
23
- - [Z] tasks completed
24
- - Checkpoint saved: [yes/no]
25
- ```
26
-
27
- ## 4. Next Steps
28
- Always end with what should happen next:
29
- ```
30
- Next session:
31
- [1] Continue with [next task]
32
- [2] Review what was built
33
- [3] [other relevant option]
34
- ```
35
-
36
- Do NOT stop without saving checkpoint. The user trusts Merlin to maintain continuity across sessions.
11
+ Respond with ONLY valid JSON, no other text:
12
+ - If stopping is appropriate: {"ok": true}
13
+ - If Claude should continue: {"ok": false, "reason": "brief explanation of what's unfinished"}
@@ -5,7 +5,7 @@
5
5
  # Advisory only — always exits 0, never blocks subagent startup.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -28,9 +28,21 @@ fi
28
28
  # Log subagent start event
29
29
  log_event "subagent_start" "$(printf '{"task":"%s"}' "${task_desc:-unknown}")"
30
30
 
31
- # If Merlin CLI available, fetch and output context for the task
31
+ # If Merlin CLI available, fetch context for the task and output as JSON
32
32
  if [ -n "$task_desc" ] && command -v merlin >/dev/null 2>&1; then
33
- merlin context "$task_desc" 2>/dev/null || true
33
+ context_text=$(merlin context "$task_desc" 2>/dev/null || true)
34
+ if [ -n "$context_text" ]; then
35
+ # Output as proper JSON additionalContext for the subagent
36
+ # Use jq if available, otherwise output empty JSON (context is best-effort)
37
+ if command -v jq >/dev/null 2>&1; then
38
+ jq -n --arg ctx "$context_text" '{hookSpecificOutput:{hookEventName:"SubagentStart",additionalContext:$ctx}}'
39
+ else
40
+ echo '{}'
41
+ fi
42
+ exit 0
43
+ fi
34
44
  fi
35
45
 
46
+ # Claude Code command hooks must output valid JSON to stdout
47
+ echo '{}'
36
48
  exit 0
@@ -1,14 +1,13 @@
1
- # Task Completion Verification - Merlin Quality Gate
1
+ You are evaluating whether a task should be marked as completed. Context: $ARGUMENTS
2
2
 
3
- Before marking this task as complete, verify:
3
+ Check these criteria:
4
+ 1. Was the task's stated objective accomplished based on the conversation?
5
+ 2. Were there any errors or test failures mentioned that haven't been resolved?
6
+ 3. Is the implementation reasonably complete (not a half-finished skeleton)?
4
7
 
5
- 1. **Code Quality**: Does the implementation follow the project's coding conventions? Check with merlin_get_conventions if unsure.
8
+ Be lenient don't block completion for minor issues like missing docs or style nits.
9
+ Only block if the core objective clearly wasn't met or there are unresolved errors.
6
10
 
7
- 2. **Sights Alignment**: Is the code consistent with existing patterns? Verify with merlin_get_context for the modified areas.
8
-
9
- 3. **No Regressions**: Run the project's test suite if it exists. Check build passes.
10
-
11
- 4. **Documentation**: If the task added new APIs or features, are they documented?
12
-
13
- If all verifications pass, allow task completion.
14
- If issues are found, list them and suggest fixes before completing.
11
+ Respond with ONLY valid JSON, no other text:
12
+ - Task is complete: {"ok": true}
13
+ - Task is not complete: {"ok": false, "reason": "brief explanation of what's unfinished"}
@@ -5,7 +5,7 @@
5
5
  # Informational only — always exits 0 for v1.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -43,4 +43,6 @@ if [ -f "tsconfig.json" ] && command -v npx >/dev/null 2>&1; then
43
43
  fi
44
44
  fi
45
45
 
46
+ # Claude Code command hooks must output valid JSON to stdout
47
+ echo '{}'
46
48
  exit 0
@@ -5,7 +5,7 @@
5
5
  # Advisory only — always exits 0, never blocks teammates.
6
6
  #
7
7
  set -euo pipefail
8
- trap 'exit 0' ERR
8
+ trap 'echo "{}"; exit 0' ERR
9
9
 
10
10
  HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
@@ -38,4 +38,6 @@ if command -v npm >/dev/null 2>&1; then
38
38
  npm run build --if-present >/dev/null 2>&1 || true
39
39
  fi
40
40
 
41
+ # Claude Code command hooks must output valid JSON to stdout
42
+ echo '{}'
41
43
  exit 0