create-merlin-brain 3.21.0 → 3.23.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 (88) hide show
  1. package/README.md +22 -4
  2. package/bin/install.cjs +23 -0
  3. package/bin/merlin-ask.cjs +111 -0
  4. package/bin/merlin-cli.cjs +22 -0
  5. package/bin/runtime-adapters.cjs +678 -28
  6. package/dist/server/api/client.d.ts +2 -0
  7. package/dist/server/api/client.d.ts.map +1 -1
  8. package/dist/server/api/client.js +4 -0
  9. package/dist/server/api/client.js.map +1 -1
  10. package/dist/server/server.d.ts.map +1 -1
  11. package/dist/server/server.js +45 -4
  12. package/dist/server/server.js.map +1 -1
  13. package/dist/server/tools/auto-mode.d.ts +9 -0
  14. package/dist/server/tools/auto-mode.d.ts.map +1 -0
  15. package/dist/server/tools/auto-mode.js +231 -0
  16. package/dist/server/tools/auto-mode.js.map +1 -0
  17. package/dist/server/tools/computer-use.d.ts +8 -0
  18. package/dist/server/tools/computer-use.d.ts.map +1 -0
  19. package/dist/server/tools/computer-use.js +355 -0
  20. package/dist/server/tools/computer-use.js.map +1 -0
  21. package/dist/server/tools/dream.d.ts +9 -0
  22. package/dist/server/tools/dream.d.ts.map +1 -0
  23. package/dist/server/tools/dream.js +246 -0
  24. package/dist/server/tools/dream.js.map +1 -0
  25. package/dist/server/tools/hud.d.ts +13 -0
  26. package/dist/server/tools/hud.d.ts.map +1 -0
  27. package/dist/server/tools/hud.js +295 -0
  28. package/dist/server/tools/hud.js.map +1 -0
  29. package/dist/server/tools/index.d.ts +4 -0
  30. package/dist/server/tools/index.d.ts.map +1 -1
  31. package/dist/server/tools/index.js +4 -0
  32. package/dist/server/tools/index.js.map +1 -1
  33. package/dist/server/tools/provider-ask.d.ts +10 -0
  34. package/dist/server/tools/provider-ask.d.ts.map +1 -0
  35. package/dist/server/tools/provider-ask.js +234 -0
  36. package/dist/server/tools/provider-ask.js.map +1 -0
  37. package/dist/server/tools/rate-limit.d.ts +8 -0
  38. package/dist/server/tools/rate-limit.d.ts.map +1 -0
  39. package/dist/server/tools/rate-limit.js +184 -0
  40. package/dist/server/tools/rate-limit.js.map +1 -0
  41. package/dist/server/tools/route.d.ts.map +1 -1
  42. package/dist/server/tools/route.js +14 -3
  43. package/dist/server/tools/route.js.map +1 -1
  44. package/dist/server/tools/skills.d.ts +16 -0
  45. package/dist/server/tools/skills.d.ts.map +1 -0
  46. package/dist/server/tools/skills.js +326 -0
  47. package/dist/server/tools/skills.js.map +1 -0
  48. package/dist/server/tools/smart-route.d.ts +19 -0
  49. package/dist/server/tools/smart-route.d.ts.map +1 -1
  50. package/dist/server/tools/smart-route.js +23 -1
  51. package/dist/server/tools/smart-route.js.map +1 -1
  52. package/dist/server/tools/team-workers.d.ts +7 -0
  53. package/dist/server/tools/team-workers.d.ts.map +1 -0
  54. package/dist/server/tools/team-workers.js +271 -0
  55. package/dist/server/tools/team-workers.js.map +1 -0
  56. package/dist/server/utils/merlin-manifest.d.ts +6 -1
  57. package/dist/server/utils/merlin-manifest.d.ts.map +1 -1
  58. package/dist/server/utils/merlin-manifest.js +34 -1
  59. package/dist/server/utils/merlin-manifest.js.map +1 -1
  60. package/files/CLAUDE.md +22 -0
  61. package/files/hooks/post-edit-logger.sh +48 -2
  62. package/files/hooks/pre-compact.sh +14 -2
  63. package/files/hooks/rate-limit-watch.sh +120 -0
  64. package/files/hooks/statusline.sh +148 -0
  65. package/files/hooks/user-prompt-router.sh +96 -0
  66. package/files/merlin/VERSION +1 -1
  67. package/files/merlin/skills/SKILLS-INDEX.md +82 -0
  68. package/files/merlin/skills/automation/payments.md +14 -0
  69. package/files/merlin/skills/automation/webhooks.md +14 -0
  70. package/files/merlin/skills/coding/accessibility.md +14 -0
  71. package/files/merlin/skills/coding/api-design.md +14 -0
  72. package/files/merlin/skills/coding/debug-mode.md +14 -0
  73. package/files/merlin/skills/coding/focus-mode.md +14 -0
  74. package/files/merlin/skills/coding/loop.md +14 -0
  75. package/files/merlin/skills/coding/performance.md +14 -0
  76. package/files/merlin/skills/coding/react-patterns.md +51 -0
  77. package/files/merlin/skills/coding/security-hardening.md +56 -0
  78. package/files/merlin/skills/coding/verify.md +14 -0
  79. package/files/merlin/skills/communication/dispatcher.md +40 -0
  80. package/files/merlin/skills/communication/email-gmail.md +31 -0
  81. package/files/merlin/skills/communication/telegram.md +50 -0
  82. package/files/merlin/skills/communication/whatsapp.md +47 -0
  83. package/files/merlin/skills/data/google-sheets.md +14 -0
  84. package/files/merlin/skills/design/animation.md +14 -0
  85. package/files/merlin/skills/devops/docker-containers.md +14 -0
  86. package/files/merlin/skills/research/brainstorm.md +14 -0
  87. package/files/merlin/skills/testing/tdd-workflow.md +58 -0
  88. package/package.json +4 -2
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Team Workers Tools — Spawn parallel AI CLI workers in tmux panes.
3
+ * Job state persisted to ~/.merlin/state/team/ for status/cleanup queries.
4
+ */
5
+ import { z } from 'zod';
6
+ import { execFile } from 'child_process';
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync } from 'fs';
8
+ import { homedir } from 'os';
9
+ import { join } from 'path';
10
+ import { promisify } from 'util';
11
+ const execFileAsync = promisify(execFile);
12
+ const TEAM_STATE_DIR = join(homedir(), '.merlin', 'state', 'team');
13
+ // ── Internal helpers ──────────────────────────────────────────────────────
14
+ async function isTmuxAvailable() {
15
+ try {
16
+ await execFileAsync('which', ['tmux']);
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ function generateJobId() {
24
+ return `merlin-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
25
+ }
26
+ async function ensureTmuxSession(session) {
27
+ try {
28
+ await execFileAsync('tmux', ['has-session', '-t', session]);
29
+ return true;
30
+ }
31
+ catch {
32
+ try {
33
+ await execFileAsync('tmux', ['new-session', '-d', '-s', session]);
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ }
41
+ /** Split a new pane in the session, send command, return pane ID. */
42
+ async function createTmuxPane(session, command) {
43
+ await execFileAsync('tmux', ['split-window', '-d', '-t', session]);
44
+ const { stdout } = await execFileAsync('tmux', [
45
+ 'list-panes', '-t', session, '-F', '#{session_name}:#{window_index}.#{pane_index}',
46
+ ]);
47
+ const panes = stdout.trim().split('\n').filter(Boolean);
48
+ if (panes.length === 0)
49
+ throw new Error('No panes found after split-window');
50
+ const paneId = panes[panes.length - 1];
51
+ await execFileAsync('tmux', ['send-keys', '-t', paneId, command, 'Enter']);
52
+ return paneId;
53
+ }
54
+ async function capturePaneOutput(paneId, lines = 50) {
55
+ try {
56
+ const { stdout } = await execFileAsync('tmux', [
57
+ 'capture-pane', '-t', paneId, '-p', '-J', '-S', String(-lines),
58
+ ]);
59
+ return stdout;
60
+ }
61
+ catch {
62
+ return '(pane output unavailable)';
63
+ }
64
+ }
65
+ async function isPaneAlive(paneId) {
66
+ try {
67
+ await execFileAsync('tmux', ['list-panes', '-t', paneId]);
68
+ return true;
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ }
74
+ /** Build provider CLI command. Escapes task string for send-keys shell boundary. */
75
+ function buildProviderCommand(provider, task, agent) {
76
+ const t = task.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
77
+ switch (provider) {
78
+ case 'claude': return `claude ${agent ? `--agent ${agent} ` : ''}-p "${t}" --output-format text`;
79
+ case 'codex': return `codex exec "${t}"`;
80
+ case 'gemini': return `gemini -p "${t}"`;
81
+ }
82
+ }
83
+ // ── State helpers ─────────────────────────────────────────────────────────
84
+ function ensureStateDir() {
85
+ if (!existsSync(TEAM_STATE_DIR))
86
+ mkdirSync(TEAM_STATE_DIR, { recursive: true });
87
+ }
88
+ function stateFilePath(teamName) {
89
+ return join(TEAM_STATE_DIR, `${teamName}.json`);
90
+ }
91
+ function saveJobState(state) {
92
+ ensureStateDir();
93
+ writeFileSync(stateFilePath(state.teamName), JSON.stringify(state, null, 2), 'utf-8');
94
+ }
95
+ function loadJobState(teamName) {
96
+ try {
97
+ const p = stateFilePath(teamName);
98
+ if (!existsSync(p))
99
+ return null;
100
+ return JSON.parse(readFileSync(p, 'utf-8'));
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
106
+ function listAllJobs() {
107
+ try {
108
+ ensureStateDir();
109
+ return readdirSync(TEAM_STATE_DIR)
110
+ .filter(f => f.endsWith('.json'))
111
+ .flatMap(f => {
112
+ try {
113
+ return [JSON.parse(readFileSync(join(TEAM_STATE_DIR, f), 'utf-8'))];
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ });
119
+ }
120
+ catch {
121
+ return [];
122
+ }
123
+ }
124
+ function resolveJobs(teamName, jobId) {
125
+ if (teamName) {
126
+ const j = loadJobState(teamName);
127
+ return j ? [j] : [];
128
+ }
129
+ if (jobId) {
130
+ const j = listAllJobs().find(x => x.jobId === jobId);
131
+ return j ? [j] : [];
132
+ }
133
+ return listAllJobs();
134
+ }
135
+ // ── Tool registration ─────────────────────────────────────────────────────
136
+ export function registerTeamWorkerTools(ctx) {
137
+ const { server } = ctx;
138
+ server.tool('merlin_spawn_workers', 'Spawn parallel AI CLI workers in tmux panes for burst execution. Each worker gets its own ' +
139
+ 'tmux pane running a claude/codex/gemini CLI instance. Use for maximum parallelism on ' +
140
+ 'independent tasks. Persists job state for status queries and cleanup. ' +
141
+ 'Requires tmux. Returns jobId and per-worker pane assignments.', {
142
+ workers: z.array(z.object({
143
+ provider: z.enum(['claude', 'codex', 'gemini']).default('claude'),
144
+ task: z.string().describe('Task or prompt for this worker'),
145
+ agent: z.string().optional().describe('For claude: agent name (e.g. implementation-dev)'),
146
+ })).min(1).describe('Workers to spawn'),
147
+ teamName: z.string().optional().default('merlin-team').describe('Logical team name for state tracking'),
148
+ sessionName: z.string().optional().describe('tmux session name — defaults to teamName'),
149
+ }, async ({ workers, teamName, sessionName }) => {
150
+ const resolvedTeam = teamName ?? 'merlin-team';
151
+ const tmuxSession = sessionName ?? resolvedTeam;
152
+ if (!(await isTmuxAvailable())) {
153
+ return {
154
+ content: [{ type: 'text',
155
+ text: 'tmux not found. Install: macOS `brew install tmux` / Linux `apt install tmux`' }],
156
+ isError: true,
157
+ };
158
+ }
159
+ if (!(await ensureTmuxSession(tmuxSession))) {
160
+ return {
161
+ content: [{ type: 'text', text: `Failed to create tmux session "${tmuxSession}".` }],
162
+ isError: true,
163
+ };
164
+ }
165
+ const jobId = generateJobId();
166
+ const workerStates = [];
167
+ const errors = [];
168
+ for (const w of workers) {
169
+ try {
170
+ const paneId = await createTmuxPane(tmuxSession, buildProviderCommand(w.provider, w.task, w.agent));
171
+ workerStates.push({ paneId, provider: w.provider, task: w.task, agent: w.agent, status: 'running' });
172
+ }
173
+ catch (err) {
174
+ errors.push(`${w.provider} / ${w.task.slice(0, 40)}: ${err instanceof Error ? err.message : String(err)}`);
175
+ }
176
+ }
177
+ saveJobState({ jobId, teamName: resolvedTeam, tmuxSession, workers: workerStates, startedAt: new Date().toISOString() });
178
+ const lines = [
179
+ `Team spawned — jobId: ${jobId}`,
180
+ `tmux session: ${tmuxSession}`,
181
+ `workers started: ${workerStates.length} / ${workers.length}`,
182
+ '',
183
+ 'Workers:',
184
+ ...workerStates.map((w, i) => ` [${i + 1}] pane=${w.paneId} provider=${w.provider}${w.agent ? ` agent=${w.agent}` : ''} task="${w.task.slice(0, 60)}"`),
185
+ ...(errors.length ? ['', 'Errors:', ...errors.map(e => ` ! ${e}`)] : []),
186
+ '',
187
+ `Status: merlin_team_status(teamName="${resolvedTeam}")`,
188
+ `Attach: tmux attach-session -t ${tmuxSession}`,
189
+ `Cleanup: merlin_team_cleanup(teamName="${resolvedTeam}")`,
190
+ ];
191
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
192
+ });
193
+ server.tool('merlin_team_status', 'Check status of running tmux team workers. Shows pane liveness and captures recent terminal ' +
194
+ 'output per worker. Provide teamName or jobId to target a specific job; omit both for all jobs.', {
195
+ teamName: z.string().optional().describe('Team name used at spawn time'),
196
+ jobId: z.string().optional().describe('Specific job ID'),
197
+ }, async ({ teamName, jobId }) => {
198
+ const jobs = resolveJobs(teamName, jobId);
199
+ if (jobs.length === 0) {
200
+ return { content: [{ type: 'text', text: 'No team jobs found. Use merlin_spawn_workers first.' }] };
201
+ }
202
+ const sections = [];
203
+ for (const job of jobs) {
204
+ sections.push(`Job: ${job.jobId} team: ${job.teamName} session: ${job.tmuxSession}`);
205
+ sections.push(`Started: ${job.startedAt}`, '');
206
+ for (const [i, worker] of job.workers.entries()) {
207
+ const alive = await isPaneAlive(worker.paneId);
208
+ sections.push(`Worker ${i + 1}: pane=${worker.paneId} status=${alive ? 'running' : 'completed/dead'}`);
209
+ sections.push(` provider=${worker.provider}${worker.agent ? ` agent=${worker.agent}` : ''}`);
210
+ sections.push(` task="${worker.task.slice(0, 80)}"`);
211
+ const out = (await capturePaneOutput(worker.paneId, 50)).trim();
212
+ if (out) {
213
+ sections.push(' --- recent output ---');
214
+ out.split('\n').slice(-20).forEach(l => sections.push(` ${l}`));
215
+ sections.push(' ---');
216
+ }
217
+ sections.push('');
218
+ }
219
+ }
220
+ return { content: [{ type: 'text', text: sections.join('\n') }] };
221
+ });
222
+ server.tool('merlin_team_cleanup', 'Clean up tmux team workers — kills panes and removes persisted job state. ' +
223
+ 'Optionally kills the entire tmux session. Omit teamName/jobId to clean up all jobs.', {
224
+ teamName: z.string().optional().describe('Team name used at spawn time'),
225
+ jobId: z.string().optional().describe('Specific job ID'),
226
+ killSession: z.boolean().optional().default(false).describe('Kill the entire tmux session instead of individual panes'),
227
+ }, async ({ teamName, jobId, killSession }) => {
228
+ const jobs = resolveJobs(teamName, jobId);
229
+ if (jobs.length === 0) {
230
+ return { content: [{ type: 'text', text: 'No team jobs found. Nothing to clean up.' }] };
231
+ }
232
+ const report = [];
233
+ for (const job of jobs) {
234
+ report.push(`Cleaning job: ${job.jobId} team: ${job.teamName}`);
235
+ if (killSession) {
236
+ try {
237
+ await execFileAsync('tmux', ['kill-session', '-t', job.tmuxSession]);
238
+ report.push(` session "${job.tmuxSession}" killed`);
239
+ }
240
+ catch {
241
+ report.push(` session "${job.tmuxSession}" already gone`);
242
+ }
243
+ }
244
+ else {
245
+ for (const w of job.workers) {
246
+ try {
247
+ await execFileAsync('tmux', ['kill-pane', '-t', w.paneId]);
248
+ report.push(` pane ${w.paneId} killed`);
249
+ }
250
+ catch {
251
+ report.push(` pane ${w.paneId} already gone`);
252
+ }
253
+ }
254
+ }
255
+ try {
256
+ const p = stateFilePath(job.teamName);
257
+ if (existsSync(p)) {
258
+ unlinkSync(p);
259
+ report.push(' state file removed');
260
+ }
261
+ }
262
+ catch {
263
+ report.push(' warning: could not remove state file');
264
+ }
265
+ report.push('');
266
+ }
267
+ report.push('Cleanup complete.');
268
+ return { content: [{ type: 'text', text: report.join('\n') }] };
269
+ });
270
+ }
271
+ //# sourceMappingURL=team-workers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-workers.js","sourceRoot":"","sources":["../../../src/server/tools/team-workers.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Discovery chain:
9
9
  * 1. .merlin.json (local file, 0 tokens, any agent)
10
- * 2. CLAUDE.md comment (agent-specific, already loaded)
10
+ * 2. Instruction file comment (CLAUDE.md / AGENTS.md / GEMINI.md)
11
11
  * 3. git remote → API lookup (network call, MCP required)
12
12
  */
13
13
  /** Filename for the manifest */
@@ -26,6 +26,8 @@ export declare const MERLIN_MCP_SERVER = "merlin-mcp-server";
26
26
  export declare const MERLIN_DEFAULT_CAPABILITIES: readonly ["context", "search", "conventions", "files", "ask"];
27
27
  /** CLAUDE.md comment marker for Sight URL injection */
28
28
  export declare const CLAUDEMD_SIGHT_MARKER = "MERLIN_SIGHT";
29
+ export declare const AGENTSMD_SIGHT_MARKER = "MERLIN_SIGHT";
30
+ export declare const GEMINIMD_SIGHT_MARKER = "MERLIN_SIGHT";
29
31
  /** MCP configuration for the manifest */
30
32
  export interface MerlinManifestMcp {
31
33
  /** npm install command (e.g., "npx create-merlin-brain") */
@@ -95,4 +97,7 @@ export declare function buildManifest(sightId: string, repoUrl: string): MerlinM
95
97
  * @returns true if injected, false if already present or no CLAUDE.md
96
98
  */
97
99
  export declare function injectSightIntoClaudeMd(repoRoot: string, sightUrl: string): boolean;
100
+ export declare function injectSightIntoAgentsMd(repoRoot: string, sightUrl: string): boolean;
101
+ export declare function injectSightIntoGeminiMd(repoRoot: string, sightUrl: string): boolean;
102
+ export declare function injectSightIntoInstructionFiles(repoRoot: string, sightUrl: string): boolean;
98
103
  //# sourceMappingURL=merlin-manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merlin-manifest.d.ts","sourceRoot":"","sources":["../../../src/server/utils/merlin-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,gCAAgC;AAChC,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAEvD,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,gDAAgD,CAAC;AAE/E,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,gCAAgC,CAAC;AAEhE,qEAAqE;AACrE,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAExE,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAE5D,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,gCAAgC;AAChC,eAAO,MAAM,2BAA2B,+DAM9B,CAAC;AAEX,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,EAAE,iBAAiB,CAAC;IACvB,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAqC1E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAKpF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAkB9E;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAyBnF"}
1
+ {"version":3,"file":"merlin-manifest.d.ts","sourceRoot":"","sources":["../../../src/server/utils/merlin-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,gCAAgC;AAChC,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAEvD,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,gDAAgD,CAAC;AAE/E,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,gCAAgC,CAAC;AAEhE,qEAAqE;AACrE,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAExE,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAE5D,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,gCAAgC;AAChC,eAAO,MAAM,2BAA2B,+DAM9B,CAAC;AAEX,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AACpD,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AACpD,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,EAAE,iBAAiB,CAAC;IACvB,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAqC1E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAKpF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAkB9E;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAyBnF;AAqBD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQ3F"}
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Discovery chain:
9
9
  * 1. .merlin.json (local file, 0 tokens, any agent)
10
- * 2. CLAUDE.md comment (agent-specific, already loaded)
10
+ * 2. Instruction file comment (CLAUDE.md / AGENTS.md / GEMINI.md)
11
11
  * 3. git remote → API lookup (network call, MCP required)
12
12
  */
13
13
  import { existsSync, readFileSync, writeFileSync } from 'fs';
@@ -34,6 +34,8 @@ export const MERLIN_DEFAULT_CAPABILITIES = [
34
34
  ];
35
35
  /** CLAUDE.md comment marker for Sight URL injection */
36
36
  export const CLAUDEMD_SIGHT_MARKER = 'MERLIN_SIGHT';
37
+ export const AGENTSMD_SIGHT_MARKER = 'MERLIN_SIGHT';
38
+ export const GEMINIMD_SIGHT_MARKER = 'MERLIN_SIGHT';
37
39
  /**
38
40
  * Extract the UUID sight ID from a Merlin Sights URL.
39
41
  *
@@ -161,4 +163,35 @@ export function injectSightIntoClaudeMd(repoRoot, sightUrl) {
161
163
  return false;
162
164
  }
163
165
  }
166
+ function injectSightMarker(filePath, markerPrefix, sightUrl) {
167
+ if (!existsSync(filePath)) {
168
+ return false;
169
+ }
170
+ try {
171
+ const content = readFileSync(filePath, 'utf-8');
172
+ if (content.includes(markerPrefix)) {
173
+ return false;
174
+ }
175
+ writeFileSync(filePath, `${markerPrefix}: ${sightUrl}\n${content}`, 'utf-8');
176
+ console.error(`[merlin-manifest] Injected Sight URL into ${filePath}`);
177
+ return true;
178
+ }
179
+ catch {
180
+ return false;
181
+ }
182
+ }
183
+ export function injectSightIntoAgentsMd(repoRoot, sightUrl) {
184
+ return injectSightMarker(join(repoRoot, 'AGENTS.md'), '# MERLIN_SIGHT', sightUrl);
185
+ }
186
+ export function injectSightIntoGeminiMd(repoRoot, sightUrl) {
187
+ return injectSightMarker(join(repoRoot, 'GEMINI.md'), '# MERLIN_SIGHT', sightUrl);
188
+ }
189
+ export function injectSightIntoInstructionFiles(repoRoot, sightUrl) {
190
+ const results = [
191
+ injectSightIntoClaudeMd(repoRoot, sightUrl),
192
+ injectSightIntoAgentsMd(repoRoot, sightUrl),
193
+ injectSightIntoGeminiMd(repoRoot, sightUrl),
194
+ ];
195
+ return results.some(Boolean);
196
+ }
164
197
  //# sourceMappingURL=merlin-manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"merlin-manifest.js","sourceRoot":"","sources":["../../../src/server/utils/merlin-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merlin-manifest.js","sourceRoot":"","sources":["../../../src/server/utils/merlin-manifest.ts"],"names":[],"mappings":"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"}
package/files/CLAUDE.md CHANGED
@@ -65,3 +65,25 @@ When user corrects you → `merlin_save_behavior`. When user says "always/never/
65
65
  - Never kill user processes (Xcode, VS Code, browsers) without explicit confirmation.
66
66
  - Never claim "done" without actually building/compiling/testing.
67
67
  - Badge on EVERY action — if the user can't see `⟡🔮 MERLIN ›`, you're not doing your job.
68
+
69
+ ## New Capabilities (March 2026)
70
+
71
+ ### Auto Mode — `merlin loop yolo`
72
+ Enable autonomous tool approval. Call `merlin_auto_mode(action: "enable", level: "yolo")` for full autonomy or `level: "safe"` for read-only mode. Disable with `merlin_auto_mode(action: "disable")`.
73
+ - "loop yolo" / "auto mode" / "go autonomous" → `merlin_auto_mode(action: "enable", level: "yolo")`
74
+
75
+ ### AutoDream — Memory Consolidation
76
+ Keep memory files clean and organized. Call `merlin_dream(action: "enable")` to turn on auto-dream, or `action: "consolidate"` to manually review and clean up memory.
77
+ - "dream" / "consolidate memory" / "clean up memory" → `merlin_dream(action: "consolidate")`
78
+
79
+ ### Computer Use — Desktop Control
80
+ Take over and control desktop apps. Call `merlin_computer_use(action: "launch", app: "AppName")` to open an app, or `merlin_screenshot()` to capture the screen.
81
+ - "take over [app]" / "open [app]" / "control [app]" → `merlin_computer_use(action: "launch", app: "[app]")`
82
+ - "screenshot" / "what's on screen" → `merlin_screenshot()`
83
+
84
+ ### Self-Evolving Skills — The Brain Gets Smarter
85
+ Skills are prompt injections that enhance your capabilities. They live at `~/.claude/merlin/skills/`.
86
+ - **Before any task**: Call `merlin_find_skill("what you need")` to discover relevant skills. Load 1-3 by reading their .md files.
87
+ - **After any task**: Call `merlin_track_skill(skillId, success)` to record whether the skill helped.
88
+ - **When a skill is wrong or missing**: Call `merlin_evolve_skill(...)` to improve it or create a new one. The improvement syncs to all users.
89
+ - Skills auto-improve over time. High success rate skills get recommended more. Failed skills get flagged for evolution.
@@ -52,6 +52,52 @@ if [ -f "$PORT_FILE" ] && command -v jq >/dev/null 2>&1; then
52
52
  fi
53
53
  fi
54
54
 
55
- # Claude Code command hooks must output valid JSON to stdout
56
- echo '{}'
55
+ # ─────────────────────────────────────────────────────────────────────────────
56
+ # SECRET DETECTION (PostToolUse — advisory only, edit already happened)
57
+ # Scans the written file for common credential patterns and warns via
58
+ # additionalContext. Never blocks — always exits 0.
59
+ # ─────────────────────────────────────────────────────────────────────────────
60
+ SECRET_WARNING=""
61
+ if [ -n "$file_path" ] && [ -f "$file_path" ]; then
62
+ # Read file content once into a variable (cap at first 500 lines for speed)
63
+ file_content=$(head -500 "$file_path" 2>/dev/null || true)
64
+
65
+ if [ -n "$file_content" ]; then
66
+ found_secrets=""
67
+
68
+ # AWS access key (AKIA...)
69
+ if echo "$file_content" | grep -qE 'AKIA[0-9A-Z]{16}' 2>/dev/null; then
70
+ found_secrets="${found_secrets}AWS-KEY "
71
+ fi
72
+
73
+ # OpenAI / Anthropic / generic sk- API keys (sk- followed by 20+ alphanum chars)
74
+ if echo "$file_content" | grep -qE 'sk-[A-Za-z0-9]{20,}' 2>/dev/null; then
75
+ found_secrets="${found_secrets}API-KEY(sk-) "
76
+ fi
77
+
78
+ # PEM private keys
79
+ if echo "$file_content" | grep -qF 'BEGIN PRIVATE KEY' 2>/dev/null || \
80
+ echo "$file_content" | grep -qF 'BEGIN RSA PRIVATE KEY' 2>/dev/null; then
81
+ found_secrets="${found_secrets}PRIVATE-KEY "
82
+ fi
83
+
84
+ # Hardcoded password assignments (password = "..." or password: "...")
85
+ if echo "$file_content" | grep -qiE '(password|passwd|pwd)\s*[:=]\s*["'"'"'][^'"'"'"]{6,}["'"'"']' 2>/dev/null; then
86
+ found_secrets="${found_secrets}HARDCODED-PASSWORD "
87
+ fi
88
+
89
+ if [ -n "$found_secrets" ]; then
90
+ SECRET_WARNING="WARNING: Possible secrets detected in ${file_path}: ${found_secrets}— review before committing."
91
+ fi
92
+ fi
93
+ fi
94
+
95
+ # Output with optional secret warning as additionalContext
96
+ if [ -n "$SECRET_WARNING" ] && command -v jq >/dev/null 2>&1; then
97
+ jq -n --arg warn "$SECRET_WARNING" '{
98
+ additionalContext: $warn
99
+ }'
100
+ else
101
+ echo '{}'
102
+ fi
57
103
  exit 0
@@ -47,17 +47,29 @@ if [ -f "$PORT_FILE" ] && command -v jq >/dev/null 2>&1; then
47
47
  fi
48
48
  fi
49
49
 
50
+ # Detect current project name (fast, no network)
51
+ PROJECT_NAME=""
52
+ # Try git remote name first (works in most Merlin project dirs)
53
+ if command -v git >/dev/null 2>&1; then
54
+ PROJECT_NAME=$(git remote get-url origin 2>/dev/null | sed 's|.*/||; s|\.git$||' || true)
55
+ fi
56
+ # Fall back to current directory basename
57
+ if [ -z "$PROJECT_NAME" ]; then
58
+ PROJECT_NAME=$(basename "$PWD" 2>/dev/null || echo "unknown")
59
+ fi
60
+
50
61
  # Build the protocol reminder that survives compaction
51
62
  SESSION_INFO=""
52
63
  if [ -n "$GUARDIAN_STATE" ] && command -v jq >/dev/null 2>&1; then
53
64
  HEALTH=$(echo "$GUARDIAN_STATE" | jq -r '.health // "?"' 2>/dev/null || echo "?")
54
65
  DRIFT=$(echo "$GUARDIAN_STATE" | jq -r '.driftLevel // "?"' 2>/dev/null || echo "?")
55
66
  EDITS=$(echo "$GUARDIAN_STATE" | jq -r '.editsSinceContext // "?"' 2>/dev/null || echo "?")
56
- SESSION_INFO=" Session health: ${HEALTH}%, drift level: ${DRIFT}, edits since context: ${EDITS}."
67
+ SESSION_INFO=" Health:${HEALTH}% drift:${DRIFT} edits:${EDITS}."
57
68
  fi
58
69
 
59
70
  # The protocol rules that MUST survive compaction
60
- CONTEXT="MERLIN PROTOCOL REMINDER (post-compaction): You are Merlin, an orchestrator. You NEVER write code — you route to agents. MANDATORY RULES: (1) YOU answer codebase questions using merlin_get_context/merlin_search — never Explore agents. (2) YOU route implementation to agents via Skill(merlin:workflow) or merlin_route(). (3) Call merlin_get_context BEFORE any file edit or codebase question. (4) Prefix EVERY action with the badge. (5) After every agent completes: show result, run verification, surface one skill, detect next intent. (6) Run agents in PARALLEL. (7) ROUTING: Bug=bug-fix workflow, Feature=feature-dev workflow, Refactor=refactor workflow, Small task=merlin_smart_route then merlin_route. (8) Save behaviors when user corrects you.${SESSION_INFO}"
71
+ # Keep under 500 chars so injection stays lean
72
+ CONTEXT="MERLIN POST-COMPACTION: Project=${PROJECT_NAME}. Mode=AI Automation. You are an ORCHESTRATOR — NEVER write code. RULES: (1) Route ALL code work to agents via Skill(merlin:workflow) or merlin_route(). (2) 1 MESSAGE = ALL OPERATIONS — run independent agents in PARALLEL, never sequential. (3) Call merlin_get_context BEFORE edits. (4) Badge EVERY action. (5) ROUTING: Bug=bug-fix, Feature=feature-dev, Refactor=refactor, Small=merlin_smart_route. (6) Save corrections via merlin_save_behavior.${SESSION_INFO}"
61
73
 
62
74
  if command -v jq >/dev/null 2>&1; then
63
75
  jq -n --arg ctx "$CONTEXT" '{
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Merlin Hook: PostToolUse — Rate-Limit Watcher
4
+ # Detects rate-limit signals in tool output and writes state to ~/.merlin/state/rate-limit.json.
5
+ # Sends a desktop notification on first detection (fire-and-forget).
6
+ #
7
+ # Always exits 0 — advisory only, never blocks.
8
+ #
9
+ set -euo pipefail
10
+ trap 'echo "{}"; exit 0' ERR
11
+
12
+ STATE_DIR="${HOME}/.merlin/state"
13
+ STATE_FILE="${STATE_DIR}/rate-limit.json"
14
+
15
+ # ── Ensure state directory exists ────────────────────────────────────────────
16
+ mkdir -p "${STATE_DIR}"
17
+
18
+ # ── Read stdin event ──────────────────────────────────────────────────────────
19
+ input=$(cat)
20
+
21
+ # ── Extract tool_result (jq with grep/sed fallback) ──────────────────────────
22
+ if command -v jq >/dev/null 2>&1; then
23
+ tool_result=$(echo "${input}" | jq -r '.tool_result // ""')
24
+ else
25
+ tool_result=$(echo "${input}" | grep -o '"tool_result":"[^"]*"' | cut -d'"' -f4 || true)
26
+ fi
27
+
28
+ # Lowercase for case-insensitive matching
29
+ tool_result_lower=$(echo "${tool_result}" | tr '[:upper:]' '[:lower:]')
30
+
31
+ # ── Rate-limit pattern matching ───────────────────────────────────────────────
32
+ is_rate_limited=false
33
+ trigger_label=""
34
+
35
+ if echo "${tool_result_lower}" | grep -qE 'rate.?limit|429|too many requests|quota exceeded|overloaded'; then
36
+ is_rate_limited=true
37
+
38
+ if echo "${tool_result_lower}" | grep -q '429'; then
39
+ trigger_label="429 response"
40
+ elif echo "${tool_result_lower}" | grep -q 'quota exceeded'; then
41
+ trigger_label="quota exceeded"
42
+ elif echo "${tool_result_lower}" | grep -q 'overloaded'; then
43
+ trigger_label="overloaded"
44
+ elif echo "${tool_result_lower}" | grep -q 'too many requests'; then
45
+ trigger_label="too many requests"
46
+ else
47
+ trigger_label="rate limit"
48
+ fi
49
+ fi
50
+
51
+ NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
52
+
53
+ # ── Compute estimated reset time (5 min from now) ────────────────────────────
54
+ # macOS date -v; Linux date -d fallback
55
+ if date -v+5M >/dev/null 2>&1; then
56
+ RESET_AT=$(date -u -v+5M +"%Y-%m-%dT%H:%M:%SZ")
57
+ else
58
+ RESET_AT=$(date -u -d "+5 minutes" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "${NOW}")
59
+ fi
60
+
61
+ # ── If rate-limited: write blocked state ─────────────────────────────────────
62
+ if [ "${is_rate_limited}" = "true" ]; then
63
+ # Only notify on new detection (when previous state wasn't already blocked)
64
+ prev_status=""
65
+ if [ -f "${STATE_FILE}" ]; then
66
+ if command -v jq >/dev/null 2>&1; then
67
+ prev_status=$(jq -r '.status // ""' "${STATE_FILE}" 2>/dev/null || true)
68
+ else
69
+ prev_status=$(grep -o '"status":"[^"]*"' "${STATE_FILE}" | cut -d'"' -f4 || true)
70
+ fi
71
+ fi
72
+
73
+ cat > "${STATE_FILE}" <<EOF
74
+ {
75
+ "status": "blocked",
76
+ "detectedAt": "${NOW}",
77
+ "trigger": "${trigger_label}",
78
+ "estimatedResetAt": "${RESET_AT}"
79
+ }
80
+ EOF
81
+
82
+ # Desktop notification only on transition to blocked (macOS)
83
+ if [ "${prev_status}" != "blocked" ] && command -v osascript >/dev/null 2>&1; then
84
+ osascript -e 'display notification "Rate limit detected — will auto-resume" with title "⟡🔮 Merlin"' &
85
+ fi
86
+
87
+ echo "{}"
88
+ exit 0
89
+ fi
90
+
91
+ # ── If not rate-limited: check if we should clear a previous blocked state ───
92
+ if [ -f "${STATE_FILE}" ]; then
93
+ if command -v jq >/dev/null 2>&1; then
94
+ prev_status=$(jq -r '.status // ""' "${STATE_FILE}" 2>/dev/null || true)
95
+ detected_at=$(jq -r '.detectedAt // ""' "${STATE_FILE}" 2>/dev/null || true)
96
+ else
97
+ prev_status=$(grep -o '"status":"[^"]*"' "${STATE_FILE}" | cut -d'"' -f4 || true)
98
+ detected_at=$(grep -o '"detectedAt":"[^"]*"' "${STATE_FILE}" | cut -d'"' -f4 || true)
99
+ fi
100
+
101
+ if [ "${prev_status}" = "blocked" ] && [ -n "${detected_at}" ]; then
102
+ # Calculate elapsed seconds using python3 (available on macOS/Linux)
103
+ elapsed=$(python3 -c "
104
+ import datetime
105
+ try:
106
+ d = datetime.datetime.fromisoformat('${detected_at}'.replace('Z','+00:00'))
107
+ print(int((datetime.datetime.now(datetime.timezone.utc) - d).total_seconds()))
108
+ except Exception:
109
+ print(0)
110
+ " 2>/dev/null || echo "0")
111
+
112
+ # Clear blocked state only after 2+ minutes have elapsed
113
+ if [ "${elapsed}" -ge 120 ] 2>/dev/null; then
114
+ printf '{\n "status": "ok",\n "clearedAt": "%s"\n}\n' "${NOW}" > "${STATE_FILE}"
115
+ fi
116
+ fi
117
+ fi
118
+
119
+ echo "{}"
120
+ exit 0