create-merlin-brain 5.3.4 → 5.3.7
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 +21 -8
- package/dist/server/tools/route-helpers.d.ts +6 -1
- package/dist/server/tools/route-helpers.d.ts.map +1 -1
- package/dist/server/tools/route-helpers.js +61 -3
- package/dist/server/tools/route-helpers.js.map +1 -1
- package/files/CLAUDE.md +13 -1
- package/files/agents/android-expert.md +9 -0
- package/files/agents/animation-expert.md +9 -0
- package/files/agents/apple-swift-expert.md +9 -0
- package/files/agents/desktop-app-expert.md +9 -0
- package/files/agents/marketing-automation.md +9 -0
- package/files/agents/orchestrator.md +8 -0
- package/files/agents/ui-builder.md +9 -0
- package/files/agents/ui-designer.md +9 -0
- package/files/commands/merlin/install.md +49 -0
- package/files/merlin/skills/TASK-OPTIMIZER.json +45 -0
- package/files/merlin-system-prompt.txt +3 -1
- package/files/rules/merlin-routing.md +35 -0
- package/files/scripts/duo-codex-call.sh +29 -10
- package/files/scripts/duo-mode-read.sh +7 -2
- package/files/scripts/task-optimize.sh +8 -0
- package/package.json +1 -1
package/bin/install.cjs
CHANGED
|
@@ -1557,6 +1557,10 @@ async function install() {
|
|
|
1557
1557
|
try {
|
|
1558
1558
|
claudeDirConfig = JSON.parse(fs.readFileSync(claudeDirDesktopConfig, 'utf8'));
|
|
1559
1559
|
} catch (e) {
|
|
1560
|
+
// Backup the malformed file before overwriting
|
|
1561
|
+
const bakPath = claudeDirDesktopConfig + '.bak.' + Date.now();
|
|
1562
|
+
fs.copyFileSync(claudeDirDesktopConfig, bakPath);
|
|
1563
|
+
logWarn(`Config file malformed, backed up to ${bakPath} before overwriting`);
|
|
1560
1564
|
claudeDirConfig = {};
|
|
1561
1565
|
}
|
|
1562
1566
|
}
|
|
@@ -1575,7 +1579,14 @@ async function install() {
|
|
|
1575
1579
|
fs.writeFileSync(claudeJsonPath, JSON.stringify(claudeJson, null, 2));
|
|
1576
1580
|
logSuccess('Merlin Sights configured for ~/.claude.json (Claude MCP registry)');
|
|
1577
1581
|
} catch (e) {
|
|
1578
|
-
|
|
1582
|
+
// Backup the malformed file before overwriting
|
|
1583
|
+
const bakPath = claudeJsonPath + '.bak.' + Date.now();
|
|
1584
|
+
fs.copyFileSync(claudeJsonPath, bakPath);
|
|
1585
|
+
logWarn(`Config file malformed, backed up to ${bakPath} before overwriting`);
|
|
1586
|
+
// Create with minimal config
|
|
1587
|
+
const claudeJson = { mcpServers: { merlin: mcpConfig(apiKey, true) } };
|
|
1588
|
+
fs.writeFileSync(claudeJsonPath, JSON.stringify(claudeJson, null, 2));
|
|
1589
|
+
logWarn('Could not update ~/.claude.json - created minimal config with backup');
|
|
1579
1590
|
}
|
|
1580
1591
|
} else {
|
|
1581
1592
|
// Create ~/.claude.json with MCP config if it doesn't exist
|
|
@@ -1739,13 +1750,15 @@ ${colors.cyan}Universal Task Optimization (NEW in 5.3.0):${colors.reset}
|
|
|
1739
1750
|
• ${colors.bright}/merlin:polish${colors.reset} - Animation polish via animation-expert
|
|
1740
1751
|
• ${colors.bright}/merlin:redesign${colors.reset} - Full redesign via ui-builder
|
|
1741
1752
|
|
|
1742
|
-
${colors.cyan}
|
|
1743
|
-
•
|
|
1744
|
-
•
|
|
1745
|
-
•
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
•
|
|
1753
|
+
${colors.cyan}Attribution hardening (NEW in 5.3.6):${colors.reset}
|
|
1754
|
+
• All shipped agents now carry provenance frontmatter (source + license + import date)
|
|
1755
|
+
• check-provenance.js now requires every agent to declare provenance
|
|
1756
|
+
• Unknown-origin agents documented in NOTICE.md (attribution pending — see issue tracker)
|
|
1757
|
+
|
|
1758
|
+
${colors.cyan}Discovery-first (NEW in 5.3.7):${colors.reset}
|
|
1759
|
+
• Brain now proactively searches 1000+ community agents before routing
|
|
1760
|
+
• ${colors.bright}/merlin:install <slug>${colors.reset} - One-keystroke install of any catalog agent
|
|
1761
|
+
• smart_route + discover_agents wired into the orchestrator protocol
|
|
1749
1762
|
|
|
1750
1763
|
${colors.cyan}Merlin works with or without Sights:${colors.reset}
|
|
1751
1764
|
• ${colors.green}With Sights${colors.reset}: Instant context, cross-session memory
|
|
@@ -38,7 +38,12 @@ export declare function buildEffortPrefix(effort: EffortLevel): {
|
|
|
38
38
|
prefix: string;
|
|
39
39
|
suffix: string;
|
|
40
40
|
};
|
|
41
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Read live agent roles from ~/.claude/agents/*.md files.
|
|
43
|
+
* Caches the result after first access.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getAgentRoles(): Record<string, string>;
|
|
46
|
+
/** Known specialist agents and their roles (live from disk, with fallback) */
|
|
42
47
|
export declare const AGENT_ROLES: Record<string, string>;
|
|
43
48
|
/** Merlin internal workflow agents */
|
|
44
49
|
export declare const WORKFLOW_AGENTS: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../../src/server/tools/route-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../../src/server/tools/route-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,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;AAkCD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA+BtD;AAED,8EAA8E;AAC9E,eAAO,MAAM,WAAW,wBAAkB,CAAC;AAE3C,sCAAsC;AACtC,eAAO,MAAM,eAAe,UAM3B,CAAC"}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* Extracted from route.ts to keep the main routing file focused on
|
|
5
5
|
* tool registration and orchestration logic.
|
|
6
6
|
*/
|
|
7
|
-
import { readFileSync } from 'fs';
|
|
7
|
+
import { readFileSync, readdirSync, existsSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
8
10
|
/**
|
|
9
11
|
* Parse the YAML frontmatter block from an agent .md file.
|
|
10
12
|
* Returns the raw frontmatter string or null if not present.
|
|
@@ -71,8 +73,8 @@ export function buildEffortPrefix(effort) {
|
|
|
71
73
|
}
|
|
72
74
|
return { prefix: '', suffix: '' };
|
|
73
75
|
}
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
+
/** Fallback specialist agents (used if agent files not readable) */
|
|
77
|
+
const FALLBACK_AGENT_ROLES = {
|
|
76
78
|
'product-spec': 'Feature specification and product definition',
|
|
77
79
|
'system-architect': 'Architecture decisions and system design',
|
|
78
80
|
'implementation-dev': 'Code implementation and feature building',
|
|
@@ -82,6 +84,62 @@ export const AGENT_ROLES = {
|
|
|
82
84
|
'ops-railway': 'Deployment, ops, Railway, Google Cloud',
|
|
83
85
|
'docs-keeper': 'Documentation updates',
|
|
84
86
|
};
|
|
87
|
+
/** Cache for agent roles read from disk */
|
|
88
|
+
let agentRolesCache = null;
|
|
89
|
+
/**
|
|
90
|
+
* Extract agent description from .md file frontmatter.
|
|
91
|
+
* Looks for 'description:' field in YAML frontmatter.
|
|
92
|
+
*/
|
|
93
|
+
function extractDescription(agentPath) {
|
|
94
|
+
try {
|
|
95
|
+
const content = readFileSync(agentPath, 'utf-8');
|
|
96
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
97
|
+
if (!match)
|
|
98
|
+
return null;
|
|
99
|
+
const fm = match[1];
|
|
100
|
+
const descMatch = fm.match(/^description:\s*["']([^"']*?)["']\s*$/m);
|
|
101
|
+
return descMatch ? descMatch[1] : null;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Read live agent roles from ~/.claude/agents/*.md files.
|
|
109
|
+
* Caches the result after first access.
|
|
110
|
+
*/
|
|
111
|
+
export function getAgentRoles() {
|
|
112
|
+
if (agentRolesCache)
|
|
113
|
+
return agentRolesCache;
|
|
114
|
+
const roles = {};
|
|
115
|
+
const agentsDir = join(homedir(), '.claude', 'agents');
|
|
116
|
+
if (existsSync(agentsDir)) {
|
|
117
|
+
try {
|
|
118
|
+
const files = readdirSync(agentsDir).filter(f => f.endsWith('.md'));
|
|
119
|
+
for (const file of files) {
|
|
120
|
+
const agentName = file.replace('.md', '');
|
|
121
|
+
const filePath = join(agentsDir, file);
|
|
122
|
+
const desc = extractDescription(filePath);
|
|
123
|
+
if (desc) {
|
|
124
|
+
roles[agentName] = desc;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Fall back to hardcoded defaults
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Merge with fallback defaults (fallback wins for missing entries)
|
|
133
|
+
for (const [name, role] of Object.entries(FALLBACK_AGENT_ROLES)) {
|
|
134
|
+
if (!roles[name]) {
|
|
135
|
+
roles[name] = role;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
agentRolesCache = roles;
|
|
139
|
+
return roles;
|
|
140
|
+
}
|
|
141
|
+
/** Known specialist agents and their roles (live from disk, with fallback) */
|
|
142
|
+
export const AGENT_ROLES = getAgentRoles();
|
|
85
143
|
/** Merlin internal workflow agents */
|
|
86
144
|
export const WORKFLOW_AGENTS = [
|
|
87
145
|
'merlin-planner', 'merlin-executor', 'merlin-codebase-mapper',
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"route-helpers.js","sourceRoot":"","sources":["../../../src/server/tools/route-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAQ7B;;;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,oEAAoE;AACpE,MAAM,oBAAoB,GAA2B;IACnD,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,4CAA4C;AAC5C,IAAI,eAAe,GAAkC,IAAI,CAAC;AAE1D;;;GAGG;AACH,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,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,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACrE,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,eAAe;QAAE,OAAO,eAAe,CAAC;IAE5C,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEvD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACvC,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,IAAI,EAAE,CAAC;oBACT,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,eAAe,GAAG,KAAK,CAAC;IACxB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC;AAE3C,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"}
|
package/files/CLAUDE.md
CHANGED
|
@@ -53,11 +53,23 @@ Do NOT spawn Explore agents or run Glob/Grep for codebase questions. Use Sights
|
|
|
53
53
|
|
|
54
54
|
Never just dump an agent result and go silent. Always follow through.
|
|
55
55
|
|
|
56
|
+
## Discovery-First Routing (1000+ community agents)
|
|
57
|
+
|
|
58
|
+
Before routing any non-trivial task to a built-in specialist, proactively check the community catalog:
|
|
59
|
+
|
|
60
|
+
1. Call `merlin_smart_route(task="<full user text>")` to score both built-in and catalog agents.
|
|
61
|
+
2. If a catalog match (Grade A+ or A) scores higher than built-in options, surface it to the user.
|
|
62
|
+
3. Example: "⟡🔮 MERLIN › Found a community agent: **Payment Integration** (Grade A). Install with `/merlin:install payment-integration`, or use built-in implementation-dev?"
|
|
63
|
+
4. Wait for user choice — never auto-install without confirmation.
|
|
64
|
+
5. Use `/merlin:install <slug>` to install, or the user can describe what they want and Merlin will auto-route.
|
|
65
|
+
|
|
66
|
+
Skip discovery for: trivial edits (single file, comment, rename), debug runs, doc updates, or when user explicitly names an agent.
|
|
67
|
+
|
|
56
68
|
## Execution
|
|
57
69
|
|
|
58
70
|
Run independent agents in PARALLEL. Never sequential when parallel is possible.
|
|
59
71
|
NEVER run `claude --agent` via Bash. Always use `Skill("merlin:route")` or `merlin_route()`.
|
|
60
|
-
For ANY routing, call `merlin_smart_route(task="...")` FIRST to check
|
|
72
|
+
For ANY routing, call `merlin_smart_route(task="...")` FIRST to check community agents + built-ins.
|
|
61
73
|
|
|
62
74
|
## Learning
|
|
63
75
|
|
|
@@ -3,6 +3,15 @@ name: android-expert
|
|
|
3
3
|
description: Full-lifecycle Android agent — implements, refactors, architects, tests, and hardens Kotlin, Jetpack Compose, Material Design 3, and Android apps.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: green
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -3,6 +3,15 @@ name: animation-expert
|
|
|
3
3
|
description: Full-lifecycle animation agent — builds, refactors, architects, tests, and hardens animations with Motion, GSAP, CSS, and 60fps performance.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: violet
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -3,6 +3,15 @@ name: apple-swift-expert
|
|
|
3
3
|
description: Full-lifecycle Apple platform agent — implements, refactors, architects, tests, and hardens Swift 6, SwiftUI, AppKit, iOS and macOS code.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: blue
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -3,6 +3,15 @@ name: desktop-app-expert
|
|
|
3
3
|
description: Full-lifecycle desktop app agent — implements, refactors, architects, tests, and hardens Electron and Tauri apps with IPC security and cross-platform distribution.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: cyan
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -3,6 +3,15 @@ name: marketing-automation
|
|
|
3
3
|
description: Full-lifecycle marketing engineering agent — builds, refactors, architects, tests, and hardens email campaigns, drip sequences, A/B tests, and analytics.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: red
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -3,6 +3,14 @@ name: orchestrator
|
|
|
3
3
|
description: Master router for a vibe coder building serious, production-leaning systems. Always choose and coordinate the right specialist agent instead of doing work yourself.
|
|
4
4
|
model: opus
|
|
5
5
|
color: red
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-01-22"
|
|
10
|
+
license: unknown
|
|
11
|
+
license_verification: unconfirmed
|
|
12
|
+
adapted: "Vendored as-is from local cache on 2026-01-22. No modifications beyond Merlin integration."
|
|
13
|
+
note: "Imported on 2026-01-22 from an unidentified source (different style than the Feb 4 batch). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
You are the orchestrator for a very strong product thinker and vibe coder who uses Claude Code as their main dev environment.
|
|
@@ -3,6 +3,15 @@ name: ui-builder
|
|
|
3
3
|
description: Full-lifecycle UI engineering agent — builds, refactors, architects, tests, and hardens React components with Tailwind, shadcn/ui, and Radix.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: orange
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -3,6 +3,15 @@ name: ui-designer
|
|
|
3
3
|
description: Full-lifecycle design agent — creates, refactors, architects, audits, and hardens design systems, accessibility, tokens, and component specs.
|
|
4
4
|
model: sonnet
|
|
5
5
|
color: pink
|
|
6
|
+
provenance:
|
|
7
|
+
upstream: unknown-origin/vendored-agents-feb2026
|
|
8
|
+
source: unknown
|
|
9
|
+
imported_date: "2026-02-04"
|
|
10
|
+
style_signature: "Full-lifecycle X agent — builds, refactors, architects, tests, and hardens"
|
|
11
|
+
license: unknown
|
|
12
|
+
license_verification: unconfirmed
|
|
13
|
+
adapted: "Vendored as-is from local cache on 2026-02-04. No modifications beyond Merlin integration."
|
|
14
|
+
note: "Imported in batch on 2026-02-04 from an unidentified source. Style is consistent with a single author/tool but no public catalog match was found (checked wshobson/agents, VoltAgent/awesome-claude-code-subagents). Curated, integrated, and shipped via create-merlin-brain. If you recognize this as your work, please open an issue at https://github.com/sandman66666/merlin and we'll update attribution."
|
|
6
15
|
---
|
|
7
16
|
|
|
8
17
|
<role>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: merlin:install
|
|
3
|
+
description: Install a community agent/skill from the Merlin catalog by slug. Wraps `npx skills add` and similar install commands per the agent's metadata.
|
|
4
|
+
argument-hint: "<slug> — agent slug from merlin_discover_agents (e.g., 'payment-integration')"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash
|
|
7
|
+
- Read
|
|
8
|
+
- mcp__merlin__merlin_get_agent_detail
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<objective>
|
|
12
|
+
Install a community agent or skill from the Merlin catalog into the user's local Claude environment.
|
|
13
|
+
</objective>
|
|
14
|
+
|
|
15
|
+
## Steps
|
|
16
|
+
|
|
17
|
+
1. Read the agent detail via `merlin_get_agent_detail(slug="$ARGUMENTS")` to get the install command and source.
|
|
18
|
+
|
|
19
|
+
2. Show the user what's about to be installed:
|
|
20
|
+
- Name, grade, description
|
|
21
|
+
- Install command from agent metadata
|
|
22
|
+
- Source repo URL
|
|
23
|
+
Then ask explicit confirmation: "Install <name>? (Y/N)"
|
|
24
|
+
|
|
25
|
+
3. On YES, run the install command:
|
|
26
|
+
- If it starts with `npx skills add`: `bash -c "<install_command>"`
|
|
27
|
+
- If it starts with `npm install`: `bash -c "<install_command>"` (in cwd or globally based on agent type)
|
|
28
|
+
- If unknown: surface the command and tell user to run it manually
|
|
29
|
+
|
|
30
|
+
4. After install, verify the agent is now reachable:
|
|
31
|
+
- For Claude agents: check `~/.claude/agents/<slug>.md` exists
|
|
32
|
+
- For skills: check `~/.claude/skills/<slug>/SKILL.md` exists
|
|
33
|
+
- Otherwise: trust the install command's exit code
|
|
34
|
+
|
|
35
|
+
5. Surface a usage hint: "Installed <name>. Use via `merlin_route(agent=\"<name>\", task=\"...\")` or just describe what you want — Merlin will route to it."
|
|
36
|
+
|
|
37
|
+
## Safety
|
|
38
|
+
|
|
39
|
+
- NEVER run install commands without explicit user Y confirmation.
|
|
40
|
+
- NEVER pipe install commands through eval or shell injection unsafe channels.
|
|
41
|
+
- If the install command from the catalog looks suspicious (contains `curl | sh`, sudo, etc.), refuse and surface the command for manual review.
|
|
42
|
+
- Honor the user's deny list (`~/.claude/settings.json` permissions.deny).
|
|
43
|
+
|
|
44
|
+
## Errors
|
|
45
|
+
|
|
46
|
+
- Slug not found → "Slug `<x>` not found. Try `merlin_discover_agents(query=\"...\")` to search."
|
|
47
|
+
- No install command in metadata → "This agent doesn't have an automated install. Visit <source_url> for instructions."
|
|
48
|
+
- Install command failed → show stderr, suggest manual run.
|
|
49
|
+
|
|
@@ -298,6 +298,51 @@
|
|
|
298
298
|
"agent": "code-organization-supervisor",
|
|
299
299
|
"intent": "organization",
|
|
300
300
|
"weight": 0.8
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"id": "platform/android",
|
|
304
|
+
"path": "platform/android",
|
|
305
|
+
"triggers": [
|
|
306
|
+
"android", "kotlin", "jetpack compose", "android studio", "google play", "material you",
|
|
307
|
+
"android ui", "android intent", "android activity", "android fragment", "viewmodel"
|
|
308
|
+
],
|
|
309
|
+
"agent": "android-expert",
|
|
310
|
+
"intent": "android",
|
|
311
|
+
"weight": 1.0
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"id": "platform/apple",
|
|
315
|
+
"path": "platform/apple",
|
|
316
|
+
"triggers": [
|
|
317
|
+
"ios", "macos", "swift", "swiftui", "objective-c", "xcode", "uikit", "appkit",
|
|
318
|
+
"iphone", "ipad", "app store", "watchos", "tvos"
|
|
319
|
+
],
|
|
320
|
+
"agent": "apple-swift-expert",
|
|
321
|
+
"intent": "apple",
|
|
322
|
+
"weight": 1.0
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"id": "platform/desktop",
|
|
326
|
+
"path": "platform/desktop",
|
|
327
|
+
"triggers": [
|
|
328
|
+
"electron", "tauri", "desktop app", "system tray", "menu bar app", "native window",
|
|
329
|
+
"ipc", "windows app", "macos app", "linux app"
|
|
330
|
+
],
|
|
331
|
+
"agent": "desktop-app-expert",
|
|
332
|
+
"intent": "desktop",
|
|
333
|
+
"weight": 1.0
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"id": "marketing/automation",
|
|
337
|
+
"path": "marketing/automation",
|
|
338
|
+
"triggers": [
|
|
339
|
+
"email campaign", "drip sequence", "marketing automation", "marketing campaign",
|
|
340
|
+
"email marketing", "mailchimp", "sendgrid", "transactional email", "newsletter",
|
|
341
|
+
"growth marketing", "lifecycle email", "ab test email"
|
|
342
|
+
],
|
|
343
|
+
"agent": "marketing-automation",
|
|
344
|
+
"intent": "marketing",
|
|
345
|
+
"weight": 1.0
|
|
301
346
|
}
|
|
302
347
|
],
|
|
303
348
|
"intent_overrides": {
|
|
@@ -32,4 +32,6 @@ wait
|
|
|
32
32
|
|
|
33
33
|
**Badge:** Always prefix every action with `⟡🔮↔🔮 MERLIN·DUO ›` when duo is on, `⟡🔮 MERLIN ›` when off.
|
|
34
34
|
|
|
35
|
-
TASK OPTIMIZATION: Before EVERY routing decision (workflows, agents, specialists), run ~/.claude/scripts/task-optimize.sh --task "<user text>". It returns {intent, skills[], agent, score, matched_phrases}. If score>=25, ALWAYS announce "⟡🔮 MERLIN › Intent: <X>. Loading <skills> + routing to <agent>." then route with skills prepended to context. Registry: ~/.claude/merlin/skills/TASK-OPTIMIZER.json. Slash commands /merlin:optimize, /merlin:design-audit, /merlin:polish, /merlin:redesign wrap common flows.
|
|
35
|
+
TASK OPTIMIZATION: Before EVERY routing decision (workflows, agents, specialists), run ~/.claude/scripts/task-optimize.sh --task "<user text>". It returns {intent, skills[], agent, score, matched_phrases}. If score>=25, ALWAYS announce "⟡🔮 MERLIN › Intent: <X>. Loading <skills> + routing to <agent>." then route with skills prepended to context. Registry: ~/.claude/merlin/skills/TASK-OPTIMIZER.json. Slash commands /merlin:optimize, /merlin:design-audit, /merlin:polish, /merlin:redesign wrap common flows.
|
|
36
|
+
|
|
37
|
+
DISCOVERY-FIRST: Before routing any non-trivial task to a built-in specialist, call `merlin_smart_route(task="...")` and `merlin_discover_agents(query="...")` to check the community catalog (1000+ indexed agents/skills). If a catalog match scores a higher grade (A+/A++) than the best built-in for the task, surface it: "⟡🔮 MERLIN › I found a community agent that fits better: <name> (Grade: <X>). Install with /merlin:install <slug> or stick with built-in <built-in>?" — then wait for user choice. NEVER install without confirmation. Skip discovery only for: trivial single-file edits, debug runs, doc updates, or when the user explicitly names an agent.
|
|
@@ -55,6 +55,41 @@ Slash commands: `/merlin:optimize`, `/merlin:design-audit`, `/merlin:polish`, `/
|
|
|
55
55
|
|
|
56
56
|
The optimizer is the AUTHORITY. Don't override its recommendations unless the user explicitly asks for a different agent.
|
|
57
57
|
|
|
58
|
+
## Discovery-First Routing (1000+ community agents)
|
|
59
|
+
|
|
60
|
+
The Merlin Sights server indexes 1000+ community agents/skills from GitHub, npm, skills.sh, and other sources. Before routing any non-trivial task to a built-in, ALWAYS check if a better community agent exists.
|
|
61
|
+
|
|
62
|
+
### Protocol
|
|
63
|
+
|
|
64
|
+
For tasks that are NOT trivial (i.e., > 5 minutes of work, or touching a new domain):
|
|
65
|
+
|
|
66
|
+
1. Call `merlin_smart_route(task="<full user text>")` — returns the best match from BOTH installed local agents AND the community catalog.
|
|
67
|
+
2. If the response includes a catalog match (source: catalog, grade A+/A++):
|
|
68
|
+
- Surface it to the user: `⟡🔮 MERLIN › Catalog match: <name> (Grade <X>). Install with /merlin:install <slug>, or use built-in <fallback>?`
|
|
69
|
+
- Wait for user choice. Never install without confirmation.
|
|
70
|
+
3. If only built-in matches, proceed with normal routing.
|
|
71
|
+
|
|
72
|
+
For tasks that ARE trivial (single-file edit, rename, comment fix, debug print):
|
|
73
|
+
- Skip discovery. Use the optimizer + built-in directly.
|
|
74
|
+
|
|
75
|
+
### When to use discover_agents vs smart_route
|
|
76
|
+
|
|
77
|
+
- `merlin_smart_route(task)` — best for "what agent should I use" decisions (returns ranked recommendation)
|
|
78
|
+
- `merlin_discover_agents(query)` — best for "what's available for X technology" exploration (returns 5-10 matches with install commands)
|
|
79
|
+
|
|
80
|
+
### Examples
|
|
81
|
+
|
|
82
|
+
Bad:
|
|
83
|
+
> User: "build me a Stripe payments integration"
|
|
84
|
+
> Merlin: routes to implementation-dev without checking catalog
|
|
85
|
+
|
|
86
|
+
Good:
|
|
87
|
+
> User: "build me a Stripe payments integration"
|
|
88
|
+
> Merlin: `merlin_smart_route("build Stripe payments...")` → finds "Payment Integration" (Grade A) catalog agent
|
|
89
|
+
> Merlin: "⟡🔮 MERLIN › Found a community agent: **Payment Integration** (Grade A) by ChatAndBuild. Install with `/merlin:install payment-integration`, or use built-in implementation-dev?"
|
|
90
|
+
|
|
91
|
+
This is what makes the "1000+ skills on the server" actually useful.
|
|
92
|
+
|
|
58
93
|
## Agent Routing
|
|
59
94
|
|
|
60
95
|
Call `merlin_smart_route(task="...")` FIRST (searches 500+ community agents). Then:
|
|
@@ -15,15 +15,9 @@ FAILURES_FILE="${HOME}/.claude/merlin-state/.duo-codex-failures"
|
|
|
15
15
|
DECISIONS_LOG="${HOME}/.claude/merlin-state/duo-decisions.log"
|
|
16
16
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
17
|
|
|
18
|
-
# --- Counter helpers ---
|
|
18
|
+
# --- Counter helpers with flock protection ---
|
|
19
19
|
_read_counter() {
|
|
20
|
-
# Reset counter if file is > 6h old (session boundary)
|
|
21
20
|
if [[ -f "$FAILURES_FILE" ]]; then
|
|
22
|
-
AGE=$(python3 -c "import os,time; print(int(time.time() - os.path.getmtime('$FAILURES_FILE')))" 2>/dev/null || echo "99999")
|
|
23
|
-
if [[ "$AGE" -gt 21600 ]]; then
|
|
24
|
-
rm -f "$FAILURES_FILE"
|
|
25
|
-
echo 0; return
|
|
26
|
-
fi
|
|
27
21
|
cat "$FAILURES_FILE" 2>/dev/null || echo 0
|
|
28
22
|
else
|
|
29
23
|
echo 0
|
|
@@ -31,9 +25,34 @@ _read_counter() {
|
|
|
31
25
|
}
|
|
32
26
|
|
|
33
27
|
_write_counter() {
|
|
28
|
+
mkdir -p "$(dirname "$FAILURES_FILE")" 2>/dev/null || true
|
|
34
29
|
echo "$1" > "$FAILURES_FILE"
|
|
35
30
|
}
|
|
36
31
|
|
|
32
|
+
_read_counter_locked() {
|
|
33
|
+
local result
|
|
34
|
+
if command -v flock >/dev/null 2>&1; then
|
|
35
|
+
(
|
|
36
|
+
flock -s 9 2>/dev/null || true
|
|
37
|
+
result=$(_read_counter)
|
|
38
|
+
echo "$result"
|
|
39
|
+
) 9>"${FAILURES_FILE}.lock" 2>/dev/null || _read_counter
|
|
40
|
+
else
|
|
41
|
+
_read_counter
|
|
42
|
+
fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
_write_counter_locked() {
|
|
46
|
+
if command -v flock >/dev/null 2>&1; then
|
|
47
|
+
(
|
|
48
|
+
flock -x 9 2>/dev/null || true
|
|
49
|
+
_write_counter "$1"
|
|
50
|
+
) 9>"${FAILURES_FILE}.lock" 2>/dev/null || _write_counter "$1"
|
|
51
|
+
else
|
|
52
|
+
_write_counter "$1"
|
|
53
|
+
fi
|
|
54
|
+
}
|
|
55
|
+
|
|
37
56
|
_log_failure() {
|
|
38
57
|
local exit_code="$1"
|
|
39
58
|
local ts
|
|
@@ -64,15 +83,15 @@ fi
|
|
|
64
83
|
|
|
65
84
|
if [[ $EXIT_CODE -eq 0 ]]; then
|
|
66
85
|
# Success — reset failure counter
|
|
67
|
-
|
|
86
|
+
_write_counter_locked 0
|
|
68
87
|
exit 0
|
|
69
88
|
fi
|
|
70
89
|
|
|
71
90
|
# Failure path
|
|
72
91
|
_log_failure "$EXIT_CODE" "$@"
|
|
73
92
|
|
|
74
|
-
COUNT=$(( $(
|
|
75
|
-
|
|
93
|
+
COUNT=$(( $(_read_counter_locked) + 1 ))
|
|
94
|
+
_write_counter_locked "$COUNT"
|
|
76
95
|
|
|
77
96
|
if [[ $COUNT -ge 3 ]]; then
|
|
78
97
|
_auto_disable_duo
|
|
@@ -33,8 +33,13 @@ pair=$(grep -o '"pair"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE_FILE" 2>/dev/nul
|
|
|
33
33
|
[[ "$enabled" != "true" ]] && { if [[ "$PAIR_MODE" == "true" ]]; then echo "none"; else echo "disabled"; fi; exit 0; }
|
|
34
34
|
[[ -z "$since" || "$since" == "null" ]] && { if [[ "$PAIR_MODE" == "true" ]]; then echo "none"; else echo "disabled"; fi; exit 0; }
|
|
35
35
|
|
|
36
|
-
# Check 24h expiry using portable date commands (macOS has date -j, Linux has date -d)
|
|
37
|
-
|
|
36
|
+
# Check 24h expiry using portable date commands (macOS has date -j, Linux has date -d).
|
|
37
|
+
# Normalize +00:00 / +0000 offsets to Z so the strict macOS parser accepts them.
|
|
38
|
+
since_normalized=$(echo "$since" | sed 's/\+00:00$/Z/; s/\+0000$/Z/; s/\.[0-9][0-9][0-9]Z$/Z/; s/\.[0-9][0-9][0-9]\+00:00$/Z/')
|
|
39
|
+
since_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$since_normalized" "+%s" 2>/dev/null \
|
|
40
|
+
|| date -d "$since" "+%s" 2>/dev/null \
|
|
41
|
+
|| date -d "$since_normalized" "+%s" 2>/dev/null \
|
|
42
|
+
|| echo "")
|
|
38
43
|
if [[ -z "$since_epoch" ]]; then
|
|
39
44
|
# Unparseable timestamp — treat as expired
|
|
40
45
|
if [[ "$PAIR_MODE" == "true" ]]; then
|
|
@@ -93,6 +93,14 @@ TEST_CASES = [
|
|
|
93
93
|
("React component refactor", "react", "merlin-frontend", 25),
|
|
94
94
|
("useState hook pattern", "react", "merlin-frontend", 25),
|
|
95
95
|
("Next.js server component", "react", "merlin-frontend", 25),
|
|
96
|
+
("build Android app with Kotlin", "android", "android-expert", 25),
|
|
97
|
+
("Jetpack Compose UI for Material You", "android", "android-expert", 25),
|
|
98
|
+
("iOS SwiftUI development", "apple", "apple-swift-expert", 25),
|
|
99
|
+
("macOS AppKit interface", "apple", "apple-swift-expert", 25),
|
|
100
|
+
("Electron app development", "desktop", "desktop-app-expert", 25),
|
|
101
|
+
("Tauri system tray application", "desktop", "desktop-app-expert", 25),
|
|
102
|
+
("email marketing campaign setup", "marketing", "marketing-automation", 25),
|
|
103
|
+
("drip sequence for onboarding", "marketing", "marketing-automation", 25),
|
|
96
104
|
("fix the database query", "none", "", 0),
|
|
97
105
|
("rename a variable", "none", "", 0),
|
|
98
106
|
("update README", "none", "", 0),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-merlin-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.7",
|
|
4
4
|
"description": "Merlin - The Ultimate AI Brain for Claude Code, Codex, and other AI CLIs. One install: workflows, agents, loop, and Sights MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/server/index.js",
|