@slamb2k/mad-skills 2.0.46 → 2.0.48

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mad-skills",
3
3
  "description": "AI-assisted planning, development and governance tools",
4
- "version": "2.0.46",
4
+ "version": "2.0.48",
5
5
  "author": {
6
6
  "name": "slamb2k",
7
7
  "url": "https://github.com/slamb2k"
@@ -13,7 +13,6 @@ const BANNER_LINES = [
13
13
  "::::: ##:.:: ##: ##.... ##: ##:::: ##::::'##::: ##: ##:. ##::: ##:: ##::::::: ##:::::::'##::: ##:::::::",
14
14
  "::::: ##:::: ##: ##:::: ##: ########:::::. ######:: ##::. ##:'####: ########: ########:. ######::::::::",
15
15
  "::::::..:::::..::..:::::..::........:::::::......:::..::::..::....::........::........:::......:::::::::",
16
- '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::',
17
16
  ];
18
17
 
19
18
  const SEPARATOR = '\u2500'.repeat(70);
@@ -62,8 +62,5 @@ module.exports = {
62
62
  'Read', 'Glob', 'Grep', 'ToolSearch', 'Agent', 'WebSearch', 'WebFetch',
63
63
  ],
64
64
  },
65
- hookify: {
66
- rulePattern: /^hookify\..*\.local\.md$/,
67
- },
68
65
  },
69
66
  };
@@ -2,7 +2,6 @@
2
2
 
3
3
  const { join } = require('path');
4
4
  const { homedir } = require('os');
5
- const { readdirSync } = require('fs');
6
5
  const config = require('./config.cjs');
7
6
  const state = require('./state.cjs');
8
7
  const { readJson } = require('./utils.cjs');
@@ -11,7 +10,6 @@ const { readJson } = require('./utils.cjs');
11
10
  * Plugin Health — detect performance anti-patterns in companion plugins.
12
11
  *
13
12
  * Checks:
14
- * - Hookify enabled with no rules (pure overhead)
15
13
  * - claude-mem missing SKIP_TOOLS for read-only tools
16
14
  * - claude-mem context injection too high (when OMC also active)
17
15
  *
@@ -27,38 +25,9 @@ function checkPluginHealth(projectDir, output) {
27
25
 
28
26
  const plugins = settings.enabledPlugins || {};
29
27
 
30
- checkHookify(projectDir, plugins, output);
31
28
  checkClaudeMem(plugins, output);
32
29
  }
33
30
 
34
- // ─── hookify ──────────────────────────────────────────────────────────
35
-
36
- function checkHookify(projectDir, plugins, output) {
37
- const hookifyKey = Object.keys(plugins).find(k => k.includes('hookify'));
38
- if (!hookifyKey || plugins[hookifyKey] !== true) return; // Not enabled
39
-
40
- // Count rule files in project .claude/ directory
41
- let ruleCount = 0;
42
- try {
43
- const projectClaudeDir = join(projectDir, '.claude');
44
- const files = readdirSync(projectClaudeDir);
45
- ruleCount = files.filter(f => config.pluginHealth.hookify.rulePattern.test(f)).length;
46
- } catch { /* directory doesn't exist — zero rules */ }
47
-
48
- // Also check global .claude/ directory
49
- try {
50
- const globalClaudeDir = join(homedir(), '.claude');
51
- const files = readdirSync(globalClaudeDir);
52
- ruleCount += files.filter(f => config.pluginHealth.hookify.rulePattern.test(f)).length;
53
- } catch { /* noop */ }
54
-
55
- if (ruleCount === 0) {
56
- output.signals.push(
57
- '\u26A0 Hookify enabled but no rules configured \u2014 fires on every tool call for nothing. Run /brace or disable in settings',
58
- );
59
- }
60
- }
61
-
62
31
  // ─── claude-mem ───────────────────────────────────────────────────────
63
32
 
64
33
  function checkClaudeMem(plugins, output) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slamb2k/mad-skills",
3
- "version": "2.0.46",
3
+ "version": "2.0.48",
4
4
  "description": "Claude Code skills collection — full lifecycle development tools",
5
5
  "type": "module",
6
6
  "repository": {
@@ -102,7 +102,7 @@ For each row, in order:
102
102
  **Plugin detection:** For plugin dependencies (Type = plugin), check
103
103
  `~/.claude/settings.json` → `enabledPlugins` for a key containing the plugin
104
104
  name set to `true`. Store results as `PLUGIN_STATE` (`claude_mem_installed`,
105
- `omc_installed`, `hookify_installed`) for use in Phase 4 and Phase 7.
105
+ `omc_installed`) for use in Phase 4 and Phase 7.
106
106
 
107
107
  1. Capture **FLAGS** from the user's request
108
108
 
@@ -170,16 +170,15 @@ Store result as `upgrade_legacy: true|false` in USER_CONFIG.
170
170
 
171
171
  4. Ask installation level via AskUserQuestion:
172
172
 
173
- Question: "Where should global preferences and universal principles go?"
173
+ Question: "Install universal guidance (preferences, principles) at user level?"
174
174
  Options:
175
- - "Both global + project (Recommended)" portable AND global coverage
176
- - "Global (~/.claude/CLAUDE.md) only" applies to all projects
177
- - "Project level only" → self-contained, portable
175
+ - "Yes, install globally (Recommended)" applies to all projects via `~/.claude/CLAUDE.md`
176
+ - "No, project level only" self-contained in this project's CLAUDE.md
178
177
 
179
178
  5. Store as USER_CONFIG:
180
179
  - project_name: from directory name or user override
181
180
  - description: from user input
182
- - install_level: "both" | "global" | "project"
181
+ - install_level: "global" | "project"
183
182
 
184
183
  **If cancelled, stop here.**
185
184
 
@@ -220,7 +219,7 @@ Will upgrade: {list of items with status "upgrade"}
220
219
  Will remove: {list of items with status "remove" — legacy cleanup}
221
220
  Will clean: {list of items with status "cleanup" — remove legacy references}
222
221
  Will skip: {count} existing items
223
- Global config: {install_level description}
222
+ Universal guidance: {install_level description}
224
223
 
225
224
  Proceed?
226
225
  ```
@@ -247,7 +246,7 @@ Before sending the prompt, substitute these variables:
247
246
  - `{ACTION_PLAN}` — the action plan from Phase 3
248
247
  - `{PROJECT_NAME}` — from USER_CONFIG
249
248
  - `{PROJECT_DESCRIPTION}` — from USER_CONFIG
250
- - `{INSTALL_LEVEL}` — from USER_CONFIG ("both", "global", or "project")
249
+ - `{INSTALL_LEVEL}` — from USER_CONFIG ("global" or "project")
251
250
  - `{CLAUDE_MD_TEMPLATE}` — read from `references/claude-md-template.md`
252
251
  (the section between BEGIN TEMPLATE and END TEMPLATE)
253
252
  - `{GITIGNORE_CONTENT}` — read from `assets/gitignore-template`
@@ -334,10 +333,10 @@ This phase modifies user-level settings files (`~/.claude/settings.json`,
334
333
  If `--force` is set, apply all recommendations without prompting.
335
334
 
336
335
  **Plugin presence guards:** Only audit plugins detected as installed during
337
- pre-flight (`PLUGIN_STATE`). Skip H1/H2 if hookify is absent. Skip M1/M2/M3
338
- if claude-mem is absent. Skip M2 if OMC is absent (M2 requires both). The
339
- `{PLUGIN_ROLE_SEPARATION}` content in CLAUDE.md is only injected when both
340
- claude-mem and OMC are confirmed enabled.
336
+ pre-flight (`PLUGIN_STATE`). Skip M1/M2/M3 if claude-mem is absent. Skip M2
337
+ if OMC is absent (M2 requires both). The `{PLUGIN_ROLE_SEPARATION}` content
338
+ in CLAUDE.md is only injected when both claude-mem and OMC are confirmed
339
+ enabled.
341
340
 
342
341
  If no companion plugins are installed at all, output:
343
342
  ```
@@ -383,8 +382,6 @@ If "Let me choose", present individual findings as multi-select.
383
382
 
384
383
  | Code | Check | Condition | Severity |
385
384
  |------|-------|-----------|----------|
386
- | H1 | Hookify: no rules | enabled + zero `hookify.*.local.md` files | high |
387
- | H2 | Hookify: python3 broken | enabled + `python3 --version` fails | high |
388
385
  | M1 | claude-mem: read-only tools | SKIP_TOOLS missing Read/Glob/Grep/ToolSearch/Agent/WebSearch/WebFetch | medium |
389
386
  | M2 | claude-mem: high context | observations > 10 or sessions > 3, AND OMC also enabled | medium |
390
387
  | M3 | claude-mem: provider=claude | provider is "claude" (SDK spawn known-broken) | low |
@@ -1,8 +1,11 @@
1
1
  # Global Preferences & Universal Principles
2
2
 
3
3
  Template appended to `~/.claude/CLAUDE.md` by brace when the user
4
- selects "global" or "both" installation level. The Phase 4 agent inserts
5
- this content before the "## Current Skills" section.
4
+ selects "global" install level. When the user selects "project" level,
5
+ this file is not used — instead, the universal principles are written
6
+ to the project CLAUDE.md (with a redundancy check against global).
7
+ The Phase 4 agent inserts this content before the "## Current Skills"
8
+ section.
6
9
 
7
10
  ---
8
11
 
@@ -4,9 +4,10 @@ Template for the generated project CLAUDE.md. The Phase 4 agent substitutes
4
4
  `{VARIABLE}` placeholders and writes to the project root.
5
5
 
6
6
  `{UNIVERSAL_PRINCIPLES}` is populated with the Question & Assumption
7
- Accountability and Communication sections when install_level is "project"
8
- or "both". Left empty when install_level is "global" (principles are in
9
- `~/.claude/CLAUDE.md` instead).
7
+ Accountability section when install_level is "project" AND those sections
8
+ are not already present in `~/.claude/CLAUDE.md`. Left empty when
9
+ install_level is "global" (principles are in the global config instead)
10
+ or when the sections would be redundant with existing global content.
10
11
 
11
12
  ---
12
13
 
@@ -146,21 +146,31 @@ skills-based workflow while preserving all other content.
146
146
  This project uses claude-mem for persistent cross-session memory.
147
147
  ```
148
148
 
149
- ### Global preferences (conditional)
149
+ ### Global preferences and universal principles
150
150
 
151
- If INSTALL_LEVEL is "global" or "both":
151
+ **If INSTALL_LEVEL is "global":**
152
152
  - Read ~/.claude/CLAUDE.md
153
153
  - If it does NOT contain "## Global Preferences", insert the Global
154
154
  Preferences Content (below) immediately before "## Current Skills"
155
155
  - If it already contains "## Global Preferences", skip (idempotent)
156
-
157
- ### {UNIVERSAL_PRINCIPLES} substitution
158
-
159
- If INSTALL_LEVEL is "project" or "both", substitute {UNIVERSAL_PRINCIPLES}
160
- in the CLAUDE.md template with the Universal Principles Content below.
161
-
162
- If INSTALL_LEVEL is "global", substitute {UNIVERSAL_PRINCIPLES} with an
163
- empty string (principles are in the global config instead).
156
+ - Substitute {UNIVERSAL_PRINCIPLES} in the project CLAUDE.md template with
157
+ an empty string (principles are in the global config instead).
158
+
159
+ **If INSTALL_LEVEL is "project":**
160
+ - Do NOT modify ~/.claude/CLAUDE.md.
161
+ - Before writing universal principles into the project CLAUDE.md, check
162
+ ~/.claude/CLAUDE.md for existing equivalent sections (redundancy guard):
163
+ - If global contains "## Global Preferences" SKIP that section in
164
+ project CLAUDE.md. Add to SCAFFOLD_REPORT.skipped_redundant.
165
+ - If global contains "## Universal Operating Principles" → SKIP that
166
+ section in project CLAUDE.md. Add to SCAFFOLD_REPORT.skipped_redundant.
167
+ - For any sections NOT found in global, substitute {UNIVERSAL_PRINCIPLES}
168
+ in the project CLAUDE.md template with only the non-redundant sections
169
+ from the Universal Principles Content below.
170
+ - If ALL sections are redundant, substitute {UNIVERSAL_PRINCIPLES} with
171
+ an empty string.
172
+ - Report each skipped section to the user:
173
+ "⏭️ Skipped {section} in project CLAUDE.md — already present in ~/.claude/CLAUDE.md"
164
174
 
165
175
  ### CLAUDE.md Template
166
176
 
@@ -206,6 +216,7 @@ SCAFFOLD_REPORT:
206
216
  cleaned: [list of files cleaned of legacy references]
207
217
  preserved_content: [any key decisions extracted from memory/MEMORY.md, or empty]
208
218
  skipped: [list of items skipped]
219
+ skipped_redundant: [sections skipped in project CLAUDE.md because already in global, or empty]
209
220
  global_updated: true|false|skipped
210
221
  errors: [any errors encountered]
211
222
  ```
@@ -286,39 +297,19 @@ Limit PLUGIN_REPORT to 30 lines maximum.
286
297
  node -e "
287
298
  const s = JSON.parse(require('fs').readFileSync('$HOME/.claude/settings.json','utf8'));
288
299
  const p = s.enabledPlugins || {};
289
- const hookify = Object.keys(p).find(k => k.includes('hookify'));
290
300
  const mem = Object.keys(p).find(k => k.includes('claude-mem'));
291
301
  const omc = Object.keys(p).find(k => k.includes('oh-my-claudecode'));
292
- console.log('hookify_installed:' + !!hookify);
293
- console.log('hookify_enabled:' + (hookify && p[hookify] === true));
294
302
  console.log('claude_mem_installed:' + !!mem);
295
303
  console.log('claude_mem_enabled:' + (mem && p[mem] === true));
296
304
  console.log('omc_installed:' + !!omc);
297
305
  console.log('omc_enabled:' + (omc && p[omc] === true));
298
306
  "
299
- Record: hookify_installed/enabled, claude_mem_installed/enabled, omc_installed/enabled
307
+ Record: claude_mem_installed/enabled, omc_installed/enabled
300
308
 
301
309
  If a plugin is not installed (not in enabledPlugins at all), skip its
302
310
  entire audit section below and report all its fields as "N/A".
303
311
 
304
- 2. **Hookify audit** (only if hookify_enabled == true)
305
- a. Check python3 availability:
306
- python3 --version >/dev/null 2>&1 && echo "python3_available:true" || echo "python3_available:false"
307
- Record: python3_available
308
-
309
- b. Count hookify rule files:
310
- RULE_COUNT=0
311
- for f in "$HOME/.claude"/hookify.*.local.md .claude/hookify.*.local.md; do
312
- [ -f "$f" ] && RULE_COUNT=$((RULE_COUNT + 1))
313
- done
314
- echo "hookify_rule_count:$RULE_COUNT"
315
- Record: hookify_rule_count
316
-
317
- c. Determine findings:
318
- - If python3_available == false → finding H2
319
- - If hookify_rule_count == 0 → finding H1
320
-
321
- 3. **claude-mem audit** (only if claude_mem_enabled == true)
312
+ 2. **claude-mem audit** (only if claude_mem_enabled == true)
322
313
  MEM_SETTINGS="$HOME/.claude-mem/settings.json"
323
314
  if [ -f "$MEM_SETTINGS" ]; then
324
315
  node -e "
@@ -349,10 +340,6 @@ Limit PLUGIN_REPORT to 30 lines maximum.
349
340
 
350
341
  PLUGIN_REPORT:
351
342
  settings_file_found: true|false
352
- hookify_installed: true|false
353
- hookify_enabled: true|false
354
- hookify_python3_available: true|false|N/A
355
- hookify_rule_count: {number}|N/A
356
343
  claude_mem_installed: true|false
357
344
  claude_mem_enabled: true|false
358
345
  claude_mem_skip_tools: {current value}|N/A
@@ -363,5 +350,5 @@ PLUGIN_REPORT:
363
350
  claude_mem_has_openrouter_key: true|false|N/A
364
351
  omc_installed: true|false
365
352
  omc_enabled: true|false
366
- findings: {comma-separated list of H1,H2,M1,M2,M3 or "none"}
353
+ findings: {comma-separated list of M1,M2,M3 or "none"}
367
354
  ```
@@ -6,28 +6,6 @@ checks current value before modifying.
6
6
 
7
7
  ---
8
8
 
9
- ## H1/H2: Disable Hookify
10
-
11
- Target: `~/.claude/settings.json`
12
-
13
- ```bash
14
- node -e "
15
- const fs = require('fs');
16
- const p = require('os').homedir() + '/.claude/settings.json';
17
- const s = JSON.parse(fs.readFileSync(p, 'utf8'));
18
- const key = Object.keys(s.enabledPlugins || {}).find(k => k.includes('hookify'));
19
- if (key && s.enabledPlugins[key] !== false) {
20
- s.enabledPlugins[key] = false;
21
- fs.writeFileSync(p, JSON.stringify(s, null, 2) + '\n');
22
- console.log('Disabled hookify');
23
- } else {
24
- console.log('Hookify already disabled — skipped');
25
- }
26
- "
27
- ```
28
-
29
- ---
30
-
31
9
  ## M1: Add Read-Only Tools to SKIP_TOOLS
32
10
 
33
11
  Target: `~/.claude-mem/settings.json`
@@ -19,6 +19,7 @@ Present this summary after verification completes.
19
19
 
20
20
  │ 📄 Files
21
21
  │ {✅|⏭️} CLAUDE.md
22
+ │ {✅|⏭️} ~/.claude/CLAUDE.md {updated / already present / skipped (project-only)}
22
23
  │ {✅|⏭️} .gitignore
23
24
 
24
25
  │ 🗑️ Removed (only if legacy items were cleaned up)
@@ -27,7 +28,6 @@ Present this summary after verification completes.
27
28
  │ {✅} memory/ Legacy memory directory
28
29
 
29
30
  │ 🔌 Plugin Tuning (only if Phase 7 ran)
30
- │ {✅|⏭️} Hookify: {disabled / already disabled / not installed / skipped / N/A}
31
31
  │ {✅|⏭️} claude-mem SKIP_TOOLS: {optimised / already optimal / not installed / skipped / N/A}
32
32
  │ {✅|⏭️} claude-mem context: {reduced / already optimal / not installed / skipped / N/A}
33
33
  │ {✅|⏭️} claude-mem provider: {switched / already optimal / not installed / skipped / N/A}
@@ -9,7 +9,7 @@ creation checklist. Phase 1 uses it to detect existing structure.
9
9
  |------|--------|-------------|
10
10
  | `CLAUDE.md` | references/claude-md-template.md | Project operating document |
11
11
  | `.gitignore` | assets/gitignore-template | Standard ignores |
12
- | `~/.claude/CLAUDE.md` | assets/global-preferences-template.md | Global preferences (conditional on install_level) |
12
+ | `~/.claude/CLAUDE.md` | assets/global-preferences-template.md | Global preferences (when install_level is "global") |
13
13
 
14
14
  ## Project Directories
15
15
 
@@ -1,12 +1,12 @@
1
1
  {
2
- "generated": "2026-04-17T04:43:53.359Z",
2
+ "generated": "2026-04-17T05:36:15.739Z",
3
3
  "count": 10,
4
4
  "skills": [
5
5
  {
6
6
  "name": "brace",
7
7
  "directory": "brace",
8
8
  "description": "'Initialize any project directory with a standard scaffold for AI-assisted development. Creates specs/ and context/ directories, a project CLAUDE.md with development workflow and guardrails, .gitignore, and branch protection. Recommends claude-mem for persistent memory. Idempotent — safe to run on existing projects. Triggers: \"init project\", \"setup brace\", \"brace\", \"initialize\", \"bootstrap\", \"scaffold\".'",
9
- "lines": 427,
9
+ "lines": 424,
10
10
  "hasScripts": false,
11
11
  "hasReferences": true,
12
12
  "hasAssets": true,