create-merlin-brain 1.1.2 → 1.1.4

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.js CHANGED
@@ -185,14 +185,43 @@ _merlin_check_update() {
185
185
  fi
186
186
  }
187
187
 
188
- # Main claude wrapper with Merlin branding
188
+ # Main claude wrapper with Merlin branding and Sights pre-check
189
189
  claude() {
190
- # Show Merlin branding
191
- echo -e "\\033[35m✦ Merlin\\033[0m"
192
-
193
190
  # Check for updates in background (silent, non-blocking)
194
191
  (_merlin_check_update &) 2>/dev/null
195
192
 
193
+ # Pre-flight: Check Sights connection (enforced at terminal level)
194
+ local status_output=$(merlin status 2>/dev/null)
195
+ local status_code=$(echo "$status_output" | head -1)
196
+
197
+ case "$status_code" in
198
+ CONNECTED)
199
+ local repo_name=$(echo "$status_output" | sed -n '2p')
200
+ echo -e "\\033[35m🔮 Merlin Sights:\\033[0m \\033[32mCONNECTED\\033[0m ✓"
201
+ echo -e " Repository: $repo_name"
202
+ ;;
203
+ NOT_CONNECTED)
204
+ local repo_url=$(echo "$status_output" | sed -n '2p')
205
+ echo -e "\\033[35m🔮 Merlin Sights:\\033[0m \\033[33mNOT CONNECTED\\033[0m"
206
+ echo ""
207
+ echo " This repo isn't in Sights yet: $repo_url"
208
+ echo ""
209
+ echo -e " \\033[36m[1]\\033[0m Connect now (analysis takes 2-5 min)"
210
+ echo -e " \\033[36m[2]\\033[0m Skip - work without Sights"
211
+ echo ""
212
+ echo -n " Choice [1/2]: "
213
+ read -r choice
214
+ if [ "$choice" = "1" ]; then
215
+ merlin connect
216
+ echo ""
217
+ fi
218
+ ;;
219
+ *)
220
+ # Not in git repo or CLI not available - just show branding
221
+ echo -e "\\033[35m✦ Merlin\\033[0m"
222
+ ;;
223
+ esac
224
+
196
225
  # Run claude with Merlin agent
197
226
  command claude --agent merlin "$@"
198
227
  }
@@ -284,7 +313,7 @@ function cleanupLegacy() {
284
313
  if (apiKey) {
285
314
  config.mcpServers.merlin = {
286
315
  command: 'npx',
287
- args: ['merlin-mcp'],
316
+ args: ['merlin-mcp@latest'],
288
317
  env: { MERLIN_API_KEY: apiKey }
289
318
  };
290
319
  }
@@ -295,7 +324,7 @@ function cleanupLegacy() {
295
324
  if (config.mcpServers?.merlin) {
296
325
  const args = config.mcpServers.merlin.args;
297
326
  if (args && (args[0] === 'create-merlin-brain' || args[0] === 'ccwiki-mcp')) {
298
- config.mcpServers.merlin.args = ['merlin-mcp'];
327
+ config.mcpServers.merlin.args = ['merlin-mcp@latest'];
299
328
  modified = true;
300
329
  }
301
330
  if (config.mcpServers.merlin.env?.CCWIKI_API_KEY) {
@@ -327,7 +356,7 @@ function cleanupLegacy() {
327
356
  if (apiKey) {
328
357
  config.mcpServers.merlin = {
329
358
  command: 'npx',
330
- args: ['merlin-mcp'],
359
+ args: ['merlin-mcp@latest'],
331
360
  env: { MERLIN_API_KEY: apiKey }
332
361
  };
333
362
  }
@@ -337,7 +366,7 @@ function cleanupLegacy() {
337
366
  if (config.mcpServers?.merlin) {
338
367
  const args = config.mcpServers.merlin.args;
339
368
  if (args && (args[0] === 'create-merlin-brain' || args[0] === 'ccwiki-mcp')) {
340
- config.mcpServers.merlin.args = ['merlin-mcp'];
369
+ config.mcpServers.merlin.args = ['merlin-mcp@latest'];
341
370
  modified = true;
342
371
  }
343
372
  if (config.mcpServers.merlin.env?.CCWIKI_API_KEY) {
@@ -546,14 +575,10 @@ async function install() {
546
575
  const claudeMdDest = path.join(CLAUDE_DIR, 'CLAUDE.md');
547
576
 
548
577
  if (fs.existsSync(claudeMdSrc)) {
549
- if (fs.existsSync(claudeMdDest)) {
550
- // Backup existing
551
- const backup = claudeMdDest + '.backup';
552
- fs.copyFileSync(claudeMdDest, backup);
553
- logWarn(`Backed up existing CLAUDE.md to CLAUDE.md.backup`);
554
- }
578
+ // Always replace CLAUDE.md - it's managed by Merlin
579
+ // Old versions are cleaned up by cleanupLegacy()
555
580
  fs.copyFileSync(claudeMdSrc, claudeMdDest);
556
- logSuccess('Installed CLAUDE.md');
581
+ logSuccess('Installed CLAUDE.md (Merlin instructions)');
557
582
  }
558
583
 
559
584
  // Step 6: Install Merlin Loop (autonomous orchestration)
@@ -604,7 +629,7 @@ async function install() {
604
629
  config.mcpServers = config.mcpServers || {};
605
630
  config.mcpServers.merlin = {
606
631
  command: 'npx',
607
- args: ['merlin-mcp'],
632
+ args: ['merlin-mcp@latest'],
608
633
  env: {
609
634
  MERLIN_API_KEY: apiKey
610
635
  }
package/bin/merlin-cli.js CHANGED
@@ -17,7 +17,7 @@
17
17
  const https = require('https');
18
18
  const { execSync } = require('child_process');
19
19
 
20
- const API_URL = process.env.MERLIN_API_URL || 'https://claude-codeapi-production.up.railway.app';
20
+ const API_URL = process.env.MERLIN_API_URL || 'https://auth.merlin.build';
21
21
  const API_KEY = process.env.MERLIN_API_KEY || '';
22
22
 
23
23
  // ============================================================
@@ -243,21 +243,53 @@ async function connect() {
243
243
  }
244
244
  }
245
245
 
246
+ async function status() {
247
+ const repoUrl = detectGitRepo();
248
+ if (!repoUrl) {
249
+ // Not in a git repo - output for shell parsing
250
+ console.log('NO_GIT_REPO');
251
+ process.exit(1);
252
+ }
253
+
254
+ const repoId = await findRepoId(repoUrl);
255
+ if (!repoId) {
256
+ // Repo not connected
257
+ console.log('NOT_CONNECTED');
258
+ console.log(repoUrl);
259
+ process.exit(0);
260
+ }
261
+
262
+ // Connected - get repo name
263
+ try {
264
+ const overview = await apiRequest(`/api/agent/${repoId}/overview`);
265
+ const nameMatch = overview.match(/Name:\s*(.+)/);
266
+ const repoName = nameMatch ? nameMatch[1].trim() : repoUrl.split('/').pop();
267
+ console.log('CONNECTED');
268
+ console.log(repoName);
269
+ console.log(repoId);
270
+ } catch {
271
+ console.log('CONNECTED');
272
+ console.log(repoUrl.split('/').pop());
273
+ console.log(repoId);
274
+ }
275
+ }
276
+
246
277
  function showHelp() {
247
278
  console.log(`
248
279
  Merlin CLI - Universal codebase intelligence for ALL AI agents
249
280
 
250
281
  Usage:
282
+ merlin status Check if current repo is connected to Sights
283
+ merlin connect Connect repo to Merlin Sights
251
284
  merlin context <task> Get context for a task
252
285
  merlin search <query> Search the codebase
253
286
  merlin brief Get project overview
254
287
  merlin rules Get coding rules
255
288
  merlin files <purpose> Find files by purpose
256
- merlin connect Connect repo to Merlin Sights
257
289
 
258
290
  Environment:
259
291
  MERLIN_API_KEY Your merlin.build API key
260
- MERLIN_API_URL API URL (default: https://claude-codeapi-production.up.railway.app)
292
+ MERLIN_API_URL API URL (default: https://auth.merlin.build)
261
293
 
262
294
  Works with: Claude, Cursor, Windsurf, Copilot, Aider, and any AI agent!
263
295
  `);
@@ -290,6 +322,9 @@ async function main() {
290
322
  case 'connect':
291
323
  await connect();
292
324
  break;
325
+ case 'status':
326
+ await status();
327
+ break;
293
328
  case 'help':
294
329
  case '--help':
295
330
  case '-h':
package/files/CLAUDE.md CHANGED
@@ -1,33 +1,40 @@
1
- # MANDATORY FIRST ACTION EXECUTE BEFORE ANYTHING ELSE
1
+ # ⚡⚡⚡ STOPREAD THIS FIRST ⚡⚡⚡
2
2
 
3
- **THIS IS NON-NEGOTIABLE. DO THIS BEFORE READING THE USER'S MESSAGE.**
3
+ ## YOUR VERY FIRST ACTION (BEFORE ANYTHING ELSE)
4
4
 
5
- ```
6
- IMMEDIATELY call: merlin_get_selected_repo
7
- ```
5
+ **DO NOT read the user's message yet. DO NOT start working. FIRST:**
6
+
7
+ 1. **Call this tool NOW:** `merlin_get_selected_repo`
8
8
 
9
- Then respond based on result:
9
+ 2. **Then show ONE of these responses:**
10
10
 
11
- **✅ Repo found in Sights:**
11
+ **If repo IS connected:**
12
12
  ```
13
- 🔮 Merlin connected: {repo_name}
13
+ 🔮 Merlin Sights: CONNECTED
14
+ Repository: {repo_name}
15
+
14
16
  What would you like to work on?
15
17
  ```
16
18
 
17
- **❌ Repo NOT in Sights (or no git repo detected):**
19
+ **If repo is NOT connected:**
18
20
  ```
19
- 🔮 This repo isn't connected to Merlin Sights yet.
21
+ 🔮 Merlin Sights: NOT CONNECTED
22
+
23
+ This repository isn't in Sights yet.
20
24
 
21
- [1] Connect now (analysis takes 2-5 min)
25
+ [1] Connect now (2-5 min analysis)
22
26
  [2] Skip - work without Sights
23
27
 
24
28
  Which would you like?
25
29
  ```
26
30
 
27
- If user picks [1]: Call `merlin_connect_repo`, then poll `merlin_check_repo_status` until ready.
28
- If user picks [2]: Proceed without Sights, use traditional file exploration.
31
+ 3. **WAIT for user response if not connected**
29
32
 
30
- **ONLY AFTER completing this flow, proceed with the user's actual request.**
33
+ 4. **ONLY THEN proceed with their actual request**
34
+
35
+ ---
36
+
37
+ **WHY THIS MATTERS:** The user needs visual confirmation that Sights is working. Always show the 🔮 status box at session start. Never skip this step.
31
38
 
32
39
  ---
33
40
 
@@ -185,47 +192,54 @@ Merlin Sights is Claude's memory. Use it **throughout every session**, not just
185
192
 
186
193
  ---
187
194
 
188
- ## Visual Sights Indicator
195
+ ## 🔮 VISUAL CUES — Show When Merlin Is Used
189
196
 
190
- **ALWAYS announce when Merlin Sights provides context.**
197
+ **ALWAYS show a visual indicator when you query Merlin Sights.**
191
198
 
192
- When you receive useful information from Merlin Sights, visibly indicate it:
199
+ After EVERY Merlin tool call, display a cue box showing what you found and whether it helped:
193
200
 
201
+ **Format:**
194
202
  ```
195
- 🔮 MERLIN SIGHTS
196
- ├─ Found: AuthService.ts, UserService.ts, SessionManager.ts
197
- ├─ Pattern: JWT with refresh tokens, middleware-based auth
198
- └─ Rule: max 400 lines per file
203
+ 🔮 SIGHTS › [tool_name]
204
+ [what you searched for]
205
+
206
+ [result indicator] [brief summary of what was found]
199
207
  ```
200
208
 
201
- **Use this format whenever:**
202
- - `merlin_get_context` returns relevant files/patterns
203
- - `merlin_find_files` locates files for a task
204
- - `merlin_get_conventions` returns coding rules
205
- - `merlin_get_brief` provides project overview
206
- - `merlin_search` finds relevant information
209
+ **Result indicators:**
210
+ - **Helped** Found useful files, patterns, or context
211
+ - ⚠️ **Partial** Found something but not exactly what was needed
212
+ - **No match** — Nothing relevant found, using other methods
207
213
 
208
- **Why:** The user wants to see when Sights is providing value and how frequently it's used. Make it visible.
214
+ **Examples:**
209
215
 
210
- **Quick indicators:**
211
- - 🔮 = Merlin Sights query
212
- - = Rule being followed
213
- - 📍 = Files located
214
- - 🧭 = Context provided
216
+ ```
217
+ 🔮 SIGHTS get_context("payment processing")
218
+ Found PaymentService.ts, StripeClient.ts
219
+ Pattern: Async handlers with retry logic
220
+ ```
215
221
 
216
- **Example in practice:**
222
+ ```
223
+ 🔮 SIGHTS › find_files("email templates")
224
+ ⚠️ Partial — Found EmailService but no templates folder
225
+ Will check manually with Glob
226
+ ```
217
227
 
218
228
  ```
219
- 🔮 MERLIN SIGHTS
220
- ├─ 📍 Found 3 files for "payment logic"
221
- ├─ 🧭 PaymentService uses Stripe SDK
222
- └─ ✓ test_required: true
229
+ 🔮 SIGHTS › search("GraphQL resolvers")
230
+ No match This codebase uses REST, not GraphQL
231
+ ```
223
232
 
224
- Based on this context, I'll create the refund method in PaymentService.ts
225
- and add tests in __tests__/PaymentService.test.ts...
233
+ **Quick format for rapid queries:**
234
+ ```
235
+ 🔮 get_context → ✅ Found 3 auth files
236
+ 🔮 find_files → ⚠️ Partial match
237
+ 🔮 conventions → ✅ max 400 lines, always test
226
238
  ```
227
239
 
228
- This lets the user see exactly when and how Sights is helping.
240
+ **Why this matters:** The user wants to see Merlin working. Every query should be visible so they know when Sights is providing value (or when it's not and you're falling back to file exploration).
241
+
242
+ ---
229
243
 
230
244
  **Merlin Sights Tools:**
231
245
  - `merlin_get_context` - Task context ("add auth", "fix bug in X")
@@ -32,7 +32,7 @@
32
32
  "decision": "DECISION:"
33
33
  },
34
34
  "cloud": {
35
- "api_base": "https://api.merlin.build/v1",
35
+ "api_base": "https://auth.merlin.build/v1",
36
36
  "endpoints": {
37
37
  "sync": "/loop/sync",
38
38
  "state": "/loop/state",
@@ -125,7 +125,7 @@ get_cloud_context() {
125
125
  project=$(basename "$PWD")
126
126
 
127
127
  local cloud_context
128
- cloud_context=$(curl -sf "https://api.merlin.build/v1/context/relevant?project=$project&mode=$mode" \
128
+ cloud_context=$(curl -sf "https://auth.merlin.build/v1/context/relevant?project=$project&mode=$mode" \
129
129
  -H "Authorization: Bearer $api_key" 2>/dev/null || echo "")
130
130
 
131
131
  if [ -n "$cloud_context" ] && [ "$cloud_context" != "{}" ]; then
@@ -331,7 +331,7 @@ sync_to_cloud() {
331
331
  project_id=$(get_state_value "project")
332
332
 
333
333
  # POST state to merlin.build
334
- curl -sf -X POST "https://api.merlin.build/v1/loop/sync" \
334
+ curl -sf -X POST "https://auth.merlin.build/v1/loop/sync" \
335
335
  -H "Authorization: Bearer $api_key" \
336
336
  -H "Content-Type: application/json" \
337
337
  -d @"$STATE_FILE" \
@@ -355,7 +355,7 @@ sync_from_cloud() {
355
355
 
356
356
  # GET state from merlin.build
357
357
  local cloud_state
358
- cloud_state=$(curl -sf "https://api.merlin.build/v1/loop/state/$project_id" \
358
+ cloud_state=$(curl -sf "https://auth.merlin.build/v1/loop/state/$project_id" \
359
359
  -H "Authorization: Bearer $api_key" 2>/dev/null || echo "")
360
360
 
361
361
  if [ -n "$cloud_state" ] && [ "$cloud_state" != "{}" ]; then
@@ -390,7 +390,7 @@ push_memory() {
390
390
  fi
391
391
 
392
392
  # Store in cloud memory for cross-session retrieval
393
- curl -sf -X POST "https://api.merlin.build/v1/memory/store" \
393
+ curl -sf -X POST "https://auth.merlin.build/v1/memory/store" \
394
394
  -H "Authorization: Bearer $api_key" \
395
395
  -H "Content-Type: application/json" \
396
396
  -d "{\"project\":\"$(basename "$PWD")\",\"key\":\"$key\",\"value\":\"$value\"}" \
@@ -407,6 +407,6 @@ pull_memory() {
407
407
  return 0
408
408
  fi
409
409
 
410
- curl -sf "https://api.merlin.build/v1/memory/get?project=$(basename "$PWD")&key=$key" \
410
+ curl -sf "https://auth.merlin.build/v1/memory/get?project=$(basename "$PWD")&key=$key" \
411
411
  -H "Authorization: Bearer $api_key" 2>/dev/null || echo ""
412
412
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-merlin-brain",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "The Ultimate AI Brain for Claude Code - Install Merlin workflows, agents, and sights integration",
5
5
  "main": "index.js",
6
6
  "bin": {