@jaggerxtrm/specialists 2.1.16 → 2.1.18
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 +51 -22
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -82,23 +82,6 @@ function registerMCP() {
|
|
|
82
82
|
|
|
83
83
|
// ── Hook installation ─────────────────────────────────────────────────────────
|
|
84
84
|
|
|
85
|
-
const WRITE_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
|
|
86
|
-
|
|
87
|
-
if (WRITE_TOOLS.has(tool)) {
|
|
88
|
-
process.stderr.write(blockMsg + '\\n');
|
|
89
|
-
process.exit(2);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (tool === 'Bash') {
|
|
93
|
-
const cmd = input.tool_input?.command ?? '';
|
|
94
|
-
if (/^git (commit|push)/.test(cmd)) {
|
|
95
|
-
process.stderr.write(blockMsg + '\\n');
|
|
96
|
-
process.exit(2);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
process.exit(0);
|
|
101
|
-
`;
|
|
102
85
|
|
|
103
86
|
const HOOK_ENTRY = {
|
|
104
87
|
matcher: 'Edit|Write|MultiEdit|NotebookEdit|Bash',
|
|
@@ -122,6 +105,36 @@ const BEADS_STOP_GATE_ENTRY = {
|
|
|
122
105
|
hooks: [{ type: 'command', command: BEADS_STOP_GATE_FILE, timeout: 10000 }],
|
|
123
106
|
};
|
|
124
107
|
|
|
108
|
+
function promptYN(question) {
|
|
109
|
+
if (!process.stdin.isTTY) return true; // non-interactive: default yes
|
|
110
|
+
process.stdout.write(`${question} [Y/n]: `);
|
|
111
|
+
const r = spawnSync('/bin/sh', ['-c', 'read ans; printf "%s" "$ans"'], {
|
|
112
|
+
stdio: ['inherit', 'pipe', 'inherit'],
|
|
113
|
+
encoding: 'utf8',
|
|
114
|
+
});
|
|
115
|
+
const ans = (r.stdout ?? '').trim().toLowerCase();
|
|
116
|
+
return ans === '' || ans === 'y' || ans === 'yes';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getHookDrift() {
|
|
120
|
+
const pairs = [
|
|
121
|
+
['specialists-main-guard.mjs', HOOK_FILE],
|
|
122
|
+
['beads-edit-gate.mjs', BEADS_EDIT_GATE_FILE],
|
|
123
|
+
['beads-commit-gate.mjs', BEADS_COMMIT_GATE_FILE],
|
|
124
|
+
['beads-stop-gate.mjs', BEADS_STOP_GATE_FILE],
|
|
125
|
+
];
|
|
126
|
+
return pairs
|
|
127
|
+
.map(([bundled, dest]) => ({
|
|
128
|
+
name: bundled,
|
|
129
|
+
dest,
|
|
130
|
+
missing: !existsSync(dest),
|
|
131
|
+
changed: existsSync(dest) &&
|
|
132
|
+
readFileSync(join(BUNDLED_HOOKS_DIR, bundled), 'utf8') !==
|
|
133
|
+
readFileSync(dest, 'utf8'),
|
|
134
|
+
}))
|
|
135
|
+
.filter(h => h.missing || h.changed);
|
|
136
|
+
}
|
|
137
|
+
|
|
125
138
|
function installHook() {
|
|
126
139
|
mkdirSync(HOOKS_DIR, { recursive: true });
|
|
127
140
|
|
|
@@ -231,11 +244,27 @@ info('Edit any .specialist.yaml in ~/.agents/specialists/ to customise models, p
|
|
|
231
244
|
|
|
232
245
|
// 6. Claude Code hooks
|
|
233
246
|
section('Claude Code hooks');
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
247
|
+
const drift = getHookDrift();
|
|
248
|
+
const hooksExist = existsSync(HOOK_FILE);
|
|
249
|
+
|
|
250
|
+
if (!hooksExist) {
|
|
251
|
+
installHook();
|
|
252
|
+
ok('hooks installed → ~/.claude/hooks/');
|
|
253
|
+
} else if (drift.length === 0) {
|
|
254
|
+
skip('hooks up to date');
|
|
255
|
+
} else {
|
|
256
|
+
const label = (h) => h.missing ? red('missing') : yellow('updated');
|
|
257
|
+
console.log(` ${yellow('○')} ${drift.length} of 4 hook(s) have changes:`);
|
|
258
|
+
for (const h of drift) info(` ${h.name} ${label(h)}`);
|
|
259
|
+
console.log();
|
|
260
|
+
const confirmed = promptYN(' Update hooks?');
|
|
261
|
+
if (confirmed) {
|
|
262
|
+
installHook();
|
|
263
|
+
ok('hooks updated');
|
|
264
|
+
} else {
|
|
265
|
+
skip('hooks update skipped');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
239
268
|
info('main-guard: blocks file edits and direct master pushes (enforces PR workflow)');
|
|
240
269
|
info('beads-edit-gate: requires in_progress bead before editing files');
|
|
241
270
|
info('beads-commit-gate: requires issues closed before git commit');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaggerxtrm/specialists",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.18",
|
|
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",
|