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.
- package/bin/install.cjs +8 -6
- package/dist/server/api/client.d.ts +8 -1
- package/dist/server/api/client.d.ts.map +1 -1
- package/dist/server/api/client.js +37 -0
- package/dist/server/api/client.js.map +1 -1
- package/dist/server/api/types.d.ts +23 -0
- package/dist/server/api/types.d.ts.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +9 -0
- package/dist/server/server.js.map +1 -1
- package/dist/server/tools/agents-index.d.ts +12 -0
- package/dist/server/tools/agents-index.d.ts.map +1 -0
- package/dist/server/tools/agents-index.js +227 -0
- package/dist/server/tools/agents-index.js.map +1 -0
- package/dist/server/tools/index.d.ts +1 -0
- package/dist/server/tools/index.d.ts.map +1 -1
- package/dist/server/tools/index.js +1 -0
- package/dist/server/tools/index.js.map +1 -1
- package/files/CLAUDE.md +16 -36
- package/files/hooks/agent-sync.sh +6 -3
- package/files/hooks/post-edit-logger.sh +3 -1
- package/files/hooks/pre-edit-sights-check.sh +3 -1
- package/files/hooks/pre-edit-sights-enforce.md +9 -22
- package/files/hooks/session-end.sh +3 -1
- package/files/hooks/session-start-context.sh +23 -0
- package/files/hooks/session-start.sh +3 -1
- package/files/hooks/stop-check.md +10 -33
- package/files/hooks/subagent-context.sh +15 -3
- package/files/hooks/task-completed-verify.md +10 -11
- package/files/hooks/task-completed-verify.sh +3 -1
- package/files/hooks/teammate-idle-verify.sh +3 -1
- package/package.json +1 -1
|
@@ -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-
|
|
1085
|
+
### AUTO-DISCOVER: Agent & Sights Recommendations
|
|
1086
1086
|
|
|
1087
|
-
|
|
1087
|
+
When starting work on a new task type this session, automatically check if pre-built agents or reference codebases exist:
|
|
1088
1088
|
|
|
1089
|
-
**
|
|
1090
|
-
|
|
1091
|
-
|
|
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
|
-
|
|
|
1098
|
-
|
|
1099
|
-
|
|
|
1100
|
-
|
|
|
1101
|
-
|
|
|
1102
|
-
|
|
|
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
|
-
**
|
|
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
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
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
|
-
|
|
1
|
+
You are evaluating whether a file edit should proceed. Context: $ARGUMENTS
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
6
|
-
If
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
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
|
-
|
|
1
|
+
You are evaluating whether Claude should stop working. Analyze the conversation context: $ARGUMENTS
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
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
|
|
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
|
-
|
|
1
|
+
You are evaluating whether a task should be marked as completed. Context: $ARGUMENTS
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|