@massu/core 0.5.0 → 0.6.1

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 (119) hide show
  1. package/README.md +40 -0
  2. package/agents/massu-architecture-reviewer.md +104 -0
  3. package/agents/massu-blast-radius-analyzer.md +84 -0
  4. package/agents/massu-competitive-scorer.md +126 -0
  5. package/agents/massu-help-sync.md +73 -0
  6. package/agents/massu-migration-writer.md +94 -0
  7. package/agents/massu-output-scorer.md +87 -0
  8. package/agents/massu-pattern-reviewer.md +84 -0
  9. package/agents/massu-plan-auditor.md +170 -0
  10. package/agents/massu-schema-sync-verifier.md +70 -0
  11. package/agents/massu-security-reviewer.md +98 -0
  12. package/agents/massu-ux-reviewer.md +106 -0
  13. package/commands/_shared-preamble.md +53 -23
  14. package/commands/_shared-references/auto-learning-protocol.md +71 -0
  15. package/commands/_shared-references/blast-radius-protocol.md +76 -0
  16. package/commands/_shared-references/security-pre-screen.md +64 -0
  17. package/commands/_shared-references/test-first-protocol.md +87 -0
  18. package/commands/_shared-references/verification-table.md +55 -0
  19. package/commands/massu-article-review.md +343 -0
  20. package/commands/massu-autoresearch/references/eval-runner.md +84 -0
  21. package/commands/massu-autoresearch/references/safety-rails.md +125 -0
  22. package/commands/massu-autoresearch/references/scoring-protocol.md +151 -0
  23. package/commands/massu-autoresearch.md +258 -0
  24. package/commands/massu-batch.md +44 -12
  25. package/commands/massu-bearings.md +42 -8
  26. package/commands/massu-checkpoint.md +588 -0
  27. package/commands/massu-ci-fix.md +2 -2
  28. package/commands/massu-command-health.md +132 -0
  29. package/commands/massu-command-improve.md +232 -0
  30. package/commands/massu-commit.md +205 -44
  31. package/commands/massu-create-plan.md +239 -57
  32. package/commands/massu-data/references/common-queries.md +79 -0
  33. package/commands/massu-data/references/table-guide.md +50 -0
  34. package/commands/massu-data.md +66 -0
  35. package/commands/massu-dead-code.md +29 -34
  36. package/commands/massu-debug/references/auto-learning.md +61 -0
  37. package/commands/massu-debug/references/codegraph-tracing.md +80 -0
  38. package/commands/massu-debug/references/common-shortcuts.md +98 -0
  39. package/commands/massu-debug/references/investigation-phases.md +294 -0
  40. package/commands/massu-debug/references/report-format.md +107 -0
  41. package/commands/massu-debug.md +105 -386
  42. package/commands/massu-docs.md +1 -1
  43. package/commands/massu-full-audit.md +61 -0
  44. package/commands/massu-gap-enhancement-analyzer.md +276 -16
  45. package/commands/massu-golden-path/references/approval-points.md +216 -0
  46. package/commands/massu-golden-path/references/competitive-mode.md +273 -0
  47. package/commands/massu-golden-path/references/error-handling.md +121 -0
  48. package/commands/massu-golden-path/references/phase-0-requirements.md +53 -0
  49. package/commands/massu-golden-path/references/phase-1-plan-creation.md +168 -0
  50. package/commands/massu-golden-path/references/phase-2-implementation.md +403 -0
  51. package/commands/massu-golden-path/references/phase-2.5-gap-analyzer.md +170 -0
  52. package/commands/massu-golden-path/references/phase-3-simplify.md +40 -0
  53. package/commands/massu-golden-path/references/phase-3.5-security-audit.md +108 -0
  54. package/commands/massu-golden-path/references/phase-4-commit.md +94 -0
  55. package/commands/massu-golden-path/references/phase-5-push.md +116 -0
  56. package/commands/massu-golden-path/references/phase-5.5-production-verify.md +170 -0
  57. package/commands/massu-golden-path/references/phase-6-completion.md +113 -0
  58. package/commands/massu-golden-path/references/qa-evaluator-spec.md +137 -0
  59. package/commands/massu-golden-path/references/sprint-contract-protocol.md +117 -0
  60. package/commands/massu-golden-path/references/vr-visual-calibration.md +73 -0
  61. package/commands/massu-golden-path.md +121 -844
  62. package/commands/massu-guide.md +72 -69
  63. package/commands/massu-hooks.md +27 -12
  64. package/commands/massu-hotfix.md +221 -144
  65. package/commands/massu-incident.md +49 -20
  66. package/commands/massu-infra-audit.md +187 -0
  67. package/commands/massu-learning-audit.md +211 -0
  68. package/commands/massu-loop/references/auto-learning.md +49 -0
  69. package/commands/massu-loop/references/checkpoint-audit.md +40 -0
  70. package/commands/massu-loop/references/guardrails.md +17 -0
  71. package/commands/massu-loop/references/iteration-structure.md +115 -0
  72. package/commands/massu-loop/references/loop-controller.md +188 -0
  73. package/commands/massu-loop/references/plan-extraction.md +78 -0
  74. package/commands/massu-loop/references/vr-plan-spec.md +140 -0
  75. package/commands/massu-loop-playwright.md +9 -9
  76. package/commands/massu-loop.md +115 -670
  77. package/commands/massu-new-pattern.md +423 -0
  78. package/commands/massu-perf.md +422 -0
  79. package/commands/massu-plan-audit.md +1 -1
  80. package/commands/massu-plan.md +389 -122
  81. package/commands/massu-production-verify.md +433 -0
  82. package/commands/massu-push.md +62 -378
  83. package/commands/massu-recap.md +29 -3
  84. package/commands/massu-rollback.md +613 -0
  85. package/commands/massu-scaffold-hook.md +2 -4
  86. package/commands/massu-scaffold-page.md +2 -3
  87. package/commands/massu-scaffold-router.md +1 -2
  88. package/commands/massu-security.md +619 -0
  89. package/commands/massu-simplify.md +115 -85
  90. package/commands/massu-squirrels.md +2 -2
  91. package/commands/massu-tdd.md +38 -22
  92. package/commands/massu-test.md +3 -3
  93. package/commands/massu-type-mismatch-audit.md +469 -0
  94. package/commands/massu-ui-audit.md +587 -0
  95. package/commands/massu-verify-playwright.md +287 -32
  96. package/commands/massu-verify.md +150 -46
  97. package/dist/cli.js +146 -95
  98. package/package.json +6 -2
  99. package/patterns/build-patterns.md +302 -0
  100. package/patterns/component-patterns.md +246 -0
  101. package/patterns/display-patterns.md +185 -0
  102. package/patterns/form-patterns.md +890 -0
  103. package/patterns/integration-testing-checklist.md +445 -0
  104. package/patterns/security-patterns.md +219 -0
  105. package/patterns/testing-patterns.md +569 -0
  106. package/patterns/tool-routing.md +81 -0
  107. package/patterns/ui-patterns.md +371 -0
  108. package/protocols/plan-implementation.md +267 -0
  109. package/protocols/recovery.md +225 -0
  110. package/protocols/verification.md +404 -0
  111. package/reference/command-taxonomy.md +178 -0
  112. package/reference/cr-rules-reference.md +76 -0
  113. package/reference/hook-execution-order.md +148 -0
  114. package/reference/lessons-learned.md +175 -0
  115. package/reference/patterns-quickref.md +208 -0
  116. package/reference/standards.md +135 -0
  117. package/reference/subagents-reference.md +17 -0
  118. package/reference/vr-verification-reference.md +867 -0
  119. package/src/commands/install-commands.ts +149 -53
@@ -2,15 +2,16 @@
2
2
  // Licensed under BSL 1.1 - see LICENSE file for details.
3
3
 
4
4
  /**
5
- * `massu install-commands` — Install massu slash commands into a project.
5
+ * `massu install-commands` — Install massu slash commands, agents, patterns,
6
+ * protocols, and reference files into a project.
6
7
  *
7
- * Copies all massu command .md files from the package's commands/ directory
8
- * into the project's .claude/commands/ directory. Existing massu commands
9
- * are updated; non-massu commands are preserved.
8
+ * Copies all massu assets from the npm package into the project's .claude/
9
+ * directory. Existing massu files are updated; non-massu files are preserved.
10
+ * Handles subdirectories recursively (e.g., golden-path/references/).
10
11
  */
11
12
 
12
- import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
13
- import { resolve, dirname } from 'path';
13
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, statSync } from 'fs';
14
+ import { resolve, dirname, relative, join } from 'path';
14
15
  import { fileURLToPath } from 'url';
15
16
  import { getConfig } from '../config.ts';
16
17
 
@@ -18,30 +19,43 @@ const __filename = fileURLToPath(import.meta.url);
18
19
  const __dirname = dirname(__filename);
19
20
 
20
21
  // ============================================================
21
- // Command Installation
22
+ // Asset Types
23
+ // ============================================================
24
+
25
+ /** Asset categories distributed by massu */
26
+ const ASSET_TYPES = [
27
+ { name: 'commands', targetSubdir: 'commands', description: 'slash commands' },
28
+ { name: 'agents', targetSubdir: 'agents', description: 'agent definitions' },
29
+ { name: 'patterns', targetSubdir: 'patterns', description: 'pattern files' },
30
+ { name: 'protocols', targetSubdir: 'protocols', description: 'protocol files' },
31
+ { name: 'reference', targetSubdir: 'reference', description: 'reference files' },
32
+ ] as const;
33
+
34
+ // ============================================================
35
+ // Directory Resolution
22
36
  // ============================================================
23
37
 
24
38
  /**
25
- * Resolve the path to the bundled commands directory.
39
+ * Resolve the path to a bundled asset directory.
26
40
  * Handles both npm-installed and local development scenarios.
27
41
  */
28
- export function resolveCommandsDir(): string | null {
42
+ export function resolveAssetDir(assetName: string): string | null {
29
43
  const cwd = process.cwd();
30
44
 
31
- // 1. npm-installed: node_modules/@massu/core/commands
32
- const nodeModulesPath = resolve(cwd, 'node_modules/@massu/core/commands');
45
+ // 1. npm-installed: node_modules/@massu/core/{assetName}
46
+ const nodeModulesPath = resolve(cwd, 'node_modules/@massu/core', assetName);
33
47
  if (existsSync(nodeModulesPath)) {
34
48
  return nodeModulesPath;
35
49
  }
36
50
 
37
- // 2. Relative to compiled dist/cli.js → ../commands
38
- const distRelPath = resolve(__dirname, '../commands');
51
+ // 2. Relative to compiled dist/cli.js → ../{assetName}
52
+ const distRelPath = resolve(__dirname, '..', assetName);
39
53
  if (existsSync(distRelPath)) {
40
54
  return distRelPath;
41
55
  }
42
56
 
43
- // 3. Relative to source src/commands/ → ../../commands
44
- const srcRelPath = resolve(__dirname, '../../commands');
57
+ // 3. Relative to source src/commands/ → ../../{assetName}
58
+ const srcRelPath = resolve(__dirname, '../..', assetName);
45
59
  if (existsSync(srcRelPath)) {
46
60
  return srcRelPath;
47
61
  }
@@ -49,6 +63,70 @@ export function resolveCommandsDir(): string | null {
49
63
  return null;
50
64
  }
51
65
 
66
+ /** Legacy alias for backwards compatibility */
67
+ export function resolveCommandsDir(): string | null {
68
+ return resolveAssetDir('commands');
69
+ }
70
+
71
+ // ============================================================
72
+ // Recursive File Sync
73
+ // ============================================================
74
+
75
+ interface SyncStats {
76
+ installed: number;
77
+ updated: number;
78
+ skipped: number;
79
+ }
80
+
81
+ /**
82
+ * Recursively sync all .md files from sourceDir to targetDir.
83
+ * Creates subdirectories as needed. Preserves non-massu files.
84
+ */
85
+ function syncDirectory(sourceDir: string, targetDir: string): SyncStats {
86
+ const stats: SyncStats = { installed: 0, updated: 0, skipped: 0 };
87
+
88
+ if (!existsSync(targetDir)) {
89
+ mkdirSync(targetDir, { recursive: true });
90
+ }
91
+
92
+ const entries = readdirSync(sourceDir);
93
+
94
+ for (const entry of entries) {
95
+ const sourcePath = resolve(sourceDir, entry);
96
+ const targetPath = resolve(targetDir, entry);
97
+ const entryStat = statSync(sourcePath);
98
+
99
+ if (entryStat.isDirectory()) {
100
+ // Recurse into subdirectories
101
+ const subStats = syncDirectory(sourcePath, targetPath);
102
+ stats.installed += subStats.installed;
103
+ stats.updated += subStats.updated;
104
+ stats.skipped += subStats.skipped;
105
+ } else if (entry.endsWith('.md')) {
106
+ const sourceContent = readFileSync(sourcePath, 'utf-8');
107
+
108
+ if (existsSync(targetPath)) {
109
+ const existingContent = readFileSync(targetPath, 'utf-8');
110
+ if (existingContent === sourceContent) {
111
+ stats.skipped++;
112
+ continue;
113
+ }
114
+ writeFileSync(targetPath, sourceContent, 'utf-8');
115
+ stats.updated++;
116
+ } else {
117
+ writeFileSync(targetPath, sourceContent, 'utf-8');
118
+ stats.installed++;
119
+ }
120
+ }
121
+ }
122
+
123
+ return stats;
124
+ }
125
+
126
+ // ============================================================
127
+ // Install Commands (legacy API — preserved for backwards compat)
128
+ // ============================================================
129
+
52
130
  export interface InstallCommandsResult {
53
131
  installed: number;
54
132
  updated: number;
@@ -60,48 +138,58 @@ export function installCommands(projectRoot: string): InstallCommandsResult {
60
138
  const claudeDirName = getConfig().conventions?.claudeDirName ?? '.claude';
61
139
  const targetDir = resolve(projectRoot, claudeDirName, 'commands');
62
140
 
63
- // Ensure .claude/commands directory exists
64
141
  if (!existsSync(targetDir)) {
65
142
  mkdirSync(targetDir, { recursive: true });
66
143
  }
67
144
 
68
- // Find source commands
69
- const sourceDir = resolveCommandsDir();
145
+ const sourceDir = resolveAssetDir('commands');
70
146
  if (!sourceDir) {
71
147
  console.error(' ERROR: Could not find massu commands directory.');
72
148
  console.error(' Try reinstalling: npm install @massu/core');
73
149
  return { installed: 0, updated: 0, skipped: 0, commandsDir: targetDir };
74
150
  }
75
151
 
76
- // Read all command files from source
77
- const sourceFiles = readdirSync(sourceDir).filter(f => f.endsWith('.md'));
152
+ const stats = syncDirectory(sourceDir, targetDir);
153
+ return { ...stats, commandsDir: targetDir };
154
+ }
78
155
 
79
- let installed = 0;
80
- let updated = 0;
81
- let skipped = 0;
156
+ // ============================================================
157
+ // Install All Assets
158
+ // ============================================================
82
159
 
83
- for (const file of sourceFiles) {
84
- const sourcePath = resolve(sourceDir, file);
85
- const targetPath = resolve(targetDir, file);
86
- const sourceContent = readFileSync(sourcePath, 'utf-8');
160
+ export interface InstallAllResult {
161
+ assets: Record<string, SyncStats>;
162
+ totalInstalled: number;
163
+ totalUpdated: number;
164
+ totalSkipped: number;
165
+ claudeDir: string;
166
+ }
87
167
 
88
- if (existsSync(targetPath)) {
89
- const existingContent = readFileSync(targetPath, 'utf-8');
90
- if (existingContent === sourceContent) {
91
- skipped++;
92
- continue;
93
- }
94
- // Update existing command
95
- writeFileSync(targetPath, sourceContent, 'utf-8');
96
- updated++;
97
- } else {
98
- // Install new command
99
- writeFileSync(targetPath, sourceContent, 'utf-8');
100
- installed++;
168
+ export function installAll(projectRoot: string): InstallAllResult {
169
+ const claudeDirName = getConfig().conventions?.claudeDirName ?? '.claude';
170
+ const claudeDir = resolve(projectRoot, claudeDirName);
171
+
172
+ const assets: Record<string, SyncStats> = {};
173
+ let totalInstalled = 0;
174
+ let totalUpdated = 0;
175
+ let totalSkipped = 0;
176
+
177
+ for (const assetType of ASSET_TYPES) {
178
+ const sourceDir = resolveAssetDir(assetType.name);
179
+ if (!sourceDir) {
180
+ continue;
101
181
  }
182
+
183
+ const targetDir = resolve(claudeDir, assetType.targetSubdir);
184
+ const stats = syncDirectory(sourceDir, targetDir);
185
+
186
+ assets[assetType.name] = stats;
187
+ totalInstalled += stats.installed;
188
+ totalUpdated += stats.updated;
189
+ totalSkipped += stats.skipped;
102
190
  }
103
191
 
104
- return { installed, updated, skipped, commandsDir: targetDir };
192
+ return { assets, totalInstalled, totalUpdated, totalSkipped, claudeDir };
105
193
  }
106
194
 
107
195
  // ============================================================
@@ -112,25 +200,33 @@ export async function runInstallCommands(): Promise<void> {
112
200
  const projectRoot = process.cwd();
113
201
 
114
202
  console.log('');
115
- console.log('Massu AI - Install Slash Commands');
203
+ console.log('Massu AI - Install Project Assets');
116
204
  console.log('==================================');
117
205
  console.log('');
118
206
 
119
- const result = installCommands(projectRoot);
207
+ const result = installAll(projectRoot);
120
208
 
121
- if (result.installed > 0) {
122
- console.log(` Installed ${result.installed} new commands`);
123
- }
124
- if (result.updated > 0) {
125
- console.log(` Updated ${result.updated} existing commands`);
126
- }
127
- if (result.skipped > 0) {
128
- console.log(` ${result.skipped} commands already up to date`);
209
+ // Report per-asset-type
210
+ for (const assetType of ASSET_TYPES) {
211
+ const stats = result.assets[assetType.name];
212
+ if (!stats) {
213
+ continue;
214
+ }
215
+ const total = stats.installed + stats.updated + stats.skipped;
216
+ if (total === 0) continue;
217
+
218
+ const parts: string[] = [];
219
+ if (stats.installed > 0) parts.push(`${stats.installed} new`);
220
+ if (stats.updated > 0) parts.push(`${stats.updated} updated`);
221
+ if (stats.skipped > 0) parts.push(`${stats.skipped} current`);
222
+
223
+ const description = assetType.description;
224
+ console.log(` ${description}: ${parts.join(', ')} (${total} total)`);
129
225
  }
130
226
 
131
- const total = result.installed + result.updated + result.skipped;
227
+ const grandTotal = result.totalInstalled + result.totalUpdated + result.totalSkipped;
132
228
  console.log('');
133
- console.log(` ${total} slash commands available in ${result.commandsDir}`);
229
+ console.log(` ${grandTotal} total files synced to ${result.claudeDir}`);
134
230
  console.log('');
135
231
  console.log(' Restart your Claude Code session to use them.');
136
232
  console.log('');