create-merlin-brain 3.11.0 → 3.13.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.
Files changed (147) hide show
  1. package/bin/install.cjs +156 -32
  2. package/bin/runtime-adapters.cjs +396 -0
  3. package/dist/server/api/types.d.ts +7 -0
  4. package/dist/server/api/types.d.ts.map +1 -1
  5. package/dist/server/cost/tracker.d.ts +38 -2
  6. package/dist/server/cost/tracker.d.ts.map +1 -1
  7. package/dist/server/cost/tracker.js +87 -15
  8. package/dist/server/cost/tracker.js.map +1 -1
  9. package/dist/server/server.d.ts.map +1 -1
  10. package/dist/server/server.js +74 -30
  11. package/dist/server/server.js.map +1 -1
  12. package/dist/server/tools/__tests__/augmentation.test.d.ts +8 -0
  13. package/dist/server/tools/__tests__/augmentation.test.d.ts.map +1 -0
  14. package/dist/server/tools/__tests__/augmentation.test.js +76 -0
  15. package/dist/server/tools/__tests__/augmentation.test.js.map +1 -0
  16. package/dist/server/tools/__tests__/route-helpers.test.d.ts +5 -0
  17. package/dist/server/tools/__tests__/route-helpers.test.d.ts.map +1 -0
  18. package/dist/server/tools/__tests__/route-helpers.test.js +49 -0
  19. package/dist/server/tools/__tests__/route-helpers.test.js.map +1 -0
  20. package/dist/server/tools/adaptive.js +1 -1
  21. package/dist/server/tools/adaptive.js.map +1 -1
  22. package/dist/server/tools/agent-spawn.d.ts +25 -0
  23. package/dist/server/tools/agent-spawn.d.ts.map +1 -0
  24. package/dist/server/tools/agent-spawn.js +95 -0
  25. package/dist/server/tools/agent-spawn.js.map +1 -0
  26. package/dist/server/tools/agents-index.js +3 -3
  27. package/dist/server/tools/agents-index.js.map +1 -1
  28. package/dist/server/tools/agents.js +5 -5
  29. package/dist/server/tools/agents.js.map +1 -1
  30. package/dist/server/tools/augmentation.d.ts +45 -0
  31. package/dist/server/tools/augmentation.d.ts.map +1 -0
  32. package/dist/server/tools/augmentation.js +167 -0
  33. package/dist/server/tools/augmentation.js.map +1 -0
  34. package/dist/server/tools/behaviors.js +4 -4
  35. package/dist/server/tools/behaviors.js.map +1 -1
  36. package/dist/server/tools/context.js +7 -7
  37. package/dist/server/tools/context.js.map +1 -1
  38. package/dist/server/tools/cost.d.ts +3 -1
  39. package/dist/server/tools/cost.d.ts.map +1 -1
  40. package/dist/server/tools/cost.js +66 -13
  41. package/dist/server/tools/cost.js.map +1 -1
  42. package/dist/server/tools/discoveries.js +6 -6
  43. package/dist/server/tools/discoveries.js.map +1 -1
  44. package/dist/server/tools/index.d.ts +4 -0
  45. package/dist/server/tools/index.d.ts.map +1 -1
  46. package/dist/server/tools/index.js +4 -0
  47. package/dist/server/tools/index.js.map +1 -1
  48. package/dist/server/tools/learning.d.ts +12 -0
  49. package/dist/server/tools/learning.d.ts.map +1 -0
  50. package/dist/server/tools/learning.js +269 -0
  51. package/dist/server/tools/learning.js.map +1 -0
  52. package/dist/server/tools/project.js +7 -7
  53. package/dist/server/tools/project.js.map +1 -1
  54. package/dist/server/tools/promote.d.ts +11 -0
  55. package/dist/server/tools/promote.d.ts.map +1 -0
  56. package/dist/server/tools/promote.js +315 -0
  57. package/dist/server/tools/promote.js.map +1 -0
  58. package/dist/server/tools/route-helpers.d.ts +45 -0
  59. package/dist/server/tools/route-helpers.d.ts.map +1 -0
  60. package/dist/server/tools/route-helpers.js +93 -0
  61. package/dist/server/tools/route-helpers.js.map +1 -0
  62. package/dist/server/tools/route.d.ts +4 -3
  63. package/dist/server/tools/route.d.ts.map +1 -1
  64. package/dist/server/tools/route.js +80 -284
  65. package/dist/server/tools/route.js.map +1 -1
  66. package/dist/server/tools/session-restore.d.ts +18 -0
  67. package/dist/server/tools/session-restore.d.ts.map +1 -0
  68. package/dist/server/tools/session-restore.js +154 -0
  69. package/dist/server/tools/session-restore.js.map +1 -0
  70. package/dist/server/tools/session-search.d.ts +16 -0
  71. package/dist/server/tools/session-search.d.ts.map +1 -0
  72. package/dist/server/tools/session-search.js +240 -0
  73. package/dist/server/tools/session-search.js.map +1 -0
  74. package/dist/server/tools/sights-index.js +2 -2
  75. package/dist/server/tools/sights-index.js.map +1 -1
  76. package/dist/server/tools/smart-route.d.ts.map +1 -1
  77. package/dist/server/tools/smart-route.js +4 -5
  78. package/dist/server/tools/smart-route.js.map +1 -1
  79. package/dist/server/tools/verification.js +1 -1
  80. package/dist/server/tools/verification.js.map +1 -1
  81. package/files/agents/code-organization-supervisor.md +1 -0
  82. package/files/agents/context-guardian.md +1 -0
  83. package/files/agents/docs-keeper.md +1 -0
  84. package/files/agents/dry-refactor.md +1 -0
  85. package/files/agents/elite-code-refactorer.md +1 -0
  86. package/files/agents/hardening-guard.md +1 -0
  87. package/files/agents/implementation-dev.md +1 -0
  88. package/files/agents/merlin-access-control-reviewer.md +248 -0
  89. package/files/agents/merlin-codebase-mapper.md +1 -1
  90. package/files/agents/merlin-dependency-auditor.md +216 -0
  91. package/files/agents/merlin-executor.md +1 -0
  92. package/files/agents/merlin-input-validator.md +247 -0
  93. package/files/agents/merlin-reviewer.md +1 -0
  94. package/files/agents/merlin-sast-reviewer.md +182 -0
  95. package/files/agents/merlin-secret-scanner.md +203 -0
  96. package/files/agents/tests-qa.md +1 -0
  97. package/files/commands/merlin/execute-phase.md +94 -197
  98. package/files/commands/merlin/execute-plan.md +116 -180
  99. package/files/commands/merlin/health.md +385 -0
  100. package/files/commands/merlin/loop-recipes.md +93 -36
  101. package/files/commands/merlin/optimize-prompts.md +158 -0
  102. package/files/commands/merlin/profiles.md +215 -0
  103. package/files/commands/merlin/promote.md +176 -0
  104. package/files/commands/merlin/quick.md +229 -0
  105. package/files/commands/merlin/resume-work.md +27 -1
  106. package/files/commands/merlin/route.md +43 -1
  107. package/files/commands/merlin/sandbox.md +359 -0
  108. package/files/commands/merlin/usage.md +55 -0
  109. package/files/docker/Dockerfile.merlin +20 -0
  110. package/files/docker/docker-compose.merlin.yml +23 -0
  111. package/files/hook-templates/auto-commit.sh +64 -0
  112. package/files/hook-templates/auto-format.sh +95 -0
  113. package/files/hook-templates/auto-test.sh +117 -0
  114. package/files/hook-templates/branch-protection.sh +72 -0
  115. package/files/hook-templates/changelog-reminder.sh +76 -0
  116. package/files/hook-templates/complexity-check.sh +112 -0
  117. package/files/hook-templates/import-audit.sh +83 -0
  118. package/files/hook-templates/license-header.sh +84 -0
  119. package/files/hook-templates/pr-description.sh +100 -0
  120. package/files/hook-templates/todo-tracker.sh +80 -0
  121. package/files/hooks/check-file-size.sh +17 -4
  122. package/files/hooks/config-change.sh +44 -16
  123. package/files/hooks/instructions-loaded.sh +22 -5
  124. package/files/hooks/notify-desktop.sh +157 -0
  125. package/files/hooks/notify-webhook.sh +141 -0
  126. package/files/hooks/pre-edit-sights-check.sh +76 -9
  127. package/files/hooks/security-scanner.sh +153 -0
  128. package/files/hooks/session-end-memory-sync.sh +97 -0
  129. package/files/hooks/session-end.sh +274 -1
  130. package/files/hooks/session-start.sh +19 -6
  131. package/files/hooks/smart-approve.sh +270 -0
  132. package/files/hooks/teammate-idle-verify.sh +87 -12
  133. package/files/hooks/worktree-create.sh +20 -3
  134. package/files/hooks/worktree-remove.sh +21 -3
  135. package/files/merlin/references/plan-format.md +37 -9
  136. package/files/merlin/sandbox.json +9 -0
  137. package/files/merlin/security.json +11 -0
  138. package/files/merlin/templates/ci/docs-update.yml +81 -0
  139. package/files/merlin/templates/ci/pr-review.yml +50 -0
  140. package/files/merlin/templates/ci/security-audit.yml +74 -0
  141. package/files/merlin/templates/config.json +9 -1
  142. package/files/rules/api-rules.md +30 -0
  143. package/files/rules/frontend-rules.md +25 -0
  144. package/files/rules/hooks-rules.md +36 -0
  145. package/files/rules/mcp-rules.md +30 -0
  146. package/files/rules/worker-rules.md +29 -0
  147. package/package.json +5 -2
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Behavior → Skill Promotion
3
+ * MCP tool for promoting high-confidence learned behaviors into reusable skills/agents.
4
+ * Behaviors at confidence >= 0.85 are flagged as promotion candidates.
5
+ *
6
+ * Clustering: behaviors with overlapping trigger keywords are grouped into
7
+ * a single skill with multiple actions, keeping the agent catalog focused.
8
+ */
9
+ import { z } from 'zod';
10
+ /** Promotion confidence threshold — behaviors above this are ready */
11
+ const PROMOTION_THRESHOLD = 0.85;
12
+ // ── Clustering helpers ───────────────────────────────────────────────────────
13
+ /**
14
+ * Extract meaningful keywords from pattern text.
15
+ * Strips stop words and short tokens.
16
+ */
17
+ function extractKeywords(text) {
18
+ const STOP_WORDS = new Set([
19
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
20
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'should',
21
+ 'can', 'could', 'may', 'might', 'must', 'shall', 'to', 'of', 'in',
22
+ 'on', 'at', 'by', 'for', 'with', 'about', 'and', 'or', 'but', 'not',
23
+ 'this', 'that', 'these', 'those', 'it', 'its', 'user', 'always',
24
+ 'when', 'after', 'before', 'if', 'then', 'any', 'all', 'new',
25
+ ]);
26
+ return text
27
+ .toLowerCase()
28
+ .replace(/[^a-z0-9\s\/\-_]/g, ' ')
29
+ .split(/\s+/)
30
+ .filter(w => w.length > 2 && !STOP_WORDS.has(w));
31
+ }
32
+ /**
33
+ * Compute Jaccard similarity between two keyword sets.
34
+ * Returns 0–1 where 1 = identical.
35
+ */
36
+ function jaccardSimilarity(a, b) {
37
+ const setA = new Set(a);
38
+ const setB = new Set(b);
39
+ const intersection = [...setA].filter(w => setB.has(w));
40
+ const union = new Set([...setA, ...setB]);
41
+ return union.size === 0 ? 0 : intersection.length / union.size;
42
+ }
43
+ /**
44
+ * Cluster behaviors by keyword overlap.
45
+ * Threshold of 0.3 similarity puts behaviors into the same cluster.
46
+ * Single-item clusters remain as standalone skills.
47
+ */
48
+ function clusterBehaviors(behaviors) {
49
+ const SIMILARITY_THRESHOLD = 0.3;
50
+ const keywords = behaviors.map(b => extractKeywords(`${b.pattern} ${b.action} ${b.context ?? ''}`));
51
+ const assigned = new Set();
52
+ const clusters = [];
53
+ for (let i = 0; i < behaviors.length; i++) {
54
+ if (assigned.has(i))
55
+ continue;
56
+ const cluster = {
57
+ behaviors: [behaviors[i]],
58
+ sharedKeywords: keywords[i],
59
+ };
60
+ assigned.add(i);
61
+ for (let j = i + 1; j < behaviors.length; j++) {
62
+ if (assigned.has(j))
63
+ continue;
64
+ const sim = jaccardSimilarity(keywords[i], keywords[j]);
65
+ if (sim >= SIMILARITY_THRESHOLD) {
66
+ cluster.behaviors.push(behaviors[j]);
67
+ // Intersect shared keywords to keep only truly common terms
68
+ const setJ = new Set(keywords[j]);
69
+ cluster.sharedKeywords = cluster.sharedKeywords.filter(w => setJ.has(w));
70
+ assigned.add(j);
71
+ }
72
+ }
73
+ clusters.push(cluster);
74
+ }
75
+ return clusters;
76
+ }
77
+ // ── Skill draft generation ───────────────────────────────────────────────────
78
+ /**
79
+ * Derive a PascalCase skill name from shared keywords.
80
+ */
81
+ function deriveSkillName(cluster) {
82
+ const topWords = cluster.sharedKeywords.slice(0, 3);
83
+ if (topWords.length === 0) {
84
+ // Fallback: use first few words of the primary pattern
85
+ const fallback = extractKeywords(cluster.behaviors[0].pattern).slice(0, 2);
86
+ return fallback.map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('') || 'LearnedSkill';
87
+ }
88
+ return topWords.map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('');
89
+ }
90
+ /**
91
+ * Determine trigger conditions from cluster behavior patterns.
92
+ */
93
+ function deriveTriggers(cluster) {
94
+ if (cluster.behaviors.length === 1) {
95
+ return cluster.behaviors[0].pattern;
96
+ }
97
+ const triggers = cluster.behaviors.map(b => `- ${b.pattern}`).join('\n');
98
+ return `Any of the following:\n${triggers}`;
99
+ }
100
+ /**
101
+ * Determine the context scope for the skill.
102
+ */
103
+ function deriveContext(cluster) {
104
+ const contexts = cluster.behaviors
105
+ .map(b => b.context)
106
+ .filter((c) => Boolean(c));
107
+ if (contexts.length === 0)
108
+ return 'General development tasks';
109
+ if (contexts.length === 1)
110
+ return contexts[0];
111
+ return contexts.join('; ');
112
+ }
113
+ /**
114
+ * Generate a SKILL.md draft from a behavior cluster.
115
+ */
116
+ function generateSkillDraft(cluster) {
117
+ const name = deriveSkillName(cluster);
118
+ const avgConfidence = cluster.behaviors.reduce((s, b) => s + b.confidence, 0) / cluster.behaviors.length;
119
+ const totalApplications = cluster.behaviors.reduce((s, b) => s + b.timesApplied, 0);
120
+ const behaviorIds = cluster.behaviors.map(b => b.id).join(', ');
121
+ const actions = cluster.behaviors.length === 1
122
+ ? cluster.behaviors[0].action
123
+ : cluster.behaviors.map((b, i) => `${i + 1}. ${b.action}`).join('\n');
124
+ const exampleUsage = cluster.behaviors[0].pattern;
125
+ return `---
126
+ name: ${name}
127
+ type: skill
128
+ promoted-from-behaviors: [${behaviorIds}]
129
+ avg-confidence: ${avgConfidence.toFixed(2)}
130
+ total-applications: ${totalApplications}
131
+ created: ${new Date().toISOString().slice(0, 10)}
132
+ ---
133
+
134
+ # ${name}
135
+
136
+ ## Description
137
+ A reusable skill promoted from ${cluster.behaviors.length} learned behavior pattern${cluster.behaviors.length > 1 ? 's' : ''} that proved effective (avg confidence: ${(avgConfidence * 100).toFixed(0)}%).
138
+
139
+ ## Trigger Conditions
140
+ ${deriveTriggers(cluster)}
141
+
142
+ ## Actions
143
+ ${actions}
144
+
145
+ ## Context / Scope
146
+ ${deriveContext(cluster)}
147
+
148
+ ## Example Usage
149
+ > "${exampleUsage}"
150
+ ${cluster.behaviors.length > 1 ? '\n## Source Behaviors\n' + cluster.behaviors.map(b => `- **${b.pattern}** → ${b.action} _(confidence: ${b.confidence})_`).join('\n') : ''}
151
+
152
+ ## Notes
153
+ - Promoted from learned behaviors — edit to refine trigger conditions or actions.
154
+ - Re-save to the agent catalog via merlin_promote_behavior if you make changes.
155
+ `;
156
+ }
157
+ // ── Tool registration ────────────────────────────────────────────────────────
158
+ export function registerPromoteTools(ctx) {
159
+ const { server, client, resolveRepoId } = ctx;
160
+ // ── DEFERRED tool: loaded on-demand for skill promotion workflow ──────────
161
+ // Tool: merlin_promote_behavior
162
+ server.tool('merlin_promote_behavior', 'Promote a learned behavior into a reusable skill or agent. Use when a behavior pattern has proven effective (confidence >= 0.85) and should become a permanent tool. Generates SKILL.md from behavior data. Accepts a behavior ID or a pattern keyword to find matching candidates. Related behaviors are automatically clustered into a single skill. Returns the draft for user review.', {
163
+ behaviorId: z.string().optional().describe('ID of the specific behavior to promote'),
164
+ patternKeyword: z.string().optional().describe('Keyword to search for in behavior patterns (if no ID)'),
165
+ approved: z.boolean().optional().describe('Set true to finalize and save the skill draft (after reviewing)'),
166
+ skillDraft: z.string().optional().describe('Edited skill draft to save (used with approved=true)'),
167
+ repoUrl: z.string().optional().describe('GitHub URL of the repository'),
168
+ }, async ({ behaviorId, patternKeyword, approved, skillDraft, repoUrl }) => {
169
+ try {
170
+ const repoId = await resolveRepoId(repoUrl);
171
+ if (!repoId) {
172
+ return {
173
+ content: [{ type: 'text', text: 'Could not find repository. Select a repo first.' }],
174
+ isError: true,
175
+ };
176
+ }
177
+ // ── Approval path: save an already-reviewed draft ──────────────────
178
+ if (approved && skillDraft) {
179
+ // Extract skill name from frontmatter for a stable filename
180
+ const nameMatch = skillDraft.match(/^name:\s*(.+)$/m);
181
+ const skillName = nameMatch ? nameMatch[1].trim() : `promoted-skill-${Date.now()}`;
182
+ const fileName = `${skillName.toLowerCase().replace(/[^a-z0-9]+/g, '-')}.md`;
183
+ // Extract description from the draft body
184
+ const descSection = skillDraft.split('## Description\n')[1];
185
+ const description = descSection
186
+ ? descSection.split('\n\n')[0]?.trim() ?? skillName
187
+ : skillName;
188
+ // Persist skill via Sights discovery endpoint.
189
+ // We encode the full SKILL.md as the "summary" and tag the query so it's
190
+ // retrievable later with merlin_get_context("skill: <name>").
191
+ await client.saveDiscovery(repoId, {
192
+ query: `skill: ${skillName}`,
193
+ summary: skillDraft,
194
+ patterns: [`promoted-skill`, `skill:${skillName}`, fileName],
195
+ relatedTopics: ['skills', 'promoted-behaviors', 'agent-catalog'],
196
+ agentId: 'merlin-promote',
197
+ });
198
+ let response = `# Skill Saved: ${skillName}\n\n`;
199
+ response += `${description}\n\n`;
200
+ response += `**Catalog file:** ${fileName}\n`;
201
+ response += `**Retrievable via:** merlin_get_context("skill: ${skillName}")\n`;
202
+ response += `\nThe skill is now part of this project's Sights index.`;
203
+ return { content: [{ type: 'text', text: response }] };
204
+ }
205
+ // ── Discovery path: find and draft the skill ───────────────────────
206
+ const allResult = await client.getBehaviors(repoId, { minConfidence: PROMOTION_THRESHOLD });
207
+ const candidates = allResult.behaviors;
208
+ if (candidates.length === 0) {
209
+ return {
210
+ content: [{
211
+ type: 'text',
212
+ text: `No behaviors have reached the promotion threshold (confidence >= ${PROMOTION_THRESHOLD}) yet.\n\nKeep applying behaviors — confidence grows by +0.05 per successful application.`,
213
+ }],
214
+ };
215
+ }
216
+ // Filter to the requested behavior or keyword
217
+ let selected = candidates;
218
+ if (behaviorId) {
219
+ selected = candidates.filter(b => b.id === behaviorId);
220
+ if (selected.length === 0) {
221
+ return {
222
+ content: [{ type: 'text', text: `Behavior "${behaviorId}" not found or has not reached confidence >= ${PROMOTION_THRESHOLD}.` }],
223
+ isError: true,
224
+ };
225
+ }
226
+ }
227
+ else if (patternKeyword) {
228
+ const kw = patternKeyword.toLowerCase();
229
+ selected = candidates.filter(b => b.pattern.toLowerCase().includes(kw) ||
230
+ b.action.toLowerCase().includes(kw) ||
231
+ (b.context ?? '').toLowerCase().includes(kw));
232
+ if (selected.length === 0) {
233
+ return {
234
+ content: [{ type: 'text', text: `No promotion-ready behaviors matched keyword "${patternKeyword}".` }],
235
+ };
236
+ }
237
+ }
238
+ // Cluster and generate drafts
239
+ const clusters = clusterBehaviors(selected);
240
+ const drafts = clusters.map(generateSkillDraft);
241
+ let response = `# Skill Promotion Draft${drafts.length > 1 ? 's' : ''}\n\n`;
242
+ response += `Found **${selected.length}** promotion-ready behavior${selected.length > 1 ? 's' : ''} clustered into **${clusters.length}** skill${clusters.length > 1 ? 's' : ''}.\n\n`;
243
+ response += `---\n\n`;
244
+ drafts.forEach((draft, i) => {
245
+ const cluster = clusters[i];
246
+ response += `## Draft ${i + 1}${drafts.length > 1 ? ` of ${drafts.length}` : ''}\n`;
247
+ if (cluster.behaviors.length > 1) {
248
+ response += `_Clusters ${cluster.behaviors.length} related behaviors._\n`;
249
+ }
250
+ response += `\n\`\`\`markdown\n${draft}\n\`\`\`\n\n`;
251
+ });
252
+ response += `---\n`;
253
+ response += `**To save:** Call merlin_promote_behavior again with:\n`;
254
+ response += `- \`approved: true\`\n`;
255
+ response += `- \`skillDraft\`: the markdown above (edit first if needed)\n`;
256
+ return { content: [{ type: 'text', text: response }] };
257
+ }
258
+ catch (error) {
259
+ return {
260
+ content: [{ type: 'text', text: `Error in promote_behavior: ${error instanceof Error ? error.message : 'Unknown'}` }],
261
+ isError: true,
262
+ };
263
+ }
264
+ });
265
+ // ── DEFERRED tool: list all promotion candidates ──────────────────────────
266
+ // Tool: merlin_list_promotion_candidates
267
+ server.tool('merlin_list_promotion_candidates', 'List all learned behaviors that have reached the promotion threshold (confidence >= 0.85) and are ready to become permanent skills. Shows behavior ID, pattern, confidence, and application count. Use before running /merlin:promote to see what is available.', {
268
+ repoUrl: z.string().optional().describe('GitHub URL of the repository'),
269
+ }, async ({ repoUrl }) => {
270
+ try {
271
+ const repoId = await resolveRepoId(repoUrl);
272
+ if (!repoId) {
273
+ return {
274
+ content: [{ type: 'text', text: 'Could not find repository. Select a repo first.' }],
275
+ isError: true,
276
+ };
277
+ }
278
+ const result = await client.getBehaviors(repoId, { minConfidence: PROMOTION_THRESHOLD });
279
+ const candidates = result.behaviors;
280
+ if (candidates.length === 0) {
281
+ return {
282
+ content: [{
283
+ type: 'text',
284
+ text: `No behaviors have reached the promotion threshold yet (confidence >= ${PROMOTION_THRESHOLD}).\n\nCurrent highest-confidence behaviors:\n_Run merlin_get_behaviors to see all patterns._`,
285
+ }],
286
+ };
287
+ }
288
+ let response = `# Promotion Candidates\n\n`;
289
+ response += `_${candidates.length} behavior${candidates.length > 1 ? 's' : ''} ready for promotion (confidence >= ${PROMOTION_THRESHOLD})_\n\n`;
290
+ candidates.forEach((b, i) => {
291
+ response += `### ${i + 1}. ${b.pattern}\n`;
292
+ response += `**ID:** \`${b.id}\`\n`;
293
+ response += `**Action:** ${b.action}\n`;
294
+ if (b.context)
295
+ response += `**Context:** ${b.context}\n`;
296
+ response += `**Confidence:** ${b.confidence} | **Applied:** ${b.timesApplied}x | **Corrected:** ${b.timesCorrected}x\n\n`;
297
+ });
298
+ // Show clustering preview
299
+ const clusters = clusterBehaviors(candidates);
300
+ if (clusters.length < candidates.length) {
301
+ response += `---\n`;
302
+ response += `_These ${candidates.length} behaviors will be clustered into ${clusters.length} skill${clusters.length > 1 ? 's' : ''} on promotion._\n`;
303
+ }
304
+ response += `\nRun \`/merlin:promote\` or call \`merlin_promote_behavior\` to generate skill drafts.`;
305
+ return { content: [{ type: 'text', text: response }] };
306
+ }
307
+ catch (error) {
308
+ return {
309
+ content: [{ type: 'text', text: `Error listing candidates: ${error instanceof Error ? error.message : 'Unknown'}` }],
310
+ isError: true,
311
+ };
312
+ }
313
+ });
314
+ }
315
+ //# sourceMappingURL=promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promote.js","sourceRoot":"","sources":["../../../src/server/tools/promote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Route Helpers — Agent frontmatter parsing, effort levels, and role constants.
3
+ *
4
+ * Extracted from route.ts to keep the main routing file focused on
5
+ * tool registration and orchestration logic.
6
+ */
7
+ /** Valid effort levels for agent definitions */
8
+ export type EffortLevel = 'high' | 'medium' | 'low';
9
+ /** Valid isolation modes for agent definitions */
10
+ export type IsolationMode = 'worktree' | null;
11
+ /**
12
+ * Parse the YAML frontmatter block from an agent .md file.
13
+ * Returns the raw frontmatter string or null if not present.
14
+ */
15
+ export declare function parseFrontmatter(agentPath: string): string | null;
16
+ /**
17
+ * Read the effort field from an agent's .md frontmatter.
18
+ * Returns 'medium' as the safe default if not found or unreadable.
19
+ */
20
+ export declare function readAgentEffort(agentPath: string): EffortLevel;
21
+ /**
22
+ * Read the isolation field from an agent's .md frontmatter.
23
+ * Returns 'worktree' if isolation: worktree is set, otherwise null.
24
+ */
25
+ export declare function readAgentIsolation(agentPath: string): IsolationMode;
26
+ /**
27
+ * Read the background field from an agent's .md frontmatter.
28
+ * Returns true if background: true is set.
29
+ */
30
+ export declare function readAgentBackground(agentPath: string): boolean;
31
+ /**
32
+ * Build the task prompt prefix based on effort level.
33
+ * - high: prepend ultrathink for deep reasoning
34
+ * - low: append concise note to avoid unnecessary exploration
35
+ * - medium: no prefix (default behavior)
36
+ */
37
+ export declare function buildEffortPrefix(effort: EffortLevel): {
38
+ prefix: string;
39
+ suffix: string;
40
+ };
41
+ /** Known specialist agents and their roles */
42
+ export declare const AGENT_ROLES: Record<string, string>;
43
+ /** Merlin internal workflow agents */
44
+ export declare const WORKFLOW_AGENTS: string[];
45
+ //# sourceMappingURL=route-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../../src/server/tools/route-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEpD,kDAAkD;AAClD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,IAAI,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAM9D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAKnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAWzF;AAED,8CAA8C;AAC9C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAS9C,CAAC;AAEF,sCAAsC;AACtC,eAAO,MAAM,eAAe,UAM3B,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Route Helpers — Agent frontmatter parsing, effort levels, and role constants.
3
+ *
4
+ * Extracted from route.ts to keep the main routing file focused on
5
+ * tool registration and orchestration logic.
6
+ */
7
+ import { readFileSync } from 'fs';
8
+ /**
9
+ * Parse the YAML frontmatter block from an agent .md file.
10
+ * Returns the raw frontmatter string or null if not present.
11
+ */
12
+ export function parseFrontmatter(agentPath) {
13
+ try {
14
+ const content = readFileSync(agentPath, 'utf-8');
15
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
16
+ return match ? match[1] : null;
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ /**
23
+ * Read the effort field from an agent's .md frontmatter.
24
+ * Returns 'medium' as the safe default if not found or unreadable.
25
+ */
26
+ export function readAgentEffort(agentPath) {
27
+ const frontmatter = parseFrontmatter(agentPath);
28
+ if (!frontmatter)
29
+ return 'medium';
30
+ const match = frontmatter.match(/^effort:\s*(high|medium|low)\s*$/m);
31
+ if (!match)
32
+ return 'medium';
33
+ return match[1];
34
+ }
35
+ /**
36
+ * Read the isolation field from an agent's .md frontmatter.
37
+ * Returns 'worktree' if isolation: worktree is set, otherwise null.
38
+ */
39
+ export function readAgentIsolation(agentPath) {
40
+ const frontmatter = parseFrontmatter(agentPath);
41
+ if (!frontmatter)
42
+ return null;
43
+ const match = frontmatter.match(/^isolation:\s*(worktree)\s*$/m);
44
+ return match ? match[1] : null;
45
+ }
46
+ /**
47
+ * Read the background field from an agent's .md frontmatter.
48
+ * Returns true if background: true is set.
49
+ */
50
+ export function readAgentBackground(agentPath) {
51
+ const frontmatter = parseFrontmatter(agentPath);
52
+ if (!frontmatter)
53
+ return false;
54
+ return /^background:\s*true\s*$/m.test(frontmatter);
55
+ }
56
+ /**
57
+ * Build the task prompt prefix based on effort level.
58
+ * - high: prepend ultrathink for deep reasoning
59
+ * - low: append concise note to avoid unnecessary exploration
60
+ * - medium: no prefix (default behavior)
61
+ */
62
+ export function buildEffortPrefix(effort) {
63
+ if (effort === 'high') {
64
+ return { prefix: 'ultrathink\n\n', suffix: '' };
65
+ }
66
+ if (effort === 'low') {
67
+ return {
68
+ prefix: '',
69
+ suffix: '\n\n> **Note:** Be concise and efficient. Focus on output over exploration.',
70
+ };
71
+ }
72
+ return { prefix: '', suffix: '' };
73
+ }
74
+ /** Known specialist agents and their roles */
75
+ export const AGENT_ROLES = {
76
+ 'product-spec': 'Feature specification and product definition',
77
+ 'system-architect': 'Architecture decisions and system design',
78
+ 'implementation-dev': 'Code implementation and feature building',
79
+ 'dry-refactor': 'Code cleanup, DRY refactoring, file organization',
80
+ 'hardening-guard': 'Security hardening, input validation, error handling',
81
+ 'tests-qa': 'Testing and quality assurance',
82
+ 'ops-railway': 'Deployment, ops, Railway, Google Cloud',
83
+ 'docs-keeper': 'Documentation updates',
84
+ };
85
+ /** Merlin internal workflow agents */
86
+ export const WORKFLOW_AGENTS = [
87
+ 'merlin-planner', 'merlin-executor', 'merlin-codebase-mapper',
88
+ 'merlin-debugger', 'merlin-researcher', 'merlin-reviewer',
89
+ 'merlin-work-verifier', 'merlin-milestone-auditor',
90
+ 'merlin-frontend', 'merlin-api-designer', 'merlin-security',
91
+ 'merlin-performance', 'merlin-migrator', 'merlin-integration-checker',
92
+ ];
93
+ //# sourceMappingURL=route-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-helpers.js","sourceRoot":"","sources":["../../../src/server/tools/route-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAQlC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,QAAQ,CAAC;IAClC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACrE,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,OAAO,KAAK,CAAC,CAAC,CAAgB,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,CAAC,CAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO;YACL,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,6EAA6E;SACtF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACpC,CAAC;AAED,8CAA8C;AAC9C,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,cAAc,EAAE,8CAA8C;IAC9D,kBAAkB,EAAE,0CAA0C;IAC9D,oBAAoB,EAAE,0CAA0C;IAChE,cAAc,EAAE,kDAAkD;IAClE,iBAAiB,EAAE,sDAAsD;IACzE,UAAU,EAAE,+BAA+B;IAC3C,aAAa,EAAE,wCAAwC;IACvD,aAAa,EAAE,uBAAuB;CACvC,CAAC;AAEF,sCAAsC;AACtC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB;IAC7D,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB;IACzD,sBAAsB,EAAE,0BAA0B;IAClD,iBAAiB,EAAE,qBAAqB,EAAE,iBAAiB;IAC3D,oBAAoB,EAAE,iBAAiB,EAAE,4BAA4B;CACtE,CAAC"}
@@ -7,9 +7,10 @@
7
7
  *
8
8
  * 1. Verifies agent exists
9
9
  * 2. Fetches Sights context for the task
10
- * 3. Builds structured handoff
11
- * 4. Spawns a fresh `claude --agent <name> -p` process
12
- * 5. Captures and returns the result
10
+ * 3. Discovers cloud agent augmentation
11
+ * 4. Builds structured handoff with domain expertise
12
+ * 5. Spawns a fresh `claude --agent <name> -p` process
13
+ * 6. Captures and returns the result
13
14
  *
14
15
  * Claude just calls `merlin_route(agent, task)` — no bash generation needed.
15
16
  */
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../src/server/tools/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA2M9C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,QAgRlD"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../src/server/tools/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAY9C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,QAoLlD"}