create-merlin-brain 5.4.3 → 5.4.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.cjs CHANGED
@@ -1400,20 +1400,16 @@ async function install() {
1400
1400
  // clean up existing prompt hooks from previous installs.
1401
1401
  // ═══════════════════════════════════════════════════════════════
1402
1402
 
1403
- // Configure Merlin statusline
1404
- settings.statusline = settings.statusline || {};
1405
- settings.statusline.enabled = true;
1406
- settings.statusline.items = settings.statusline.items || [];
1407
-
1408
- // Add Merlin status if not already present
1409
- const hasMerlinStatus = settings.statusline.items.some(item =>
1410
- item.command && item.command.includes('merlin')
1411
- );
1412
- if (!hasMerlinStatus) {
1413
- settings.statusline.items.push({
1414
- command: 'bash -c \'echo "⟡🔮 MERLIN"\'',
1415
- interval: 30
1416
- });
1403
+ // Configure Merlin statusLine — the ALWAYS-ON purple Merlin presence.
1404
+ // Claude Code uses `statusLine` (camelCase): a command whose plain-text
1405
+ // stdout is rendered. The old lowercase `statusline.items` block was a no-op
1406
+ // (not a format Claude Code reads), so Merlin never actually appeared.
1407
+ // Wire up the real command, but never clobber a user's custom statusLine.
1408
+ if (settings.statusline) delete settings.statusline; // remove legacy no-op
1409
+ const merlinStatusCmd = 'sh ~/.claude/scripts/merlin-statusline.sh';
1410
+ const existingStatus = settings.statusLine && settings.statusLine.command;
1411
+ if (!existingStatus || existingStatus.includes('merlin-statusline')) {
1412
+ settings.statusLine = { type: 'command', command: merlinStatusCmd };
1417
1413
  }
1418
1414
 
1419
1415
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
@@ -0,0 +1,75 @@
1
+ ---
2
+ name: merlin:duo
3
+ description: Toggle and inspect Merlin's duo mode — parallel + sequential dual-brain (Claude+Codex or twin-Claude) execution. Subcommands: on, off, status, unsuppress, offer.
4
+ argument-hint: "[on|off|status|unsuppress|offer]"
5
+ allowed-tools:
6
+ - Bash
7
+ - Read
8
+ ---
9
+
10
+ <objective>
11
+ Manage Merlin's duo mode. Duo runs two brains on the same task — parallel for
12
+ plans/docs/review/tests, sequential for code write/modify — with an arbiter
13
+ merging or a decider gating. This command is the registered entry point for
14
+ `/merlin:duo` and `Skill("merlin:duo", args="…")`.
15
+
16
+ State lives in `~/.claude/merlin-state/duo-mode.json` (24h auto-expire). The
17
+ canonical routing rules are `~/.claude/rules/duo-routing.md` — this command only
18
+ toggles/inspects state; it does not duplicate routing logic.
19
+ </objective>
20
+
21
+ <dispatch>
22
+ Parse the argument (default to `status` when none is given) and run the matching
23
+ section. Each section drives the shell scripts under `~/.claude/scripts/`; the
24
+ detailed prose for each lives in `~/.claude/merlin/skills/duo/<sub>.md`.
25
+
26
+ - `on` → enable duo (see Step: ON)
27
+ - `off` → disable duo (see Step: OFF)
28
+ - `status` → report state (see Step: STATUS)
29
+ - `unsuppress`→ clear suppression memory (see Step: UNSUPPRESS)
30
+ - `offer` → present the duo opt-in for a risky task (see Step: OFFER)
31
+ </dispatch>
32
+
33
+ <step name="ON">
34
+ ## ON
35
+ 1. `~/.claude/scripts/duo-mode-read.sh` — if it prints `enabled`, duo is already on; show status and stop.
36
+ 2. Detect pair: `~/.claude/scripts/codex-installed.sh` (exit 0 → `claude+codex`, else `claude+claude`); `MERLIN_RUNTIME=codex` → `codex+codex`.
37
+ 3. Enable: `~/.claude/scripts/duo-mode-write.sh on "<the user phrase that triggered enable>" "$PAIR"`.
38
+ 4. Compute badge with `~/.claude/scripts/duo-badge.sh` and emit the pair-specific confirmation block from `~/.claude/merlin/skills/duo/on.md`.
39
+ 5. If `codex-mode.json` is also enabled, append: `(codex-mode also active — duo wins per precedence rule)`.
40
+ </step>
41
+
42
+ <step name="OFF">
43
+ ## OFF
44
+ 1. `~/.claude/scripts/duo-mode-write.sh off "<the user phrase that triggered disable>"`.
45
+ 2. Check `~/.claude/merlin-state/codex-mode.json`.
46
+ 3. Emit: if codex-mode still active → `⟡🔮 MERLIN › Duo off. (codex-mode is still active.)`; otherwise → `⟡🔮 MERLIN › Duo off. Back to solo routing.`
47
+ </step>
48
+
49
+ <step name="STATUS">
50
+ ## STATUS
51
+ Follow `~/.claude/merlin/skills/duo/status.md`: parse `duo-mode.json` with 24h
52
+ expiry logic, check the Codex install gate, parse `duo-suppress.json`, and emit
53
+ ON / OFF / AUTO-EXPIRED plus gate + suppression lines. Always prefix with the
54
+ badge from `~/.claude/scripts/duo-badge.sh`.
55
+ </step>
56
+
57
+ <step name="UNSUPPRESS">
58
+ ## UNSUPPRESS
59
+ Follow `~/.claude/merlin/skills/duo/unsuppress.md` to clear `session_skip`,
60
+ `never_for_intents`, and `task_hashes_declined` in `duo-suppress.json`, then
61
+ confirm what was cleared.
62
+ </step>
63
+
64
+ <step name="OFFER">
65
+ ## OFFER
66
+ Follow `~/.claude/merlin/skills/duo/offer.md`: present the one-shot duo opt-in
67
+ for a risky task, record the user's choice in `duo-suppress.json`, and route
68
+ accordingly. Never offer mid-flight or more than once per task.
69
+ </step>
70
+
71
+ <notes>
72
+ - Badge: ALWAYS prefix output with `~/.claude/scripts/duo-badge.sh` output (`⟡🔮↔🔮 MERLIN·DUO ›` when on, `⟡🔮 MERLIN ›` when off).
73
+ - The gate authority `reviewer-decider` is Claude-only and must never run via `codex-as.sh`.
74
+ - If a script is missing, fall back to writing `duo-mode.json` directly per the schema in `duo-routing.md` and say so — do not silently no-op.
75
+ </notes>
@@ -0,0 +1,62 @@
1
+ #!/bin/sh
2
+ # Merlin statusLine command — PLAIN TEXT output for Claude Code's `statusLine`.
3
+ #
4
+ # Always-on, model-independent "is Merlin active?" indicator: a purple Merlin
5
+ # badge (duo-aware) + version, followed by the live model / dir / context%.
6
+ # Unlike the in-chat badge (which is model behavior and drifts), this renders on
7
+ # every status refresh regardless of what the model does.
8
+ #
9
+ # IMPORTANT: Claude Code's statusLine takes the command's STDOUT as literal text
10
+ # (ANSI allowed). Do NOT emit JSON here — that is the Notification-hook format
11
+ # (see hooks/statusline.sh), which Claude Code would print verbatim.
12
+ #
13
+ # Reads session JSON from stdin. Local files only — no network. Fast (<100ms).
14
+
15
+ input=$(cat)
16
+
17
+ # ── parse stdin (jq if present, grep fallback) ──
18
+ if command -v jq >/dev/null 2>&1; then
19
+ model=$(printf '%s' "$input" | jq -r '.model.display_name // "Claude"' 2>/dev/null)
20
+ cwd=$(printf '%s' "$input" | jq -r '.workspace.current_dir // .cwd // ""' 2>/dev/null)
21
+ used=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty' 2>/dev/null)
22
+ else
23
+ model=$(printf '%s' "$input" | grep -o '"display_name":"[^"]*"' | head -1 | cut -d'"' -f4)
24
+ cwd=$(printf '%s' "$input" | grep -o '"current_dir":"[^"]*"' | head -1 | cut -d'"' -f4)
25
+ used=""
26
+ fi
27
+ [ -z "$model" ] && model="Claude"
28
+ dir=$(basename "$cwd" 2>/dev/null)
29
+ [ -z "$dir" ] && dir="project"
30
+
31
+ # ── Merlin badge (duo-aware) ──
32
+ badge="⟡🔮 MERLIN ›"
33
+ if [ -x "$HOME/.claude/scripts/duo-badge.sh" ]; then
34
+ b=$("$HOME/.claude/scripts/duo-badge.sh" 2>/dev/null)
35
+ [ -n "$b" ] && badge="$b"
36
+ fi
37
+
38
+ # ── version (best-effort) ──
39
+ mver=""
40
+ if [ -f "$HOME/.claude/merlin/VERSION" ]; then
41
+ v=$(cat "$HOME/.claude/merlin/VERSION" 2>/dev/null)
42
+ [ -n "$v" ] && mver=" \033[90mv${v}\033[0m"
43
+ fi
44
+
45
+ # ── context% indicator (green/yellow/red) ──
46
+ ctx_part=""
47
+ if [ -n "$used" ]; then
48
+ ui=$(printf "%.0f" "$used" 2>/dev/null)
49
+ if [ -n "$ui" ]; then
50
+ if [ "$ui" -ge 80 ] 2>/dev/null; then
51
+ ctx_part=" \033[31m${ui}%ctx\033[0m"
52
+ elif [ "$ui" -ge 50 ] 2>/dev/null; then
53
+ ctx_part=" \033[33m${ui}%ctx\033[0m"
54
+ else
55
+ ctx_part=" \033[32m${ui}%ctx\033[0m"
56
+ fi
57
+ fi
58
+ fi
59
+
60
+ # Bold magenta badge leads so the purple Merlin icon is always visible.
61
+ printf "\033[1;35m%s\033[0m%s \033[90m·\033[0m \033[36m%s\033[0m \033[90m%s\033[0m%s" \
62
+ "$badge" "$mver" "$model" "$dir" "$ctx_part"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-merlin-brain",
3
- "version": "5.4.3",
3
+ "version": "5.4.4",
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",