create-merlin-brain 3.7.2 → 3.8.0-beta.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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4CpE,0CAA0C;AAC1C,wBAAgB,YAAY,IAAI,SAAS,CAm1FxC;AAED,gDAAgD;AAChD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAoCjD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4CpE,0CAA0C;AAC1C,wBAAgB,YAAY,IAAI,SAAS,CAs1FxC;AAED,gDAAgD;AAChD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAoCjD"}
@@ -48,10 +48,13 @@ export function createServer() {
48
48
  description: 'Merlin Brain. MANDATORY BOOT: Call merlin_get_selected_repo then merlin_get_project_status BEFORE responding to user. Call merlin_get_context before every file edit. Never run claude --agent via Bash — use Skill("merlin:route") instead.',
49
49
  });
50
50
  const client = getClient();
51
- // Tool loading mode: core (15 tools) vs all (67 tools)
52
- // Core mode stays under Claude Code's 10% context threshold to avoid Tool Search lazy loading
53
- // Set MERLIN_CORE_ONLY=true to load only 22 essential tools (if context is tight)
54
- const allToolsMode = process.env.MERLIN_CORE_ONLY !== 'true';
51
+ // Tool loading tiers:
52
+ // 1. Core tools (always loaded): get_context, search, find_files, get_brief, etc.
53
+ // 2. Free/local tools (always loaded): auto-teach, route, lite
54
+ // 3. Cloud tools (need API key): behaviors, verification, agents-index, sights-index, etc.
55
+ // Set MERLIN_CORE_ONLY=true to load only core tools (minimal footprint)
56
+ const coreOnly = process.env.MERLIN_CORE_ONLY === 'true';
57
+ const hasCloudApi = !!process.env.MERLIN_API_KEY;
55
58
  // Cache for resolved repo IDs to avoid repeated git/API calls
56
59
  // Key: url or 'auto' for auto-detected, Value: { repoId, expiresAt }
57
60
  const repoIdCache = new Map();
@@ -1190,7 +1193,7 @@ export function createServer() {
1190
1193
  throw error;
1191
1194
  }
1192
1195
  });
1193
- if (allToolsMode) { // Tool: merlin_check_repo_status
1196
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_check_repo_status
1194
1197
  server.tool('merlin_check_repo_status', 'Check if a repository analysis is complete. Use after merlin_connect_repo to poll for completion. Returns status: pending, analyzing, completed, or failed.', {
1195
1198
  repoUrl: z.string().optional().describe('GitHub URL of the repository (uses selected repo if omitted)'),
1196
1199
  }, async ({ repoUrl }) => {
@@ -1291,7 +1294,7 @@ export function createServer() {
1291
1294
  };
1292
1295
  }
1293
1296
  });
1294
- } // end allToolsMode: merlin_check_repo_status
1297
+ } // end cloud: merlin_check_repo_status
1295
1298
  // Tool: merlin_connect_repo
1296
1299
  server.tool('merlin_connect_repo', 'Connect a new repository to Merlin Sights for analysis. Use this when working on a repo that is not yet in Sights. Analysis takes 2-5 minutes.', {
1297
1300
  repoUrl: z.string().describe('GitHub URL of the repository (e.g., "https://github.com/user/repo")'),
@@ -1496,7 +1499,7 @@ export function createServer() {
1496
1499
  };
1497
1500
  }
1498
1501
  });
1499
- if (allToolsMode) { // Tool: merlin_similar_code
1502
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_similar_code
1500
1503
  server.tool('merlin_similar_code', 'Find similar implementations in the codebase BEFORE writing new code. Prevents duplicating existing patterns. Use this when implementing anything — there is likely an existing pattern to follow.', {
1501
1504
  description: z.string().describe('What you\'re trying to implement (e.g., "API endpoint with authentication", "database query with pagination", "React form with validation")'),
1502
1505
  repoUrl: z.string().optional().describe('GitHub URL of the repository (auto-detected from git if omitted)'),
@@ -1526,8 +1529,8 @@ export function createServer() {
1526
1529
  };
1527
1530
  }
1528
1531
  });
1529
- } // end allToolsMode: merlin_similar_code
1530
- if (allToolsMode) { // Tool: merlin_code_examples
1532
+ } // end cloud: merlin_similar_code
1533
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_code_examples
1531
1534
  server.tool('merlin_code_examples', 'Get real code examples from this codebase for common tasks. Shows actual patterns used in this project.', {
1532
1535
  task: z.string().optional().describe('Specific task (e.g., "add endpoint", "add test", "error handling"). Leave empty for all examples.'),
1533
1536
  repoUrl: z.string().optional().describe('GitHub URL of the repository (auto-detected from git if omitted)'),
@@ -1557,7 +1560,7 @@ export function createServer() {
1557
1560
  };
1558
1561
  }
1559
1562
  });
1560
- } // end allToolsMode: merlin_code_examples
1563
+ } // end cloud: merlin_code_examples
1561
1564
  // Tool: merlin_ask
1562
1565
  server.tool('merlin_ask', 'Ask ANY question about the codebase in natural language. Uses AI-powered semantic search + RAG to find relevant context and generate accurate answers with source citations. Perfect for questions like "How does authentication work?", "Where should I add a new API endpoint?", "Why is X structured this way?"', {
1563
1566
  question: z.string().describe('Your question in natural language (e.g., "How does the payment flow work?", "Where is user validation handled?", "What patterns are used for error handling?")'),
@@ -1772,7 +1775,7 @@ export function createServer() {
1772
1775
  };
1773
1776
  }
1774
1777
  });
1775
- if (allToolsMode) { // Tool: merlin_log_activity
1778
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_log_activity
1776
1779
  server.tool('merlin_log_activity', 'Log an activity event to the team timeline. Use for tracking progress, milestones, and decisions.', {
1777
1780
  eventType: z.string().describe('Event type (e.g., "phase_started", "task_completed", "blocker_hit", "decision_made")'),
1778
1781
  eventData: z.any().optional().describe('Additional event data (JSON object)'),
@@ -1820,8 +1823,8 @@ export function createServer() {
1820
1823
  };
1821
1824
  }
1822
1825
  });
1823
- } // end allToolsMode: merlin_log_activity
1824
- if (allToolsMode) { // Tool: merlin_sync_task
1826
+ } // end cloud: merlin_log_activity
1827
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_sync_task
1825
1828
  server.tool('merlin_sync_task', 'Sync a task to Merlin cloud. Use to track work items, their status, and dependencies for team visibility.', {
1826
1829
  title: z.string().describe('Task title'),
1827
1830
  status: z.enum(['pending', 'in_progress', 'completed', 'blocked', 'skipped']).optional().describe('Task status'),
@@ -1887,8 +1890,8 @@ export function createServer() {
1887
1890
  };
1888
1891
  }
1889
1892
  });
1890
- } // end allToolsMode: merlin_sync_task
1891
- if (allToolsMode) { // Tool: merlin_get_tasks
1893
+ } // end cloud: merlin_sync_task
1894
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_get_tasks
1892
1895
  server.tool('merlin_get_tasks', 'Get tasks synced to Merlin. Shows work items from all agents for team coordination.', {
1893
1896
  status: z.string().optional().describe('Filter by status (pending, in_progress, completed, blocked)'),
1894
1897
  phase: z.string().optional().describe('Filter by phase'),
@@ -1950,8 +1953,8 @@ export function createServer() {
1950
1953
  };
1951
1954
  }
1952
1955
  });
1953
- } // end allToolsMode: merlin_get_tasks
1954
- if (allToolsMode) { // Tool: merlin_report_blocker
1956
+ } // end cloud: merlin_get_tasks
1957
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_report_blocker
1955
1958
  server.tool('merlin_report_blocker', 'Report a blocker that requires human attention. The blocker will appear in the team dashboard for resolution.', {
1956
1959
  title: z.string().describe('Brief description of the blocker'),
1957
1960
  blockerType: z.enum(['human_verify', 'auth_required', 'clarification', 'decision_point', 'external', 'error', 'other']).describe('Type of blocker'),
@@ -2003,8 +2006,8 @@ export function createServer() {
2003
2006
  };
2004
2007
  }
2005
2008
  });
2006
- } // end allToolsMode: merlin_report_blocker
2007
- if (allToolsMode) { // Tool: merlin_get_blockers
2009
+ } // end cloud: merlin_report_blocker
2010
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_get_blockers
2008
2011
  server.tool('merlin_get_blockers', 'Get open blockers awaiting resolution. Check before starting work to see if there are issues to resolve.', {
2009
2012
  status: z.string().optional().default('open').describe('Filter by status (open, resolved, all)'),
2010
2013
  repoUrl: z.string().optional().describe('GitHub URL of the repository (auto-detected from git if omitted)'),
@@ -2055,8 +2058,8 @@ export function createServer() {
2055
2058
  };
2056
2059
  }
2057
2060
  });
2058
- } // end allToolsMode: merlin_get_blockers
2059
- if (allToolsMode) { // Tool: merlin_create_checkpoint
2061
+ } // end cloud: merlin_get_blockers
2062
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_create_checkpoint
2060
2063
  server.tool('merlin_create_checkpoint', 'Create a checkpoint requiring human verification or decision. Pauses agent work until human responds.', {
2061
2064
  title: z.string().describe('Checkpoint title'),
2062
2065
  checkpointType: z.enum(['human_verify', 'auth_gate', 'decision_point', 'approval', 'review']).describe('Type of checkpoint'),
@@ -2114,8 +2117,8 @@ export function createServer() {
2114
2117
  };
2115
2118
  }
2116
2119
  });
2117
- } // end allToolsMode: merlin_create_checkpoint
2118
- if (allToolsMode) { // Tool: merlin_get_team_state
2120
+ } // end cloud: merlin_create_checkpoint
2121
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_get_team_state
2119
2122
  server.tool('merlin_get_team_state', 'Get consolidated team state: active sessions, pending checkpoints, open blockers, task summary. Use at session start to see what others are working on.', {
2120
2123
  repoUrl: z.string().optional().describe('GitHub URL of the repository (auto-detected from git if omitted)'),
2121
2124
  }, async ({ repoUrl }) => {
@@ -2209,8 +2212,8 @@ export function createServer() {
2209
2212
  };
2210
2213
  }
2211
2214
  });
2212
- } // end allToolsMode: merlin_get_team_state
2213
- if (allToolsMode) { // Tool: merlin_update_session
2215
+ } // end cloud: merlin_get_team_state
2216
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_update_session
2214
2217
  server.tool('merlin_update_session', 'Update your session status. Use to track your work progress and enable pause/resume across context resets.', {
2215
2218
  sessionId: z.string().describe('Unique session identifier'),
2216
2219
  agentId: z.string().describe('Agent identifier'),
@@ -2270,11 +2273,11 @@ export function createServer() {
2270
2273
  };
2271
2274
  }
2272
2275
  });
2273
- } // end allToolsMode: merlin_update_session
2276
+ } // end cloud: merlin_update_session
2274
2277
  // ============================================================
2275
2278
  // CODING RULES
2276
2279
  // ============================================================
2277
- if (allToolsMode) { // Tool: merlin_save_rule
2280
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_save_rule
2278
2281
  server.tool('merlin_save_rule', 'Save a coding rule or preference to Merlin. Rules are returned with every context query and must be followed. Use when user expresses a preference that should persist.', {
2279
2282
  rule: z.string().describe('The rule to save (e.g., "max 400 lines per file", "always use async/await", "no console.log in production")'),
2280
2283
  category: z.enum(['file_size', 'testing', 'style', 'patterns', 'custom']).optional().default('custom').describe('Rule category for organization'),
@@ -2334,8 +2337,8 @@ export function createServer() {
2334
2337
  };
2335
2338
  }
2336
2339
  });
2337
- } // end allToolsMode: merlin_save_rule
2338
- if (allToolsMode) { // Tool: merlin_get_rules
2340
+ } // end cloud: merlin_save_rule
2341
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_get_rules
2339
2342
  server.tool('merlin_get_rules', 'Get all coding rules for this project. Returns rules that must be followed when writing code.', {
2340
2343
  repoUrl: z.string().optional().describe('GitHub URL of the repository (auto-detected from git if omitted)'),
2341
2344
  }, async ({ repoUrl }) => {
@@ -2383,8 +2386,8 @@ export function createServer() {
2383
2386
  };
2384
2387
  }
2385
2388
  });
2386
- } // end allToolsMode: merlin_get_rules
2387
- if (allToolsMode) { // Tool: merlin_remove_rule
2389
+ } // end cloud: merlin_get_rules
2390
+ if (hasCloudApi && !coreOnly) { // Tool: merlin_remove_rule
2388
2391
  server.tool('merlin_remove_rule', 'Remove a coding rule from this project.', {
2389
2392
  rule: z.string().describe('The exact rule text to remove'),
2390
2393
  repoUrl: z.string().optional().describe('GitHub URL of the repository (auto-detected from git if omitted)'),
@@ -2447,7 +2450,7 @@ export function createServer() {
2447
2450
  };
2448
2451
  }
2449
2452
  });
2450
- } // end allToolsMode: merlin_remove_rule
2453
+ } // end cloud: merlin_remove_rule
2451
2454
  // ============================================================
2452
2455
  // RESOURCES
2453
2456
  // ============================================================
@@ -2470,7 +2473,7 @@ export function createServer() {
2470
2473
  // ============================================================
2471
2474
  registerProjectTools(server, () => client, resolveRepoId, getRepoRootPath);
2472
2475
  // ============================================================
2473
- if (allToolsMode) {
2476
+ if (hasCloudApi && !coreOnly) {
2474
2477
  // LEARNED BEHAVIORS TOOLS
2475
2478
  // ============================================================
2476
2479
  registerBehaviorTools({
@@ -2478,9 +2481,9 @@ export function createServer() {
2478
2481
  client,
2479
2482
  resolveRepoId,
2480
2483
  });
2481
- } // end allToolsMode: registerBehaviorTools
2484
+ } // end cloud: registerBehaviorTools
2482
2485
  // ============================================================
2483
- if (allToolsMode) {
2486
+ if (hasCloudApi && !coreOnly) {
2484
2487
  // VERIFICATION CHECKPOINTS TOOLS
2485
2488
  // ============================================================
2486
2489
  registerVerificationTools({
@@ -2489,9 +2492,9 @@ export function createServer() {
2489
2492
  resolveRepoId,
2490
2493
  getRepoRootPath,
2491
2494
  });
2492
- } // end allToolsMode: registerVerificationTools
2495
+ } // end cloud: registerVerificationTools
2493
2496
  // ============================================================
2494
- if (allToolsMode) {
2497
+ if (hasCloudApi && !coreOnly) {
2495
2498
  // ADAPTIVE CONTEXT DISCOVERY TOOLS
2496
2499
  // ============================================================
2497
2500
  registerAdaptiveTools({
@@ -2499,9 +2502,9 @@ export function createServer() {
2499
2502
  client,
2500
2503
  resolveRepoId,
2501
2504
  });
2502
- } // end allToolsMode: registerAdaptiveTools
2505
+ } // end cloud: registerAdaptiveTools
2503
2506
  // ============================================================
2504
- if (allToolsMode) {
2507
+ if (hasCloudApi && !coreOnly) {
2505
2508
  // STRUCTURED AGENT TOOLS
2506
2509
  // ============================================================
2507
2510
  registerAgentTools({
@@ -2509,9 +2512,9 @@ export function createServer() {
2509
2512
  client,
2510
2513
  resolveRepoId,
2511
2514
  });
2512
- } // end allToolsMode: registerAgentTools
2515
+ } // end cloud: registerAgentTools
2513
2516
  // ============================================================
2514
- if (allToolsMode) {
2517
+ if (hasCloudApi && !coreOnly) {
2515
2518
  // DISCOVERY TOOLS - Teach Sights what Claude learns
2516
2519
  // ============================================================
2517
2520
  registerDiscoveryTools({
@@ -2519,20 +2522,20 @@ export function createServer() {
2519
2522
  client,
2520
2523
  resolveRepoId,
2521
2524
  });
2522
- } // end allToolsMode: registerDiscoveryTools
2525
+ } // end cloud: registerDiscoveryTools
2523
2526
  // ============================================================
2524
- if (allToolsMode) {
2525
- // AUTO-TEACH TOOLS - Confidence detection + teach-back loop
2527
+ if (!coreOnly) {
2528
+ // AUTO-TEACH TOOLS - Confidence detection + teach-back loop (works locally)
2526
2529
  // ============================================================
2527
2530
  registerAutoTeachTools({
2528
2531
  server,
2529
2532
  client,
2530
2533
  resolveRepoId,
2531
2534
  });
2532
- } // end allToolsMode: registerAutoTeachTools
2535
+ } // end free: registerAutoTeachTools
2533
2536
  // ============================================================
2534
- if (allToolsMode) {
2535
- // AGENT ROUTE TOOLS - Fresh process spawning for specialists
2537
+ if (!coreOnly) {
2538
+ // AGENT ROUTE TOOLS - Fresh process spawning for specialists (local)
2536
2539
  // ============================================================
2537
2540
  registerRouteTools({
2538
2541
  server,
@@ -2540,9 +2543,9 @@ export function createServer() {
2540
2543
  resolveRepoId,
2541
2544
  getRepoRootPath,
2542
2545
  });
2543
- } // end allToolsMode: registerRouteTools
2546
+ } // end free: registerRouteTools
2544
2547
  // ============================================================
2545
- if (allToolsMode) {
2548
+ if (hasCloudApi && !coreOnly) {
2546
2549
  // PUBLIC SIGHTS INDEX - Browse open source analyzed codebases
2547
2550
  // ============================================================
2548
2551
  registerSightsIndexTools({
@@ -2550,9 +2553,9 @@ export function createServer() {
2550
2553
  client,
2551
2554
  resolveRepoId,
2552
2555
  });
2553
- } // end allToolsMode: registerSightsIndexTools
2556
+ } // end cloud: registerSightsIndexTools
2554
2557
  // ============================================================
2555
- if (allToolsMode) {
2558
+ if (hasCloudApi && !coreOnly) {
2556
2559
  // AGENTS INDEX - Browse discovered AI agents catalog
2557
2560
  // ============================================================
2558
2561
  registerAgentsIndexTools({
@@ -2560,10 +2563,10 @@ export function createServer() {
2560
2563
  client,
2561
2564
  resolveRepoId,
2562
2565
  });
2563
- } // end allToolsMode: registerAgentsIndexTools
2566
+ } // end cloud: registerAgentsIndexTools
2564
2567
  // ============================================================
2565
- if (allToolsMode) {
2566
- // LITE MODE TOOLS - Local file-based context for small repos
2568
+ if (!coreOnly) {
2569
+ // LITE MODE TOOLS - Local file-based context for small repos (always available)
2567
2570
  // ============================================================
2568
2571
  registerLiteTools({
2569
2572
  server,
@@ -2574,9 +2577,9 @@ export function createServer() {
2574
2577
  return config?.apiKey || null;
2575
2578
  },
2576
2579
  });
2577
- } // end allToolsMode: registerLiteTools
2580
+ } // end free: registerLiteTools
2578
2581
  // ============================================================
2579
- if (allToolsMode) {
2582
+ if (hasCloudApi && !coreOnly) {
2580
2583
  // CONFIG SYNC TOOLS - Sync CLAUDE.md across team
2581
2584
  // ============================================================
2582
2585
  registerConfigSyncTools({
@@ -2586,7 +2589,7 @@ export function createServer() {
2586
2589
  return config?.apiKey || null;
2587
2590
  },
2588
2591
  });
2589
- } // end allToolsMode: registerConfigSyncTools
2592
+ } // end cloud: registerConfigSyncTools
2590
2593
  return server;
2591
2594
  }
2592
2595
  /** Start the MCP server with stdio transport */