@jaggerxtrm/specialists 2.1.3 → 2.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.
Files changed (2) hide show
  1. package/bin/install.js +52 -39
  2. package/package.json +1 -1
package/bin/install.js CHANGED
@@ -12,7 +12,7 @@ const SPECIALISTS_DIR = join(HOME, '.agents', 'specialists');
12
12
  const CLAUDE_DIR = join(HOME, '.claude');
13
13
  const HOOKS_DIR = join(CLAUDE_DIR, 'hooks');
14
14
  const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
15
- const HOOK_FILE = join(HOOKS_DIR, 'specialists-main-guard.sh');
15
+ const HOOK_FILE = join(HOOKS_DIR, 'specialists-main-guard.mjs');
16
16
  const MCP_NAME = 'specialists';
17
17
  const GITHUB_PKG = '@jaggerxtrm/specialists';
18
18
 
@@ -78,43 +78,56 @@ function registerMCP() {
78
78
 
79
79
  // ── Hook installation ─────────────────────────────────────────────────────────
80
80
 
81
- const HOOK_SCRIPT = `#!/usr/bin/env bash
82
- # specialists — Claude Code PreToolUse hook
83
- # Blocks writes and git commit/push on main/master branch.
84
- # Exit 0: allow | Exit 2: block (message shown to user)
85
- #
86
- # Installed by: npx --package=@jaggerxtrm/specialists install
87
-
88
- BRANCH=$(git branch --show-current 2>/dev/null)
89
-
90
- # Not in a git repo or not on a protected branch — allow
91
- if [ -z "$BRANCH" ] || { [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; }; then
92
- exit 0
93
- fi
94
-
95
- INPUT=$(cat)
96
- TOOL=$(echo "$INPUT" | jq -r '.tool_name' 2>/dev/null)
97
-
98
- BLOCK_MSG="⛔ Direct edits on '$BRANCH' are not allowed.
99
- Create a feature branch first: git checkout -b feature/<name>"
100
-
101
- case "$TOOL" in
102
- Edit|Write|MultiEdit|NotebookEdit)
103
- echo "$BLOCK_MSG" >&2
104
- exit 2
105
- ;;
106
- Bash)
107
- CMD=$(echo "$INPUT" | jq -r '.tool_input.command' 2>/dev/null)
108
- if echo "$CMD" | grep -qE '^git (commit|push)'; then
109
- echo "$BLOCK_MSG" >&2
110
- exit 2
111
- fi
112
- exit 0
113
- ;;
114
- *)
115
- exit 0
116
- ;;
117
- esac
81
+ const HOOK_SCRIPT = `#!/usr/bin/env node
82
+ // specialists — Claude Code PreToolUse hook
83
+ // Blocks writes and git commit/push on main/master branch.
84
+ // Exit 0: allow | Exit 2: block (message shown to user)
85
+ //
86
+ // Installed by: npx --package=@jaggerxtrm/specialists install
87
+
88
+ import { execSync } from 'node:child_process';
89
+ import { readFileSync } from 'node:fs';
90
+
91
+ let branch = '';
92
+ try {
93
+ branch = execSync('git branch --show-current', {
94
+ encoding: 'utf8',
95
+ stdio: ['pipe', 'pipe', 'pipe'],
96
+ }).trim();
97
+ } catch {}
98
+
99
+ if (!branch || (branch !== 'main' && branch !== 'master')) {
100
+ process.exit(0);
101
+ }
102
+
103
+ let input;
104
+ try {
105
+ input = JSON.parse(readFileSync(0, 'utf8'));
106
+ } catch {
107
+ process.exit(0);
108
+ }
109
+
110
+ const tool = input.tool_name ?? '';
111
+ const blockMsg =
112
+ \`⛔ Direct edits on '\${branch}' are not allowed.\\n\` +
113
+ \`Create a feature branch first: git checkout -b feature/<name>\`;
114
+
115
+ const WRITE_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
116
+
117
+ if (WRITE_TOOLS.has(tool)) {
118
+ process.stderr.write(blockMsg + '\\n');
119
+ process.exit(2);
120
+ }
121
+
122
+ if (tool === 'Bash') {
123
+ const cmd = input.tool_input?.command ?? '';
124
+ if (/^git (commit|push)/.test(cmd)) {
125
+ process.stderr.write(blockMsg + '\\n');
126
+ process.exit(2);
127
+ }
128
+ }
129
+
130
+ process.exit(0);
118
131
  `;
119
132
 
120
133
  const HOOK_ENTRY = {
@@ -202,7 +215,7 @@ installHook();
202
215
  hookExisted
203
216
  ? ok('main-guard hook updated')
204
217
  : ok('main-guard hook installed → ~/.claude/hooks/specialists-main-guard.sh');
205
- info('Blocks Edit/Write/git commit/push on main or master branch');
218
+ info('Blocks Edit/Write/git commit/push on main or master branch (JS, no jq needed)');
206
219
 
207
220
  // 7. Health check
208
221
  section('Health check');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaggerxtrm/specialists",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "OmniSpecialist — 7-tool MCP orchestration layer powered by the Specialist System. Discover and execute .specialist.yaml files across project/user/system scopes via pi.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",