create-merlin-brain 3.5.1 → 3.5.2

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
@@ -980,32 +980,28 @@ async function install() {
980
980
  hooks: [{ type: 'command', command: 'bash ~/.claude/hooks/subagent-context.sh' }]
981
981
  });
982
982
 
983
- // --- Prompt-based hooks (LLM evaluates .md content) ---
984
- // On update, old prompt hooks have stale content. Remove all Merlin prompt hooks
985
- // first (identified by containing 'merlin' or 'Merlin' in their prompt text),
986
- // then re-add fresh ones. This prevents duplicate hooks across version upgrades.
987
- const removeMerlinPromptHooks = (hookArray) => {
983
+ // --- Prompt-based hooks cleanup & registration ---
984
+ // Remove ALL prompt-type hooks from Merlin (identified by type: 'prompt').
985
+ // This prevents duplicates across version upgrades and removes broken hooks.
986
+ const removeAllPromptHooks = (hookArray) => {
988
987
  return hookArray.filter(entry => {
989
988
  if (!entry.hooks || !Array.isArray(entry.hooks)) return true;
990
- // Remove entry if ALL its hooks are Merlin prompt hooks
991
- const allMerlinPrompts = entry.hooks.every(h => {
992
- if (h.type !== 'prompt') return false;
993
- const prompt = (h.prompt || '').toLowerCase();
994
- return prompt.includes('merlin') || prompt.includes('sights');
995
- });
996
- return !allMerlinPrompts;
989
+ // Remove entry if ALL its hooks are prompt-type (Merlin is the only
990
+ // source of prompt hooks in settings.local.json)
991
+ const allPrompts = entry.hooks.every(h => h.type === 'prompt');
992
+ return !allPrompts;
997
993
  });
998
994
  };
999
995
 
1000
- settings.hooks.SessionStart = removeMerlinPromptHooks(settings.hooks.SessionStart);
1001
- settings.hooks.PreToolUse = removeMerlinPromptHooks(settings.hooks.PreToolUse);
1002
- settings.hooks.Stop = removeMerlinPromptHooks(settings.hooks.Stop);
996
+ settings.hooks.SessionStart = removeAllPromptHooks(settings.hooks.SessionStart);
997
+ settings.hooks.PreToolUse = removeAllPromptHooks(settings.hooks.PreToolUse);
998
+ settings.hooks.Stop = removeAllPromptHooks(settings.hooks.Stop);
1003
999
  settings.hooks.Notification = settings.hooks.Notification || [];
1004
- settings.hooks.Notification = removeMerlinPromptHooks(settings.hooks.Notification);
1000
+ settings.hooks.Notification = removeAllPromptHooks(settings.hooks.Notification);
1005
1001
  settings.hooks.TaskCompleted = settings.hooks.TaskCompleted || [];
1006
- settings.hooks.TaskCompleted = removeMerlinPromptHooks(settings.hooks.TaskCompleted);
1002
+ settings.hooks.TaskCompleted = removeAllPromptHooks(settings.hooks.TaskCompleted);
1007
1003
 
1008
- // Now add fresh prompt/command hooks in new format
1004
+ // Now add fresh hooks in new format
1009
1005
  // NOTE: SessionStart does NOT support prompt hooks (only command hooks).
1010
1006
  // The Merlin boot sequence is handled via CLAUDE.md instructions instead.
1011
1007
  // We use a command hook to inject additionalContext at session start.
@@ -1013,11 +1009,11 @@ async function install() {
1013
1009
  hooks: [{ type: 'command', command: 'bash ~/.claude/hooks/session-start-context.sh' }]
1014
1010
  });
1015
1011
 
1016
- // Prompt-based PreToolUse hook: evaluate Sights check before edits
1017
- settings.hooks.PreToolUse.push({
1018
- matcher: 'Edit|Write',
1019
- hooks: [{ type: 'prompt', prompt: fs.readFileSync(path.join(HOOKS_DIR, 'pre-edit-sights-enforce.md'), 'utf8') }]
1020
- });
1012
+ // NOTE: The PreToolUse prompt hook has been REMOVED. It caused an infinite
1013
+ // rejection loop because the evaluator model cannot see conversation history
1014
+ // to verify whether merlin_get_context was called. The command-type hook
1015
+ // (pre-edit-sights-check.sh) handles advisory logging instead.
1016
+ // Sights enforcement is done via CLAUDE.md instructions, not hook blocking.
1021
1017
 
1022
1018
  // Prompt-based Stop hook: evaluate whether stopping is appropriate
1023
1019
  settings.hooks.Stop.push({
@@ -1,12 +1 @@
1
- You are evaluating whether a file edit should proceed. Context: $ARGUMENTS
2
-
3
- Check: Has the assistant recently called merlin_get_context, merlin_find_files, or merlin_search for this file's area in the current conversation? Look at recent tool calls in the transcript.
4
-
5
- Rules:
6
- - If Sights was consulted recently (within the last few messages) for this area: allow the edit
7
- - If this is a minor/trivial edit (formatting, typo fix, small change): allow the edit
8
- - If this is a significant edit and Sights was NOT consulted: suggest checking first
9
-
10
- Respond with ONLY valid JSON, no other text:
11
- - Allow the edit: {"ok": true}
12
- - Suggest Sights check first: {"ok": false, "reason": "Call merlin_get_context before editing this file to check for existing patterns and conventions"}
1
+ Always allow this edit. Respond with ONLY: {"ok": true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-merlin-brain",
3
- "version": "3.5.1",
3
+ "version": "3.5.2",
4
4
  "description": "Merlin - The Ultimate AI Brain for Claude Code. One install: workflows, agents, loop, and Sights MCP server.",
5
5
  "type": "module",
6
6
  "main": "./dist/server/index.js",