mdan-method 2.6.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 (612) hide show
  1. package/.mdan/config/config.yaml +36 -0
  2. package/.mdan/state/MDAN-STATE.template.json +39 -0
  3. package/AGENTS.md +308 -0
  4. package/AGENTS_LIST.md +946 -0
  5. package/ARCHITECTURE.md +590 -0
  6. package/CHANGELOG.md +1770 -0
  7. package/CONTRIBUTING.md +512 -0
  8. package/INSTALL.md +246 -0
  9. package/LICENSE +30 -0
  10. package/MDAN.fr.md +259 -0
  11. package/README.md +233 -0
  12. package/SECURITY.md +85 -0
  13. package/USAGE.md +368 -0
  14. package/app/__init__.py +5 -0
  15. package/app/cis/agents/__init__.py +31 -0
  16. package/app/cis/agents/brainstorming-coach/__init__.py +3 -0
  17. package/app/cis/agents/brainstorming-coach/agent.py +162 -0
  18. package/app/cis/agents/brainstorming-coach/prompt.yaml +53 -0
  19. package/app/cis/agents/creative-problem-solver/__init__.py +3 -0
  20. package/app/cis/agents/creative-problem-solver/agent.py +233 -0
  21. package/app/cis/agents/creative-problem-solver/prompt.yaml +74 -0
  22. package/app/cis/agents/design-thinking-coach/__init__.py +3 -0
  23. package/app/cis/agents/design-thinking-coach/agent.py +241 -0
  24. package/app/cis/agents/design-thinking-coach/prompt.yaml +77 -0
  25. package/app/cis/agents/innovation-strategist/__init__.py +3 -0
  26. package/app/cis/agents/innovation-strategist/agent.py +271 -0
  27. package/app/cis/agents/innovation-strategist/prompt.yaml +70 -0
  28. package/app/cis/agents/presentation-master/__init__.py +3 -0
  29. package/app/cis/agents/presentation-master/agent.py +420 -0
  30. package/app/cis/agents/presentation-master/prompt.yaml +62 -0
  31. package/app/cis/agents/storyteller/__init__.py +3 -0
  32. package/app/cis/agents/storyteller/agent.py +303 -0
  33. package/app/cis/agents/storyteller/prompt.yaml +99 -0
  34. package/app/core/__init__.py +5 -0
  35. package/app/core/agents/__init__.py +5 -0
  36. package/app/core/agents/mdan-master/__init__.py +7 -0
  37. package/app/core/agents/mdan-master/agent.py +302 -0
  38. package/app/core/agents/mdan-master/prompt.yaml +105 -0
  39. package/app/mmb/agents/__init__.py +24 -0
  40. package/app/mmb/agents/agent-builder/__init__.py +5 -0
  41. package/app/mmb/agents/agent-builder/agent.py +261 -0
  42. package/app/mmb/agents/agent-builder/prompt.yaml +48 -0
  43. package/app/mmb/agents/module-builder/__init__.py +5 -0
  44. package/app/mmb/agents/module-builder/agent.py +299 -0
  45. package/app/mmb/agents/module-builder/prompt.yaml +50 -0
  46. package/app/mmb/agents/workflow-builder/__init__.py +5 -0
  47. package/app/mmb/agents/workflow-builder/agent.py +318 -0
  48. package/app/mmb/agents/workflow-builder/prompt.yaml +52 -0
  49. package/app/mmm/agents/__init__.py +48 -0
  50. package/app/mmm/agents/analyst/__init__.py +7 -0
  51. package/app/mmm/agents/analyst/agent.py +384 -0
  52. package/app/mmm/agents/analyst/prompt.yaml +62 -0
  53. package/app/mmm/agents/architect/__init__.py +7 -0
  54. package/app/mmm/agents/architect/agent.py +300 -0
  55. package/app/mmm/agents/architect/prompt.yaml +66 -0
  56. package/app/mmm/agents/dev/__init__.py +7 -0
  57. package/app/mmm/agents/dev/agent.py +285 -0
  58. package/app/mmm/agents/dev/prompt.yaml +62 -0
  59. package/app/mmm/agents/pm/__init__.py +7 -0
  60. package/app/mmm/agents/pm/agent.py +417 -0
  61. package/app/mmm/agents/pm/prompt.yaml +64 -0
  62. package/app/mmm/agents/qa/__init__.py +7 -0
  63. package/app/mmm/agents/qa/agent.py +267 -0
  64. package/app/mmm/agents/qa/prompt.yaml +67 -0
  65. package/app/mmm/agents/quick-flow-solo-dev/__init__.py +7 -0
  66. package/app/mmm/agents/quick-flow-solo-dev/agent.py +319 -0
  67. package/app/mmm/agents/quick-flow-solo-dev/prompt.yaml +60 -0
  68. package/app/mmm/agents/sm/__init__.py +7 -0
  69. package/app/mmm/agents/sm/agent.py +357 -0
  70. package/app/mmm/agents/sm/prompt.yaml +61 -0
  71. package/app/mmm/agents/tech-writer/__init__.py +7 -0
  72. package/app/mmm/agents/tech-writer/agent.py +420 -0
  73. package/app/mmm/agents/tech-writer/prompt.yaml +70 -0
  74. package/app/mmm/agents/ux-designer/__init__.py +14 -0
  75. package/app/mmm/agents/ux-designer/agent.py +412 -0
  76. package/app/mmm/agents/ux-designer/prompt.yaml +37 -0
  77. package/app/packs/__init__.py +32 -0
  78. package/app/packs/db-optimization/__init__.py +13 -0
  79. package/app/packs/db-optimization/agents/__init__.py +11 -0
  80. package/app/packs/db-optimization/agents/db-performance-analyst/__init__.py +5 -0
  81. package/app/packs/db-optimization/agents/db-performance-analyst/agent.py +559 -0
  82. package/app/packs/db-optimization/agents/db-performance-analyst/prompt.yaml +63 -0
  83. package/app/packs/db-optimization/agents/indexing-specialist/__init__.py +5 -0
  84. package/app/packs/db-optimization/agents/indexing-specialist/agent.py +713 -0
  85. package/app/packs/db-optimization/agents/indexing-specialist/prompt.yaml +92 -0
  86. package/app/packs/db-optimization/agents/query-optimizer/__init__.py +5 -0
  87. package/app/packs/db-optimization/agents/query-optimizer/agent.py +566 -0
  88. package/app/packs/db-optimization/agents/query-optimizer/prompt.yaml +74 -0
  89. package/app/packs/devops-azure/__init__.py +13 -0
  90. package/app/packs/devops-azure/agents/__init__.py +11 -0
  91. package/app/packs/devops-azure/agents/azure-specialist/__init__.py +5 -0
  92. package/app/packs/devops-azure/agents/azure-specialist/agent.py +584 -0
  93. package/app/packs/devops-azure/agents/azure-specialist/prompt.yaml +301 -0
  94. package/app/packs/devops-azure/agents/cicd-architect/__init__.py +5 -0
  95. package/app/packs/devops-azure/agents/cicd-architect/agent.py +665 -0
  96. package/app/packs/devops-azure/agents/cicd-architect/prompt.yaml +409 -0
  97. package/app/packs/devops-azure/agents/devops-engineer/__init__.py +5 -0
  98. package/app/packs/devops-azure/agents/devops-engineer/agent.py +545 -0
  99. package/app/packs/devops-azure/agents/devops-engineer/prompt.yaml +263 -0
  100. package/app/packs/fintech/__init__.py +13 -0
  101. package/app/packs/fintech/agents/__init__.py +11 -0
  102. package/app/packs/fintech/agents/compliance-officer/__init__.py +5 -0
  103. package/app/packs/fintech/agents/compliance-officer/agent.py +449 -0
  104. package/app/packs/fintech/agents/compliance-officer/prompt.yaml +135 -0
  105. package/app/packs/fintech/agents/financial-analyst/__init__.py +5 -0
  106. package/app/packs/fintech/agents/financial-analyst/agent.py +392 -0
  107. package/app/packs/fintech/agents/financial-analyst/prompt.yaml +143 -0
  108. package/app/packs/fintech/agents/risk-manager/__init__.py +5 -0
  109. package/app/packs/fintech/agents/risk-manager/agent.py +664 -0
  110. package/app/packs/fintech/agents/risk-manager/prompt.yaml +240 -0
  111. package/app/tea/agents/tea/__init__.py +9 -0
  112. package/app/tea/agents/tea/agent.py +689 -0
  113. package/app/tea/agents/tea/prompt.yaml +100 -0
  114. package/cli/v1/mdan.py +421 -0
  115. package/cli/v1/mdan.sh +724 -0
  116. package/cli/v1/mdan_crewai.py +539 -0
  117. package/docs/404.md +9 -0
  118. package/docs/_STYLE_GUIDE.md +370 -0
  119. package/docs/explanation/advanced-elicitation.md +49 -0
  120. package/docs/explanation/adversarial-review.md +59 -0
  121. package/docs/explanation/brainstorming.md +33 -0
  122. package/docs/explanation/established-projects-faq.md +50 -0
  123. package/docs/explanation/party-mode.md +59 -0
  124. package/docs/explanation/preventing-agent-conflicts.md +112 -0
  125. package/docs/explanation/project-context.md +157 -0
  126. package/docs/explanation/quick-flow.md +73 -0
  127. package/docs/explanation/why-solutioning-matters.md +77 -0
  128. package/docs/how-to/customize-mdan.md +172 -0
  129. package/docs/how-to/established-projects.md +117 -0
  130. package/docs/how-to/get-answers-about-mdan.md +134 -0
  131. package/docs/how-to/install-mdan.md +97 -0
  132. package/docs/how-to/non-interactive-installation.md +171 -0
  133. package/docs/how-to/project-context.md +136 -0
  134. package/docs/how-to/quick-fixes.md +123 -0
  135. package/docs/how-to/shard-large-documents.md +78 -0
  136. package/docs/how-to/upgrade-to-v6.md +97 -0
  137. package/docs/index.md +59 -0
  138. package/docs/reference/agents.md +28 -0
  139. package/docs/reference/commands.md +151 -0
  140. package/docs/reference/modules.md +76 -0
  141. package/docs/reference/testing.md +106 -0
  142. package/docs/reference/workflow-map.md +89 -0
  143. package/docs/roadmap.mdx +136 -0
  144. package/docs/tutorials/getting-started.md +286 -0
  145. package/examples/crewai/crewai_auto_mode.py +62 -0
  146. package/examples/crewai/crewai_custom_crew.py +85 -0
  147. package/examples/crewai/crewai_debate.py +57 -0
  148. package/examples/crewai/crewai_with_serper.py +82 -0
  149. package/examples/crewai/crewai_with_sql.py +117 -0
  150. package/integrations/__init__.py +33 -0
  151. package/integrations/crewai/__init__.py +27 -0
  152. package/integrations/crewai/agents/__init__.py +21 -0
  153. package/integrations/crewai/agents/architect_agent.py +264 -0
  154. package/integrations/crewai/agents/dev_agent.py +271 -0
  155. package/integrations/crewai/agents/devops_agent.py +421 -0
  156. package/integrations/crewai/agents/doc_agent.py +388 -0
  157. package/integrations/crewai/agents/product_agent.py +203 -0
  158. package/integrations/crewai/agents/security_agent.py +386 -0
  159. package/integrations/crewai/agents/test_agent.py +358 -0
  160. package/integrations/crewai/agents/ux_agent.py +257 -0
  161. package/integrations/crewai/flows/__init__.py +13 -0
  162. package/integrations/crewai/flows/auto_flow.py +451 -0
  163. package/integrations/crewai/flows/build_flow.py +297 -0
  164. package/integrations/crewai/flows/debate_flow.py +422 -0
  165. package/integrations/crewai/flows/discovery_flow.py +267 -0
  166. package/integrations/crewai/orchestrator.py +558 -0
  167. package/integrations/crewai/skills/__init__.py +8 -0
  168. package/integrations/crewai/skills/skill_router.py +534 -0
  169. package/integrations/crewai/tools/__init__.py +11 -0
  170. package/integrations/crewai/tools/file_tool.py +355 -0
  171. package/integrations/crewai/tools/serper_tool.py +169 -0
  172. package/integrations/crewai/tools/sql_tool.py +435 -0
  173. package/integrations/docs/all-integrations.md +300 -0
  174. package/integrations/docs/cursor.md +74 -0
  175. package/integrations/docs/mcp.md +153 -0
  176. package/integrations/docs/windsurf.md +48 -0
  177. package/package.json +119 -0
  178. package/prompts/cis/brainstorming-coach.yaml +53 -0
  179. package/prompts/cis/creative-problem-solver.yaml +74 -0
  180. package/prompts/cis/design-thinking-coach.yaml +77 -0
  181. package/prompts/cis/innovation-strategist.yaml +70 -0
  182. package/prompts/cis/presentation-master.yaml +62 -0
  183. package/prompts/cis/storyteller.yaml +99 -0
  184. package/prompts/core/mdan-master.yaml +105 -0
  185. package/prompts/mmb/agent-builder.yaml +48 -0
  186. package/prompts/mmb/module-builder.yaml +50 -0
  187. package/prompts/mmb/workflow-builder.yaml +52 -0
  188. package/prompts/mmm/analyst.yaml +62 -0
  189. package/prompts/mmm/architect.yaml +66 -0
  190. package/prompts/mmm/dev.yaml +62 -0
  191. package/prompts/mmm/pm.yaml +64 -0
  192. package/prompts/mmm/qa.yaml +67 -0
  193. package/prompts/mmm/quick-flow-solo-dev.yaml +60 -0
  194. package/prompts/mmm/sm.yaml +61 -0
  195. package/prompts/mmm/tech-writer.yaml +70 -0
  196. package/prompts/mmm/ux-designer.yaml +33 -0
  197. package/prompts/packs/db-optimization/db-performance-analyst.yaml +63 -0
  198. package/prompts/packs/db-optimization/indexing-specialist.yaml +92 -0
  199. package/prompts/packs/db-optimization/query-optimizer.yaml +74 -0
  200. package/prompts/packs/devops-azure/azure-specialist.yaml +301 -0
  201. package/prompts/packs/devops-azure/cicd-architect.yaml +409 -0
  202. package/prompts/packs/devops-azure/devops-engineer.yaml +263 -0
  203. package/prompts/packs/fintech/compliance-officer.yaml +135 -0
  204. package/prompts/packs/fintech/financial-analyst.yaml +143 -0
  205. package/prompts/packs/fintech/risk-manager.yaml +240 -0
  206. package/prompts/tea/tea.yaml +100 -0
  207. package/requirements.txt +5 -0
  208. package/requirements_crewai.txt +37 -0
  209. package/src/agents/module-help.csv +31 -0
  210. package/src/agents/module.yaml +50 -0
  211. package/src/agents/team/analyst.agent.yaml +43 -0
  212. package/src/agents/team/architect.agent.yaml +29 -0
  213. package/src/agents/team/dev.agent.yaml +38 -0
  214. package/src/agents/team/pm.agent.yaml +44 -0
  215. package/src/agents/team/qa.agent.yaml +58 -0
  216. package/src/agents/team/quick-flow-solo-dev.agent.yaml +32 -0
  217. package/src/agents/team/sm.agent.yaml +37 -0
  218. package/src/agents/team/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
  219. package/src/agents/team/tech-writer/tech-writer.agent.yaml +46 -0
  220. package/src/agents/team/ux-designer.agent.yaml +27 -0
  221. package/src/agents/teams/default-party.csv +20 -0
  222. package/src/agents/teams/team-fullstack.yaml +12 -0
  223. package/src/core/WIZARD-ENGINE.md +94 -0
  224. package/src/core/agents/mdan-master.agent.yaml +133 -0
  225. package/src/core/tasks/editorial-review-prose.xml +102 -0
  226. package/src/core/tasks/editorial-review-structure.xml +208 -0
  227. package/src/core/tasks/help.md +86 -0
  228. package/src/core/tasks/index-docs.xml +65 -0
  229. package/src/core/tasks/review-adversarial-general.xml +49 -0
  230. package/src/core/tasks/shard-doc.xml +108 -0
  231. package/src/core/tasks/workflow.xml +235 -0
  232. package/src/memory/MEMORY-AUTO.json +66 -0
  233. package/src/memory/MEMORY-SYSTEM.md +61 -0
  234. package/src/memory/v1-memory-system.md +197 -0
  235. package/src/memory/v1-resume-protocol.md +379 -0
  236. package/src/packs/db-optimization/agents/prompt.yaml +63 -0
  237. package/src/packs/devops-azure/agents/prompt.yaml +301 -0
  238. package/src/packs/fintech/agents/prompt.yaml +135 -0
  239. package/src/phases/auto/auto-01-load.md +165 -0
  240. package/src/phases/auto/auto-02-discover.md +207 -0
  241. package/src/phases/auto/auto-03-plan.md +509 -0
  242. package/src/phases/auto/auto-04-architect.md +567 -0
  243. package/src/phases/auto/auto-05-implement.md +713 -0
  244. package/src/phases/auto/auto-06-test.md +559 -0
  245. package/src/phases/auto/auto-07-deploy.md +510 -0
  246. package/src/phases/auto/auto-08-doc.md +970 -0
  247. package/src/phases/manual/01-discover.md +136 -0
  248. package/src/phases/manual/02-design.md +147 -0
  249. package/src/phases/manual/03-build.md +113 -0
  250. package/src/phases/manual/04-verify.md +107 -0
  251. package/src/phases/manual/05-ship.md +156 -0
  252. package/src/protocols/debate-protocol.md +58 -0
  253. package/src/protocols/universal-envelope.md +42 -0
  254. package/src/protocols/v1-debate-protocol.md +454 -0
  255. package/src/protocols/v1-universal-envelope.md +273 -0
  256. package/src/utility/agent-components/activation-rules.txt +6 -0
  257. package/src/utility/agent-components/activation-steps.txt +14 -0
  258. package/src/utility/agent-components/agent-command-header.md +1 -0
  259. package/src/utility/agent-components/agent.customize.template.yaml +41 -0
  260. package/src/utility/agent-components/handler-action.txt +4 -0
  261. package/src/utility/agent-components/handler-data.txt +5 -0
  262. package/src/utility/agent-components/handler-exec.txt +6 -0
  263. package/src/utility/agent-components/handler-multi.txt +14 -0
  264. package/src/utility/agent-components/handler-tmpl.txt +5 -0
  265. package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
  266. package/src/utility/agent-components/handler-workflow.txt +10 -0
  267. package/src/utility/agent-components/menu-handlers.txt +6 -0
  268. package/src/wizards/01-discover/create-product-brief/steps/step-01-init.md +7 -0
  269. package/src/wizards/01-discover/create-product-brief/steps/step-02-vision.md +7 -0
  270. package/src/wizards/01-discover/create-product-brief/steps/step-03-users.md +7 -0
  271. package/src/wizards/01-discover/create-product-brief/steps/step-04-scope.md +7 -0
  272. package/src/wizards/01-discover/create-product-brief/steps/step-05-metrics.md +7 -0
  273. package/src/wizards/01-discover/create-product-brief/steps/step-06-complete.md +7 -0
  274. package/src/wizards/01-discover/create-product-brief/templates/product-brief.template.md +14 -0
  275. package/src/wizards/01-discover/create-product-brief/wizard.md +105 -0
  276. package/src/wizards/01-discover/research/domain-steps/step-01-init.md +137 -0
  277. package/src/wizards/01-discover/research/domain-steps/step-02-domain-analysis.md +229 -0
  278. package/src/wizards/01-discover/research/domain-steps/step-03-competitive-landscape.md +238 -0
  279. package/src/wizards/01-discover/research/domain-steps/step-04-regulatory-focus.md +206 -0
  280. package/src/wizards/01-discover/research/domain-steps/step-05-technical-trends.md +234 -0
  281. package/src/wizards/01-discover/research/domain-steps/step-06-research-synthesis.md +444 -0
  282. package/src/wizards/01-discover/research/market-steps/step-01-init.md +182 -0
  283. package/src/wizards/01-discover/research/market-steps/step-02-customer-behavior.md +237 -0
  284. package/src/wizards/01-discover/research/market-steps/step-03-customer-pain-points.md +249 -0
  285. package/src/wizards/01-discover/research/market-steps/step-04-customer-decisions.md +259 -0
  286. package/src/wizards/01-discover/research/market-steps/step-05-competitive-analysis.md +177 -0
  287. package/src/wizards/01-discover/research/market-steps/step-06-research-completion.md +476 -0
  288. package/src/wizards/01-discover/research/technical-steps/step-01-init.md +137 -0
  289. package/src/wizards/01-discover/research/technical-steps/step-02-technical-overview.md +239 -0
  290. package/src/wizards/01-discover/research/technical-steps/step-03-integration-patterns.md +248 -0
  291. package/src/wizards/01-discover/research/technical-steps/step-04-architectural-patterns.md +202 -0
  292. package/src/wizards/01-discover/research/technical-steps/step-05-implementation-research.md +233 -0
  293. package/src/wizards/01-discover/research/technical-steps/step-06-research-synthesis.md +487 -0
  294. package/src/wizards/01-discover/research/templates/research.template.md +29 -0
  295. package/src/wizards/01-discover/research/workflow-domain-research.md +54 -0
  296. package/src/wizards/01-discover/research/workflow-market-research.md +54 -0
  297. package/src/wizards/01-discover/research/workflow-technical-research.md +54 -0
  298. package/src/wizards/02-plan/create-prd/data/domain-complexity.csv +15 -0
  299. package/src/wizards/02-plan/create-prd/data/prd-purpose.md +197 -0
  300. package/src/wizards/02-plan/create-prd/data/project-types.csv +11 -0
  301. package/src/wizards/02-plan/create-prd/steps/step-01-init.md +191 -0
  302. package/src/wizards/02-plan/create-prd/steps/step-01b-continue.md +152 -0
  303. package/src/wizards/02-plan/create-prd/steps/step-02-discovery.md +224 -0
  304. package/src/wizards/02-plan/create-prd/steps/step-02b-vision.md +154 -0
  305. package/src/wizards/02-plan/create-prd/steps/step-02c-executive-summary.md +170 -0
  306. package/src/wizards/02-plan/create-prd/steps/step-03-success.md +226 -0
  307. package/src/wizards/02-plan/create-prd/steps/step-04-journeys.md +213 -0
  308. package/src/wizards/02-plan/create-prd/steps/step-05-domain.md +207 -0
  309. package/src/wizards/02-plan/create-prd/steps/step-06-innovation.md +226 -0
  310. package/src/wizards/02-plan/create-prd/steps/step-07-project-type.md +237 -0
  311. package/src/wizards/02-plan/create-prd/steps/step-08-scoping.md +228 -0
  312. package/src/wizards/02-plan/create-prd/steps/step-09-functional.md +231 -0
  313. package/src/wizards/02-plan/create-prd/steps/step-10-nonfunctional.md +242 -0
  314. package/src/wizards/02-plan/create-prd/steps/step-11-polish.md +217 -0
  315. package/src/wizards/02-plan/create-prd/steps/step-12-complete.md +124 -0
  316. package/src/wizards/02-plan/create-prd/templates/prd-template.md +10 -0
  317. package/src/wizards/02-plan/create-prd/wizard.md +63 -0
  318. package/src/wizards/02-plan/create-ux-design/steps/step-01-init.md +135 -0
  319. package/src/wizards/02-plan/create-ux-design/steps/step-01b-continue.md +127 -0
  320. package/src/wizards/02-plan/create-ux-design/steps/step-02-discovery.md +190 -0
  321. package/src/wizards/02-plan/create-ux-design/steps/step-03-core-experience.md +216 -0
  322. package/src/wizards/02-plan/create-ux-design/steps/step-04-emotional-response.md +219 -0
  323. package/src/wizards/02-plan/create-ux-design/steps/step-05-inspiration.md +234 -0
  324. package/src/wizards/02-plan/create-ux-design/steps/step-06-design-system.md +252 -0
  325. package/src/wizards/02-plan/create-ux-design/steps/step-07-defining-experience.md +254 -0
  326. package/src/wizards/02-plan/create-ux-design/steps/step-08-visual-foundation.md +224 -0
  327. package/src/wizards/02-plan/create-ux-design/steps/step-09-design-directions.md +224 -0
  328. package/src/wizards/02-plan/create-ux-design/steps/step-10-user-journeys.md +241 -0
  329. package/src/wizards/02-plan/create-ux-design/steps/step-11-component-strategy.md +248 -0
  330. package/src/wizards/02-plan/create-ux-design/steps/step-12-ux-patterns.md +237 -0
  331. package/src/wizards/02-plan/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
  332. package/src/wizards/02-plan/create-ux-design/steps/step-14-complete.md +171 -0
  333. package/src/wizards/02-plan/create-ux-design/templates/ux-design-template.md +13 -0
  334. package/src/wizards/02-plan/create-ux-design/wizard.md +42 -0
  335. package/src/wizards/03-architect/create-architecture/data/domain-complexity.csv +13 -0
  336. package/src/wizards/03-architect/create-architecture/data/project-types.csv +7 -0
  337. package/src/wizards/03-architect/create-architecture/steps/step-01-init.md +153 -0
  338. package/src/wizards/03-architect/create-architecture/steps/step-01b-continue.md +173 -0
  339. package/src/wizards/03-architect/create-architecture/steps/step-02-context.md +224 -0
  340. package/src/wizards/03-architect/create-architecture/steps/step-03-starter.md +329 -0
  341. package/src/wizards/03-architect/create-architecture/steps/step-04-decisions.md +318 -0
  342. package/src/wizards/03-architect/create-architecture/steps/step-05-patterns.md +359 -0
  343. package/src/wizards/03-architect/create-architecture/steps/step-06-structure.md +379 -0
  344. package/src/wizards/03-architect/create-architecture/steps/step-07-validation.md +359 -0
  345. package/src/wizards/03-architect/create-architecture/steps/step-08-complete.md +76 -0
  346. package/src/wizards/03-architect/create-architecture/templates/architecture-decision-template.md +12 -0
  347. package/src/wizards/03-architect/create-architecture/wizard.md +49 -0
  348. package/src/wizards/03-architect/create-epics/steps/step-01-validate-prerequisites.md +259 -0
  349. package/src/wizards/03-architect/create-epics/steps/step-02-design-epics.md +233 -0
  350. package/src/wizards/03-architect/create-epics/steps/step-03-create-stories.md +272 -0
  351. package/src/wizards/03-architect/create-epics/steps/step-04-final-validation.md +149 -0
  352. package/src/wizards/03-architect/create-epics/templates/epics-template.md +57 -0
  353. package/src/wizards/03-architect/create-epics/wizard.md +58 -0
  354. package/src/wizards/04-build/code-review/checklist.md +23 -0
  355. package/src/wizards/04-build/code-review/instructions.xml +227 -0
  356. package/src/wizards/04-build/code-review/workflow.yaml +43 -0
  357. package/src/wizards/04-build/dev-story/checklist.md +80 -0
  358. package/src/wizards/04-build/dev-story/instructions.xml +410 -0
  359. package/src/wizards/04-build/dev-story/workflow.yaml +20 -0
  360. package/src/wizards/04-build/sprint-planning/checklist.md +33 -0
  361. package/src/wizards/04-build/sprint-planning/instructions.md +226 -0
  362. package/src/wizards/04-build/sprint-planning/sprint-status-template.yaml +55 -0
  363. package/src/wizards/04-build/sprint-planning/workflow.yaml +47 -0
  364. package/src/wizards/05-ship/document-project/templates/deep-dive-template.md +345 -0
  365. package/src/wizards/05-ship/document-project/templates/index-template.md +169 -0
  366. package/src/wizards/05-ship/document-project/templates/project-overview-template.md +103 -0
  367. package/src/wizards/05-ship/document-project/templates/project-scan-report-schema.json +160 -0
  368. package/src/wizards/05-ship/document-project/templates/source-tree-template.md +135 -0
  369. package/src/wizards/05-ship/document-project/wizard.md +130 -0
  370. package/src/wizards/quick/quick-dev/steps/step-01-mode-detection.md +174 -0
  371. package/src/wizards/quick/quick-dev/steps/step-02-context-gathering.md +118 -0
  372. package/src/wizards/quick/quick-dev/steps/step-03-execute.md +111 -0
  373. package/src/wizards/quick/quick-dev/steps/step-04-self-check.md +111 -0
  374. package/src/wizards/quick/quick-dev/steps/step-05-adversarial-review.md +104 -0
  375. package/src/wizards/quick/quick-dev/steps/step-06-resolve-findings.md +146 -0
  376. package/src/wizards/quick/quick-dev/wizard.md +50 -0
  377. package/src/wizards/quick/quick-spec/steps/step-01-understand.md +189 -0
  378. package/src/wizards/quick/quick-spec/steps/step-02-investigate.md +143 -0
  379. package/src/wizards/quick/quick-spec/steps/step-03-generate.md +126 -0
  380. package/src/wizards/quick/quick-spec/steps/step-04-review.md +200 -0
  381. package/src/wizards/quick/quick-spec/templates/tech-spec-template.md +74 -0
  382. package/src/wizards/quick/quick-spec/wizard.md +79 -0
  383. package/src/wizards/special/brainstorming/methods/brain-methods.csv +62 -0
  384. package/src/wizards/special/brainstorming/steps/step-01-session-setup.md +197 -0
  385. package/src/wizards/special/brainstorming/steps/step-01b-continue.md +122 -0
  386. package/src/wizards/special/brainstorming/steps/step-02a-user-selected.md +225 -0
  387. package/src/wizards/special/brainstorming/steps/step-02b-ai-recommended.md +237 -0
  388. package/src/wizards/special/brainstorming/steps/step-02c-random-selection.md +209 -0
  389. package/src/wizards/special/brainstorming/steps/step-02d-progressive-flow.md +264 -0
  390. package/src/wizards/special/brainstorming/steps/step-03-technique-execution.md +399 -0
  391. package/src/wizards/special/brainstorming/steps/step-04-idea-organization.md +303 -0
  392. package/src/wizards/special/brainstorming/wizard.md +58 -0
  393. package/src/wizards/special/party-mode/steps/step-01-agent-loading.md +138 -0
  394. package/src/wizards/special/party-mode/steps/step-02-discussion-orchestration.md +187 -0
  395. package/src/wizards/special/party-mode/steps/step-03-graceful-exit.md +168 -0
  396. package/src/wizards/special/party-mode/wizard.md +194 -0
  397. package/test/README.md +295 -0
  398. package/test/adversarial-review-tests/README.md +56 -0
  399. package/test/adversarial-review-tests/sample-content.md +46 -0
  400. package/test/adversarial-review-tests/test-cases.yaml +103 -0
  401. package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
  402. package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
  403. package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
  404. package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
  405. package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
  406. package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
  407. package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
  408. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
  409. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
  410. package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
  411. package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
  412. package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
  413. package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
  414. package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
  415. package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
  416. package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
  417. package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
  418. package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
  419. package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
  420. package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
  421. package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
  422. package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
  423. package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
  424. package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
  425. package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
  426. package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
  427. package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
  428. package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
  429. package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
  430. package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
  431. package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
  432. package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
  433. package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
  434. package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
  435. package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
  436. package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
  437. package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
  438. package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +24 -0
  439. package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
  440. package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
  441. package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
  442. package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
  443. package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
  444. package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
  445. package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
  446. package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
  447. package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
  448. package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
  449. package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
  450. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
  451. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
  452. package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
  453. package/test/fixtures/file-refs-csv/invalid/all-empty-workflow.csv +3 -0
  454. package/test/fixtures/file-refs-csv/invalid/empty-data.csv +1 -0
  455. package/test/fixtures/file-refs-csv/invalid/no-workflow-column.csv +3 -0
  456. package/test/fixtures/file-refs-csv/invalid/unresolvable-vars.csv +3 -0
  457. package/test/fixtures/file-refs-csv/valid/bmm-style.csv +3 -0
  458. package/test/fixtures/file-refs-csv/valid/core-style.csv +3 -0
  459. package/test/fixtures/file-refs-csv/valid/minimal.csv +2 -0
  460. package/test/test-agent-schema.js +387 -0
  461. package/test/test-cli-integration.sh +159 -0
  462. package/test/test-file-refs-csv.js +133 -0
  463. package/test/test-installation-components.js +212 -0
  464. package/test/test-rehype-plugins.mjs +1050 -0
  465. package/test/unit-test-schema.js +133 -0
  466. package/tests/run_all_tests.py +80 -0
  467. package/tests/scenarios/cis/brainstorming-coach.test.py +150 -0
  468. package/tests/scenarios/cis/creative-problem-solver.test.py +167 -0
  469. package/tests/scenarios/cis/design-thinking-coach.test.py +177 -0
  470. package/tests/scenarios/cis/innovation-strategist.test.py +191 -0
  471. package/tests/scenarios/cis/presentation-master.test.py +240 -0
  472. package/tests/scenarios/cis/storyteller.test.py +324 -0
  473. package/tests/scenarios/core/mdan-master.test.py +281 -0
  474. package/tests/scenarios/mmb/agent-builder.test.py +124 -0
  475. package/tests/scenarios/mmb/module-builder.test.py +124 -0
  476. package/tests/scenarios/mmb/workflow-builder.test.py +124 -0
  477. package/tests/scenarios/mmm/analyst.test.py +138 -0
  478. package/tests/scenarios/mmm/architect.test.py +138 -0
  479. package/tests/scenarios/mmm/dev.test.py +138 -0
  480. package/tests/scenarios/mmm/pm.test.py +138 -0
  481. package/tests/scenarios/mmm/qa.test.py +138 -0
  482. package/tests/scenarios/mmm/quick-flow-solo-dev.test.py +138 -0
  483. package/tests/scenarios/mmm/sm.test.py +138 -0
  484. package/tests/scenarios/mmm/tech-writer.test.py +138 -0
  485. package/tests/scenarios/mmm/ux-designer.test.py +294 -0
  486. package/tests/scenarios/packs/db-optimization/db-performance-analyst.test.py +108 -0
  487. package/tests/scenarios/packs/db-optimization/indexing-specialist.test.py +108 -0
  488. package/tests/scenarios/packs/db-optimization/query-optimizer.test.py +106 -0
  489. package/tests/scenarios/packs/devops-azure/azure-specialist.test.py +125 -0
  490. package/tests/scenarios/packs/devops-azure/cicd-architect.test.py +122 -0
  491. package/tests/scenarios/packs/devops-azure/devops-engineer.test.py +128 -0
  492. package/tests/scenarios/packs/fintech/compliance-officer.test.py +165 -0
  493. package/tests/scenarios/packs/fintech/financial-analyst.test.py +184 -0
  494. package/tests/scenarios/packs/fintech/risk-manager.test.py +171 -0
  495. package/tests/scenarios/tea/tea.test.py +346 -0
  496. package/tests/simple_cis_test.py +285 -0
  497. package/tests/simple_db_optimization_test.py +199 -0
  498. package/tests/simple_devops_test.py +193 -0
  499. package/tests/simple_fintech_test.py +205 -0
  500. package/tests/simple_mmb_test.py +103 -0
  501. package/tests/simple_mmm_test.py +159 -0
  502. package/tests/simple_tea_test.py +80 -0
  503. package/tests/simple_test.py +111 -0
  504. package/tests/simple_ux_designer_test.py +144 -0
  505. package/tests/validate_yaml.py +86 -0
  506. package/tools/build-docs.mjs +463 -0
  507. package/tools/cli/README.md +60 -0
  508. package/tools/cli/commands/install.js +87 -0
  509. package/tools/cli/commands/status.js +65 -0
  510. package/tools/cli/commands/uninstall.js +167 -0
  511. package/tools/cli/external-official-modules.yaml +53 -0
  512. package/tools/cli/installers/install-messages.yaml +39 -0
  513. package/tools/cli/installers/lib/core/config-collector.js +1285 -0
  514. package/tools/cli/installers/lib/core/custom-module-cache.js +260 -0
  515. package/tools/cli/installers/lib/core/dependency-resolver.js +743 -0
  516. package/tools/cli/installers/lib/core/detector.js +223 -0
  517. package/tools/cli/installers/lib/core/ide-config-manager.js +157 -0
  518. package/tools/cli/installers/lib/core/installer.js +3162 -0
  519. package/tools/cli/installers/lib/core/manifest-generator.js +1081 -0
  520. package/tools/cli/installers/lib/core/manifest.js +1038 -0
  521. package/tools/cli/installers/lib/custom/handler.js +358 -0
  522. package/tools/cli/installers/lib/ide/_base-ide.js +665 -0
  523. package/tools/cli/installers/lib/ide/_config-driven.js +634 -0
  524. package/tools/cli/installers/lib/ide/codex.js +440 -0
  525. package/tools/cli/installers/lib/ide/github-copilot.js +699 -0
  526. package/tools/cli/installers/lib/ide/kilo.js +269 -0
  527. package/tools/cli/installers/lib/ide/manager.js +342 -0
  528. package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
  529. package/tools/cli/installers/lib/ide/platform-codes.yaml +243 -0
  530. package/tools/cli/installers/lib/ide/rovodev.js +257 -0
  531. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +180 -0
  532. package/tools/cli/installers/lib/ide/shared/mdan-artifacts.js +174 -0
  533. package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
  534. package/tools/cli/installers/lib/ide/shared/path-utils.js +299 -0
  535. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +366 -0
  536. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +318 -0
  537. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
  538. package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
  539. package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
  540. package/tools/cli/installers/lib/ide/templates/combined/default-task.md +10 -0
  541. package/tools/cli/installers/lib/ide/templates/combined/default-tool.md +10 -0
  542. package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
  543. package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
  544. package/tools/cli/installers/lib/ide/templates/combined/gemini-agent.toml +14 -0
  545. package/tools/cli/installers/lib/ide/templates/combined/gemini-task.toml +11 -0
  546. package/tools/cli/installers/lib/ide/templates/combined/gemini-tool.toml +11 -0
  547. package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow-yaml.toml +16 -0
  548. package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow.toml +14 -0
  549. package/tools/cli/installers/lib/ide/templates/combined/kiro-agent.md +16 -0
  550. package/tools/cli/installers/lib/ide/templates/combined/kiro-task.md +9 -0
  551. package/tools/cli/installers/lib/ide/templates/combined/kiro-tool.md +9 -0
  552. package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow-yaml.md +15 -0
  553. package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow.md +7 -0
  554. package/tools/cli/installers/lib/ide/templates/combined/opencode-agent.md +15 -0
  555. package/tools/cli/installers/lib/ide/templates/combined/opencode-task.md +13 -0
  556. package/tools/cli/installers/lib/ide/templates/combined/opencode-tool.md +13 -0
  557. package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow-yaml.md +16 -0
  558. package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow.md +16 -0
  559. package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
  560. package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
  561. package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
  562. package/tools/cli/installers/lib/ide/templates/split/.gitkeep +0 -0
  563. package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
  564. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
  565. package/tools/cli/installers/lib/message-loader.js +83 -0
  566. package/tools/cli/installers/lib/modules/external-manager.js +136 -0
  567. package/tools/cli/installers/lib/modules/manager.js +1498 -0
  568. package/tools/cli/lib/activation-builder.js +165 -0
  569. package/tools/cli/lib/agent/compiler.js +525 -0
  570. package/tools/cli/lib/agent/installer.js +680 -0
  571. package/tools/cli/lib/agent/template-engine.js +152 -0
  572. package/tools/cli/lib/agent-analyzer.js +109 -0
  573. package/tools/cli/lib/agent-party-generator.js +194 -0
  574. package/tools/cli/lib/cli-utils.js +182 -0
  575. package/tools/cli/lib/config.js +213 -0
  576. package/tools/cli/lib/file-ops.js +204 -0
  577. package/tools/cli/lib/platform-codes.js +116 -0
  578. package/tools/cli/lib/project-root.js +77 -0
  579. package/tools/cli/lib/prompts.js +809 -0
  580. package/tools/cli/lib/ui.js +1936 -0
  581. package/tools/cli/lib/xml-handler.js +177 -0
  582. package/tools/cli/lib/xml-to-markdown.js +82 -0
  583. package/tools/cli/lib/yaml-format.js +245 -0
  584. package/tools/cli/lib/yaml-xml-builder.js +587 -0
  585. package/tools/cli/mdan-cli.js +106 -0
  586. package/tools/docs/_prompt-external-modules-page.md +59 -0
  587. package/tools/docs/fix-refs.md +91 -0
  588. package/tools/fix-doc-links.js +285 -0
  589. package/tools/format-workflow-md.js +263 -0
  590. package/tools/lib/xml-utils.js +13 -0
  591. package/tools/mdan-npx-wrapper.js +38 -0
  592. package/tools/migrate-custom-module-paths.js +124 -0
  593. package/tools/platform-codes.yaml +157 -0
  594. package/tools/schema/agent.js +491 -0
  595. package/tools/validate-agent-schema.js +110 -0
  596. package/tools/validate-doc-links.js +407 -0
  597. package/tools/validate-file-refs.js +554 -0
  598. package/tools/validate-svg-changes.sh +356 -0
  599. package/website/README.md +75 -0
  600. package/website/astro.config.mjs +136 -0
  601. package/website/public/favicon.ico +0 -0
  602. package/website/public/workflow-map-diagram.html +361 -0
  603. package/website/src/components/Banner.astro +62 -0
  604. package/website/src/components/Header.astro +96 -0
  605. package/website/src/components/MobileMenuFooter.astro +33 -0
  606. package/website/src/content/config.ts +6 -0
  607. package/website/src/lib/site-url.mjs +25 -0
  608. package/website/src/pages/404.astro +11 -0
  609. package/website/src/pages/robots.txt.ts +48 -0
  610. package/website/src/rehype-base-paths.js +112 -0
  611. package/website/src/rehype-markdown-links.js +119 -0
  612. package/website/src/styles/custom.css +805 -0
@@ -0,0 +1,144 @@
1
+ """
2
+ Simple integration test for UX Designer Agent
3
+
4
+ This test verifies that the UX Designer agent can be imported and used correctly.
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import asyncio
10
+ import importlib.util
11
+
12
+ # Load the agent directly from file path (due to hyphen in directory name)
13
+ agent_path = os.path.join(
14
+ os.path.dirname(__file__), "..", "app", "mmm", "agents", "ux-designer", "agent.py"
15
+ )
16
+ spec = importlib.util.spec_from_file_location("ux_designer_agent", agent_path)
17
+ ux_designer_module = importlib.util.module_from_spec(spec)
18
+ sys.modules["ux_designer_agent"] = ux_designer_module
19
+ spec.loader.exec_module(ux_designer_module)
20
+
21
+ UXDesigner = ux_designer_module.UXDesigner
22
+ UXDesignerRequest = ux_designer_module.UXDesignerRequest
23
+ UXDesignerResponse = ux_designer_module.UXDesignerResponse
24
+ UXDesignAction = ux_designer_module.UXDesignAction
25
+
26
+
27
+ def test_agent_creation():
28
+ """Test that the agent can be created"""
29
+ agent = UXDesigner()
30
+ assert agent.name == "Sally"
31
+ assert agent.title == "UX Designer"
32
+ assert agent.icon == "🎨"
33
+ assert len(agent.capabilities) > 0
34
+ print("✓ Agent creation works")
35
+
36
+
37
+ def test_menu_retrieval():
38
+ """Test that the menu can be retrieved"""
39
+ agent = UXDesigner()
40
+ menu = agent.get_menu()
41
+ assert isinstance(menu, list)
42
+ assert len(menu) > 0
43
+ assert all("cmd" in item and "label" in item for item in menu)
44
+ print("✓ Menu retrieval works")
45
+
46
+
47
+ async def test_redisplay_menu():
48
+ """Test redisplay menu action"""
49
+ agent = UXDesigner()
50
+ request = UXDesignerRequest(action=UXDesignAction.REDISPLAY_MENU)
51
+ response = await agent.process(request)
52
+
53
+ assert isinstance(response, UXDesignerResponse)
54
+ assert response.action_taken == UXDesignAction.REDISPLAY_MENU
55
+ assert "Menu" in response.content
56
+ print("✓ Redisplay menu works")
57
+
58
+
59
+ async def test_chat():
60
+ """Test chat action"""
61
+ agent = UXDesigner()
62
+ request = UXDesignerRequest(
63
+ action=UXDesignAction.CHAT, user_input="I need help with UX design"
64
+ )
65
+ response = await agent.process(request)
66
+
67
+ assert isinstance(response, UXDesignerResponse)
68
+ assert response.action_taken == UXDesignAction.CHAT
69
+ assert len(response.content) > 0
70
+ print("✓ Chat works")
71
+
72
+
73
+ async def test_create_ux_design():
74
+ """Test create UX design action"""
75
+ agent = UXDesigner()
76
+ request = UXDesignerRequest(
77
+ action=UXDesignAction.CREATE_UX_DESIGN,
78
+ target_audience="young professionals",
79
+ platform="mobile",
80
+ user_stories=[
81
+ "As a user, I want to quickly find nearby restaurants",
82
+ "As a user, I want to see ratings and reviews",
83
+ ],
84
+ )
85
+ response = await agent.process(request)
86
+
87
+ assert isinstance(response, UXDesignerResponse)
88
+ assert response.action_taken == UXDesignAction.CREATE_UX_DESIGN
89
+ assert response.user_flows is not None
90
+ assert len(response.user_flows) > 0
91
+ assert response.wireframes is not None
92
+ assert len(response.wireframes) > 0
93
+ assert response.recommendations is not None
94
+ assert len(response.recommendations) > 0
95
+ assert response.next_steps is not None
96
+ assert len(response.next_steps) > 0
97
+ print("✓ Create UX design works")
98
+
99
+
100
+ async def test_party_mode():
101
+ """Test party mode action"""
102
+ agent = UXDesigner()
103
+ request = UXDesignerRequest(action=UXDesignAction.PARTY_MODE)
104
+ response = await agent.process(request)
105
+
106
+ assert isinstance(response, UXDesignerResponse)
107
+ assert response.action_taken == UXDesignAction.PARTY_MODE
108
+ assert "party" in response.content.lower() or "PARTY" in response.content
109
+ print("✓ Party mode works")
110
+
111
+
112
+ async def test_dismiss():
113
+ """Test dismiss action"""
114
+ agent = UXDesigner()
115
+ request = UXDesignerRequest(action=UXDesignAction.DISMISS)
116
+ response = await agent.process(request)
117
+
118
+ assert isinstance(response, UXDesignerResponse)
119
+ assert response.action_taken == UXDesignAction.DISMISS
120
+ assert len(response.content) > 0
121
+ print("✓ Dismiss works")
122
+
123
+
124
+ async def run_all_tests():
125
+ """Run all integration tests"""
126
+ print("\\n" + "=" * 60)
127
+ print("UX Designer Agent - Integration Tests")
128
+ print("=" * 60 + "\\n")
129
+
130
+ test_agent_creation()
131
+ test_menu_retrieval()
132
+ await test_redisplay_menu()
133
+ await test_chat()
134
+ await test_create_ux_design()
135
+ await test_party_mode()
136
+ await test_dismiss()
137
+
138
+ print("\\n" + "=" * 60)
139
+ print("✓ All 7 integration tests passed!")
140
+ print("=" * 60 + "\\n")
141
+
142
+
143
+ if __name__ == "__main__":
144
+ asyncio.run(run_all_tests())
@@ -0,0 +1,86 @@
1
+ """
2
+ Simple YAML validator that checks basic YAML syntax without requiring PyYAML
3
+ """
4
+
5
+ import sys
6
+ import re
7
+
8
+
9
+ def validate_yaml_file(filepath):
10
+ """Basic YAML validation - checks for common syntax errors"""
11
+ try:
12
+ with open(filepath, "r") as f:
13
+ content = f.read()
14
+
15
+ # Check for basic YAML structure
16
+ lines = content.split("\n")
17
+
18
+ # Check for proper indentation (YAML uses spaces, not tabs)
19
+ for i, line in enumerate(lines, 1):
20
+ if "\t" in line:
21
+ return False, f"Line {i}: Contains tabs (YAML requires spaces)"
22
+
23
+ # Check for proper key-value pairs (key: value)
24
+ for i, line in enumerate(lines, 1):
25
+ stripped = line.strip()
26
+ if (
27
+ stripped
28
+ and not stripped.startswith("#")
29
+ and not stripped.startswith("-")
30
+ ):
31
+ if ":" in stripped:
32
+ # This looks like a key-value pair
33
+ parts = stripped.split(":", 1)
34
+ if len(parts) == 2:
35
+ key = parts[0].strip()
36
+ if not key:
37
+ return False, f"Line {i}: Empty key"
38
+
39
+ return True, "Valid YAML structure"
40
+
41
+ except Exception as e:
42
+ return False, f"Error reading file: {str(e)}"
43
+
44
+
45
+ def main():
46
+ """Validate all YAML files in the prompts directory"""
47
+ import os
48
+
49
+ if len(sys.argv) > 1:
50
+ # Validate specific file
51
+ filepath = sys.argv[1]
52
+ valid, message = validate_yaml_file(filepath)
53
+ print(f"{filepath}: {message}")
54
+ return 0 if valid else 1
55
+ else:
56
+ # Validate all YAML files
57
+ prompts_dir = os.path.join(os.path.dirname(__file__), "..", "prompts")
58
+ yaml_files = []
59
+
60
+ for root, dirs, files in os.walk(prompts_dir):
61
+ for file in files:
62
+ if file.endswith(".yaml"):
63
+ yaml_files.append(os.path.join(root, file))
64
+
65
+ print(f"Found {len(yaml_files)} YAML files to validate\n")
66
+
67
+ all_valid = True
68
+ for filepath in sorted(yaml_files):
69
+ valid, message = validate_yaml_file(filepath)
70
+ status = "✓" if valid else "✗"
71
+ print(f"{status} {filepath}: {message}")
72
+ if not valid:
73
+ all_valid = False
74
+
75
+ print(f"\n{'=' * 60}")
76
+ if all_valid:
77
+ print(f"✓ All {len(yaml_files)} YAML files are valid!")
78
+ else:
79
+ print(f"✗ Some YAML files have errors")
80
+ print(f"{'=' * 60}")
81
+
82
+ return 0 if all_valid else 1
83
+
84
+
85
+ if __name__ == "__main__":
86
+ sys.exit(main())
@@ -0,0 +1,463 @@
1
+ /**
2
+ * MDAN Documentation Build Pipeline
3
+ *
4
+ * Consolidates docs from multiple sources, generates LLM-friendly files,
5
+ * and builds the Astro+Starlight site.
6
+ *
7
+ * Build outputs:
8
+ * build/artifacts/ - With llms.txt, llms-full.txt
9
+ * build/site/ - Final Astro output (deployable)
10
+ */
11
+
12
+ import { execSync } from 'node:child_process';
13
+ import fs from 'node:fs';
14
+ import path from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { getSiteUrl } from '../website/src/lib/site-url.mjs';
17
+
18
+ // =============================================================================
19
+ // Configuration
20
+ // =============================================================================
21
+
22
+ const PROJECT_ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
23
+ const BUILD_DIR = path.join(PROJECT_ROOT, 'build');
24
+
25
+ const REPO_URL = 'https://github.com/mdan-code-org/MDAN';
26
+
27
+ // DO NOT CHANGE THESE VALUES!
28
+ // llms-full.txt is consumed by AI agents as context. Most LLMs have ~200k token limits.
29
+ // 600k chars ≈ 150k tokens (safe margin). Exceeding this breaks AI agent functionality.
30
+ const LLM_MAX_CHARS = 600_000;
31
+ const LLM_WARN_CHARS = 500_000;
32
+
33
+ const LLM_EXCLUDE_PATTERNS = [
34
+ 'changelog',
35
+ 'ide-info/',
36
+ 'v4-to-v6-upgrade',
37
+ 'faq',
38
+ 'reference/glossary/',
39
+ 'explanation/game-dev/',
40
+ 'bmgd/',
41
+ // Note: Files/dirs starting with _ (like _STYLE_GUIDE.md, _archive/) are excluded in shouldExcludeFromLlm()
42
+ ];
43
+
44
+ // =============================================================================
45
+ // Main Entry Point
46
+ /**
47
+ * Orchestrates the full MDAN documentation build pipeline.
48
+ *
49
+ * Executes the high-level build steps in sequence: prints headers and paths, validates internal
50
+ * documentation links, cleans the build directory, generates artifacts from the `docs/` folder,
51
+ * builds the Astro site, and prints a final build summary.
52
+ */
53
+
54
+ async function main() {
55
+ if (process.platform === 'win32') {
56
+ console.error('Error: The docs build pipeline does not support Windows.');
57
+ console.error('Please build on Linux, macOS, or WSL.');
58
+ process.exit(1);
59
+ }
60
+
61
+ console.log();
62
+ printBanner('MDAN Documentation Build Pipeline');
63
+ console.log();
64
+ console.log(`Project root: ${PROJECT_ROOT}`);
65
+ console.log(`Build directory: ${BUILD_DIR}`);
66
+ console.log();
67
+
68
+ // Check for broken internal links before building
69
+ checkDocLinks();
70
+
71
+ cleanBuildDirectory();
72
+
73
+ const docsDir = path.join(PROJECT_ROOT, 'docs');
74
+ const artifactsDir = await generateArtifacts(docsDir);
75
+ const siteDir = buildAstroSite();
76
+
77
+ printBuildSummary(docsDir, artifactsDir, siteDir);
78
+ }
79
+
80
+ main().catch((error) => {
81
+ console.error(error);
82
+ process.exit(1);
83
+ });
84
+
85
+ // =============================================================================
86
+ // Pipeline Stages
87
+ /**
88
+ * Generate LLM files for the documentation pipeline.
89
+ *
90
+ * Creates the build/artifacts directory and writes `llms.txt` and `llms-full.txt` (sourced from the provided docs directory).
91
+ *
92
+ * @param {string} docsDir - Path to the source docs directory containing Markdown files.
93
+ * @returns {string} Path to the created artifacts directory.
94
+ */
95
+
96
+ async function generateArtifacts(docsDir) {
97
+ printHeader('Generating LLM files');
98
+
99
+ const outputDir = path.join(BUILD_DIR, 'artifacts');
100
+ fs.mkdirSync(outputDir, { recursive: true });
101
+
102
+ // Generate LLM files reading from docs/, output to artifacts/
103
+ generateLlmsTxt(outputDir);
104
+ generateLlmsFullTxt(docsDir, outputDir);
105
+
106
+ console.log();
107
+ console.log(` \u001B[32m✓\u001B[0m Artifact generation complete`);
108
+
109
+ return outputDir;
110
+ }
111
+
112
+ /**
113
+ * Builds the Astro + Starlight site and copies generated artifacts into the site output directory.
114
+ *
115
+ * @returns {string} The filesystem path to the built site directory (e.g., build/site).
116
+ */
117
+ function buildAstroSite() {
118
+ printHeader('Building Astro + Starlight site');
119
+
120
+ const siteDir = path.join(BUILD_DIR, 'site');
121
+ const artifactsDir = path.join(BUILD_DIR, 'artifacts');
122
+
123
+ // Build Astro site (outputs to build/site via astro.config.mjs)
124
+ runAstroBuild();
125
+ copyArtifactsToSite(artifactsDir, siteDir);
126
+
127
+ console.log();
128
+ console.log(` \u001B[32m✓\u001B[0m Astro build complete`);
129
+
130
+ return siteDir;
131
+ }
132
+
133
+ // =============================================================================
134
+ // LLM File Generation
135
+ /**
136
+ * Create a concise llms.txt summary file containing project metadata, core links, and quick navigation entries for LLM consumption.
137
+ *
138
+ * Writes the file to `${outputDir}/llms.txt`.
139
+ *
140
+ * @param {string} outputDir - Destination directory where `llms.txt` will be written.
141
+ */
142
+
143
+ function generateLlmsTxt(outputDir) {
144
+ console.log(' → Generating llms.txt...');
145
+
146
+ const siteUrl = getSiteUrl();
147
+ const content = [
148
+ '# MDAN Method Documentation',
149
+ '',
150
+ '> AI-driven agile development with specialized agents and workflows that scale from bug fixes to enterprise platforms.',
151
+ '',
152
+ `Documentation: ${siteUrl}`,
153
+ `Repository: ${REPO_URL}`,
154
+ `Full docs: ${siteUrl}/llms-full.txt`,
155
+ '',
156
+ '## Quick Start',
157
+ '',
158
+ `- **[Getting Started](${siteUrl}/tutorials/getting-started/)** - Tutorial: install and learn how MDAN works`,
159
+ `- **[Installation](${siteUrl}/how-to/install-mdan/)** - How to install MDAN Method`,
160
+ '',
161
+ '## Core Concepts',
162
+ '',
163
+ `- **[Quick Flow](${siteUrl}/explanation/quick-flow/)** - Fast development workflow`,
164
+ `- **[Party Mode](${siteUrl}/explanation/party-mode/)** - Multi-agent collaboration`,
165
+ `- **[Workflow Map](${siteUrl}/reference/workflow-map/)** - Visual overview of phases and workflows`,
166
+ '',
167
+ '## Modules',
168
+ '',
169
+ `- **[Official Modules](${siteUrl}/reference/modules/)** - BMM, BMB, BMGD, and more`,
170
+ '',
171
+ '---',
172
+ '',
173
+ '## Quick Links',
174
+ '',
175
+ `- [Full Documentation (llms-full.txt)](${siteUrl}/llms-full.txt) - Complete docs for AI context`,
176
+ '',
177
+ ].join('\n');
178
+
179
+ const outputPath = path.join(outputDir, 'llms.txt');
180
+ fs.writeFileSync(outputPath, content, 'utf-8');
181
+ console.log(` Generated llms.txt (${content.length.toLocaleString()} chars)`);
182
+ }
183
+
184
+ /**
185
+ * Builds a consolidated llms-full.txt containing all Markdown files under docsDir wrapped in <document path="..."> tags for LLM consumption.
186
+ *
187
+ * Writes the generated file to outputDir/llms-full.txt. Files matching LLM_EXCLUDE_PATTERNS are skipped; read errors for individual files are logged. The combined content is validated against configured size thresholds (will exit on overflow and warn if near limit).
188
+ * @param {string} docsDir - Root directory containing source Markdown files; paths in the output are relative to this directory.
189
+ * @param {string} outputDir - Directory where llms-full.txt will be written.
190
+ */
191
+ function generateLlmsFullTxt(docsDir, outputDir) {
192
+ console.log(' → Generating llms-full.txt...');
193
+
194
+ const date = new Date().toISOString().split('T')[0];
195
+ const files = getAllMarkdownFiles(docsDir).sort(compareLlmDocs);
196
+
197
+ const output = [
198
+ '# MDAN Method Documentation (Full)',
199
+ '',
200
+ '> Complete documentation for AI consumption',
201
+ `> Generated: ${date}`,
202
+ `> Repository: ${REPO_URL}`,
203
+ '',
204
+ ];
205
+
206
+ let fileCount = 0;
207
+ let skippedCount = 0;
208
+
209
+ for (const mdPath of files) {
210
+ if (shouldExcludeFromLlm(mdPath)) {
211
+ skippedCount++;
212
+ continue;
213
+ }
214
+
215
+ const fullPath = path.join(docsDir, mdPath);
216
+ try {
217
+ const content = readMarkdownContent(fullPath);
218
+ output.push(`<document path="${mdPath}">`, content, '</document>', '');
219
+ fileCount++;
220
+ } catch (error) {
221
+ console.error(` Warning: Could not read ${mdPath}: ${error.message}`);
222
+ }
223
+ }
224
+
225
+ const result = output.join('\n');
226
+ validateLlmSize(result);
227
+
228
+ const outputPath = path.join(outputDir, 'llms-full.txt');
229
+ fs.writeFileSync(outputPath, result, 'utf-8');
230
+
231
+ const tokenEstimate = Math.floor(result.length / 4).toLocaleString();
232
+ console.log(
233
+ ` Processed ${fileCount} files (skipped ${skippedCount}), ${result.length.toLocaleString()} chars (~${tokenEstimate} tokens)`,
234
+ );
235
+ }
236
+
237
+ function compareLlmDocs(a, b) {
238
+ const aKey = getLlmSortKey(a);
239
+ const bKey = getLlmSortKey(b);
240
+
241
+ if (aKey !== bKey) return aKey - bKey;
242
+ return a.localeCompare(b);
243
+ }
244
+
245
+ function getLlmSortKey(filePath) {
246
+ if (filePath === 'index.md') return 0;
247
+ if (filePath.startsWith(`tutorials${path.sep}`) || filePath.startsWith('tutorials/')) return 2;
248
+ if (filePath.startsWith(`how-to${path.sep}`) || filePath.startsWith('how-to/')) return 3;
249
+ if (filePath.startsWith(`explanation${path.sep}`) || filePath.startsWith('explanation/')) return 4;
250
+ if (filePath.startsWith(`reference${path.sep}`) || filePath.startsWith('reference/')) return 5;
251
+ if (filePath.startsWith(`bmgd${path.sep}`) || filePath.startsWith('bmgd/')) return 6;
252
+ return 7;
253
+ }
254
+
255
+ /**
256
+ * Collects all Markdown (.md) files under a directory and returns their paths relative to a base directory.
257
+ * @param {string} dir - Directory to search for Markdown files.
258
+ * @param {string} [baseDir=dir] - Base directory used to compute returned relative paths.
259
+ * @returns {string[]} An array of file paths (relative to `baseDir`) for every `.md` file found under `dir`.
260
+ */
261
+ function getAllMarkdownFiles(dir, baseDir = dir) {
262
+ const files = [];
263
+
264
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
265
+ const fullPath = path.join(dir, entry.name);
266
+
267
+ if (entry.isDirectory()) {
268
+ files.push(...getAllMarkdownFiles(fullPath, baseDir));
269
+ } else if (entry.name.endsWith('.md')) {
270
+ // Return relative path from baseDir
271
+ const relativePath = path.relative(baseDir, fullPath);
272
+ files.push(relativePath);
273
+ }
274
+ }
275
+
276
+ return files;
277
+ }
278
+
279
+ /**
280
+ * Determine whether a file path matches any configured LLM exclusion pattern.
281
+ * Also excludes any files or directories starting with underscore.
282
+ * @param {string} filePath - The file path to test.
283
+ * @returns {boolean} `true` if excluded, `false` otherwise.
284
+ */
285
+ function shouldExcludeFromLlm(filePath) {
286
+ // Exclude if ANY path component starts with underscore
287
+ // (e.g., _STYLE_GUIDE.md, _archive/file.md, dir/_STYLE_GUIDE.md)
288
+ const pathParts = filePath.split(path.sep);
289
+ if (pathParts.some((part) => part.startsWith('_'))) return true;
290
+
291
+ // Check configured patterns
292
+ return LLM_EXCLUDE_PATTERNS.some((pattern) => filePath.includes(pattern));
293
+ }
294
+
295
+ function readMarkdownContent(filePath) {
296
+ let content = fs.readFileSync(filePath, 'utf-8');
297
+
298
+ if (content.startsWith('---')) {
299
+ const end = content.indexOf('---', 3);
300
+ if (end !== -1) {
301
+ content = content.slice(end + 3).trim();
302
+ }
303
+ }
304
+
305
+ return content;
306
+ }
307
+
308
+ function validateLlmSize(content) {
309
+ const charCount = content.length;
310
+
311
+ if (charCount > LLM_MAX_CHARS) {
312
+ console.error(` ERROR: Exceeds ${LLM_MAX_CHARS.toLocaleString()} char limit`);
313
+ process.exit(1);
314
+ } else if (charCount > LLM_WARN_CHARS) {
315
+ console.warn(` \u001B[33mWARNING: Approaching ${LLM_WARN_CHARS.toLocaleString()} char limit\u001B[0m`);
316
+ }
317
+ }
318
+
319
+ // =============================================================================
320
+ // Astro Build
321
+ /**
322
+ * Builds the Astro site to build/site (configured in astro.config.mjs).
323
+ */
324
+ function runAstroBuild() {
325
+ console.log(' → Running astro build...');
326
+ execSync('npx astro build --root website', {
327
+ cwd: PROJECT_ROOT,
328
+ stdio: 'inherit',
329
+ env: {
330
+ ...process.env,
331
+ },
332
+ });
333
+ }
334
+
335
+ /**
336
+ * Copy generated artifact files into the built site directory.
337
+ *
338
+ * Copies llms.txt and llms-full.txt from the artifacts directory into the site directory.
339
+ *
340
+ * @param {string} artifactsDir - Path to the build artifacts directory containing generated files.
341
+ * @param {string} siteDir - Path to the target site directory where artifacts should be placed.
342
+ */
343
+ function copyArtifactsToSite(artifactsDir, siteDir) {
344
+ console.log(' → Copying artifacts to site...');
345
+
346
+ fs.copyFileSync(path.join(artifactsDir, 'llms.txt'), path.join(siteDir, 'llms.txt'));
347
+ fs.copyFileSync(path.join(artifactsDir, 'llms-full.txt'), path.join(siteDir, 'llms-full.txt'));
348
+ }
349
+
350
+ // =============================================================================
351
+ // Build Summary
352
+ /**
353
+ * Prints a concise end-of-build summary and displays a sample listing of the final site directory.
354
+ *
355
+ * @param {string} docsDir - Path to the source documentation directory used for the build.
356
+ * @param {string} artifactsDir - Path to the directory containing generated artifacts (e.g., llms.txt).
357
+ * @param {string} siteDir - Path to the final built site directory whose contents will be listed.
358
+ */
359
+
360
+ function printBuildSummary(docsDir, artifactsDir, siteDir) {
361
+ console.log();
362
+ printBanner('Build Complete!');
363
+ console.log();
364
+ console.log('Build artifacts:');
365
+ console.log(` Source docs: ${docsDir}`);
366
+ console.log(` Generated files: ${artifactsDir}`);
367
+ console.log(` Final site: ${siteDir}`);
368
+ console.log();
369
+ console.log(`Deployable output: ${siteDir}/`);
370
+ console.log();
371
+
372
+ listDirectoryContents(siteDir);
373
+ }
374
+
375
+ function listDirectoryContents(dir) {
376
+ const entries = fs.readdirSync(dir).slice(0, 15);
377
+
378
+ for (const entry of entries) {
379
+ const fullPath = path.join(dir, entry);
380
+ const stat = fs.statSync(fullPath);
381
+
382
+ if (stat.isFile()) {
383
+ const sizeStr = formatFileSize(stat.size);
384
+ console.log(` ${entry.padEnd(40)} ${sizeStr.padStart(8)}`);
385
+ } else {
386
+ console.log(` ${entry}/`);
387
+ }
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Format a byte count into a compact human-readable string using B, K, or M units.
393
+ * @param {number} bytes - The number of bytes to format.
394
+ * @returns {string} The formatted size: bytes as `N B` (e.g. `512B`), kilobytes truncated to an integer with `K` (e.g. `2K`), or megabytes with one decimal and `M` (e.g. `1.2M`).
395
+ */
396
+ function formatFileSize(bytes) {
397
+ if (bytes > 1024 * 1024) {
398
+ return `${(bytes / 1024 / 1024).toFixed(1)}M`;
399
+ } else if (bytes > 1024) {
400
+ return `${Math.floor(bytes / 1024)}K`;
401
+ }
402
+ return `${bytes}B`;
403
+ }
404
+
405
+ // =============================================================================
406
+ // File System Utilities
407
+ /**
408
+ * Remove any existing build output and recreate the build directory.
409
+ *
410
+ * Ensures the configured BUILD_DIR is empty by deleting it if present and then creating a fresh directory.
411
+ */
412
+
413
+ function cleanBuildDirectory() {
414
+ console.log('Cleaning previous build...');
415
+
416
+ if (fs.existsSync(BUILD_DIR)) {
417
+ fs.rmSync(BUILD_DIR, { recursive: true });
418
+ }
419
+ fs.mkdirSync(BUILD_DIR, { recursive: true });
420
+ }
421
+
422
+ // =============================================================================
423
+ // Console Output Formatting
424
+ // =============================================================================
425
+
426
+ function printHeader(title) {
427
+ console.log();
428
+ console.log('┌' + '─'.repeat(62) + '┐');
429
+ console.log(`│ ${title.padEnd(60)} │`);
430
+ console.log('└' + '─'.repeat(62) + '┘');
431
+ }
432
+
433
+ /**
434
+ * Prints a centered decorative ASCII banner to the console using the provided title.
435
+ * @param {string} title - Text to display centered inside the banner. */
436
+ function printBanner(title) {
437
+ console.log('╔' + '═'.repeat(62) + '╗');
438
+ console.log(`║${title.padStart(31 + title.length / 2).padEnd(62)}║`);
439
+ console.log('╚' + '═'.repeat(62) + '╝');
440
+ }
441
+
442
+ // =============================================================================
443
+ // Link Checking
444
+ /**
445
+ * Verify internal documentation links by running the link-checking script.
446
+ *
447
+ * Executes the Node script tools/validate-doc-links.js from the project root and
448
+ * exits the process with code 1 if the check fails.
449
+ */
450
+
451
+ function checkDocLinks() {
452
+ printHeader('Checking documentation links');
453
+
454
+ try {
455
+ execSync('node tools/validate-doc-links.js', {
456
+ cwd: PROJECT_ROOT,
457
+ stdio: 'inherit',
458
+ });
459
+ } catch {
460
+ console.error('\n \u001B[31m✗\u001B[0m Link check failed - fix broken links before building\n');
461
+ process.exit(1);
462
+ }
463
+ }