bmad-method 4.37.0-beta.2 → 4.37.0-beta.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.
Files changed (206) hide show
  1. package/README.md +3 -214
  2. package/package.json +26 -63
  3. package/.github/FUNDING.yaml +0 -15
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -22
  6. package/.github/workflows/discord.yaml +0 -16
  7. package/.github/workflows/release.yaml +0 -60
  8. package/.releaserc.json +0 -21
  9. package/.vscode/settings.json +0 -44
  10. package/CHANGELOG.md +0 -689
  11. package/CONTRIBUTING.md +0 -209
  12. package/LICENSE +0 -21
  13. package/bmad-core/agent-teams/team-all.yaml +0 -14
  14. package/bmad-core/agent-teams/team-fullstack.yaml +0 -18
  15. package/bmad-core/agent-teams/team-ide-minimal.yaml +0 -10
  16. package/bmad-core/agent-teams/team-no-ui.yaml +0 -13
  17. package/bmad-core/agents/analyst.md +0 -81
  18. package/bmad-core/agents/architect.md +0 -84
  19. package/bmad-core/agents/bmad-master.md +0 -108
  20. package/bmad-core/agents/bmad-orchestrator.md +0 -150
  21. package/bmad-core/agents/dev.md +0 -76
  22. package/bmad-core/agents/pm.md +0 -81
  23. package/bmad-core/agents/po.md +0 -76
  24. package/bmad-core/agents/qa.md +0 -69
  25. package/bmad-core/agents/sm.md +0 -62
  26. package/bmad-core/agents/ux-expert.md +0 -66
  27. package/bmad-core/checklists/architect-checklist.md +0 -443
  28. package/bmad-core/checklists/change-checklist.md +0 -182
  29. package/bmad-core/checklists/pm-checklist.md +0 -375
  30. package/bmad-core/checklists/po-master-checklist.md +0 -441
  31. package/bmad-core/checklists/story-dod-checklist.md +0 -101
  32. package/bmad-core/checklists/story-draft-checklist.md +0 -156
  33. package/bmad-core/core-config.yaml +0 -20
  34. package/bmad-core/data/bmad-kb.md +0 -803
  35. package/bmad-core/data/brainstorming-techniques.md +0 -36
  36. package/bmad-core/data/elicitation-methods.md +0 -134
  37. package/bmad-core/data/technical-preferences.md +0 -3
  38. package/bmad-core/tasks/advanced-elicitation.md +0 -117
  39. package/bmad-core/tasks/brownfield-create-epic.md +0 -160
  40. package/bmad-core/tasks/brownfield-create-story.md +0 -147
  41. package/bmad-core/tasks/correct-course.md +0 -70
  42. package/bmad-core/tasks/create-brownfield-story.md +0 -304
  43. package/bmad-core/tasks/create-deep-research-prompt.md +0 -289
  44. package/bmad-core/tasks/create-next-story.md +0 -112
  45. package/bmad-core/tasks/document-project.md +0 -341
  46. package/bmad-core/tasks/facilitate-brainstorming-session.md +0 -136
  47. package/bmad-core/tasks/generate-ai-frontend-prompt.md +0 -51
  48. package/bmad-core/tasks/index-docs.md +0 -179
  49. package/bmad-core/tasks/kb-mode-interaction.md +0 -75
  50. package/bmad-core/tasks/review-story.md +0 -145
  51. package/bmad-core/tasks/shard-doc.md +0 -187
  52. package/bmad-core/tasks/validate-next-story.md +0 -134
  53. package/bmad-core/templates/architecture-tmpl.yaml +0 -650
  54. package/bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
  55. package/bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -476
  56. package/bmad-core/templates/brownfield-prd-tmpl.yaml +0 -280
  57. package/bmad-core/templates/competitor-analysis-tmpl.yaml +0 -293
  58. package/bmad-core/templates/front-end-architecture-tmpl.yaml +0 -206
  59. package/bmad-core/templates/front-end-spec-tmpl.yaml +0 -349
  60. package/bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -805
  61. package/bmad-core/templates/market-research-tmpl.yaml +0 -252
  62. package/bmad-core/templates/prd-tmpl.yaml +0 -202
  63. package/bmad-core/templates/project-brief-tmpl.yaml +0 -221
  64. package/bmad-core/templates/story-tmpl.yaml +0 -137
  65. package/bmad-core/workflows/brownfield-fullstack.yaml +0 -297
  66. package/bmad-core/workflows/brownfield-service.yaml +0 -187
  67. package/bmad-core/workflows/brownfield-ui.yaml +0 -197
  68. package/bmad-core/workflows/greenfield-fullstack.yaml +0 -240
  69. package/bmad-core/workflows/greenfield-service.yaml +0 -206
  70. package/bmad-core/workflows/greenfield-ui.yaml +0 -235
  71. package/common/tasks/create-doc.md +0 -101
  72. package/common/tasks/execute-checklist.md +0 -93
  73. package/common/utils/bmad-doc-template.md +0 -325
  74. package/common/utils/workflow-management.md +0 -69
  75. package/dist/agents/analyst.txt +0 -2882
  76. package/dist/agents/architect.txt +0 -3543
  77. package/dist/agents/bmad-master.txt +0 -8756
  78. package/dist/agents/bmad-orchestrator.txt +0 -1490
  79. package/dist/agents/dev.txt +0 -428
  80. package/dist/agents/pm.txt +0 -2229
  81. package/dist/agents/po.txt +0 -1364
  82. package/dist/agents/qa.txt +0 -386
  83. package/dist/agents/sm.txt +0 -668
  84. package/dist/agents/ux-expert.txt +0 -701
  85. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +0 -2408
  86. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +0 -1631
  87. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +0 -822
  88. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +0 -10989
  89. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +0 -4047
  90. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +0 -3744
  91. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +0 -465
  92. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +0 -990
  93. package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +0 -15467
  94. package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +0 -2077
  95. package/dist/teams/team-all.txt +0 -11062
  96. package/dist/teams/team-fullstack.txt +0 -10392
  97. package/dist/teams/team-ide-minimal.txt +0 -3507
  98. package/dist/teams/team-no-ui.txt +0 -8951
  99. package/docs/GUIDING-PRINCIPLES.md +0 -91
  100. package/docs/core-architecture.md +0 -219
  101. package/docs/enhanced-ide-development-workflow.md +0 -43
  102. package/docs/expansion-packs.md +0 -280
  103. package/docs/how-to-contribute-with-pull-requests.md +0 -158
  104. package/docs/user-guide.md +0 -251
  105. package/docs/versioning-and-releases.md +0 -77
  106. package/docs/versions.md +0 -48
  107. package/docs/working-in-the-brownfield.md +0 -364
  108. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/Complete AI Agent System - Flowchart.svg +0 -102
  109. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash copy.txt +0 -13
  110. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash.txt +0 -13
  111. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.2 Agent Development Kit Installation/1.2.2 - Basic Project Structure - txt.txt +0 -25
  112. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.1 - settings.py +0 -34
  113. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.2 - main.py - Base Application.py +0 -70
  114. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.4 Deployment Configuration/1.4.2 - cloudbuild.yaml +0 -26
  115. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +0 -109
  116. package/expansion-packs/README.md +0 -3
  117. package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/phaser-2d-nodejs-game-team.yaml +0 -13
  118. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +0 -71
  119. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +0 -78
  120. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +0 -64
  121. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +0 -201
  122. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +0 -160
  123. package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +0 -8
  124. package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +0 -254
  125. package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +0 -651
  126. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +0 -111
  127. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +0 -216
  128. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +0 -308
  129. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +0 -613
  130. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +0 -356
  131. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +0 -343
  132. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +0 -253
  133. package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +0 -484
  134. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +0 -183
  135. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +0 -175
  136. package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +0 -14
  137. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.md +0 -80
  138. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +0 -77
  139. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +0 -78
  140. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.md +0 -65
  141. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-architect-checklist.md +0 -396
  142. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-change-checklist.md +0 -203
  143. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +0 -201
  144. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +0 -132
  145. package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +0 -6
  146. package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +0 -776
  147. package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +0 -590
  148. package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +0 -111
  149. package/expansion-packs/bmad-2d-unity-game-dev/tasks/correct-course-game.md +0 -151
  150. package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +0 -184
  151. package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +0 -308
  152. package/expansion-packs/bmad-2d-unity-game-dev/tasks/validate-game-story.md +0 -200
  153. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +0 -1030
  154. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +0 -356
  155. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +0 -705
  156. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +0 -256
  157. package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +0 -484
  158. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +0 -183
  159. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +0 -175
  160. package/expansion-packs/bmad-infrastructure-devops/README.md +0 -147
  161. package/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.md +0 -71
  162. package/expansion-packs/bmad-infrastructure-devops/checklists/infrastructure-checklist.md +0 -484
  163. package/expansion-packs/bmad-infrastructure-devops/config.yaml +0 -9
  164. package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +0 -308
  165. package/expansion-packs/bmad-infrastructure-devops/tasks/review-infrastructure.md +0 -160
  166. package/expansion-packs/bmad-infrastructure-devops/tasks/validate-infrastructure.md +0 -154
  167. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +0 -424
  168. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +0 -629
  169. package/tools/bmad-npx-wrapper.js +0 -39
  170. package/tools/builders/web-builder.js +0 -681
  171. package/tools/bump-all-versions.js +0 -106
  172. package/tools/bump-expansion-version.js +0 -83
  173. package/tools/cli.js +0 -154
  174. package/tools/flattener/aggregate.js +0 -76
  175. package/tools/flattener/binary.js +0 -53
  176. package/tools/flattener/discovery.js +0 -70
  177. package/tools/flattener/files.js +0 -35
  178. package/tools/flattener/ignoreRules.js +0 -176
  179. package/tools/flattener/main.js +0 -217
  180. package/tools/flattener/projectRoot.js +0 -45
  181. package/tools/flattener/prompts.js +0 -44
  182. package/tools/flattener/stats.js +0 -30
  183. package/tools/flattener/xml.js +0 -86
  184. package/tools/installer/README.md +0 -8
  185. package/tools/installer/package.json +0 -44
  186. package/tools/lib/dependency-resolver.js +0 -179
  187. package/tools/lib/yaml-utils.js +0 -29
  188. package/tools/md-assets/web-agent-startup-instructions.md +0 -39
  189. package/tools/semantic-release-sync-installer.js +0 -30
  190. package/tools/shared/bannerArt.js +0 -105
  191. package/tools/sync-installer-version.js +0 -34
  192. package/tools/update-expansion-version.js +0 -54
  193. package/tools/upgraders/v3-to-v4-upgrader.js +0 -763
  194. package/tools/version-bump.js +0 -79
  195. package/tools/yaml-format.js +0 -240
  196. /package/{tools/installer/bin → bin}/bmad.js +0 -0
  197. /package/{tools/installer/config → config}/ide-agent-config.yaml +0 -0
  198. /package/{tools/installer/config → config}/install.config.yaml +0 -0
  199. /package/{tools/installer/lib → lib}/config-loader.js +0 -0
  200. /package/{tools/installer/lib → lib}/file-manager.js +0 -0
  201. /package/{tools/installer/lib → lib}/ide-base-setup.js +0 -0
  202. /package/{tools/installer/lib → lib}/ide-setup.js +0 -0
  203. /package/{tools/installer/lib → lib}/installer.js +0 -0
  204. /package/{tools/installer/lib → lib}/memory-profiler.js +0 -0
  205. /package/{tools/installer/lib → lib}/module-manager.js +0 -0
  206. /package/{tools/installer/lib → lib}/resource-locator.js +0 -0
@@ -1,176 +0,0 @@
1
- const fs = require("fs-extra");
2
- const path = require("node:path");
3
- const ignore = require("ignore");
4
-
5
- // Central default ignore patterns for discovery and filtering.
6
- // These complement .gitignore and are applied regardless of VCS presence.
7
- const DEFAULT_PATTERNS = [
8
- // Project/VCS
9
- "**/.bmad-core/**",
10
- "**/.git/**",
11
- "**/.svn/**",
12
- "**/.hg/**",
13
- "**/.bzr/**",
14
- // Package/build outputs
15
- "**/node_modules/**",
16
- "**/bower_components/**",
17
- "**/vendor/**",
18
- "**/packages/**",
19
- "**/build/**",
20
- "**/dist/**",
21
- "**/out/**",
22
- "**/target/**",
23
- "**/bin/**",
24
- "**/obj/**",
25
- "**/release/**",
26
- "**/debug/**",
27
- // Environments
28
- "**/.venv/**",
29
- "**/venv/**",
30
- "**/.virtualenv/**",
31
- "**/virtualenv/**",
32
- "**/env/**",
33
- // Logs & coverage
34
- "**/*.log",
35
- "**/npm-debug.log*",
36
- "**/yarn-debug.log*",
37
- "**/yarn-error.log*",
38
- "**/lerna-debug.log*",
39
- "**/coverage/**",
40
- "**/.nyc_output/**",
41
- "**/.coverage/**",
42
- "**/test-results/**",
43
- // Caches & temp
44
- "**/.cache/**",
45
- "**/.tmp/**",
46
- "**/.temp/**",
47
- "**/tmp/**",
48
- "**/temp/**",
49
- "**/.sass-cache/**",
50
- // IDE/editor
51
- "**/.vscode/**",
52
- "**/.idea/**",
53
- "**/*.swp",
54
- "**/*.swo",
55
- "**/*~",
56
- "**/.project",
57
- "**/.classpath",
58
- "**/.settings/**",
59
- "**/*.sublime-project",
60
- "**/*.sublime-workspace",
61
- // Lockfiles
62
- "**/package-lock.json",
63
- "**/yarn.lock",
64
- "**/pnpm-lock.yaml",
65
- "**/composer.lock",
66
- "**/Pipfile.lock",
67
- // Python/Java/compiled artifacts
68
- "**/*.pyc",
69
- "**/*.pyo",
70
- "**/*.pyd",
71
- "**/__pycache__/**",
72
- "**/*.class",
73
- "**/*.jar",
74
- "**/*.war",
75
- "**/*.ear",
76
- "**/*.o",
77
- "**/*.so",
78
- "**/*.dll",
79
- "**/*.exe",
80
- // System junk
81
- "**/lib64/**",
82
- "**/.venv/lib64/**",
83
- "**/venv/lib64/**",
84
- "**/_site/**",
85
- "**/.jekyll-cache/**",
86
- "**/.jekyll-metadata",
87
- "**/.DS_Store",
88
- "**/.DS_Store?",
89
- "**/._*",
90
- "**/.Spotlight-V100/**",
91
- "**/.Trashes/**",
92
- "**/ehthumbs.db",
93
- "**/Thumbs.db",
94
- "**/desktop.ini",
95
- // XML outputs
96
- "**/flattened-codebase.xml",
97
- "**/repomix-output.xml",
98
- // Images, media, fonts, archives, docs, dylibs
99
- "**/*.jpg",
100
- "**/*.jpeg",
101
- "**/*.png",
102
- "**/*.gif",
103
- "**/*.bmp",
104
- "**/*.ico",
105
- "**/*.svg",
106
- "**/*.pdf",
107
- "**/*.doc",
108
- "**/*.docx",
109
- "**/*.xls",
110
- "**/*.xlsx",
111
- "**/*.ppt",
112
- "**/*.pptx",
113
- "**/*.zip",
114
- "**/*.tar",
115
- "**/*.gz",
116
- "**/*.rar",
117
- "**/*.7z",
118
- "**/*.dylib",
119
- "**/*.mp3",
120
- "**/*.mp4",
121
- "**/*.avi",
122
- "**/*.mov",
123
- "**/*.wav",
124
- "**/*.ttf",
125
- "**/*.otf",
126
- "**/*.woff",
127
- "**/*.woff2",
128
- // Env files
129
- "**/.env",
130
- "**/.env.*",
131
- "**/*.env",
132
- // Misc
133
- "**/junit.xml",
134
- ];
135
-
136
- async function readIgnoreFile(filePath) {
137
- try {
138
- if (!await fs.pathExists(filePath)) return [];
139
- const content = await fs.readFile(filePath, "utf8");
140
- return content
141
- .split("\n")
142
- .map((l) => l.trim())
143
- .filter((l) => l && !l.startsWith("#"));
144
- } catch (err) {
145
- return [];
146
- }
147
- }
148
-
149
- // Backward compatible export matching previous signature
150
- async function parseGitignore(gitignorePath) {
151
- return readIgnoreFile(gitignorePath);
152
- }
153
-
154
- async function loadIgnore(rootDir, extraPatterns = []) {
155
- const ig = ignore();
156
- const gitignorePath = path.join(rootDir, ".gitignore");
157
- const patterns = [
158
- ...await readIgnoreFile(gitignorePath),
159
- ...DEFAULT_PATTERNS,
160
- ...extraPatterns,
161
- ];
162
- // De-duplicate
163
- const unique = Array.from(new Set(patterns.map((p) => String(p))));
164
- ig.add(unique);
165
-
166
- // Include-only filter: return true if path should be included
167
- const filter = (relativePath) => !ig.ignores(relativePath.replace(/\\/g, "/"));
168
-
169
- return { ig, filter, patterns: unique };
170
- }
171
-
172
- module.exports = {
173
- DEFAULT_PATTERNS,
174
- parseGitignore,
175
- loadIgnore,
176
- };
@@ -1,217 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const { Command } = require("commander");
4
- const fs = require("fs-extra");
5
- const path = require("node:path");
6
- const process = require("node:process");
7
-
8
- // Modularized components
9
- const { findProjectRoot } = require("./projectRoot.js");
10
- const { promptYesNo, promptPath } = require("./prompts.js");
11
- const {
12
- discoverFiles,
13
- filterFiles,
14
- aggregateFileContents,
15
- } = require("./files.js");
16
- const { generateXMLOutput } = require("./xml.js");
17
- const { calculateStatistics } = require("./stats.js");
18
-
19
- /**
20
- * Recursively discover all files in a directory
21
- * @param {string} rootDir - The root directory to scan
22
- * @returns {Promise<string[]>} Array of file paths
23
- */
24
-
25
- /**
26
- * Parse .gitignore file and return ignore patterns
27
- * @param {string} gitignorePath - Path to .gitignore file
28
- * @returns {Promise<string[]>} Array of ignore patterns
29
- */
30
-
31
- /**
32
- * Check if a file is binary using file command and heuristics
33
- * @param {string} filePath - Path to the file
34
- * @returns {Promise<boolean>} True if file is binary
35
- */
36
-
37
- /**
38
- * Read and aggregate content from text files
39
- * @param {string[]} files - Array of file paths
40
- * @param {string} rootDir - The root directory
41
- * @param {Object} spinner - Optional spinner instance for progress display
42
- * @returns {Promise<Object>} Object containing file contents and metadata
43
- */
44
-
45
- /**
46
- * Generate XML output with aggregated file contents using streaming
47
- * @param {Object} aggregatedContent - The aggregated content object
48
- * @param {string} outputPath - The output file path
49
- * @returns {Promise<void>} Promise that resolves when writing is complete
50
- */
51
-
52
- /**
53
- * Calculate statistics for the processed files
54
- * @param {Object} aggregatedContent - The aggregated content object
55
- * @param {number} xmlFileSize - The size of the generated XML file in bytes
56
- * @returns {Object} Statistics object
57
- */
58
-
59
- /**
60
- * Filter files based on .gitignore patterns
61
- * @param {string[]} files - Array of file paths
62
- * @param {string} rootDir - The root directory
63
- * @returns {Promise<string[]>} Filtered array of file paths
64
- */
65
-
66
- /**
67
- * Attempt to find the project root by walking up from startDir
68
- * Looks for common project markers like .git, package.json, pyproject.toml, etc.
69
- * @param {string} startDir
70
- * @returns {Promise<string|null>} project root directory or null if not found
71
- */
72
-
73
- const program = new Command();
74
-
75
- program
76
- .name("bmad-flatten")
77
- .description("BMad-Method codebase flattener tool")
78
- .version("1.0.0")
79
- .option("-i, --input <path>", "Input directory to flatten", process.cwd())
80
- .option("-o, --output <path>", "Output file path", "flattened-codebase.xml")
81
- .action(async (options) => {
82
- let inputDir = path.resolve(options.input);
83
- let outputPath = path.resolve(options.output);
84
-
85
- // Detect if user explicitly provided -i/--input or -o/--output
86
- const argv = process.argv.slice(2);
87
- const userSpecifiedInput = argv.some((a) =>
88
- a === "-i" || a === "--input" || a.startsWith("--input=")
89
- );
90
- const userSpecifiedOutput = argv.some((a) =>
91
- a === "-o" || a === "--output" || a.startsWith("--output=")
92
- );
93
- const noPathArgs = !userSpecifiedInput && !userSpecifiedOutput;
94
-
95
- if (noPathArgs) {
96
- const detectedRoot = await findProjectRoot(process.cwd());
97
- const suggestedOutput = detectedRoot
98
- ? path.join(detectedRoot, "flattened-codebase.xml")
99
- : path.resolve("flattened-codebase.xml");
100
-
101
- if (detectedRoot) {
102
- const useDefaults = await promptYesNo(
103
- `Detected project root at "${detectedRoot}". Use it as input and write output to "${suggestedOutput}"?`,
104
- true,
105
- );
106
- if (useDefaults) {
107
- inputDir = detectedRoot;
108
- outputPath = suggestedOutput;
109
- } else {
110
- inputDir = await promptPath(
111
- "Enter input directory path",
112
- process.cwd(),
113
- );
114
- outputPath = await promptPath(
115
- "Enter output file path",
116
- path.join(inputDir, "flattened-codebase.xml"),
117
- );
118
- }
119
- } else {
120
- console.log("Could not auto-detect a project root.");
121
- inputDir = await promptPath(
122
- "Enter input directory path",
123
- process.cwd(),
124
- );
125
- outputPath = await promptPath(
126
- "Enter output file path",
127
- path.join(inputDir, "flattened-codebase.xml"),
128
- );
129
- }
130
- } else {
131
- console.error(
132
- "Could not auto-detect a project root and no arguments were provided. Please specify -i/--input and -o/--output.",
133
- );
134
- process.exit(1);
135
- }
136
-
137
- // Ensure output directory exists
138
- await fs.ensureDir(path.dirname(outputPath));
139
-
140
- console.log(`Flattening codebase from: ${inputDir}`);
141
- console.log(`Output file: ${outputPath}`);
142
-
143
- try {
144
- // Verify input directory exists
145
- if (!await fs.pathExists(inputDir)) {
146
- console.error(`❌ Error: Input directory does not exist: ${inputDir}`);
147
- process.exit(1);
148
- }
149
-
150
- // Import ora dynamically
151
- const { default: ora } = await import("ora");
152
-
153
- // Start file discovery with spinner
154
- const discoverySpinner = ora("🔍 Discovering files...").start();
155
- const files = await discoverFiles(inputDir);
156
- const filteredFiles = await filterFiles(files, inputDir);
157
- discoverySpinner.succeed(
158
- `📁 Found ${filteredFiles.length} files to include`,
159
- );
160
-
161
- // Process files with progress tracking
162
- console.log("Reading file contents");
163
- const processingSpinner = ora("📄 Processing files...").start();
164
- const aggregatedContent = await aggregateFileContents(
165
- filteredFiles,
166
- inputDir,
167
- processingSpinner,
168
- );
169
- processingSpinner.succeed(
170
- `✅ Processed ${aggregatedContent.processedFiles}/${filteredFiles.length} files`,
171
- );
172
- if (aggregatedContent.errors.length > 0) {
173
- console.log(`Errors: ${aggregatedContent.errors.length}`);
174
- }
175
- console.log(`Text files: ${aggregatedContent.textFiles.length}`);
176
- if (aggregatedContent.binaryFiles.length > 0) {
177
- console.log(`Binary files: ${aggregatedContent.binaryFiles.length}`);
178
- }
179
-
180
- // Generate XML output using streaming
181
- const xmlSpinner = ora("🔧 Generating XML output...").start();
182
- await generateXMLOutput(aggregatedContent, outputPath);
183
- xmlSpinner.succeed("📝 XML generation completed");
184
-
185
- // Calculate and display statistics
186
- const outputStats = await fs.stat(outputPath);
187
- const stats = calculateStatistics(aggregatedContent, outputStats.size);
188
-
189
- // Display completion summary
190
- console.log("\n📊 Completion Summary:");
191
- console.log(
192
- `✅ Successfully processed ${filteredFiles.length} files into ${
193
- path.basename(outputPath)
194
- }`,
195
- );
196
- console.log(`📁 Output file: ${outputPath}`);
197
- console.log(`📏 Total source size: ${stats.totalSize}`);
198
- console.log(`📄 Generated XML size: ${stats.xmlSize}`);
199
- console.log(
200
- `📝 Total lines of code: ${stats.totalLines.toLocaleString()}`,
201
- );
202
- console.log(`🔢 Estimated tokens: ${stats.estimatedTokens}`);
203
- console.log(
204
- `📊 File breakdown: ${stats.textFiles} text, ${stats.binaryFiles} binary, ${stats.errorFiles} errors`,
205
- );
206
- } catch (error) {
207
- console.error("❌ Critical error:", error.message);
208
- console.error("An unexpected error occurred.");
209
- process.exit(1);
210
- }
211
- });
212
-
213
- if (require.main === module) {
214
- program.parse();
215
- }
216
-
217
- module.exports = program;
@@ -1,45 +0,0 @@
1
- const fs = require("fs-extra");
2
- const path = require("node:path");
3
-
4
- /**
5
- * Attempt to find the project root by walking up from startDir
6
- * Looks for common project markers like .git, package.json, pyproject.toml, etc.
7
- * @param {string} startDir
8
- * @returns {Promise<string|null>} project root directory or null if not found
9
- */
10
- async function findProjectRoot(startDir) {
11
- try {
12
- let dir = path.resolve(startDir);
13
- const root = path.parse(dir).root;
14
- const markers = [
15
- ".git",
16
- "package.json",
17
- "pnpm-workspace.yaml",
18
- "yarn.lock",
19
- "pnpm-lock.yaml",
20
- "pyproject.toml",
21
- "requirements.txt",
22
- "go.mod",
23
- "Cargo.toml",
24
- "composer.json",
25
- ".hg",
26
- ".svn",
27
- ];
28
-
29
- while (true) {
30
- const exists = await Promise.all(
31
- markers.map((m) => fs.pathExists(path.join(dir, m))),
32
- );
33
- if (exists.some(Boolean)) {
34
- return dir;
35
- }
36
- if (dir === root) break;
37
- dir = path.dirname(dir);
38
- }
39
- return null;
40
- } catch {
41
- return null;
42
- }
43
- }
44
-
45
- module.exports = { findProjectRoot };
@@ -1,44 +0,0 @@
1
- const os = require("node:os");
2
- const path = require("node:path");
3
- const readline = require("node:readline");
4
- const process = require("node:process");
5
-
6
- function expandHome(p) {
7
- if (!p) return p;
8
- if (p.startsWith("~")) return path.join(os.homedir(), p.slice(1));
9
- return p;
10
- }
11
-
12
- function createRl() {
13
- return readline.createInterface({
14
- input: process.stdin,
15
- output: process.stdout,
16
- });
17
- }
18
-
19
- function promptQuestion(question) {
20
- return new Promise((resolve) => {
21
- const rl = createRl();
22
- rl.question(question, (answer) => {
23
- rl.close();
24
- resolve(answer);
25
- });
26
- });
27
- }
28
-
29
- async function promptYesNo(question, defaultYes = true) {
30
- const suffix = defaultYes ? " [Y/n] " : " [y/N] ";
31
- const ans = (await promptQuestion(`${question}${suffix}`)).trim().toLowerCase();
32
- if (!ans) return defaultYes;
33
- if (["y", "yes"].includes(ans)) return true;
34
- if (["n", "no"].includes(ans)) return false;
35
- return promptYesNo(question, defaultYes);
36
- }
37
-
38
- async function promptPath(question, defaultValue) {
39
- const prompt = `${question}${defaultValue ? ` (default: ${defaultValue})` : ""}: `;
40
- const ans = (await promptQuestion(prompt)).trim();
41
- return expandHome(ans || defaultValue);
42
- }
43
-
44
- module.exports = { promptYesNo, promptPath, promptQuestion, expandHome };
@@ -1,30 +0,0 @@
1
- function calculateStatistics(aggregatedContent, xmlFileSize) {
2
- const { textFiles, binaryFiles, errors } = aggregatedContent;
3
-
4
- const totalTextSize = textFiles.reduce((sum, file) => sum + file.size, 0);
5
- const totalBinarySize = binaryFiles.reduce((sum, file) => sum + file.size, 0);
6
- const totalSize = totalTextSize + totalBinarySize;
7
-
8
- const totalLines = textFiles.reduce((sum, file) => sum + file.lines, 0);
9
-
10
- const estimatedTokens = Math.ceil(xmlFileSize / 4);
11
-
12
- const formatSize = (bytes) => {
13
- if (bytes < 1024) return `${bytes} B`;
14
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
15
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
16
- };
17
-
18
- return {
19
- totalFiles: textFiles.length + binaryFiles.length,
20
- textFiles: textFiles.length,
21
- binaryFiles: binaryFiles.length,
22
- errorFiles: errors.length,
23
- totalSize: formatSize(totalSize),
24
- xmlSize: formatSize(xmlFileSize),
25
- totalLines,
26
- estimatedTokens: estimatedTokens.toLocaleString(),
27
- };
28
- }
29
-
30
- module.exports = { calculateStatistics };
@@ -1,86 +0,0 @@
1
- const fs = require("fs-extra");
2
-
3
- function escapeXml(str) {
4
- if (typeof str !== "string") {
5
- return String(str);
6
- }
7
- return str
8
- .replace(/&/g, "&amp;")
9
- .replace(/</g, "&lt;")
10
- .replace(/'/g, "&apos;");
11
- }
12
-
13
- function indentFileContent(content) {
14
- if (typeof content !== "string") {
15
- return String(content);
16
- }
17
- return content.split("\n").map((line) => ` ${line}`);
18
- }
19
-
20
- function generateXMLOutput(aggregatedContent, outputPath) {
21
- const { textFiles } = aggregatedContent;
22
- const writeStream = fs.createWriteStream(outputPath, { encoding: "utf8" });
23
-
24
- return new Promise((resolve, reject) => {
25
- writeStream.on("error", reject);
26
- writeStream.on("finish", resolve);
27
-
28
- writeStream.write('<?xml version="1.0" encoding="UTF-8"?>\n');
29
- writeStream.write("<files>\n");
30
-
31
- // Sort files by path for deterministic order
32
- const filesSorted = [...textFiles].sort((a, b) =>
33
- a.path.localeCompare(b.path)
34
- );
35
- let index = 0;
36
-
37
- const writeNext = () => {
38
- if (index >= filesSorted.length) {
39
- writeStream.write("</files>\n");
40
- writeStream.end();
41
- return;
42
- }
43
-
44
- const file = filesSorted[index++];
45
- const p = escapeXml(file.path);
46
- const content = typeof file.content === "string" ? file.content : "";
47
-
48
- if (content.length === 0) {
49
- writeStream.write(`\t<file path='${p}'/>\n`);
50
- setTimeout(writeNext, 0);
51
- return;
52
- }
53
-
54
- const needsCdata = content.includes("<") || content.includes("&") ||
55
- content.includes("]]>");
56
- if (needsCdata) {
57
- // Open tag and CDATA on their own line with tab indent; content lines indented with two tabs
58
- writeStream.write(`\t<file path='${p}'><![CDATA[\n`);
59
- // Safely split any occurrences of "]]>" inside content, trim trailing newlines, indent each line with two tabs
60
- const safe = content.replace(/]]>/g, "]]]]><![CDATA[>");
61
- const trimmed = safe.replace(/[\r\n]+$/, "");
62
- const indented = trimmed.length > 0
63
- ? trimmed.split("\n").map((line) => `\t\t${line}`).join("\n")
64
- : "";
65
- writeStream.write(indented);
66
- // Close CDATA and attach closing tag directly after the last content line
67
- writeStream.write("]]></file>\n");
68
- } else {
69
- // Write opening tag then newline; indent content with two tabs; attach closing tag directly after last content char
70
- writeStream.write(`\t<file path='${p}'>\n`);
71
- const trimmed = content.replace(/[\r\n]+$/, "");
72
- const indented = trimmed.length > 0
73
- ? trimmed.split("\n").map((line) => `\t\t${line}`).join("\n")
74
- : "";
75
- writeStream.write(indented);
76
- writeStream.write(`</file>\n`);
77
- }
78
-
79
- setTimeout(writeNext, 0);
80
- };
81
-
82
- writeNext();
83
- });
84
- }
85
-
86
- module.exports = { generateXMLOutput };
@@ -1,8 +0,0 @@
1
- # BMad Method Installer
2
-
3
- ## Usage
4
-
5
- ```bash
6
- # Interactive installation
7
- npx bmad-method install
8
- ```
@@ -1,44 +0,0 @@
1
- {
2
- "name": "bmad-method",
3
- "version": "4.37.0-beta.2",
4
- "description": "BMad Method installer - AI-powered Agile development framework",
5
- "main": "lib/installer.js",
6
- "bin": {
7
- "bmad": "./bin/bmad.js",
8
- "bmad-method": "./bin/bmad.js"
9
- },
10
- "scripts": {
11
- "test": "echo \"Error: no test specified\" && exit 1"
12
- },
13
- "keywords": [
14
- "bmad",
15
- "agile",
16
- "ai",
17
- "development",
18
- "framework",
19
- "installer",
20
- "agents"
21
- ],
22
- "author": "BMad Team",
23
- "license": "MIT",
24
- "dependencies": {
25
- "chalk": "^4.1.2",
26
- "commander": "^14.0.0",
27
- "fs-extra": "^11.3.0",
28
- "inquirer": "^8.2.6",
29
- "js-yaml": "^4.1.0",
30
- "ora": "^5.4.1",
31
- "semver": "^7.6.3"
32
- },
33
- "engines": {
34
- "node": ">=20.0.0"
35
- },
36
- "repository": {
37
- "type": "git",
38
- "url": "https://github.com/bmad-team/bmad-method.git"
39
- },
40
- "bugs": {
41
- "url": "https://github.com/bmad-team/bmad-method/issues"
42
- },
43
- "homepage": "https://github.com/bmad-team/bmad-method#readme"
44
- }