create-byan-agent 2.0.1 → 2.1.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 (240) hide show
  1. package/API-BYAN-V2.md +741 -0
  2. package/BMAD-QUICK-REFERENCE.md +370 -0
  3. package/CHANGELOG-v2.1.0.md +371 -0
  4. package/LICENSE +1 -1
  5. package/MIGRATION-v2.0-to-v2.1.md +430 -0
  6. package/README-BYAN-V2.md +446 -0
  7. package/README.md +264 -201
  8. package/install/.eslintrc.js +20 -0
  9. package/install/.prettierrc +7 -0
  10. package/install/BUGFIX-CHALK.md +173 -0
  11. package/install/BUGFIX-DOCUMENTATION-INDEX.md +299 -0
  12. package/install/BUGFIX-PATH-RESOLUTION.md +293 -0
  13. package/install/BUGFIX-QUICKSTART.md +184 -0
  14. package/install/BUGFIX-SUMMARY.txt +91 -0
  15. package/install/BUGFIX-VISUAL-SUMMARY.md +253 -0
  16. package/install/DEPLOYMENT-GUIDE-V2.md +431 -0
  17. package/install/DOCS-INDEX.md +261 -0
  18. package/install/GUIDE-INSTALLATION-BYAN-SIMPLE.md +1083 -0
  19. package/install/INSTALLER-V2-CHANGES.md +472 -0
  20. package/install/LICENSE +21 -0
  21. package/install/PUBLICATION-CHECKLIST.md +265 -0
  22. package/install/PUBLISH-GUIDE.md +190 -0
  23. package/install/QUICKSTART.md +311 -0
  24. package/install/README-NPM-PUBLISH.md +298 -0
  25. package/install/README-NPM-SHORT.md +298 -0
  26. package/install/README-NPM.md +433 -0
  27. package/install/README-RACHID.md +302 -0
  28. package/install/README-V2-INDEX.md +306 -0
  29. package/install/README.md +298 -0
  30. package/install/RESUME-EXECUTIF-YAN.md +408 -0
  31. package/install/UPDATE-SUMMARY.md +205 -0
  32. package/install/__tests__/integration/detection-flow.test.js +154 -0
  33. package/install/__tests__/platforms/claude-code.test.js +175 -0
  34. package/install/__tests__/platforms/codex.test.js +80 -0
  35. package/install/__tests__/platforms/copilot-cli.test.js +118 -0
  36. package/install/__tests__/platforms/vscode.test.js +67 -0
  37. package/install/__tests__/utils/file-utils.test.js +87 -0
  38. package/install/__tests__/utils/git-detector.test.js +80 -0
  39. package/install/__tests__/utils/logger.test.js +83 -0
  40. package/install/__tests__/utils/node-detector.test.js +71 -0
  41. package/install/__tests__/utils/os-detector.test.js +63 -0
  42. package/install/__tests__/utils/yaml-utils.test.js +85 -0
  43. package/install/__tests__/yanstaller/detector.test.js +210 -0
  44. package/install/coverage/clover.xml +219 -0
  45. package/install/coverage/coverage-final.json +13 -0
  46. package/install/coverage/lcov-report/base.css +224 -0
  47. package/install/coverage/lcov-report/block-navigation.js +87 -0
  48. package/install/coverage/lcov-report/favicon.png +0 -0
  49. package/install/coverage/lcov-report/index.html +146 -0
  50. package/install/coverage/lcov-report/lib/errors.js.html +268 -0
  51. package/install/coverage/lcov-report/lib/exit-codes.js.html +247 -0
  52. package/install/coverage/lcov-report/lib/index.html +131 -0
  53. package/install/coverage/lcov-report/lib/platforms/claude-code.js.html +343 -0
  54. package/install/coverage/lcov-report/lib/platforms/codex.js.html +361 -0
  55. package/install/coverage/lcov-report/lib/platforms/copilot-cli.js.html +454 -0
  56. package/install/coverage/lcov-report/lib/platforms/index.html +176 -0
  57. package/install/coverage/lcov-report/lib/platforms/index.js.html +127 -0
  58. package/install/coverage/lcov-report/lib/platforms/vscode.js.html +238 -0
  59. package/install/coverage/lcov-report/lib/utils/config-loader.js.html +322 -0
  60. package/install/coverage/lcov-report/lib/utils/file-utils.js.html +397 -0
  61. package/install/coverage/lcov-report/lib/utils/git-detector.js.html +190 -0
  62. package/install/coverage/lcov-report/lib/utils/index.html +206 -0
  63. package/install/coverage/lcov-report/lib/utils/logger.js.html +277 -0
  64. package/install/coverage/lcov-report/lib/utils/node-detector.js.html +259 -0
  65. package/install/coverage/lcov-report/lib/utils/os-detector.js.html +307 -0
  66. package/install/coverage/lcov-report/lib/utils/yaml-utils.js.html +346 -0
  67. package/install/coverage/lcov-report/lib/yanstaller/backuper.js.html +409 -0
  68. package/install/coverage/lcov-report/lib/yanstaller/detector.js.html +508 -0
  69. package/install/coverage/lcov-report/lib/yanstaller/index.html +236 -0
  70. package/install/coverage/lcov-report/lib/yanstaller/index.js.html +364 -0
  71. package/install/coverage/lcov-report/lib/yanstaller/installer.js.html +505 -0
  72. package/install/coverage/lcov-report/lib/yanstaller/interviewer.js.html +349 -0
  73. package/install/coverage/lcov-report/lib/yanstaller/recommender.js.html +379 -0
  74. package/install/coverage/lcov-report/lib/yanstaller/troubleshooter.js.html +352 -0
  75. package/install/coverage/lcov-report/lib/yanstaller/validator.js.html +679 -0
  76. package/install/coverage/lcov-report/lib/yanstaller/wizard.js.html +412 -0
  77. package/install/coverage/lcov-report/platforms/claude-code.js.html +343 -0
  78. package/install/coverage/lcov-report/platforms/codex.js.html +361 -0
  79. package/install/coverage/lcov-report/platforms/copilot-cli.js.html +454 -0
  80. package/install/coverage/lcov-report/platforms/index.html +176 -0
  81. package/install/coverage/lcov-report/platforms/index.js.html +127 -0
  82. package/install/coverage/lcov-report/platforms/vscode.js.html +238 -0
  83. package/install/coverage/lcov-report/prettify.css +1 -0
  84. package/install/coverage/lcov-report/prettify.js +2 -0
  85. package/install/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  86. package/install/coverage/lcov-report/sorter.js +210 -0
  87. package/install/coverage/lcov-report/utils/file-utils.js.html +397 -0
  88. package/install/coverage/lcov-report/utils/git-detector.js.html +190 -0
  89. package/install/coverage/lcov-report/utils/index.html +191 -0
  90. package/install/coverage/lcov-report/utils/logger.js.html +277 -0
  91. package/install/coverage/lcov-report/utils/node-detector.js.html +259 -0
  92. package/install/coverage/lcov-report/utils/os-detector.js.html +307 -0
  93. package/install/coverage/lcov-report/utils/yaml-utils.js.html +346 -0
  94. package/install/coverage/lcov-report/yanstaller/detector.js.html +508 -0
  95. package/install/coverage/lcov-report/yanstaller/index.html +116 -0
  96. package/install/coverage/lcov.info +414 -0
  97. package/install/install.sh +239 -0
  98. package/install/jest.config.js +33 -0
  99. package/install/lib/errors.js +61 -0
  100. package/install/lib/exit-codes.js +54 -0
  101. package/install/lib/platforms/claude-code.js +86 -0
  102. package/install/lib/platforms/codex.js +92 -0
  103. package/install/lib/platforms/copilot-cli.js +123 -0
  104. package/install/lib/platforms/index.js +14 -0
  105. package/install/lib/platforms/vscode.js +51 -0
  106. package/install/lib/utils/config-loader.js +79 -0
  107. package/install/lib/utils/file-utils.js +104 -0
  108. package/install/lib/utils/git-detector.js +35 -0
  109. package/install/lib/utils/logger.js +64 -0
  110. package/install/lib/utils/node-detector.js +58 -0
  111. package/install/lib/utils/os-detector.js +74 -0
  112. package/install/lib/utils/yaml-utils.js +87 -0
  113. package/install/lib/yanstaller/backuper.js +108 -0
  114. package/install/lib/yanstaller/detector.js +141 -0
  115. package/install/lib/yanstaller/index.js +93 -0
  116. package/install/lib/yanstaller/installer.js +140 -0
  117. package/install/lib/yanstaller/interviewer.js +88 -0
  118. package/install/lib/yanstaller/recommender.js +98 -0
  119. package/install/lib/yanstaller/troubleshooter.js +89 -0
  120. package/install/lib/yanstaller/validator.js +198 -0
  121. package/install/lib/yanstaller/wizard.js +109 -0
  122. package/install/package-npm.json +55 -0
  123. package/install/package.json +63 -0
  124. package/install/src/byan-v2/context/copilot-context.js +79 -0
  125. package/install/src/byan-v2/context/session-state.js +98 -0
  126. package/install/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
  127. package/install/src/byan-v2/dispatcher/local-executor.js +221 -0
  128. package/install/src/byan-v2/dispatcher/task-router.js +122 -0
  129. package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
  130. package/install/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
  131. package/install/src/byan-v2/generation/agent-profile-validator.js +113 -0
  132. package/install/src/byan-v2/generation/profile-template.js +113 -0
  133. package/install/src/byan-v2/generation/templates/default-agent.md +49 -0
  134. package/install/src/byan-v2/generation/templates/test-template.md +1 -0
  135. package/install/src/byan-v2/index.js +199 -0
  136. package/install/src/byan-v2/observability/error-tracker.js +105 -0
  137. package/install/src/byan-v2/observability/logger.js +154 -0
  138. package/install/src/byan-v2/observability/metrics-collector.js +194 -0
  139. package/install/src/byan-v2/orchestrator/analysis-state.js +268 -0
  140. package/install/src/byan-v2/orchestrator/generation-state.js +340 -0
  141. package/install/src/byan-v2/orchestrator/interview-state.js +271 -0
  142. package/install/src/byan-v2/orchestrator/state-machine.js +204 -0
  143. package/install/src/core/cache/cache.js +126 -0
  144. package/install/src/core/context/context.js +86 -0
  145. package/install/src/core/dispatcher/dispatcher.js +135 -0
  146. package/install/src/core/worker-pool/worker-pool.js +194 -0
  147. package/install/src/core/workflow/workflow-executor.js +220 -0
  148. package/install/src/index.js +139 -0
  149. package/install/src/observability/dashboard/dashboard.js +191 -0
  150. package/install/src/observability/logger/structured-logger.js +254 -0
  151. package/install/src/observability/metrics/metrics-collector.js +325 -0
  152. package/install/switch-to-v2.sh +126 -0
  153. package/install/test-chalk-fix.sh +210 -0
  154. package/install/test-installer-v2.sh +204 -0
  155. package/install/test-path-resolution.sh +200 -0
  156. package/package.json +53 -33
  157. package/src/byan-v2/context/copilot-context.js +79 -0
  158. package/src/byan-v2/context/session-state.js +98 -0
  159. package/src/byan-v2/data/mantras.json +852 -0
  160. package/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
  161. package/src/byan-v2/dispatcher/five-whys-analyzer.js +310 -0
  162. package/src/byan-v2/dispatcher/local-executor.js +221 -0
  163. package/src/byan-v2/dispatcher/task-router.js +122 -0
  164. package/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
  165. package/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
  166. package/src/byan-v2/generation/agent-profile-validator.js +113 -0
  167. package/src/byan-v2/generation/mantra-validator.js +416 -0
  168. package/src/byan-v2/generation/profile-template.js +113 -0
  169. package/src/byan-v2/generation/templates/default-agent.md +49 -0
  170. package/src/byan-v2/generation/templates/test-template.md +1 -0
  171. package/src/byan-v2/index.js +652 -0
  172. package/src/byan-v2/integration/voice-integration.js +295 -0
  173. package/src/byan-v2/observability/error-tracker.js +105 -0
  174. package/src/byan-v2/observability/logger.js +154 -0
  175. package/src/byan-v2/observability/metrics-collector.js +194 -0
  176. package/src/byan-v2/orchestrator/active-listener.js +541 -0
  177. package/src/byan-v2/orchestrator/analysis-state.js +268 -0
  178. package/src/byan-v2/orchestrator/generation-state.js +340 -0
  179. package/src/byan-v2/orchestrator/glossary-builder.js +431 -0
  180. package/src/byan-v2/orchestrator/interview-state.js +353 -0
  181. package/src/byan-v2/orchestrator/state-machine.js +253 -0
  182. package/src/core/cache/cache.js +126 -0
  183. package/src/core/context/context.js +86 -0
  184. package/src/core/dispatcher/dispatcher.js +135 -0
  185. package/src/core/worker-pool/worker-pool.js +194 -0
  186. package/src/core/workflow/workflow-executor.js +220 -0
  187. package/src/index.js +139 -0
  188. package/src/observability/dashboard/dashboard.js +191 -0
  189. package/src/observability/logger/structured-logger.js +254 -0
  190. package/src/observability/metrics/metrics-collector.js +325 -0
  191. package/templates/.github/agents/bmad-agent-test-dynamic.md +0 -21
  192. package/templates/.github/agents/franck.md +0 -379
  193. /package/{CHANGELOG.md → install/CHANGELOG.md} +0 -0
  194. /package/{bin → install/bin}/create-byan-agent-backup.js +0 -0
  195. /package/{bin → install/bin}/create-byan-agent-fixed.js +0 -0
  196. /package/{bin → install/bin}/create-byan-agent-v2.js +0 -0
  197. /package/{bin → install/bin}/create-byan-agent.js +0 -0
  198. /package/{templates → install/templates}/.github/agents/bmad-agent-bmad-master.md +0 -0
  199. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-agent-builder.md +0 -0
  200. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-module-builder.md +0 -0
  201. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -0
  202. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-analyst.md +0 -0
  203. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-architect.md +0 -0
  204. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-dev.md +0 -0
  205. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-pm.md +0 -0
  206. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -0
  207. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quinn.md +0 -0
  208. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-sm.md +0 -0
  209. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-tech-writer.md +0 -0
  210. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-ux-designer.md +0 -0
  211. /package/{templates → install/templates}/.github/agents/bmad-agent-byan-test.md +0 -0
  212. /package/{templates → install/templates}/.github/agents/bmad-agent-byan.md +0 -0
  213. /package/{templates → install/templates}/.github/agents/bmad-agent-carmack.md +0 -0
  214. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -0
  215. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -0
  216. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -0
  217. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -0
  218. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-presentation-master.md +0 -0
  219. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-storyteller.md +0 -0
  220. /package/{templates → install/templates}/.github/agents/bmad-agent-marc.md +0 -0
  221. /package/{templates → install/templates}/.github/agents/bmad-agent-patnote.md +0 -0
  222. /package/{templates → install/templates}/.github/agents/bmad-agent-rachid.md +0 -0
  223. /package/{templates → install/templates}/.github/agents/bmad-agent-tea-tea.md +0 -0
  224. /package/{templates → install/templates}/_bmad/bmb/agents/agent-builder.md +0 -0
  225. /package/{templates → install/templates}/_bmad/bmb/agents/byan-test.md +0 -0
  226. /package/{templates → install/templates}/_bmad/bmb/agents/byan.md +0 -0
  227. /package/{templates → install/templates}/_bmad/bmb/agents/marc.md +0 -0
  228. /package/{templates → install/templates}/_bmad/bmb/agents/module-builder.md +0 -0
  229. /package/{templates → install/templates}/_bmad/bmb/agents/patnote.md +0 -0
  230. /package/{templates → install/templates}/_bmad/bmb/agents/rachid.md +0 -0
  231. /package/{templates → install/templates}/_bmad/bmb/agents/workflow-builder.md +0 -0
  232. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -0
  233. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/templates.yaml +0 -0
  234. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -0
  235. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -0
  236. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/interview-workflow.md +0 -0
  237. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -0
  238. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -0
  239. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -0
  240. /package/{templates → install/templates}/_bmad/core/agents/carmack.md +0 -0
@@ -0,0 +1,416 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ class MantraValidator {
5
+ constructor(mantrasData = null) {
6
+ if (mantrasData) {
7
+ this.mantrasData = mantrasData;
8
+ } else {
9
+ const mantrasPath = path.join(__dirname, '../data/mantras.json');
10
+ this.mantrasData = JSON.parse(fs.readFileSync(mantrasPath, 'utf8'));
11
+ }
12
+
13
+ this.mantras = this.mantrasData.mantras;
14
+ this.results = null;
15
+ this.agentContent = null;
16
+ }
17
+
18
+ validate(agentDefinition) {
19
+ if (agentDefinition === null || agentDefinition === undefined) {
20
+ throw new Error('Agent definition is required');
21
+ }
22
+
23
+ this.agentContent = typeof agentDefinition === 'string'
24
+ ? agentDefinition
25
+ : JSON.stringify(agentDefinition);
26
+
27
+ this.results = {
28
+ totalMantras: this.mantras.length,
29
+ compliant: [],
30
+ nonCompliant: [],
31
+ warnings: [],
32
+ errors: [],
33
+ timestamp: new Date().toISOString()
34
+ };
35
+
36
+ const startTime = Date.now();
37
+
38
+ for (const mantra of this.mantras) {
39
+ const result = this.checkMantra(mantra.id, agentDefinition);
40
+
41
+ if (result.compliant) {
42
+ this.results.compliant.push({
43
+ id: mantra.id,
44
+ title: mantra.title,
45
+ priority: mantra.priority
46
+ });
47
+ } else {
48
+ this.results.nonCompliant.push({
49
+ id: mantra.id,
50
+ title: mantra.title,
51
+ priority: mantra.priority,
52
+ reason: result.reason
53
+ });
54
+
55
+ if (mantra.priority === 'critical') {
56
+ this.results.errors.push(`Critical mantra ${mantra.id} not met: ${mantra.title}`);
57
+ } else if (mantra.priority === 'high') {
58
+ this.results.warnings.push(`High priority mantra ${mantra.id} not met: ${mantra.title}`);
59
+ }
60
+ }
61
+ }
62
+
63
+ this.results.executionTimeMs = Date.now() - startTime;
64
+ this.results.score = this.calculateScore();
65
+
66
+ return this.results;
67
+ }
68
+
69
+ checkMantra(mantraId, agentDefinition = null) {
70
+ const mantra = this.mantras.find(m => m.id === mantraId);
71
+
72
+ if (!mantra) {
73
+ return { compliant: false, reason: 'Mantra not found' };
74
+ }
75
+
76
+ const content = agentDefinition
77
+ ? (typeof agentDefinition === 'string' ? agentDefinition : JSON.stringify(agentDefinition))
78
+ : this.agentContent;
79
+
80
+ if (!content) {
81
+ return { compliant: false, reason: 'No agent content to validate' };
82
+ }
83
+
84
+ const validation = mantra.validation;
85
+
86
+ if (validation.type === 'keyword') {
87
+ return this._validateKeywords(content, validation, mantra);
88
+ } else if (validation.type === 'pattern') {
89
+ return this._validatePattern(content, validation, mantra);
90
+ } else if (validation.type === 'coverage') {
91
+ return this._validateCoverage(content, validation, mantra);
92
+ }
93
+
94
+ return { compliant: false, reason: 'Unknown validation type' };
95
+ }
96
+
97
+ _validateKeywords(content, validation, mantra) {
98
+ const contentLower = content.toLowerCase();
99
+ const keywordsFound = validation.keywords.filter(keyword =>
100
+ contentLower.includes(keyword.toLowerCase())
101
+ );
102
+
103
+ const isCompliant = keywordsFound.length > 0;
104
+
105
+ if (!isCompliant && validation.required) {
106
+ return {
107
+ compliant: false,
108
+ reason: `Required keywords not found: ${validation.keywords.join(', ')}`
109
+ };
110
+ }
111
+
112
+ return {
113
+ compliant: isCompliant,
114
+ reason: isCompliant
115
+ ? `Keywords found: ${keywordsFound.join(', ')}`
116
+ : 'Optional keywords not found'
117
+ };
118
+ }
119
+
120
+ _validatePattern(content, validation, mantra) {
121
+ try {
122
+ const regex = new RegExp(validation.pattern, validation.flags || '');
123
+ const matches = content.match(regex);
124
+ const hasMatches = matches && matches.length > 0;
125
+
126
+ if (validation.mustNotMatch) {
127
+ const isCompliant = !hasMatches;
128
+ return {
129
+ compliant: isCompliant,
130
+ reason: isCompliant
131
+ ? 'Pattern correctly not found'
132
+ : `Forbidden pattern found: ${matches ? matches[0] : 'match'}`
133
+ };
134
+ } else {
135
+ return {
136
+ compliant: hasMatches,
137
+ reason: hasMatches
138
+ ? `Pattern matched ${matches.length} times`
139
+ : 'Required pattern not found'
140
+ };
141
+ }
142
+ } catch (error) {
143
+ return {
144
+ compliant: false,
145
+ reason: `Pattern validation error: ${error.message}`
146
+ };
147
+ }
148
+ }
149
+
150
+ _validateCoverage(content, validation, mantra) {
151
+ const coverageMatch = content.match(/coverage[:\s]+(\d+(?:\.\d+)?)%?/i);
152
+
153
+ if (!coverageMatch) {
154
+ return {
155
+ compliant: false,
156
+ reason: 'No coverage information found'
157
+ };
158
+ }
159
+
160
+ const coverage = parseFloat(coverageMatch[1]);
161
+ const isCompliant = coverage >= validation.threshold;
162
+
163
+ return {
164
+ compliant: isCompliant,
165
+ reason: isCompliant
166
+ ? `Coverage ${coverage}% meets threshold ${validation.threshold}%`
167
+ : `Coverage ${coverage}% below threshold ${validation.threshold}%`
168
+ };
169
+ }
170
+
171
+ calculateScore() {
172
+ if (!this.results) {
173
+ return 0;
174
+ }
175
+
176
+ const compliantCount = this.results.compliant.length;
177
+ const totalCount = this.results.totalMantras;
178
+
179
+ return totalCount > 0
180
+ ? Math.round((compliantCount / totalCount) * 100)
181
+ : 0;
182
+ }
183
+
184
+ getMissingMantras() {
185
+ if (!this.results) {
186
+ return [];
187
+ }
188
+
189
+ return this.results.nonCompliant.map(nc => {
190
+ const mantra = this.mantras.find(m => m.id === nc.id);
191
+ return {
192
+ id: nc.id,
193
+ title: nc.title,
194
+ description: mantra ? mantra.description : '',
195
+ priority: nc.priority,
196
+ reason: nc.reason
197
+ };
198
+ });
199
+ }
200
+
201
+ getCompliantMantras() {
202
+ if (!this.results) {
203
+ return [];
204
+ }
205
+
206
+ return this.results.compliant.map(c => {
207
+ const mantra = this.mantras.find(m => m.id === c.id);
208
+ return {
209
+ id: c.id,
210
+ title: c.title,
211
+ description: mantra ? mantra.description : '',
212
+ priority: c.priority
213
+ };
214
+ });
215
+ }
216
+
217
+ generateReport() {
218
+ if (!this.results) {
219
+ return 'No validation results available. Run validate() first.';
220
+ }
221
+
222
+ const score = this.results.score;
223
+ const level = score >= 80 ? 'PASS' : score >= 60 ? 'WARNING' : 'FAIL';
224
+
225
+ let report = '';
226
+ report += '='.repeat(60) + '\n';
227
+ report += 'MANTRA VALIDATION REPORT\n';
228
+ report += '='.repeat(60) + '\n\n';
229
+ report += `Validation Date: ${this.results.timestamp}\n`;
230
+ report += `Execution Time: ${this.results.executionTimeMs}ms\n`;
231
+ report += `Status: ${level}\n`;
232
+ report += `Score: ${score}% (${this.results.compliant.length}/${this.results.totalMantras})\n\n`;
233
+
234
+ report += '-'.repeat(60) + '\n';
235
+ report += 'COMPLIANCE SUMMARY\n';
236
+ report += '-'.repeat(60) + '\n';
237
+ report += `Compliant Mantras: ${this.results.compliant.length}\n`;
238
+ report += `Non-Compliant Mantras: ${this.results.nonCompliant.length}\n`;
239
+ report += `Critical Errors: ${this.results.errors.length}\n`;
240
+ report += `Warnings: ${this.results.warnings.length}\n\n`;
241
+
242
+ if (this.results.errors.length > 0) {
243
+ report += '-'.repeat(60) + '\n';
244
+ report += 'CRITICAL ERRORS\n';
245
+ report += '-'.repeat(60) + '\n';
246
+ this.results.errors.forEach(error => {
247
+ report += `- ${error}\n`;
248
+ });
249
+ report += '\n';
250
+ }
251
+
252
+ if (this.results.warnings.length > 0) {
253
+ report += '-'.repeat(60) + '\n';
254
+ report += 'WARNINGS\n';
255
+ report += '-'.repeat(60) + '\n';
256
+ this.results.warnings.forEach(warning => {
257
+ report += `- ${warning}\n`;
258
+ });
259
+ report += '\n';
260
+ }
261
+
262
+ const missing = this.getMissingMantras();
263
+ if (missing.length > 0) {
264
+ report += '-'.repeat(60) + '\n';
265
+ report += 'MISSING MANTRAS\n';
266
+ report += '-'.repeat(60) + '\n';
267
+
268
+ const criticalMissing = missing.filter(m => m.priority === 'critical');
269
+ const highMissing = missing.filter(m => m.priority === 'high');
270
+ const otherMissing = missing.filter(m => m.priority !== 'critical' && m.priority !== 'high');
271
+
272
+ if (criticalMissing.length > 0) {
273
+ report += '\nCRITICAL PRIORITY:\n';
274
+ criticalMissing.forEach(m => {
275
+ report += ` ${m.id} - ${m.title}\n`;
276
+ report += ` Reason: ${m.reason}\n`;
277
+ });
278
+ }
279
+
280
+ if (highMissing.length > 0) {
281
+ report += '\nHIGH PRIORITY:\n';
282
+ highMissing.forEach(m => {
283
+ report += ` ${m.id} - ${m.title}\n`;
284
+ report += ` Reason: ${m.reason}\n`;
285
+ });
286
+ }
287
+
288
+ if (otherMissing.length > 0) {
289
+ report += '\nOTHER:\n';
290
+ otherMissing.forEach(m => {
291
+ report += ` ${m.id} - ${m.title}\n`;
292
+ });
293
+ }
294
+ report += '\n';
295
+ }
296
+
297
+ report += '='.repeat(60) + '\n';
298
+
299
+ return report;
300
+ }
301
+
302
+ suggestImprovements() {
303
+ if (!this.results) {
304
+ return [];
305
+ }
306
+
307
+ const suggestions = [];
308
+ const missing = this.getMissingMantras();
309
+
310
+ const criticalMissing = missing.filter(m => m.priority === 'critical');
311
+ if (criticalMissing.length > 0) {
312
+ suggestions.push({
313
+ priority: 'critical',
314
+ category: 'Critical Improvements',
315
+ items: criticalMissing.map(m => ({
316
+ mantra: m.id,
317
+ title: m.title,
318
+ suggestion: this._getSuggestionForMantra(m)
319
+ }))
320
+ });
321
+ }
322
+
323
+ const highMissing = missing.filter(m => m.priority === 'high');
324
+ if (highMissing.length > 0) {
325
+ suggestions.push({
326
+ priority: 'high',
327
+ category: 'High Priority Improvements',
328
+ items: highMissing.map(m => ({
329
+ mantra: m.id,
330
+ title: m.title,
331
+ suggestion: this._getSuggestionForMantra(m)
332
+ }))
333
+ });
334
+ }
335
+
336
+ const mediumMissing = missing.filter(m => m.priority === 'medium');
337
+ if (mediumMissing.length > 0 && mediumMissing.length <= 5) {
338
+ suggestions.push({
339
+ priority: 'medium',
340
+ category: 'Quick Wins',
341
+ items: mediumMissing.slice(0, 5).map(m => ({
342
+ mantra: m.id,
343
+ title: m.title,
344
+ suggestion: this._getSuggestionForMantra(m)
345
+ }))
346
+ });
347
+ }
348
+
349
+ return suggestions;
350
+ }
351
+
352
+ _getSuggestionForMantra(mantra) {
353
+ const mantraData = this.mantras.find(m => m.id === mantra.id);
354
+
355
+ if (!mantraData) {
356
+ return 'Review mantra requirements and update agent definition';
357
+ }
358
+
359
+ const validation = mantraData.validation;
360
+
361
+ if (validation.type === 'keyword') {
362
+ return `Include one or more of these keywords: ${validation.keywords.join(', ')}`;
363
+ } else if (validation.type === 'pattern') {
364
+ if (validation.mustNotMatch) {
365
+ return `Remove forbidden patterns matching: ${validation.pattern}`;
366
+ } else {
367
+ return `Add content matching pattern: ${validation.pattern}`;
368
+ }
369
+ } else if (validation.type === 'coverage') {
370
+ return `Increase test coverage to at least ${validation.threshold}%`;
371
+ }
372
+
373
+ return mantraData.description;
374
+ }
375
+
376
+ export(format = 'json') {
377
+ if (!this.results) {
378
+ throw new Error('No validation results available. Run validate() first.');
379
+ }
380
+
381
+ if (format === 'json') {
382
+ return JSON.stringify({
383
+ ...this.results,
384
+ missingMantras: this.getMissingMantras(),
385
+ suggestions: this.suggestImprovements()
386
+ }, null, 2);
387
+ } else if (format === 'text') {
388
+ return this.generateReport();
389
+ } else if (format === 'summary') {
390
+ return {
391
+ score: this.results.score,
392
+ status: this.results.score >= 80 ? 'PASS' : this.results.score >= 60 ? 'WARNING' : 'FAIL',
393
+ compliant: this.results.compliant.length,
394
+ nonCompliant: this.results.nonCompliant.length,
395
+ criticalErrors: this.results.errors.length,
396
+ executionTimeMs: this.results.executionTimeMs
397
+ };
398
+ }
399
+
400
+ throw new Error(`Unsupported export format: ${format}`);
401
+ }
402
+
403
+ getMantraById(mantraId) {
404
+ return this.mantras.find(m => m.id === mantraId);
405
+ }
406
+
407
+ getMantrasByCategory(category) {
408
+ return this.mantras.filter(m => m.category === category);
409
+ }
410
+
411
+ getMantrasByPriority(priority) {
412
+ return this.mantras.filter(m => m.priority === priority);
413
+ }
414
+ }
415
+
416
+ module.exports = MantraValidator;
@@ -0,0 +1,113 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const yaml = require('js-yaml');
4
+
5
+ class ProfileTemplate {
6
+ static render(template, data) {
7
+ let result = template;
8
+
9
+ const placeholders = this.extractPlaceholders(template);
10
+
11
+ for (const placeholder of placeholders) {
12
+ const value = this.resolvePlaceholder(placeholder, data);
13
+
14
+ if (value !== undefined && value !== null) {
15
+ const regex = new RegExp(`\\{\\{${placeholder.replace(/\./g, '\\.')}\\}\\}`, 'g');
16
+ result = result.replace(regex, value);
17
+ }
18
+ }
19
+
20
+ return result;
21
+ }
22
+
23
+ static loadTemplate(templateName) {
24
+ const templatesDir = path.join(__dirname, 'templates');
25
+ const templatePath = path.join(templatesDir, `${templateName}.md`);
26
+
27
+ if (!fs.existsSync(templatePath)) {
28
+ throw new Error(`Template not found: ${templateName}`);
29
+ }
30
+
31
+ return fs.readFileSync(templatePath, 'utf-8');
32
+ }
33
+
34
+ static renderFromFile(templateName, data) {
35
+ const template = this.loadTemplate(templateName);
36
+ return this.render(template, data);
37
+ }
38
+
39
+ static validateTemplate(template, requiredPlaceholders = []) {
40
+ const result = {
41
+ valid: true,
42
+ errors: [],
43
+ warnings: []
44
+ };
45
+
46
+ const frontmatterMatch = template.match(/^---\n([\s\S]*?)\n---/);
47
+
48
+ if (!frontmatterMatch) {
49
+ result.valid = false;
50
+ result.errors.push('Missing YAML frontmatter');
51
+ return result;
52
+ }
53
+
54
+ try {
55
+ yaml.load(frontmatterMatch[1]);
56
+ } catch (e) {
57
+ result.valid = false;
58
+ result.errors.push(`Invalid YAML frontmatter: ${e.message}`);
59
+ return result;
60
+ }
61
+
62
+ const templatePlaceholders = this.extractPlaceholders(template);
63
+
64
+ for (const required of requiredPlaceholders) {
65
+ if (!templatePlaceholders.includes(required)) {
66
+ result.warnings.push(`Missing required placeholder: ${required}`);
67
+ }
68
+ }
69
+
70
+ const xmlMatch = template.match(/```xml\n([\s\S]*?)\n```/);
71
+ if (xmlMatch) {
72
+ const xmlContent = xmlMatch[1];
73
+ const openTags = (xmlContent.match(/<(\w+)[^>]*>/g) || []).map(tag => tag.match(/<(\w+)/)[1]);
74
+ const closeTags = (xmlContent.match(/<\/(\w+)>/g) || []).map(tag => tag.match(/<\/(\w+)>/)[1]);
75
+
76
+ if (openTags.length !== closeTags.length) {
77
+ result.warnings.push('Potentially malformed XML: tag count mismatch');
78
+ }
79
+ }
80
+
81
+ return result;
82
+ }
83
+
84
+ static extractPlaceholders(template) {
85
+ const regex = /\{\{([^}]+)\}\}/g;
86
+ const matches = [];
87
+ let match;
88
+
89
+ while ((match = regex.exec(template)) !== null) {
90
+ if (!matches.includes(match[1])) {
91
+ matches.push(match[1]);
92
+ }
93
+ }
94
+
95
+ return matches;
96
+ }
97
+
98
+ static resolvePlaceholder(path, data) {
99
+ const parts = path.split('.');
100
+ let current = data;
101
+
102
+ for (const part of parts) {
103
+ if (current === undefined || current === null) {
104
+ return undefined;
105
+ }
106
+ current = current[part];
107
+ }
108
+
109
+ return current;
110
+ }
111
+ }
112
+
113
+ module.exports = ProfileTemplate;
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: "{{agent_name}}"
3
+ description: "{{description}}"
4
+ ---
5
+
6
+ You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
7
+
8
+ ```xml
9
+ <agent id="{{agent_id}}" name="{{agent_name}}" title="{{title}}" icon="{{icon}}">
10
+ <activation critical="MANDATORY">
11
+ <step n="1">Load persona from current file</step>
12
+ <step n="2">Load config from {project-root}/_byan/config.yaml - store {user_name}, {communication_language}, {output_folder}</step>
13
+ <step n="3">Show greeting using {user_name} in {communication_language}</step>
14
+ <step n="4">Inform about `/bmad-help` command</step>
15
+ <step n="5">WAIT for user input</step>
16
+ <rules>
17
+ <r>Communicate in {communication_language}</r>
18
+ <r>Stay in character until EXIT</r>
19
+ <r>Apply Merise Agile + TDD + 64 mantras</r>
20
+ </rules>
21
+ </activation>
22
+
23
+ <persona>
24
+ <role>{{role}}</role>
25
+ <identity>{{identity}}</identity>
26
+ <communication_style>{{communication_style}}</communication_style>
27
+
28
+ <principles>
29
+ {{principles}}
30
+ </principles>
31
+ </persona>
32
+
33
+ <knowledge_base>
34
+ {{knowledge_base}}
35
+ </knowledge_base>
36
+
37
+ <capabilities>
38
+ {{capabilities}}
39
+ </capabilities>
40
+
41
+ <anti_patterns>
42
+ {{anti_patterns}}
43
+ </anti_patterns>
44
+
45
+ <exit_protocol>
46
+ EXIT: Save state → Summarize → Next steps → File locations → Remind reactivation → Return control
47
+ </exit_protocol>
48
+ </agent>
49
+ ```
@@ -0,0 +1 @@
1
+ Agent: {{agent_name}}, Role: {{role}}