bmad-method 6.0.5-next.8 → 6.1.0

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 (262) hide show
  1. package/package.json +1 -1
  2. package/src/bmm/agents/analyst.agent.yaml +1 -1
  3. package/src/bmm/module-help.csv +1 -1
  4. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +1 -1
  5. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +1 -1
  6. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +1 -1
  7. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +1 -1
  8. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +1 -1
  9. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +1 -1
  10. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +1 -1
  11. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +1 -1
  12. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +1 -1
  13. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +1 -1
  14. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +1 -1
  15. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +1 -1
  16. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +1 -1
  17. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +1 -1
  18. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +1 -1
  19. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +1 -1
  20. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +1 -1
  21. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +1 -1
  22. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +1 -1
  23. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +2 -2
  24. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +2 -2
  25. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +2 -2
  26. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +2 -2
  27. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +2 -2
  28. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +2 -2
  29. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +2 -2
  30. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +2 -2
  31. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +2 -2
  32. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +2 -2
  33. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +2 -2
  34. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +2 -2
  35. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +2 -2
  36. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +2 -2
  37. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +2 -2
  38. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +2 -2
  39. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +2 -2
  40. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +31 -13
  41. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +1 -1
  42. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +6 -2
  43. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +1 -1
  44. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +4 -0
  45. package/src/bmm/workflows/4-implementation/code-review/workflow.md +4 -7
  46. package/src/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/workflow.md +0 -4
  47. package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +1 -1
  48. package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +1 -1
  49. package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +1 -1
  50. package/src/core/module-help.csv +2 -2
  51. package/src/core/workflows/bmad-brainstorming/SKILL.md +6 -0
  52. package/src/core/workflows/bmad-brainstorming/bmad-skill-manifest.yaml +1 -0
  53. package/src/core/workflows/{brainstorming → bmad-brainstorming}/workflow.md +2 -5
  54. package/src/core/workflows/bmad-party-mode/SKILL.md +6 -0
  55. package/src/core/workflows/bmad-party-mode/bmad-skill-manifest.yaml +1 -0
  56. package/src/core/workflows/{party-mode → bmad-party-mode}/steps/step-03-graceful-exit.md +0 -1
  57. package/src/core/workflows/{party-mode → bmad-party-mode}/workflow.md +0 -4
  58. package/tools/cli/external-official-modules.yaml +18 -18
  59. package/tools/cli/installers/lib/core/installer.js +25 -8
  60. package/tools/cli/installers/lib/ide/_base-ide.js +0 -1
  61. package/tools/cli/installers/lib/ide/_config-driven.js +9 -4
  62. package/tools/cli/installers/lib/ide/manager.js +3 -3
  63. package/tools/cli/lib/agent/compiler.js +1 -1
  64. package/.augment/code_review_guidelines.yaml +0 -231
  65. package/.coderabbit.yaml +0 -85
  66. package/.github/CODE_OF_CONDUCT.md +0 -128
  67. package/.github/FUNDING.yaml +0 -15
  68. package/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -124
  69. package/.github/ISSUE_TEMPLATE/config.yaml +0 -8
  70. package/.github/ISSUE_TEMPLATE/documentation.yaml +0 -55
  71. package/.github/ISSUE_TEMPLATE/feature-request.md +0 -22
  72. package/.github/ISSUE_TEMPLATE/issue.md +0 -32
  73. package/.github/PULL_REQUEST_TEMPLATE.md +0 -13
  74. package/.github/scripts/discord-helpers.sh +0 -34
  75. package/.github/workflows/coderabbit-review.yaml +0 -22
  76. package/.github/workflows/discord.yaml +0 -90
  77. package/.github/workflows/docs.yaml +0 -64
  78. package/.github/workflows/publish.yaml +0 -133
  79. package/.github/workflows/quality.yaml +0 -116
  80. package/.husky/pre-commit +0 -20
  81. package/.markdownlint-cli2.yaml +0 -41
  82. package/.nvmrc +0 -1
  83. package/.prettierignore +0 -12
  84. package/.vscode/settings.json +0 -96
  85. package/CHANGELOG.md +0 -1785
  86. package/CNAME +0 -1
  87. package/CONTRIBUTING.md +0 -176
  88. package/CONTRIBUTORS.md +0 -32
  89. package/SECURITY.md +0 -85
  90. package/TRADEMARK.md +0 -55
  91. package/Wordmark.png +0 -0
  92. package/banner-bmad-method.png +0 -0
  93. package/docs/404.md +0 -9
  94. package/docs/_STYLE_GUIDE.md +0 -370
  95. package/docs/explanation/advanced-elicitation.md +0 -49
  96. package/docs/explanation/adversarial-review.md +0 -59
  97. package/docs/explanation/brainstorming.md +0 -33
  98. package/docs/explanation/established-projects-faq.md +0 -50
  99. package/docs/explanation/party-mode.md +0 -59
  100. package/docs/explanation/preventing-agent-conflicts.md +0 -112
  101. package/docs/explanation/project-context.md +0 -157
  102. package/docs/explanation/quick-dev-new-preview.md +0 -73
  103. package/docs/explanation/quick-flow.md +0 -77
  104. package/docs/explanation/why-solutioning-matters.md +0 -77
  105. package/docs/how-to/customize-bmad.md +0 -172
  106. package/docs/how-to/established-projects.md +0 -117
  107. package/docs/how-to/get-answers-about-bmad.md +0 -138
  108. package/docs/how-to/install-bmad.md +0 -116
  109. package/docs/how-to/non-interactive-installation.md +0 -171
  110. package/docs/how-to/project-context.md +0 -136
  111. package/docs/how-to/quick-fixes.md +0 -123
  112. package/docs/how-to/shard-large-documents.md +0 -78
  113. package/docs/how-to/upgrade-to-v6.md +0 -100
  114. package/docs/index.md +0 -60
  115. package/docs/reference/agents.md +0 -28
  116. package/docs/reference/commands.md +0 -145
  117. package/docs/reference/modules.md +0 -76
  118. package/docs/reference/testing.md +0 -106
  119. package/docs/reference/workflow-map.md +0 -89
  120. package/docs/roadmap.mdx +0 -136
  121. package/docs/tutorials/getting-started.md +0 -275
  122. package/docs/zh-cn/404.md +0 -9
  123. package/docs/zh-cn/_STYLE_GUIDE.md +0 -370
  124. package/docs/zh-cn/explanation/advanced-elicitation.md +0 -62
  125. package/docs/zh-cn/explanation/adversarial-review.md +0 -71
  126. package/docs/zh-cn/explanation/brainstorming.md +0 -43
  127. package/docs/zh-cn/explanation/established-projects-faq.md +0 -60
  128. package/docs/zh-cn/explanation/party-mode.md +0 -79
  129. package/docs/zh-cn/explanation/preventing-agent-conflicts.md +0 -137
  130. package/docs/zh-cn/explanation/project-context.md +0 -176
  131. package/docs/zh-cn/explanation/quick-flow.md +0 -93
  132. package/docs/zh-cn/explanation/why-solutioning-matters.md +0 -90
  133. package/docs/zh-cn/how-to/customize-bmad.md +0 -182
  134. package/docs/zh-cn/how-to/established-projects.md +0 -134
  135. package/docs/zh-cn/how-to/get-answers-about-bmad.md +0 -144
  136. package/docs/zh-cn/how-to/install-bmad.md +0 -105
  137. package/docs/zh-cn/how-to/non-interactive-installation.md +0 -181
  138. package/docs/zh-cn/how-to/project-context.md +0 -152
  139. package/docs/zh-cn/how-to/quick-fixes.md +0 -140
  140. package/docs/zh-cn/how-to/shard-large-documents.md +0 -86
  141. package/docs/zh-cn/how-to/upgrade-to-v6.md +0 -120
  142. package/docs/zh-cn/index.md +0 -69
  143. package/docs/zh-cn/reference/agents.md +0 -41
  144. package/docs/zh-cn/reference/commands.md +0 -166
  145. package/docs/zh-cn/reference/modules.md +0 -94
  146. package/docs/zh-cn/reference/testing.md +0 -122
  147. package/docs/zh-cn/reference/workflow-map.md +0 -104
  148. package/docs/zh-cn/roadmap.mdx +0 -152
  149. package/docs/zh-cn/tutorials/getting-started.md +0 -300
  150. package/eslint.config.mjs +0 -141
  151. package/prettier.config.mjs +0 -32
  152. package/src/core/workflows/brainstorming/bmad-skill-manifest.yaml +0 -3
  153. package/src/core/workflows/party-mode/bmad-skill-manifest.yaml +0 -3
  154. package/test/README.md +0 -295
  155. package/test/adversarial-review-tests/README.md +0 -56
  156. package/test/adversarial-review-tests/sample-content.md +0 -46
  157. package/test/adversarial-review-tests/test-cases.yaml +0 -103
  158. package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +0 -27
  159. package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +0 -30
  160. package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +0 -22
  161. package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +0 -20
  162. package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +0 -25
  163. package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +0 -24
  164. package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +0 -25
  165. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +0 -25
  166. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +0 -25
  167. package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +0 -31
  168. package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +0 -25
  169. package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +0 -25
  170. package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +0 -25
  171. package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +0 -25
  172. package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +0 -26
  173. package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +0 -24
  174. package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +0 -27
  175. package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +0 -23
  176. package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +0 -24
  177. package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +0 -27
  178. package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +0 -27
  179. package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +0 -24
  180. package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +0 -29
  181. package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +0 -31
  182. package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +0 -28
  183. package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +0 -28
  184. package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +0 -5
  185. package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +0 -28
  186. package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +0 -11
  187. package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +0 -19
  188. package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +0 -18
  189. package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +0 -24
  190. package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +0 -22
  191. package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +0 -27
  192. package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +0 -31
  193. package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +0 -22
  194. package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +0 -38
  195. package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +0 -23
  196. package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +0 -31
  197. package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +0 -34
  198. package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +0 -24
  199. package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +0 -24
  200. package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +0 -24
  201. package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +0 -24
  202. package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +0 -23
  203. package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +0 -24
  204. package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +0 -24
  205. package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +0 -24
  206. package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +0 -22
  207. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +0 -28
  208. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +0 -30
  209. package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +0 -24
  210. package/test/fixtures/file-refs-csv/invalid/all-empty-workflow.csv +0 -3
  211. package/test/fixtures/file-refs-csv/invalid/empty-data.csv +0 -1
  212. package/test/fixtures/file-refs-csv/invalid/no-workflow-column.csv +0 -3
  213. package/test/fixtures/file-refs-csv/invalid/unresolvable-vars.csv +0 -3
  214. package/test/fixtures/file-refs-csv/valid/bmm-style.csv +0 -3
  215. package/test/fixtures/file-refs-csv/valid/core-style.csv +0 -3
  216. package/test/fixtures/file-refs-csv/valid/minimal.csv +0 -2
  217. package/test/test-agent-schema.js +0 -387
  218. package/test/test-cli-integration.sh +0 -159
  219. package/test/test-file-refs-csv.js +0 -133
  220. package/test/test-install-to-bmad.js +0 -154
  221. package/test/test-installation-components.js +0 -1796
  222. package/test/test-rehype-plugins.mjs +0 -1050
  223. package/test/test-workflow-path-regex.js +0 -88
  224. package/test/unit-test-schema.js +0 -133
  225. package/tools/build-docs.mjs +0 -464
  226. package/tools/docs/_prompt-external-modules-page.md +0 -59
  227. package/tools/docs/fix-refs.md +0 -91
  228. package/tools/docs/native-skills-migration-checklist.md +0 -281
  229. package/tools/fix-doc-links.js +0 -285
  230. package/tools/validate-agent-schema.js +0 -110
  231. package/tools/validate-doc-links.js +0 -407
  232. package/tools/validate-file-refs.js +0 -556
  233. package/website/README.md +0 -75
  234. package/website/astro.config.mjs +0 -157
  235. package/website/public/diagrams/quick-dev-diagram.png +0 -0
  236. package/website/public/favicon.ico +0 -0
  237. package/website/public/img/bmad-dark.png +0 -0
  238. package/website/public/img/bmad-light.png +0 -0
  239. package/website/public/workflow-map-diagram.html +0 -361
  240. package/website/src/components/Banner.astro +0 -62
  241. package/website/src/components/Header.astro +0 -96
  242. package/website/src/components/MobileMenuFooter.astro +0 -33
  243. package/website/src/content/config.ts +0 -7
  244. package/website/src/content/i18n/zh-CN.json +0 -28
  245. package/website/src/lib/site-url.mjs +0 -25
  246. package/website/src/pages/404.astro +0 -11
  247. package/website/src/pages/robots.txt.ts +0 -48
  248. package/website/src/rehype-base-paths.js +0 -112
  249. package/website/src/rehype-markdown-links.js +0 -119
  250. package/website/src/styles/custom.css +0 -805
  251. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/brain-methods.csv +0 -0
  252. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-01-session-setup.md +0 -0
  253. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-01b-continue.md +0 -0
  254. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-02a-user-selected.md +0 -0
  255. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-02b-ai-recommended.md +0 -0
  256. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-02c-random-selection.md +0 -0
  257. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-02d-progressive-flow.md +0 -0
  258. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-03-technique-execution.md +0 -0
  259. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/steps/step-04-idea-organization.md +0 -0
  260. /package/src/core/workflows/{brainstorming → bmad-brainstorming}/template.md +0 -0
  261. /package/src/core/workflows/{party-mode → bmad-party-mode}/steps/step-01-agent-loading.md +0 -0
  262. /package/src/core/workflows/{party-mode → bmad-party-mode}/steps/step-02-discussion-orchestration.md +0 -0
@@ -1,387 +0,0 @@
1
- /**
2
- * Agent Schema Validation Test Runner
3
- *
4
- * Runs all test fixtures and verifies expected outcomes.
5
- * Reports pass/fail for each test and overall coverage statistics.
6
- *
7
- * Usage: node test/test-agent-schema.js
8
- * Exit codes: 0 = all tests pass, 1 = test failures
9
- */
10
-
11
- const fs = require('node:fs');
12
- const path = require('node:path');
13
- const yaml = require('yaml');
14
- const { validateAgentFile } = require('../tools/schema/agent.js');
15
- const { glob } = require('glob');
16
-
17
- // ANSI color codes
18
- const colors = {
19
- reset: '\u001B[0m',
20
- green: '\u001B[32m',
21
- red: '\u001B[31m',
22
- yellow: '\u001B[33m',
23
- blue: '\u001B[34m',
24
- cyan: '\u001B[36m',
25
- dim: '\u001B[2m',
26
- };
27
-
28
- /**
29
- * Parse test metadata from YAML comments
30
- * @param {string} filePath
31
- * @returns {{shouldPass: boolean, errorExpectation?: object, pathContext?: string}}
32
- */
33
- function parseTestMetadata(filePath) {
34
- const content = fs.readFileSync(filePath, 'utf8');
35
- const lines = content.split('\n');
36
-
37
- let shouldPass = true;
38
- let pathContext = null;
39
- const errorExpectation = {};
40
-
41
- for (const line of lines) {
42
- if (line.includes('Expected: PASS')) {
43
- shouldPass = true;
44
- } else if (line.includes('Expected: FAIL')) {
45
- shouldPass = false;
46
- }
47
-
48
- // Parse error metadata
49
- const codeMatch = line.match(/^# Error code: (.+)$/);
50
- if (codeMatch) {
51
- errorExpectation.code = codeMatch[1].trim();
52
- }
53
-
54
- const pathMatch = line.match(/^# Error path: (.+)$/);
55
- if (pathMatch) {
56
- errorExpectation.path = pathMatch[1].trim();
57
- }
58
-
59
- const messageMatch = line.match(/^# Error message: (.+)$/);
60
- if (messageMatch) {
61
- errorExpectation.message = messageMatch[1].trim();
62
- }
63
-
64
- const minimumMatch = line.match(/^# Error minimum: (\d+)$/);
65
- if (minimumMatch) {
66
- errorExpectation.minimum = parseInt(minimumMatch[1], 10);
67
- }
68
-
69
- const expectedMatch = line.match(/^# Error expected: (.+)$/);
70
- if (expectedMatch) {
71
- errorExpectation.expected = expectedMatch[1].trim();
72
- }
73
-
74
- const receivedMatch = line.match(/^# Error received: (.+)$/);
75
- if (receivedMatch) {
76
- errorExpectation.received = receivedMatch[1].trim();
77
- }
78
-
79
- const keysMatch = line.match(/^# Error keys: \[(.+)\]$/);
80
- if (keysMatch) {
81
- errorExpectation.keys = keysMatch[1].split(',').map((k) => k.trim().replaceAll(/['"]/g, ''));
82
- }
83
-
84
- const contextMatch = line.match(/^# Path context: (.+)$/);
85
- if (contextMatch) {
86
- pathContext = contextMatch[1].trim();
87
- }
88
- }
89
-
90
- return {
91
- shouldPass,
92
- errorExpectation: Object.keys(errorExpectation).length > 0 ? errorExpectation : null,
93
- pathContext,
94
- };
95
- }
96
-
97
- /**
98
- * Convert dot-notation path string to array (handles array indices)
99
- * e.g., "agent.menu[0].trigger" => ["agent", "menu", 0, "trigger"]
100
- */
101
- function parsePathString(pathString) {
102
- return pathString
103
- .replaceAll(/\[(\d+)\]/g, '.$1') // Convert [0] to .0
104
- .split('.')
105
- .map((part) => {
106
- const num = parseInt(part, 10);
107
- return isNaN(num) ? part : num;
108
- });
109
- }
110
-
111
- /**
112
- * Validate error against expectations
113
- * @param {object} error - Zod error issue
114
- * @param {object} expectation - Expected error structure
115
- * @returns {{valid: boolean, reason?: string}}
116
- */
117
- function validateError(error, expectation) {
118
- // Check error code
119
- if (expectation.code && error.code !== expectation.code) {
120
- return { valid: false, reason: `Expected code "${expectation.code}", got "${error.code}"` };
121
- }
122
-
123
- // Check error path
124
- if (expectation.path) {
125
- const expectedPath = parsePathString(expectation.path);
126
- const actualPath = error.path;
127
-
128
- if (JSON.stringify(expectedPath) !== JSON.stringify(actualPath)) {
129
- return {
130
- valid: false,
131
- reason: `Expected path ${JSON.stringify(expectedPath)}, got ${JSON.stringify(actualPath)}`,
132
- };
133
- }
134
- }
135
-
136
- // For custom errors, strictly check message
137
- if (expectation.code === 'custom' && expectation.message && error.message !== expectation.message) {
138
- return {
139
- valid: false,
140
- reason: `Expected message "${expectation.message}", got "${error.message}"`,
141
- };
142
- }
143
-
144
- // For Zod errors, check type-specific fields
145
- if (expectation.minimum !== undefined && error.minimum !== expectation.minimum) {
146
- return { valid: false, reason: `Expected minimum ${expectation.minimum}, got ${error.minimum}` };
147
- }
148
-
149
- if (expectation.expected && error.expected !== expectation.expected) {
150
- return { valid: false, reason: `Expected type "${expectation.expected}", got "${error.expected}"` };
151
- }
152
-
153
- if (expectation.received && error.received !== expectation.received) {
154
- return { valid: false, reason: `Expected received "${expectation.received}", got "${error.received}"` };
155
- }
156
-
157
- if (expectation.keys) {
158
- const expectedKeys = expectation.keys.sort();
159
- const actualKeys = (error.keys || []).sort();
160
- if (JSON.stringify(expectedKeys) !== JSON.stringify(actualKeys)) {
161
- return {
162
- valid: false,
163
- reason: `Expected keys ${JSON.stringify(expectedKeys)}, got ${JSON.stringify(actualKeys)}`,
164
- };
165
- }
166
- }
167
-
168
- return { valid: true };
169
- }
170
-
171
- /**
172
- * Run a single test case
173
- * @param {string} filePath
174
- * @returns {{passed: boolean, message: string}}
175
- */
176
- function runTest(filePath) {
177
- const metadata = parseTestMetadata(filePath);
178
- const { shouldPass, errorExpectation, pathContext } = metadata;
179
-
180
- try {
181
- const fileContent = fs.readFileSync(filePath, 'utf8');
182
- let agentData;
183
-
184
- try {
185
- agentData = yaml.parse(fileContent);
186
- } catch (parseError) {
187
- // YAML parse error
188
- if (shouldPass) {
189
- return {
190
- passed: false,
191
- message: `Expected PASS but got YAML parse error: ${parseError.message}`,
192
- };
193
- }
194
- return {
195
- passed: true,
196
- message: 'Got expected YAML parse error',
197
- };
198
- }
199
-
200
- // Determine validation path
201
- // If pathContext is specified in comments, use it; otherwise derive from fixture location
202
- let validationPath = pathContext;
203
- if (!validationPath) {
204
- // Map fixture location to simulated src/ path
205
- const relativePath = path.relative(path.join(__dirname, 'fixtures/agent-schema'), filePath);
206
- const parts = relativePath.split(path.sep);
207
-
208
- if (parts.includes('metadata') && parts[0] === 'valid') {
209
- // Valid metadata tests: check if filename suggests module or core
210
- const filename = path.basename(filePath);
211
- if (filename.includes('module')) {
212
- validationPath = 'src/bmm/agents/test.agent.yaml';
213
- } else {
214
- validationPath = 'src/core/agents/test.agent.yaml';
215
- }
216
- } else if (parts.includes('metadata') && parts[0] === 'invalid') {
217
- // Invalid metadata tests: derive from filename
218
- const filename = path.basename(filePath);
219
- if (filename.includes('module') || filename.includes('wrong-module')) {
220
- validationPath = 'src/bmm/agents/test.agent.yaml';
221
- } else if (filename.includes('core')) {
222
- validationPath = 'src/core/agents/test.agent.yaml';
223
- } else {
224
- validationPath = 'src/core/agents/test.agent.yaml';
225
- }
226
- } else {
227
- // Default to core agent path
228
- validationPath = 'src/core/agents/test.agent.yaml';
229
- }
230
- }
231
-
232
- const result = validateAgentFile(validationPath, agentData);
233
-
234
- if (result.success && shouldPass) {
235
- return {
236
- passed: true,
237
- message: 'Validation passed as expected',
238
- };
239
- }
240
-
241
- if (!result.success && !shouldPass) {
242
- const actualError = result.error.issues[0];
243
-
244
- // If we have error expectations, validate strictly
245
- if (errorExpectation) {
246
- const validation = validateError(actualError, errorExpectation);
247
-
248
- if (!validation.valid) {
249
- return {
250
- passed: false,
251
- message: `Error validation failed: ${validation.reason}`,
252
- };
253
- }
254
-
255
- return {
256
- passed: true,
257
- message: `Got expected error (${errorExpectation.code}): ${actualError.message}`,
258
- };
259
- }
260
-
261
- // No specific expectations - just check that it failed
262
- return {
263
- passed: true,
264
- message: `Got expected validation error: ${actualError?.message}`,
265
- };
266
- }
267
-
268
- if (result.success && !shouldPass) {
269
- return {
270
- passed: false,
271
- message: 'Expected validation to FAIL but it PASSED',
272
- };
273
- }
274
-
275
- if (!result.success && shouldPass) {
276
- return {
277
- passed: false,
278
- message: `Expected validation to PASS but it FAILED: ${result.error.issues[0]?.message}`,
279
- };
280
- }
281
-
282
- return {
283
- passed: false,
284
- message: 'Unexpected test state',
285
- };
286
- } catch (error) {
287
- return {
288
- passed: false,
289
- message: `Test execution error: ${error.message}`,
290
- };
291
- }
292
- }
293
-
294
- /**
295
- * Main test runner
296
- */
297
- async function main() {
298
- console.log(`${colors.cyan}╔═══════════════════════════════════════════════════════════╗${colors.reset}`);
299
- console.log(`${colors.cyan}║ Agent Schema Validation Test Suite ║${colors.reset}`);
300
- console.log(`${colors.cyan}╚═══════════════════════════════════════════════════════════╝${colors.reset}\n`);
301
-
302
- // Find all test fixtures
303
- const testFiles = await glob('test/fixtures/agent-schema/**/*.agent.yaml', {
304
- cwd: path.join(__dirname, '..'),
305
- absolute: true,
306
- });
307
-
308
- if (testFiles.length === 0) {
309
- console.log(`${colors.yellow}⚠️ No test fixtures found${colors.reset}`);
310
- process.exit(0);
311
- }
312
-
313
- console.log(`Found ${colors.cyan}${testFiles.length}${colors.reset} test fixture(s)\n`);
314
-
315
- // Group tests by category
316
- const categories = {};
317
- for (const testFile of testFiles) {
318
- const relativePath = path.relative(path.join(__dirname, 'fixtures/agent-schema'), testFile);
319
- const parts = relativePath.split(path.sep);
320
- const validInvalid = parts[0]; // 'valid' or 'invalid'
321
- const category = parts[1]; // 'top-level', 'metadata', etc.
322
-
323
- const categoryKey = `${validInvalid}/${category}`;
324
- if (!categories[categoryKey]) {
325
- categories[categoryKey] = [];
326
- }
327
- categories[categoryKey].push(testFile);
328
- }
329
-
330
- // Run tests by category
331
- let totalTests = 0;
332
- let passedTests = 0;
333
- const failures = [];
334
-
335
- for (const [categoryKey, files] of Object.entries(categories).sort()) {
336
- const [validInvalid, category] = categoryKey.split('/');
337
- const categoryLabel = category.replaceAll('-', ' ').toUpperCase();
338
- const validLabel = validInvalid === 'valid' ? '✅' : '❌';
339
-
340
- console.log(`${colors.blue}${validLabel} ${categoryLabel} (${validInvalid})${colors.reset}`);
341
-
342
- for (const testFile of files) {
343
- totalTests++;
344
- const testName = path.basename(testFile, '.agent.yaml');
345
- const result = runTest(testFile);
346
-
347
- if (result.passed) {
348
- passedTests++;
349
- console.log(` ${colors.green}✓${colors.reset} ${testName} ${colors.dim}${result.message}${colors.reset}`);
350
- } else {
351
- console.log(` ${colors.red}✗${colors.reset} ${testName} ${colors.red}${result.message}${colors.reset}`);
352
- failures.push({
353
- file: path.relative(process.cwd(), testFile),
354
- message: result.message,
355
- });
356
- }
357
- }
358
- console.log('');
359
- }
360
-
361
- // Summary
362
- console.log(`${colors.cyan}═══════════════════════════════════════════════════════════${colors.reset}`);
363
- console.log(`${colors.cyan}Test Results:${colors.reset}`);
364
- console.log(` Total: ${totalTests}`);
365
- console.log(` Passed: ${colors.green}${passedTests}${colors.reset}`);
366
- console.log(` Failed: ${passedTests === totalTests ? colors.green : colors.red}${totalTests - passedTests}${colors.reset}`);
367
- console.log(`${colors.cyan}═══════════════════════════════════════════════════════════${colors.reset}\n`);
368
-
369
- // Report failures
370
- if (failures.length > 0) {
371
- console.log(`${colors.red}❌ FAILED TESTS:${colors.reset}\n`);
372
- for (const failure of failures) {
373
- console.log(`${colors.red}✗${colors.reset} ${failure.file}`);
374
- console.log(` ${failure.message}\n`);
375
- }
376
- process.exit(1);
377
- }
378
-
379
- console.log(`${colors.green}✨ All tests passed!${colors.reset}\n`);
380
- process.exit(0);
381
- }
382
-
383
- // Run
384
- main().catch((error) => {
385
- console.error(`${colors.red}Fatal error:${colors.reset}`, error);
386
- process.exit(1);
387
- });
@@ -1,159 +0,0 @@
1
- #!/bin/bash
2
- # CLI Integration Tests for Agent Schema Validator
3
- # Tests the CLI wrapper (tools/validate-agent-schema.js) behavior and error handling
4
- # NOTE: Tests CLI functionality using temporary test fixtures
5
-
6
- echo "========================================"
7
- echo "CLI Integration Tests"
8
- echo "========================================"
9
- echo ""
10
-
11
- # Colors
12
- GREEN='\033[0;32m'
13
- RED='\033[0;31m'
14
- YELLOW='\033[1;33m'
15
- NC='\033[0m' # No Color
16
-
17
- PASSED=0
18
- FAILED=0
19
-
20
- # Get the repo root (assuming script is in test/ directory)
21
- REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
22
-
23
- # Create temp directory for test fixtures
24
- TEMP_DIR=$(mktemp -d)
25
- cleanup() {
26
- rm -rf "$TEMP_DIR"
27
- }
28
- trap cleanup EXIT
29
-
30
- # Test 1: CLI fails when no files found (exit 1)
31
- echo "Test 1: CLI fails when no agent files found (should exit 1)"
32
- mkdir -p "$TEMP_DIR/empty/src/core/agents"
33
- OUTPUT=$(node "$REPO_ROOT/tools/validate-agent-schema.js" "$TEMP_DIR/empty" 2>&1)
34
- EXIT_CODE=$?
35
- if [ $EXIT_CODE -eq 1 ] && echo "$OUTPUT" | grep -q "No agent files found"; then
36
- echo -e "${GREEN}✓${NC} CLI fails correctly when no files found (exit 1)"
37
- PASSED=$((PASSED + 1))
38
- else
39
- echo -e "${RED}✗${NC} CLI failed to handle no files properly (exit code: $EXIT_CODE)"
40
- FAILED=$((FAILED + 1))
41
- fi
42
- echo ""
43
-
44
- # Test 2: CLI reports validation errors with exit code 1
45
- echo "Test 2: CLI reports validation errors (should exit 1)"
46
- mkdir -p "$TEMP_DIR/invalid/src/core/agents"
47
- cat > "$TEMP_DIR/invalid/src/core/agents/bad.agent.yaml" << 'EOF'
48
- agent:
49
- metadata:
50
- id: bad
51
- name: Bad
52
- title: Bad
53
- icon: 🧪
54
- persona:
55
- role: Test
56
- identity: Test
57
- communication_style: Test
58
- principles: []
59
- menu: []
60
- EOF
61
- OUTPUT=$(node "$REPO_ROOT/tools/validate-agent-schema.js" "$TEMP_DIR/invalid" 2>&1)
62
- EXIT_CODE=$?
63
- if [ $EXIT_CODE -eq 1 ] && echo "$OUTPUT" | grep -q "failed validation"; then
64
- echo -e "${GREEN}✓${NC} CLI reports errors correctly (exit 1)"
65
- PASSED=$((PASSED + 1))
66
- else
67
- echo -e "${RED}✗${NC} CLI failed to report errors (exit code: $EXIT_CODE)"
68
- FAILED=$((FAILED + 1))
69
- fi
70
- echo ""
71
-
72
- # Test 3: CLI discovers and counts agent files correctly
73
- echo "Test 3: CLI discovers and counts agent files"
74
- mkdir -p "$TEMP_DIR/valid/src/core/agents"
75
- cat > "$TEMP_DIR/valid/src/core/agents/test1.agent.yaml" << 'EOF'
76
- agent:
77
- metadata:
78
- id: test1
79
- name: Test1
80
- title: Test1
81
- icon: 🧪
82
- persona:
83
- role: Test
84
- identity: Test
85
- communication_style: Test
86
- principles: [Test]
87
- menu:
88
- - trigger: help
89
- description: Help
90
- action: help
91
- EOF
92
- cat > "$TEMP_DIR/valid/src/core/agents/test2.agent.yaml" << 'EOF'
93
- agent:
94
- metadata:
95
- id: test2
96
- name: Test2
97
- title: Test2
98
- icon: 🧪
99
- persona:
100
- role: Test
101
- identity: Test
102
- communication_style: Test
103
- principles: [Test]
104
- menu:
105
- - trigger: help
106
- description: Help
107
- action: help
108
- EOF
109
- OUTPUT=$(node "$REPO_ROOT/tools/validate-agent-schema.js" "$TEMP_DIR/valid" 2>&1)
110
- EXIT_CODE=$?
111
- if [ $EXIT_CODE -eq 0 ] && echo "$OUTPUT" | grep -q "Found 2 agent file"; then
112
- echo -e "${GREEN}✓${NC} CLI discovers and counts files correctly"
113
- PASSED=$((PASSED + 1))
114
- else
115
- echo -e "${RED}✗${NC} CLI file discovery failed"
116
- echo "Output: $OUTPUT"
117
- FAILED=$((FAILED + 1))
118
- fi
119
- echo ""
120
-
121
- # Test 4: CLI provides detailed error messages
122
- echo "Test 4: CLI provides detailed error messages"
123
- OUTPUT=$(node "$REPO_ROOT/tools/validate-agent-schema.js" "$TEMP_DIR/invalid" 2>&1)
124
- if echo "$OUTPUT" | grep -q "Path:" && echo "$OUTPUT" | grep -q "Error:"; then
125
- echo -e "${GREEN}✓${NC} CLI provides error details (Path and Error)"
126
- PASSED=$((PASSED + 1))
127
- else
128
- echo -e "${RED}✗${NC} CLI error details missing"
129
- FAILED=$((FAILED + 1))
130
- fi
131
- echo ""
132
-
133
- # Test 5: CLI validates real BMAD agents (smoke test)
134
- echo "Test 5: CLI validates actual BMAD agents (smoke test)"
135
- OUTPUT=$(node "$REPO_ROOT/tools/validate-agent-schema.js" 2>&1)
136
- EXIT_CODE=$?
137
- if [ $EXIT_CODE -eq 0 ] && echo "$OUTPUT" | grep -qE "Found [0-9]+ agent file"; then
138
- echo -e "${GREEN}✓${NC} CLI validates real BMAD agents successfully"
139
- PASSED=$((PASSED + 1))
140
- else
141
- echo -e "${RED}✗${NC} CLI failed on real BMAD agents (exit code: $EXIT_CODE)"
142
- FAILED=$((FAILED + 1))
143
- fi
144
- echo ""
145
-
146
- # Summary
147
- echo "========================================"
148
- echo "Test Results:"
149
- echo " Passed: ${GREEN}$PASSED${NC}"
150
- echo " Failed: ${RED}$FAILED${NC}"
151
- echo "========================================"
152
-
153
- if [ $FAILED -eq 0 ]; then
154
- echo -e "\n${GREEN}✨ All CLI integration tests passed!${NC}\n"
155
- exit 0
156
- else
157
- echo -e "\n${RED}❌ Some CLI integration tests failed${NC}\n"
158
- exit 1
159
- fi
@@ -1,133 +0,0 @@
1
- /**
2
- * CSV File Reference Extraction Test Runner
3
- *
4
- * Tests extractCsvRefs() from validate-file-refs.js against fixtures.
5
- * Verifies correct extraction of workflow-file references from CSV files.
6
- *
7
- * Usage: node test/test-file-refs-csv.js
8
- * Exit codes: 0 = all tests pass, 1 = test failures
9
- */
10
-
11
- const fs = require('node:fs');
12
- const path = require('node:path');
13
- const { extractCsvRefs } = require('../tools/validate-file-refs.js');
14
-
15
- // ANSI color codes
16
- const colors = {
17
- reset: '\u001B[0m',
18
- green: '\u001B[32m',
19
- red: '\u001B[31m',
20
- cyan: '\u001B[36m',
21
- dim: '\u001B[2m',
22
- };
23
-
24
- const FIXTURES = path.join(__dirname, 'fixtures/file-refs-csv');
25
-
26
- let totalTests = 0;
27
- let passedTests = 0;
28
- const failures = [];
29
-
30
- function test(name, fn) {
31
- totalTests++;
32
- try {
33
- fn();
34
- passedTests++;
35
- console.log(` ${colors.green}\u2713${colors.reset} ${name}`);
36
- } catch (error) {
37
- console.log(` ${colors.red}\u2717${colors.reset} ${name} ${colors.red}${error.message}${colors.reset}`);
38
- failures.push({ name, message: error.message });
39
- }
40
- }
41
-
42
- function assert(condition, message) {
43
- if (!condition) throw new Error(message);
44
- }
45
-
46
- function loadFixture(relativePath) {
47
- const fullPath = path.join(FIXTURES, relativePath);
48
- const content = fs.readFileSync(fullPath, 'utf-8');
49
- return { fullPath, content };
50
- }
51
-
52
- // --- Valid fixtures ---
53
-
54
- console.log(`\n${colors.cyan}CSV File Reference Extraction Tests${colors.reset}\n`);
55
- console.log(`${colors.cyan}Valid fixtures${colors.reset}`);
56
-
57
- test('bmm-style.csv: extracts workflow-file refs with trailing commas', () => {
58
- const { fullPath, content } = loadFixture('valid/bmm-style.csv');
59
- const refs = extractCsvRefs(fullPath, content);
60
- assert(refs.length === 2, `Expected 2 refs, got ${refs.length}`);
61
- assert(refs[0].raw === '_bmad/bmm/workflows/document-project/workflow.md', `Wrong raw[0]: ${refs[0].raw}`);
62
- assert(refs[1].raw === '_bmad/core/workflows/brainstorming/workflow.md', `Wrong raw[1]: ${refs[1].raw}`);
63
- assert(refs[0].type === 'project-root', `Wrong type: ${refs[0].type}`);
64
- assert(refs[0].line === 2, `Wrong line for row 0: ${refs[0].line}`);
65
- assert(refs[1].line === 3, `Wrong line for row 1: ${refs[1].line}`);
66
- assert(refs[0].file === fullPath, 'Wrong file path');
67
- });
68
-
69
- test('core-style.csv: extracts refs from core module-help format', () => {
70
- const { fullPath, content } = loadFixture('valid/core-style.csv');
71
- const refs = extractCsvRefs(fullPath, content);
72
- assert(refs.length === 2, `Expected 2 refs, got ${refs.length}`);
73
- assert(refs[0].raw === '_bmad/core/workflows/brainstorming/workflow.md', `Wrong raw[0]: ${refs[0].raw}`);
74
- assert(refs[1].raw === '_bmad/core/workflows/party-mode/workflow.md', `Wrong raw[1]: ${refs[1].raw}`);
75
- });
76
-
77
- test('minimal.csv: extracts refs from minimal 3-column CSV', () => {
78
- const { fullPath, content } = loadFixture('valid/minimal.csv');
79
- const refs = extractCsvRefs(fullPath, content);
80
- assert(refs.length === 1, `Expected 1 ref, got ${refs.length}`);
81
- assert(refs[0].raw === '_bmad/core/tasks/help.md', `Wrong raw: ${refs[0].raw}`);
82
- assert(refs[0].line === 2, `Wrong line: ${refs[0].line}`);
83
- });
84
-
85
- // --- Invalid fixtures ---
86
-
87
- console.log(`\n${colors.cyan}Invalid fixtures (expect 0 refs)${colors.reset}`);
88
-
89
- test('no-workflow-column.csv: returns 0 refs when workflow-file column missing', () => {
90
- const { fullPath, content } = loadFixture('invalid/no-workflow-column.csv');
91
- const refs = extractCsvRefs(fullPath, content);
92
- assert(refs.length === 0, `Expected 0 refs, got ${refs.length}`);
93
- });
94
-
95
- test('empty-data.csv: returns 0 refs when CSV has header only', () => {
96
- const { fullPath, content } = loadFixture('invalid/empty-data.csv');
97
- const refs = extractCsvRefs(fullPath, content);
98
- assert(refs.length === 0, `Expected 0 refs, got ${refs.length}`);
99
- });
100
-
101
- test('all-empty-workflow.csv: returns 0 refs when all workflow-file cells empty', () => {
102
- const { fullPath, content } = loadFixture('invalid/all-empty-workflow.csv');
103
- const refs = extractCsvRefs(fullPath, content);
104
- assert(refs.length === 0, `Expected 0 refs, got ${refs.length}`);
105
- });
106
-
107
- test('unresolvable-vars.csv: filters out template variables, keeps normal refs', () => {
108
- const { fullPath, content } = loadFixture('invalid/unresolvable-vars.csv');
109
- const refs = extractCsvRefs(fullPath, content);
110
- assert(refs.length === 1, `Expected 1 ref, got ${refs.length}`);
111
- assert(refs[0].raw === '_bmad/core/tasks/help.md', `Wrong raw: ${refs[0].raw}`);
112
- });
113
-
114
- // --- Summary ---
115
-
116
- console.log(`\n${colors.cyan}${'═'.repeat(55)}${colors.reset}`);
117
- console.log(`${colors.cyan}Test Results:${colors.reset}`);
118
- console.log(` Total: ${totalTests}`);
119
- console.log(` Passed: ${colors.green}${passedTests}${colors.reset}`);
120
- console.log(` Failed: ${passedTests === totalTests ? colors.green : colors.red}${totalTests - passedTests}${colors.reset}`);
121
- console.log(`${colors.cyan}${'═'.repeat(55)}${colors.reset}\n`);
122
-
123
- if (failures.length > 0) {
124
- console.log(`${colors.red}FAILED TESTS:${colors.reset}\n`);
125
- for (const failure of failures) {
126
- console.log(`${colors.red}\u2717${colors.reset} ${failure.name}`);
127
- console.log(` ${failure.message}\n`);
128
- }
129
- process.exit(1);
130
- }
131
-
132
- console.log(`${colors.green}All tests passed!${colors.reset}\n`);
133
- process.exit(0);