@clfhhc/bmad-methods-skills 0.0.2 → 0.0.3

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.
@@ -79,7 +79,7 @@ async function install(args) {
79
79
  );
80
80
  }
81
81
 
82
- console.log(`\n✅ Installation complete.`);
82
+ console.log('\n✅ Installation complete.');
83
83
  }
84
84
 
85
85
  async function init(args) {
@@ -88,6 +88,88 @@ async function init(args) {
88
88
  const toolInfo = await detectTool(args);
89
89
  if (!toolInfo) return;
90
90
 
91
+ // Check for bootstrap flag
92
+ const isBootstrap = args.includes('--bootstrap');
93
+
94
+ if (isBootstrap) {
95
+ console.log('🔄 Bootstrapping full BMAD suite...');
96
+
97
+ // 1. Run conversion
98
+ const tempDir = '.temp/converted-skills-bootstrap';
99
+ console.log(`\n--- Step 1: Fetching & Converting (${tempDir}) ---`);
100
+ process.env.BMAD_OUTPUT_DIR = tempDir; // Pass specific output dir to convert.js
101
+
102
+ // Create synthetic args for convert.js
103
+ // We filter out init-specific args to avoid confusion, but keep repo/branch overrides
104
+ const convertArgs = args.filter(a =>
105
+ !['init', '--bootstrap', '--force', '--tool'].some(x => a.includes(x))
106
+ );
107
+
108
+ // Temporarily override argv for the imported module
109
+ const originalArgv = process.argv;
110
+ process.argv = [process.argv[0], process.argv[1], ...convertArgs, '--output-dir', tempDir];
111
+
112
+ try {
113
+ // Import runs the main function automatically if we aren't careful?
114
+ // Wait, convert.js runs main() at the end. We should probably refactor convert.js to export main
115
+ // but simpler hack: just run it as a child process if import is messy,
116
+ // OR rely on dynamic import executing top-level code.
117
+ // Dynamic import executes top-level code ONCE. If we imported it before, it won't run again.
118
+ // Safe bet: spawn a clean process.
119
+ const { spawn } = await import('node:child_process');
120
+ const binPath = fileURLToPath(import.meta.url); // this file
121
+
122
+ await new Promise((resolve, reject) => {
123
+ // Run self without command -> trigger convert logic
124
+ const child = spawn(process.execPath, [binPath, ...convertArgs, '--output-dir', tempDir], {
125
+ stdio: 'inherit'
126
+ });
127
+ child.on('close', (code) => {
128
+ if (code === 0) resolve();
129
+ else reject(new Error(`Conversion failed with code ${code}`));
130
+ });
131
+ });
132
+
133
+ } catch (error) {
134
+ console.error(`❌ Bootstrap conversion failed: ${error.message}`);
135
+ process.argv = originalArgv; // Restore
136
+ return;
137
+ }
138
+ process.argv = originalArgv; // Restore
139
+
140
+ // 2. Install
141
+ console.log(`\n--- Step 2: Installing to ${toolInfo.name} ---`);
142
+ await install([
143
+ 'install',
144
+ `--from=${tempDir}`,
145
+ `--tool=${toolInfo.name.toLowerCase()}`, // Ensure generic name match
146
+ '--force' // Always force in bootstrap mode? Or respect args? Let's use force for bootstrap convenience
147
+ ]);
148
+
149
+ // 3. Install bundled skills (bootstrap-bmad-skills, enhance-bmad-skills)
150
+ // We reuse the logic from the standard init, but silence it slightly or just run it
151
+ const skillsDir = path.join(pkgRoot, 'skills');
152
+ if (await fs.pathExists(skillsDir)) {
153
+ const skills = await fs.readdir(skillsDir);
154
+ for (const skill of skills) {
155
+ if ((await fs.stat(path.join(skillsDir, skill))).isDirectory()) {
156
+ await installSkill(skill, path.join(skillsDir, skill), path.join(process.cwd(), toolInfo.path, skill), true);
157
+ }
158
+ }
159
+ }
160
+
161
+ // Cleanup
162
+ try {
163
+ await fs.remove('.temp'); // Remove generic temp if used
164
+ // Note: we used specific temp dir, removing that
165
+ if (tempDir.startsWith('.temp')) await fs.remove('.temp');
166
+ } catch (e) { /* ignore */ }
167
+
168
+ console.log('\n✨ Bootstrap functionality complete!');
169
+ return;
170
+ }
171
+
172
+ // STANDARD INIT (Bootstrap skills only)
91
173
  console.log(`📦 Installing Bootstrap Skills for ${toolInfo.name}...`);
92
174
 
93
175
  // Dynamically find skills in package
@@ -125,7 +207,8 @@ async function init(args) {
125
207
  console.log(`\n✅ Successfully initialized in: ${toolInfo.path}/`);
126
208
  console.log('\nNext steps:');
127
209
  console.log(`1. Open your AI chat (${toolInfo.name}).`);
128
- console.log('2. Type "BS" or "bootstrap-skills" to fetch and install the full BMAD method suite.');
210
+ console.log('2. Run "npx @clfhhc/bmad-methods-skills init --bootstrap" to auto-install everything.');
211
+ console.log(' OR Type "BS" in chat for the guided workflow.');
129
212
  } catch (error) {
130
213
  console.error(`\n❌ Installation failed: ${error.message}`);
131
214
  }
@@ -138,7 +221,7 @@ async function installSkill(name, source, target, force) {
138
221
  if (await fs.pathExists(target)) {
139
222
  if (!force) {
140
223
  console.warn(` ⚠ Skill '${name}' already exists. Skipping.`);
141
- console.warn(' (Use --force to overwrite)');
224
+ console.warn(' (Use --force to overwrite)');
142
225
  return;
143
226
  }
144
227
  console.log(` ↻ Updating ${name}...`);
@@ -196,6 +279,7 @@ Commands:
196
279
  Options (for init/install):
197
280
  --tool=<name> Specify tool (antigravity, cursor, claude)
198
281
  --force Overwrite existing skills / Force installation
282
+ --bootstrap Automatically fetch, convert, and install full suite
199
283
  --from=<path> (install only) Source directory containing skills
200
284
 
201
285
  Options (for conversion):
package/convert.js CHANGED
@@ -6,6 +6,7 @@ import { findAgentsAndWorkflows } from './src/utils/file-finder.js';
6
6
  import { convertAgentToSkill } from './src/converters/agent-converter.js';
7
7
  import { convertWorkflowToSkill } from './src/converters/workflow-converter.js';
8
8
  import { writeSkill } from './src/utils/skill-writer.js';
9
+ import { migrateResources } from './src/utils/resource-migrator.js';
9
10
 
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = path.dirname(__filename);
@@ -300,7 +301,10 @@ async function main() {
300
301
  console.log();
301
302
  }
302
303
 
303
- // Step 6: Generate summary
304
+ // Step 6: Migrate auxiliary resources
305
+ await migrateResources(bmadRoot, outputDir);
306
+
307
+ // Step 7: Generate summary
304
308
  await printSummary();
305
309
  } catch (error) {
306
310
  console.error(`\n❌ Fatal error: ${error.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clfhhc/bmad-methods-skills",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Convert BMAD-METHOD agents and workflows to Claude Skills format",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.28.0",
@@ -15,52 +15,28 @@ This skill guides the user through fetching, converting, enhancing, and installi
15
15
 
16
16
  ---
17
17
 
18
- ## Workflow
18
+ ### Step 1: Automated Bootstrap (Recommended)
19
+ Run the automated bootstrap command to fetch, convert, and install the full BMAD method suite.
20
+ 1. **Run**: `npx @clfhhc/bmad-methods-skills init --bootstrap`
21
+ 2. **Verify**: Check that skills are installed in the tool directory (e.g., `.agent/skills`).
19
22
 
20
- ### Step 1: Tool Identification
21
- Ask the user which tool(s) they are using. Multiple selections are allowed.
22
- - [ ] Claude Code
23
- - [ ] Cursor
24
- - [ ] Antigravity
25
- - [ ] Other (Specify)
23
+ ### Step 2: Manual Workflow (Alternative)
24
+ If custom configuration is needed, follow these steps:
26
25
 
27
- ### Step 2: Installation Scope
28
- Ask whether to install the skills as global or project-specific.
29
- - **Global**: Skills will be available across all projects for that tool.
30
- - **Project-Specific**: Skills will be limited to the current repository.
26
+ **2.1 Fetch & Convert**
27
+ Run `npx @clfhhc/bmad-methods-skills --output-dir .temp/converted-skills` to fetch the `main` branch and convert agents/workflows.
31
28
 
32
- ### Step 3: Fetch & Convert
33
- Inform the user that you will now fetch the `bmad-methods` main branch and convert it in a temporary folder.
29
+ **2.2 Apply Enhancements**
30
+ 1. **Scan Paths**: Check for `{project-root}` references.
31
+ 2. **Adapt Paths**: Adjust paths for your specific installation scope.
34
32
 
35
- 1. **Convert**: Run `npx @clfhhc/bmad-methods-skills --output-dir .temp/converted-skills`
36
- - This fetches the `main` branch of BMAD-METHOD and converts all agents/workflows.
33
+ **2.3 Install Skills**
34
+ Run the `install` command to move skills to their final destination.
35
+ - Run `npx @clfhhc/bmad-methods-skills install --from .temp/converted-skills --tool [TOOL] --force`
36
+ - Replace `[TOOL]` with `antigravity`, `cursor`, or `claude`.
37
37
 
38
- ### Step 4: Apply Enhancements
39
- Apply Phase 2 path adaptations and Phase 3 meta-docs.
40
-
41
- 1. **Scan Paths**: Use the `enhance-bmad-skills` (`SP`) command to scan the converted skills for `{project-root}` references.
42
- 2. **Adapt Paths**: Propose path adaptations (relative vs absolute) based on the target installation type.
43
- - If **Global**: Prefer absolute paths or relative to a fixed global root.
44
- - If **Project-Specific**: Prefer relative paths within the project.
45
-
46
- ### Step 5: Install Skills
47
- Run the `install` command to move the enhanced skills to their final destination.
48
-
49
- 1. **Install**: Run `npx @clfhhc/bmad-methods-skills install --from .temp/converted-skills --tool [TOOL] --force`
50
- - Replace `[TOOL]` with `antigravity`, `cursor`, or `claude`.
51
- - Use `--force` to overwrite if you are sure.
52
-
53
- | Tool | Scope | Destination |
54
- |------|-------|-------------|
55
- | **Claude Code** | Global | `~/.claude/skills/` |
56
- | **Claude Code** | Local | `./.claude/skills/` |
57
- | **Cursor** | Local | `./.cursor/skills/` |
58
- | **Antigravity** | Local | `./.agent/skills/` |
59
-
60
- *Note: The CLI will handle directory creation and copying.*
61
-
62
- ### Step 6: Verify
63
- Ensure all file paths in the `SKILL.md` files are correct and that any referenced `data/` or `knowledge/` folders were moved correctly.
38
+ ### Step 3: Verify
39
+ Ensure all file paths in the `SKILL.md` files are correct and that `data/` or `knowledge/` folders were moved correctly (automated in Step 1).
64
40
 
65
41
  ---
66
42
 
@@ -148,6 +148,17 @@ export function rewriteBmadPaths(content, _currentModule = 'bmm') {
148
148
  `${relativePrefix}/bmm/tea/tea-index.csv`
149
149
  );
150
150
 
151
+ // Rewrite documentation-standards.md references (migrated to tech-writer/data)
152
+ // {project-root}/_bmad/bmm/data/documentation-standards.md -> ../../bmm/tech-writer/data/documentation-standards.md
153
+ // But wait, if we are IN tech-writer, it should be ./data/documentation-standards.md
154
+ // The relativePrefix logic handles ../.. but we might prefer a direct replacement here
155
+ // since it's a specific file.
156
+ // Let's rely on the generic ../..bmm/tech-writer/data approach which works from anywhere.
157
+ result = result.replace(
158
+ /\{project-root\}\/_bmad\/bmm\/data\/documentation-standards\.md/g,
159
+ `${relativePrefix}/bmm/tech-writer/data/documentation-standards.md`
160
+ );
161
+
151
162
  // Rewrite _memory sidecar references (these are runtime, mark as placeholder)
152
163
  result = result.replace(
153
164
  /\{project-root\}\/_bmad\/_memory\/([^/\s'"]+)/g,
@@ -0,0 +1,65 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+
4
+ /**
5
+ * Migrates specific data and knowledge resources from BMAD repo to skills output
6
+ * @param {string} bmadRoot - Root of the fetched BMAD repo
7
+ * @param {string} outputDir - Root of the skills output directory
8
+ */
9
+ export async function migrateResources(bmadRoot, outputDir) {
10
+ console.log('📦 Migrating auxiliary resources...');
11
+
12
+ const migrations = [
13
+ {
14
+ // Tech Writer: documentation-standards.md
15
+ // From: src/modules/bmm/data/documentation-standards.md
16
+ // To: bmm/tech-writer/data/documentation-standards.md
17
+ src: path.join('src', 'modules', 'bmm', 'data', 'documentation-standards.md'),
18
+ dest: path.join('bmm', 'tech-writer', 'data', 'documentation-standards.md'),
19
+ name: 'Documentation Standards',
20
+ },
21
+ {
22
+ // TEA: tea-index.csv
23
+ // From: src/modules/bmm/testarch/tea-index.csv
24
+ // To: bmm/tea/tea-index.csv
25
+ src: path.join('src', 'modules', 'bmm', 'testarch', 'tea-index.csv'),
26
+ dest: path.join('bmm', 'tea', 'tea-index.csv'),
27
+ name: 'TEA Index',
28
+ },
29
+ {
30
+ // TEA: knowledge directory
31
+ // From: src/modules/bmm/testarch/knowledge/
32
+ // To: bmm/tea/knowledge/
33
+ src: path.join('src', 'modules', 'bmm', 'testarch', 'knowledge'),
34
+ dest: path.join('bmm', 'tea', 'knowledge'),
35
+ name: 'TEA Knowledge Base',
36
+ isDirectory: true,
37
+ }
38
+ ];
39
+
40
+ let migratedCount = 0;
41
+
42
+ for (const migration of migrations) {
43
+ try {
44
+ const srcPath = path.join(bmadRoot, migration.src);
45
+ const destPath = path.join(outputDir, migration.dest);
46
+
47
+ if (await fs.pathExists(srcPath)) {
48
+ await fs.ensureDir(path.dirname(destPath));
49
+ await fs.copy(srcPath, destPath, { overwrite: true });
50
+ console.log(` ✓ Migrated ${migration.name}`);
51
+ migratedCount++;
52
+ } else {
53
+ console.warn(` ⚠️ Source not found for ${migration.name}: ${migration.src}`);
54
+ }
55
+ } catch (error) {
56
+ console.error(` ✗ Failed to migrate ${migration.name}: ${error.message}`);
57
+ }
58
+ }
59
+
60
+ console.log(` ✓ Migrated ${migratedCount} resources\n`);
61
+ if (migratedCount < migrations.length) {
62
+ console.warn(' ⚠️ Some resources were not found. This may happen if the BMAD repository structure has changed.');
63
+ console.warn(' Please check if a newer version of @clfhhc/bmad-methods-skills is available.');
64
+ }
65
+ }