@zeyue0329/xiaoma-cli 1.0.49 → 1.6.4

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 (895) hide show
  1. package/.github/workflows/quality.yaml +116 -0
  2. package/.husky/pre-commit +26 -0
  3. package/.idea/codeStyles/Project.xml +60 -0
  4. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  5. package/.idea/jsLibraryMappings.xml +6 -0
  6. package/.idea/modules.xml +1 -1
  7. package/.idea/vcs.xml +0 -1
  8. package/.idea/workspace.xml +40 -24
  9. package/.markdownlint-cli2.yaml +41 -0
  10. package/.prettierignore +12 -0
  11. package/.vscode/settings.json +96 -0
  12. package/LICENSE +30 -0
  13. package/README.md +108 -2
  14. package/XIAOMA-CLI-GUIDE.md +512 -0
  15. package/{.idea/XiaoMa-Cli.iml → XiaoMa-Cli.iml} +1 -1
  16. package/custom/src/agents/commit-poet/commit-poet.agent.yaml +129 -0
  17. package/custom/src/agents/commit-poet/installation-guide.md +36 -0
  18. package/custom/src/agents/toolsmith/installation-guide.md +36 -0
  19. package/custom/src/agents/toolsmith/toolsmith-sidecar/instructions.md +70 -0
  20. package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +111 -0
  21. package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +70 -0
  22. package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +114 -0
  23. package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +134 -0
  24. package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +160 -0
  25. package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +103 -0
  26. package/custom/src/agents/toolsmith/toolsmith-sidecar/memories.md +17 -0
  27. package/custom/src/agents/toolsmith/toolsmith.agent.yaml +108 -0
  28. package/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
  29. package/docs/agent-customization-guide.md +208 -0
  30. package/docs/custom-agent-installation.md +183 -0
  31. package/docs/document-sharding-guide.md +449 -0
  32. package/docs/explanation/advanced-elicitation.md +49 -0
  33. package/docs/explanation/adversarial-review.md +59 -0
  34. package/docs/explanation/brainstorming.md +33 -0
  35. package/docs/explanation/established-projects-faq.md +50 -0
  36. package/docs/explanation/party-mode.md +59 -0
  37. package/docs/explanation/preventing-agent-conflicts.md +112 -0
  38. package/docs/explanation/project-context.md +157 -0
  39. package/docs/explanation/quick-dev-new-preview.md +73 -0
  40. package/docs/explanation/quick-flow.md +77 -0
  41. package/docs/explanation/why-solutioning-matters.md +77 -0
  42. package/docs/how-to/customize-xiaoma.md +172 -0
  43. package/docs/how-to/established-projects.md +117 -0
  44. package/docs/how-to/get-answers-about-xiaoma.md +134 -0
  45. package/docs/how-to/install-xiaoma.md +107 -0
  46. package/docs/how-to/non-interactive-installation.md +171 -0
  47. package/docs/how-to/project-context.md +136 -0
  48. package/docs/how-to/quick-fixes.md +123 -0
  49. package/docs/how-to/shard-large-documents.md +78 -0
  50. package/docs/how-to/upgrade-to-v6.md +100 -0
  51. package/docs/ide-info/auggie.md +31 -0
  52. package/docs/ide-info/claude-code.md +25 -0
  53. package/docs/ide-info/cline.md +31 -0
  54. package/docs/ide-info/codex.md +21 -0
  55. package/docs/ide-info/crush.md +30 -0
  56. package/docs/ide-info/cursor.md +25 -0
  57. package/docs/ide-info/gemini.md +25 -0
  58. package/docs/ide-info/github-copilot.md +26 -0
  59. package/docs/ide-info/iflow.md +33 -0
  60. package/docs/ide-info/kilo.md +24 -0
  61. package/docs/ide-info/opencode.md +24 -0
  62. package/docs/ide-info/qwen.md +25 -0
  63. package/docs/ide-info/roo.md +27 -0
  64. package/docs/ide-info/rovo-dev.md +388 -0
  65. package/docs/ide-info/trae.md +25 -0
  66. package/docs/ide-info/windsurf.md +22 -0
  67. package/docs/index.md +60 -0
  68. package/docs/installers-bundlers/ide-injections.md +186 -0
  69. package/docs/installers-bundlers/installers-modules-platforms-reference.md +379 -0
  70. package/docs/rag/rag.md +856 -0
  71. package/docs/reference/agents.md +28 -0
  72. package/docs/reference/commands.md +145 -0
  73. package/docs/reference/modules.md +76 -0
  74. package/docs/reference/testing.md +106 -0
  75. package/docs/reference/workflow-map.md +89 -0
  76. package/docs/roadmap.mdx +136 -0
  77. package/docs/superpowers/plans/2026-03-11-upstream-sync-with-branding.md +586 -0
  78. package/docs/tutorials/getting-started.md +273 -0
  79. package/docs/v4-to-v6-upgrade.md +220 -0
  80. package/docs/v6-open-items.md +17 -0
  81. package/docs/web-bundles-gemini-gpt-guide.md +468 -0
  82. package/docs/zh-cn/404.md +9 -0
  83. package/docs/zh-cn/_STYLE_GUIDE.md +370 -0
  84. package/docs/zh-cn/explanation/advanced-elicitation.md +62 -0
  85. package/docs/zh-cn/explanation/adversarial-review.md +71 -0
  86. package/docs/zh-cn/explanation/brainstorming.md +43 -0
  87. package/docs/zh-cn/explanation/established-projects-faq.md +60 -0
  88. package/docs/zh-cn/explanation/party-mode.md +79 -0
  89. package/docs/zh-cn/explanation/preventing-agent-conflicts.md +137 -0
  90. package/docs/zh-cn/explanation/project-context.md +176 -0
  91. package/docs/zh-cn/explanation/quick-flow.md +93 -0
  92. package/docs/zh-cn/explanation/why-solutioning-matters.md +90 -0
  93. package/docs/zh-cn/how-to/customize-xiaoma.md +182 -0
  94. package/docs/zh-cn/how-to/established-projects.md +134 -0
  95. package/docs/zh-cn/how-to/get-answers-about-xiaoma.md +144 -0
  96. package/docs/zh-cn/how-to/install-xiaoma.md +105 -0
  97. package/docs/zh-cn/how-to/non-interactive-installation.md +181 -0
  98. package/docs/zh-cn/how-to/project-context.md +152 -0
  99. package/docs/zh-cn/how-to/quick-fixes.md +140 -0
  100. package/docs/zh-cn/how-to/shard-large-documents.md +86 -0
  101. package/docs/zh-cn/how-to/upgrade-to-v6.md +120 -0
  102. package/docs/zh-cn/index.md +69 -0
  103. package/docs/zh-cn/reference/agents.md +41 -0
  104. package/docs/zh-cn/reference/commands.md +166 -0
  105. package/docs/zh-cn/reference/modules.md +94 -0
  106. package/docs/zh-cn/reference/testing.md +122 -0
  107. package/docs/zh-cn/reference/workflow-map.md +104 -0
  108. package/docs/zh-cn/roadmap.mdx +152 -0
  109. package/docs/zh-cn/tutorials/getting-started.md +300 -0
  110. package/eslint.config.mjs +144 -0
  111. package/package.json +56 -58
  112. package/prettier.config.mjs +32 -0
  113. package/src/core/_module-installer/install-config.yaml +29 -0
  114. package/src/core/_module-installer/installer.js +60 -0
  115. package/src/core/agents/xiaoma-master.agent.yaml +30 -0
  116. package/src/core/agents/xiaoma-skill-manifest.yaml +3 -0
  117. package/src/core/agents/xiaoma-web-orchestrator.agent.xml +113 -0
  118. package/src/core/module-help.csv +10 -0
  119. package/src/core/module.yaml +25 -0
  120. package/src/core/resources/excalidraw/README.md +160 -0
  121. package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
  122. package/src/core/resources/excalidraw/library-loader.md +50 -0
  123. package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
  124. package/src/core/tasks/advanced-elicitation-methods.csv +51 -0
  125. package/src/core/tasks/advanced-elicitation.xml +116 -0
  126. package/src/core/tasks/editorial-review-prose.xml +102 -0
  127. package/src/core/tasks/editorial-review-structure.xml +208 -0
  128. package/src/core/tasks/help.md +92 -0
  129. package/src/core/tasks/index-docs.xml +65 -0
  130. package/src/core/tasks/review-adversarial-general.xml +49 -0
  131. package/src/core/tasks/review-edge-case-hunter.xml +63 -0
  132. package/src/core/tasks/shard-doc.xml +108 -0
  133. package/src/core/tasks/validate-workflow.xml +89 -0
  134. package/src/core/tasks/workflow.xml +235 -0
  135. package/src/core/tasks/xiaoma-help/SKILL.md +6 -0
  136. package/src/core/tasks/xiaoma-help/workflow.md +88 -0
  137. package/src/core/tasks/xiaoma-help/xiaoma-skill-manifest.yaml +1 -0
  138. package/src/core/tasks/xiaoma-review-adversarial-general/SKILL.md +6 -0
  139. package/src/core/tasks/xiaoma-review-adversarial-general/workflow.md +32 -0
  140. package/src/core/tasks/xiaoma-review-adversarial-general/xiaoma-skill-manifest.yaml +1 -0
  141. package/src/core/tasks/xiaoma-review-edge-case-hunter/SKILL.md +6 -0
  142. package/src/core/tasks/xiaoma-review-edge-case-hunter/workflow.md +62 -0
  143. package/src/core/tasks/xiaoma-review-edge-case-hunter/xiaoma-skill-manifest.yaml +1 -0
  144. package/src/core/tasks/xiaoma-skill-manifest.yaml +19 -0
  145. package/src/core/tools/shard-doc.xml +109 -0
  146. package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
  147. package/src/core/workflows/advanced-elicitation/workflow.md +138 -0
  148. package/src/core/workflows/advanced-elicitation/workflow.xml +118 -0
  149. package/src/core/workflows/advanced-elicitation/xiaoma-skill-manifest.yaml +3 -0
  150. package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
  151. package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +210 -0
  152. package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
  153. package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
  154. package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
  155. package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
  156. package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
  157. package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
  158. package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
  159. package/src/core/workflows/brainstorming/template.md +15 -0
  160. package/src/core/workflows/brainstorming/workflow.md +60 -0
  161. package/src/core/workflows/brainstorming/xiaoma-skill-manifest.yaml +3 -0
  162. package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
  163. package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
  164. package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +168 -0
  165. package/src/core/workflows/party-mode/workflow.md +194 -0
  166. package/src/core/workflows/party-mode/xiaoma-skill-manifest.yaml +3 -0
  167. package/src/utility/agent-components/activation-rules.txt +6 -0
  168. package/src/utility/agent-components/activation-steps.txt +14 -0
  169. package/src/utility/agent-components/agent-command-header.md +1 -0
  170. package/src/utility/agent-components/agent.customize.template.yaml +41 -0
  171. package/src/utility/agent-components/handler-action.txt +4 -0
  172. package/src/utility/agent-components/handler-data.txt +5 -0
  173. package/src/utility/agent-components/handler-exec.txt +6 -0
  174. package/src/utility/agent-components/handler-multi.txt +13 -0
  175. package/src/utility/agent-components/handler-tmpl.txt +5 -0
  176. package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
  177. package/src/utility/agent-components/handler-workflow.txt +10 -0
  178. package/src/utility/agent-components/menu-handlers.txt +6 -0
  179. package/src/utility/models/action-command-header.md +0 -0
  180. package/src/utility/models/agent-activation-ide.xml +51 -0
  181. package/src/utility/models/agent-activation-web.xml +50 -0
  182. package/src/utility/models/agent-command-header.md +1 -0
  183. package/src/utility/models/agent-config-template.md +23 -0
  184. package/src/utility/models/agent-in-team-activation.xml +3 -0
  185. package/src/utility/models/fragments/activation-rules.xml +7 -0
  186. package/src/utility/models/fragments/activation-steps.xml +16 -0
  187. package/src/utility/models/fragments/handler-action.xml +4 -0
  188. package/src/utility/models/fragments/handler-data.xml +5 -0
  189. package/src/utility/models/fragments/handler-exec.xml +6 -0
  190. package/src/utility/models/fragments/handler-multi.xml +14 -0
  191. package/src/utility/models/fragments/handler-tmpl.xml +5 -0
  192. package/src/utility/models/fragments/handler-validate-workflow.xml +7 -0
  193. package/src/utility/models/fragments/handler-workflow.xml +9 -0
  194. package/src/utility/models/fragments/menu-handlers.xml +6 -0
  195. package/src/utility/models/fragments/web-bundle-activation-steps.xml +32 -0
  196. package/src/utility/templates/agent.customize.template.yaml +42 -0
  197. package/src/xmc/_module-installer/install-config.yaml +53 -0
  198. package/src/xmc/_module-installer/installer.js +131 -0
  199. package/src/xmc/_module-installer/platform-specifics/claude-code.js +35 -0
  200. package/src/xmc/_module-installer/platform-specifics/windsurf.js +32 -0
  201. package/src/xmc/agents/analyst.agent.yaml +43 -0
  202. package/src/xmc/agents/architect.agent.yaml +29 -0
  203. package/src/xmc/agents/dev.agent.yaml +38 -0
  204. package/src/xmc/agents/pm.agent.yaml +44 -0
  205. package/src/xmc/agents/qa.agent.yaml +58 -0
  206. package/src/xmc/agents/quick-flow-solo-dev.agent.yaml +36 -0
  207. package/src/xmc/agents/sm.agent.yaml +37 -0
  208. package/src/xmc/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
  209. package/src/xmc/agents/tech-writer/tech-writer.agent.yaml +46 -0
  210. package/src/xmc/agents/tech-writer/xiaoma-skill-manifest.yaml +3 -0
  211. package/src/xmc/agents/ux-designer.agent.yaml +27 -0
  212. package/src/xmc/agents/xiaoma-skill-manifest.yaml +39 -0
  213. package/src/xmc/data/project-context-template.md +26 -0
  214. package/src/xmc/module-help.csv +32 -0
  215. package/src/xmc/module.yaml +50 -0
  216. package/src/xmc/sub-modules/claude-code/config.yaml +5 -0
  217. package/src/xmc/sub-modules/claude-code/injections.yaml +242 -0
  218. package/src/xmc/sub-modules/claude-code/readme.md +87 -0
  219. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/api-documenter.md +102 -0
  220. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/codebase-analyzer.md +82 -0
  221. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/data-analyst.md +101 -0
  222. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/pattern-detector.md +84 -0
  223. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/dependency-mapper.md +83 -0
  224. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/epic-optimizer.md +81 -0
  225. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/requirements-analyst.md +61 -0
  226. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/technical-decisions-curator.md +168 -0
  227. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/trend-spotter.md +115 -0
  228. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/user-journey-mapper.md +123 -0
  229. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/user-researcher.md +72 -0
  230. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-research/market-researcher.md +51 -0
  231. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-research/tech-debt-auditor.md +106 -0
  232. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-review/document-reviewer.md +102 -0
  233. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-review/technical-evaluator.md +68 -0
  234. package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-review/test-coverage-analyzer.md +108 -0
  235. package/src/xmc/teams/default-party.csv +20 -0
  236. package/src/xmc/teams/team-fullstack.yaml +12 -0
  237. package/src/xmc/testarch/knowledge/api-request.md +303 -0
  238. package/src/xmc/testarch/knowledge/auth-session.md +356 -0
  239. package/src/xmc/testarch/knowledge/burn-in.md +273 -0
  240. package/src/xmc/testarch/knowledge/ci-burn-in.md +675 -0
  241. package/src/xmc/testarch/knowledge/component-tdd.md +486 -0
  242. package/src/xmc/testarch/knowledge/contract-testing.md +957 -0
  243. package/src/xmc/testarch/knowledge/data-factories.md +500 -0
  244. package/src/xmc/testarch/knowledge/email-auth.md +721 -0
  245. package/src/xmc/testarch/knowledge/error-handling.md +725 -0
  246. package/src/xmc/testarch/knowledge/feature-flags.md +750 -0
  247. package/src/xmc/testarch/knowledge/file-utils.md +260 -0
  248. package/src/xmc/testarch/knowledge/fixture-architecture.md +401 -0
  249. package/src/xmc/testarch/knowledge/fixtures-composition.md +382 -0
  250. package/src/xmc/testarch/knowledge/intercept-network-call.md +280 -0
  251. package/src/xmc/testarch/knowledge/log.md +294 -0
  252. package/src/xmc/testarch/knowledge/network-error-monitor.md +272 -0
  253. package/src/xmc/testarch/knowledge/network-first.md +486 -0
  254. package/src/xmc/testarch/knowledge/network-recorder.md +265 -0
  255. package/src/xmc/testarch/knowledge/nfr-criteria.md +670 -0
  256. package/src/xmc/testarch/knowledge/overview.md +284 -0
  257. package/src/xmc/testarch/knowledge/playwright-config.md +730 -0
  258. package/src/xmc/testarch/knowledge/probability-impact.md +601 -0
  259. package/src/xmc/testarch/knowledge/recurse.md +296 -0
  260. package/src/xmc/testarch/knowledge/risk-governance.md +615 -0
  261. package/src/xmc/testarch/knowledge/selective-testing.md +732 -0
  262. package/src/xmc/testarch/knowledge/selector-resilience.md +527 -0
  263. package/src/xmc/testarch/knowledge/test-healing-patterns.md +644 -0
  264. package/src/xmc/testarch/knowledge/test-levels-framework.md +473 -0
  265. package/src/xmc/testarch/knowledge/test-priorities-matrix.md +373 -0
  266. package/src/xmc/testarch/knowledge/test-quality.md +664 -0
  267. package/src/xmc/testarch/knowledge/timing-debugging.md +372 -0
  268. package/src/xmc/testarch/knowledge/visual-debugging.md +524 -0
  269. package/src/xmc/testarch/tea-index.csv +33 -0
  270. package/src/xmc/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
  271. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
  272. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
  273. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
  274. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
  275. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
  276. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
  277. package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
  278. package/src/xmc/workflows/1-analysis/create-product-brief/workflow.md +57 -0
  279. package/src/xmc/workflows/1-analysis/create-product-brief/xiaoma-skill-manifest.yaml +3 -0
  280. package/src/xmc/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
  281. package/src/xmc/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
  282. package/src/xmc/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
  283. package/src/xmc/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
  284. package/src/xmc/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
  285. package/src/xmc/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +444 -0
  286. package/src/xmc/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
  287. package/src/xmc/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
  288. package/src/xmc/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
  289. package/src/xmc/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
  290. package/src/xmc/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
  291. package/src/xmc/workflows/1-analysis/research/market-steps/step-06-research-completion.md +476 -0
  292. package/src/xmc/workflows/1-analysis/research/research.template.md +29 -0
  293. package/src/xmc/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
  294. package/src/xmc/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
  295. package/src/xmc/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
  296. package/src/xmc/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
  297. package/src/xmc/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +233 -0
  298. package/src/xmc/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +487 -0
  299. package/src/xmc/workflows/1-analysis/research/workflow-domain-research.md +54 -0
  300. package/src/xmc/workflows/1-analysis/research/workflow-market-research.md +54 -0
  301. package/src/xmc/workflows/1-analysis/research/workflow-technical-research.md +54 -0
  302. package/src/xmc/workflows/1-analysis/research/xiaoma-skill-manifest.yaml +14 -0
  303. package/src/xmc/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +15 -0
  304. package/src/xmc/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
  305. package/src/xmc/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
  306. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +191 -0
  307. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +152 -0
  308. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +224 -0
  309. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +154 -0
  310. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +170 -0
  311. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +226 -0
  312. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +213 -0
  313. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +207 -0
  314. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +226 -0
  315. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +237 -0
  316. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +228 -0
  317. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +231 -0
  318. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +242 -0
  319. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +217 -0
  320. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +124 -0
  321. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +247 -0
  322. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
  323. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +249 -0
  324. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +253 -0
  325. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +168 -0
  326. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +226 -0
  327. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
  328. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
  329. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
  330. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
  331. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
  332. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
  333. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
  334. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
  335. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
  336. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
  337. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
  338. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
  339. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +231 -0
  340. package/src/xmc/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -0
  341. package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +63 -0
  342. package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -0
  343. package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -0
  344. package/src/xmc/workflows/2-plan-workflows/create-prd/xiaoma-skill-manifest.yaml +14 -0
  345. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
  346. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
  347. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
  348. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
  349. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
  350. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
  351. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
  352. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
  353. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
  354. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
  355. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
  356. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
  357. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
  358. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
  359. package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
  360. package/src/xmc/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
  361. package/src/xmc/workflows/2-plan-workflows/create-ux-design/workflow.md +42 -0
  362. package/src/xmc/workflows/2-plan-workflows/create-ux-design/xiaoma-skill-manifest.yaml +3 -0
  363. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +184 -0
  364. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +172 -0
  365. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +173 -0
  366. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +133 -0
  367. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +245 -0
  368. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -0
  369. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
  370. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -0
  371. package/src/xmc/workflows/3-solutioning/check-implementation-readiness/xiaoma-skill-manifest.yaml +3 -0
  372. package/src/xmc/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
  373. package/src/xmc/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +13 -0
  374. package/src/xmc/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
  375. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
  376. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +173 -0
  377. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
  378. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +329 -0
  379. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
  380. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
  381. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
  382. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
  383. package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
  384. package/src/xmc/workflows/3-solutioning/create-architecture/workflow.md +49 -0
  385. package/src/xmc/workflows/3-solutioning/create-architecture/xiaoma-skill-manifest.yaml +3 -0
  386. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
  387. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
  388. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
  389. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
  390. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
  391. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -0
  392. package/src/xmc/workflows/3-solutioning/create-epics-and-stories/xiaoma-skill-manifest.yaml +3 -0
  393. package/src/xmc/workflows/4-implementation/code-review/checklist.md +23 -0
  394. package/src/xmc/workflows/4-implementation/code-review/discover-inputs.md +88 -0
  395. package/src/xmc/workflows/4-implementation/code-review/workflow.md +271 -0
  396. package/src/xmc/workflows/4-implementation/code-review/xiaoma-skill-manifest.yaml +3 -0
  397. package/src/xmc/workflows/4-implementation/correct-course/checklist.md +288 -0
  398. package/src/xmc/workflows/4-implementation/correct-course/workflow.md +274 -0
  399. package/src/xmc/workflows/4-implementation/correct-course/xiaoma-skill-manifest.yaml +3 -0
  400. package/src/xmc/workflows/4-implementation/create-story/checklist.md +357 -0
  401. package/src/xmc/workflows/4-implementation/create-story/discover-inputs.md +88 -0
  402. package/src/xmc/workflows/4-implementation/create-story/template.md +49 -0
  403. package/src/xmc/workflows/4-implementation/create-story/workflow.md +388 -0
  404. package/src/xmc/workflows/4-implementation/create-story/xiaoma-skill-manifest.yaml +3 -0
  405. package/src/xmc/workflows/4-implementation/dev-story/checklist.md +80 -0
  406. package/src/xmc/workflows/4-implementation/dev-story/workflow.md +457 -0
  407. package/src/xmc/workflows/4-implementation/dev-story/xiaoma-skill-manifest.yaml +3 -0
  408. package/src/xmc/workflows/4-implementation/retrospective/workflow.md +1485 -0
  409. package/src/xmc/workflows/4-implementation/retrospective/xiaoma-skill-manifest.yaml +3 -0
  410. package/src/xmc/workflows/4-implementation/sprint-planning/checklist.md +33 -0
  411. package/src/xmc/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +56 -0
  412. package/src/xmc/workflows/4-implementation/sprint-planning/workflow.md +271 -0
  413. package/src/xmc/workflows/4-implementation/sprint-planning/xiaoma-skill-manifest.yaml +3 -0
  414. package/src/xmc/workflows/4-implementation/sprint-status/workflow.md +267 -0
  415. package/src/xmc/workflows/4-implementation/sprint-status/xiaoma-skill-manifest.yaml +3 -0
  416. package/src/xmc/workflows/document-project/checklist.md +245 -0
  417. package/src/xmc/workflows/document-project/documentation-requirements.csv +12 -0
  418. package/src/xmc/workflows/document-project/instructions.md +128 -0
  419. package/src/xmc/workflows/document-project/templates/deep-dive-template.md +345 -0
  420. package/src/xmc/workflows/document-project/templates/index-template.md +169 -0
  421. package/src/xmc/workflows/document-project/templates/project-overview-template.md +103 -0
  422. package/src/xmc/workflows/document-project/templates/project-scan-report-schema.json +160 -0
  423. package/src/xmc/workflows/document-project/templates/source-tree-template.md +135 -0
  424. package/src/xmc/workflows/document-project/workflow.md +39 -0
  425. package/src/xmc/workflows/document-project/workflows/deep-dive-instructions.md +297 -0
  426. package/src/xmc/workflows/document-project/workflows/deep-dive-workflow.md +42 -0
  427. package/src/xmc/workflows/document-project/workflows/full-scan-instructions.md +1105 -0
  428. package/src/xmc/workflows/document-project/workflows/full-scan-workflow.md +42 -0
  429. package/src/xmc/workflows/document-project/xiaoma-skill-manifest.yaml +3 -0
  430. package/src/xmc/workflows/generate-project-context/project-context-template.md +21 -0
  431. package/src/xmc/workflows/generate-project-context/steps/step-01-discover.md +184 -0
  432. package/src/xmc/workflows/generate-project-context/steps/step-02-generate.md +318 -0
  433. package/src/xmc/workflows/generate-project-context/steps/step-03-complete.md +278 -0
  434. package/src/xmc/workflows/generate-project-context/workflow.md +49 -0
  435. package/src/xmc/workflows/generate-project-context/xiaoma-skill-manifest.yaml +3 -0
  436. package/src/xmc/workflows/qa-generate-e2e-tests/checklist.md +33 -0
  437. package/src/xmc/workflows/qa-generate-e2e-tests/workflow.md +143 -0
  438. package/src/xmc/workflows/qa-generate-e2e-tests/xiaoma-skill-manifest.yaml +3 -0
  439. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-01-mode-detection.md +174 -0
  440. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-02-context-gathering.md +118 -0
  441. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-03-execute.md +111 -0
  442. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-04-self-check.md +111 -0
  443. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-05-adversarial-review.md +98 -0
  444. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -0
  445. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/workflow.md +50 -0
  446. package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/xiaoma-skill-manifest.yaml +3 -0
  447. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-01-understand.md +189 -0
  448. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-02-investigate.md +143 -0
  449. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-03-generate.md +126 -0
  450. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-04-review.md +198 -0
  451. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/tech-spec-template.md +74 -0
  452. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/workflow.md +79 -0
  453. package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/xiaoma-skill-manifest.yaml +3 -0
  454. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/SKILL.md +6 -0
  455. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-01-clarify-and-route.md +54 -0
  456. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-02-plan.md +39 -0
  457. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-03-implement.md +35 -0
  458. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-04-review.md +55 -0
  459. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-05-present.md +19 -0
  460. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/tech-spec-template.md +90 -0
  461. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/workflow.md +84 -0
  462. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/xiaoma-skill-manifest.yaml +1 -0
  463. package/test/README.md +295 -0
  464. package/test/adversarial-review-tests/README.md +56 -0
  465. package/test/adversarial-review-tests/sample-content.md +46 -0
  466. package/test/adversarial-review-tests/test-cases.yaml +103 -0
  467. package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
  468. package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
  469. package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
  470. package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
  471. package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
  472. package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
  473. package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
  474. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
  475. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
  476. package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
  477. package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
  478. package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
  479. package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
  480. package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
  481. package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
  482. package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
  483. package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
  484. package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
  485. package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
  486. package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
  487. package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
  488. package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
  489. package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
  490. package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
  491. package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
  492. package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
  493. package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
  494. package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
  495. package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
  496. package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
  497. package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
  498. package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
  499. package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
  500. package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
  501. package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
  502. package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
  503. package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
  504. package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +23 -0
  505. package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
  506. package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
  507. package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
  508. package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
  509. package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
  510. package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
  511. package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
  512. package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
  513. package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
  514. package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
  515. package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
  516. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
  517. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
  518. package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
  519. package/test/fixtures/file-refs-csv/invalid/all-empty-workflow.csv +3 -0
  520. package/test/fixtures/file-refs-csv/invalid/empty-data.csv +1 -0
  521. package/test/fixtures/file-refs-csv/invalid/no-workflow-column.csv +3 -0
  522. package/test/fixtures/file-refs-csv/invalid/unresolvable-vars.csv +3 -0
  523. package/test/fixtures/file-refs-csv/valid/core-style.csv +3 -0
  524. package/test/fixtures/file-refs-csv/valid/minimal.csv +2 -0
  525. package/test/fixtures/file-refs-csv/valid/xmc-style.csv +3 -0
  526. package/test/test-agent-schema.js +387 -0
  527. package/test/test-cli-integration.sh +159 -0
  528. package/test/test-file-refs-csv.js +133 -0
  529. package/test/test-install-to-xiaoma.js +154 -0
  530. package/test/test-installation-components.js +1802 -0
  531. package/test/test-rehype-plugins.mjs +1050 -0
  532. package/test/test-workflow-path-regex.js +88 -0
  533. package/test/unit-test-schema.js +133 -0
  534. package/tools/build-docs.mjs +464 -0
  535. package/tools/cli/README.md +60 -0
  536. package/tools/cli/bundlers/bundle-web.js +179 -0
  537. package/tools/cli/bundlers/bundlers/bundle-web.js +179 -0
  538. package/tools/cli/bundlers/bundlers/test-analyst.js +28 -0
  539. package/tools/cli/bundlers/bundlers/test-bundler.js +119 -0
  540. package/tools/cli/bundlers/bundlers/web-bundler.js +1754 -0
  541. package/tools/cli/bundlers/test-analyst.js +28 -0
  542. package/tools/cli/bundlers/test-bundler.js +119 -0
  543. package/tools/cli/bundlers/web-bundler.js +1754 -0
  544. package/tools/cli/commands/agent-install.js +409 -0
  545. package/tools/cli/commands/build.js +458 -0
  546. package/tools/cli/commands/cleanup.js +144 -0
  547. package/tools/cli/commands/install.js +87 -0
  548. package/tools/cli/commands/list.js +43 -0
  549. package/tools/cli/commands/status.js +65 -0
  550. package/tools/cli/commands/uninstall.js +167 -0
  551. package/tools/cli/commands/update.js +28 -0
  552. package/tools/cli/external-official-modules.yaml +53 -0
  553. package/tools/cli/installers/install-messages.yaml +39 -0
  554. package/tools/cli/installers/lib/core/config-collector.js +1285 -0
  555. package/tools/cli/installers/lib/core/custom-module-cache.js +260 -0
  556. package/tools/cli/installers/lib/core/dependency-resolver.js +743 -0
  557. package/tools/cli/installers/lib/core/detector.js +223 -0
  558. package/tools/cli/installers/lib/core/ide-config-manager.js +157 -0
  559. package/tools/cli/installers/lib/core/installer.js +3195 -0
  560. package/tools/cli/installers/lib/core/manifest-generator.js +1374 -0
  561. package/tools/cli/installers/lib/core/manifest.js +1038 -0
  562. package/tools/cli/installers/lib/custom/handler.js +358 -0
  563. package/tools/cli/installers/lib/ide/_base-ide.js +674 -0
  564. package/tools/cli/installers/lib/ide/_config-driven.js +1053 -0
  565. package/tools/cli/installers/lib/ide/antigravity.js +510 -0
  566. package/tools/cli/installers/lib/ide/auggie.js +232 -0
  567. package/tools/cli/installers/lib/ide/claude-code.js +512 -0
  568. package/tools/cli/installers/lib/ide/cline.js +269 -0
  569. package/tools/cli/installers/lib/ide/codex.js +440 -0
  570. package/tools/cli/installers/lib/ide/crush.js +287 -0
  571. package/tools/cli/installers/lib/ide/cursor.js +400 -0
  572. package/tools/cli/installers/lib/ide/gemini.js +253 -0
  573. package/tools/cli/installers/lib/ide/github-copilot.js +699 -0
  574. package/tools/cli/installers/lib/ide/iflow.js +172 -0
  575. package/tools/cli/installers/lib/ide/kilo.js +269 -0
  576. package/tools/cli/installers/lib/ide/manager.js +304 -0
  577. package/tools/cli/installers/lib/ide/opencode.js +257 -0
  578. package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
  579. package/tools/cli/installers/lib/ide/platform-codes.yaml +321 -0
  580. package/tools/cli/installers/lib/ide/qwen.js +372 -0
  581. package/tools/cli/installers/lib/ide/roo.js +324 -0
  582. package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
  583. package/tools/cli/installers/lib/ide/rovodev.js +257 -0
  584. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +181 -0
  585. package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
  586. package/tools/cli/installers/lib/ide/shared/path-utils.js +364 -0
  587. package/tools/cli/installers/lib/ide/shared/skill-manifest.js +90 -0
  588. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +368 -0
  589. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +179 -0
  590. package/tools/cli/installers/lib/ide/shared/xiaoma-artifacts.js +181 -0
  591. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
  592. package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
  593. package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
  594. package/tools/cli/installers/lib/ide/templates/combined/default-task.md +10 -0
  595. package/tools/cli/installers/lib/ide/templates/combined/default-tool.md +10 -0
  596. package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
  597. package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
  598. package/tools/cli/installers/lib/ide/templates/combined/gemini-agent.toml +14 -0
  599. package/tools/cli/installers/lib/ide/templates/combined/gemini-task.toml +11 -0
  600. package/tools/cli/installers/lib/ide/templates/combined/gemini-tool.toml +11 -0
  601. package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow-yaml.toml +16 -0
  602. package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow.toml +14 -0
  603. package/tools/cli/installers/lib/ide/templates/combined/kiro-agent.md +16 -0
  604. package/tools/cli/installers/lib/ide/templates/combined/kiro-task.md +9 -0
  605. package/tools/cli/installers/lib/ide/templates/combined/kiro-tool.md +9 -0
  606. package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow-yaml.md +15 -0
  607. package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow.md +7 -0
  608. package/tools/cli/installers/lib/ide/templates/combined/opencode-agent.md +15 -0
  609. package/tools/cli/installers/lib/ide/templates/combined/opencode-task.md +13 -0
  610. package/tools/cli/installers/lib/ide/templates/combined/opencode-tool.md +13 -0
  611. package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow-yaml.md +16 -0
  612. package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow.md +16 -0
  613. package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
  614. package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
  615. package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
  616. package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
  617. package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
  618. package/tools/cli/installers/lib/ide/templates/split/.gitkeep +0 -0
  619. package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
  620. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
  621. package/tools/cli/installers/lib/ide/trae.js +313 -0
  622. package/tools/cli/installers/lib/ide/windsurf.js +258 -0
  623. package/tools/cli/installers/lib/message-loader.js +83 -0
  624. package/tools/cli/installers/lib/modules/external-manager.js +136 -0
  625. package/tools/cli/installers/lib/modules/manager.js +1382 -0
  626. package/tools/cli/lib/activation-builder.js +165 -0
  627. package/tools/cli/lib/agent/compiler.js +516 -0
  628. package/tools/cli/lib/agent/installer.js +680 -0
  629. package/tools/cli/lib/agent/template-engine.js +152 -0
  630. package/tools/cli/lib/agent-analyzer.js +97 -0
  631. package/tools/cli/lib/agent-party-generator.js +194 -0
  632. package/tools/cli/lib/cli-utils.js +182 -0
  633. package/tools/cli/lib/config.js +213 -0
  634. package/tools/cli/lib/file-ops.js +204 -0
  635. package/tools/cli/lib/platform-codes.js +116 -0
  636. package/tools/cli/lib/project-root.js +77 -0
  637. package/tools/cli/lib/prompts.js +809 -0
  638. package/tools/cli/lib/replace-project-root.js +239 -0
  639. package/tools/cli/lib/ui.js +1940 -0
  640. package/tools/cli/lib/xml-handler.js +177 -0
  641. package/tools/cli/lib/xml-to-markdown.js +82 -0
  642. package/tools/{yaml-format.js → cli/lib/yaml-format.js} +39 -71
  643. package/tools/cli/lib/yaml-xml-builder.js +570 -0
  644. package/tools/cli/regenerate-manifests.js +28 -0
  645. package/tools/cli/test-yaml-builder.js +43 -0
  646. package/tools/cli/xiaoma-cli.js +106 -0
  647. package/tools/docs/_prompt-external-modules-page.md +59 -0
  648. package/tools/docs/fix-refs.md +91 -0
  649. package/tools/docs/native-skills-migration-checklist.md +281 -0
  650. package/tools/fix-doc-links.js +285 -0
  651. package/tools/flattener/aggregate.js +12 -30
  652. package/tools/flattener/binary.js +43 -46
  653. package/tools/flattener/discovery.js +15 -23
  654. package/tools/flattener/files.js +6 -6
  655. package/tools/flattener/flattener/aggregate.js +76 -0
  656. package/tools/flattener/flattener/binary.js +80 -0
  657. package/tools/flattener/flattener/discovery.js +71 -0
  658. package/tools/flattener/flattener/files.js +35 -0
  659. package/tools/flattener/flattener/ignoreRules.js +172 -0
  660. package/tools/flattener/flattener/main.js +483 -0
  661. package/tools/flattener/flattener/projectRoot.js +201 -0
  662. package/tools/flattener/flattener/prompts.js +44 -0
  663. package/tools/flattener/flattener/stats.helpers.js +368 -0
  664. package/tools/flattener/flattener/stats.js +75 -0
  665. package/tools/flattener/flattener/test-matrix.js +409 -0
  666. package/tools/flattener/flattener/xml.js +88 -0
  667. package/tools/flattener/ignoreRules.js +122 -127
  668. package/tools/flattener/main.js +140 -330
  669. package/tools/flattener/projectRoot.js +71 -81
  670. package/tools/flattener/prompts.js +10 -12
  671. package/tools/flattener/stats.helpers.js +63 -119
  672. package/tools/flattener/stats.js +2 -7
  673. package/tools/flattener/test-matrix.js +169 -228
  674. package/tools/flattener/xml.js +23 -31
  675. package/tools/format-workflow-md.js +263 -0
  676. package/tools/lib/xml-utils.js +13 -0
  677. package/tools/migrate-custom-module-paths.js +124 -0
  678. package/tools/platform-codes.yaml +157 -0
  679. package/tools/schema/agent.js +489 -0
  680. package/tools/validate-agent-schema.js +110 -0
  681. package/tools/validate-bundles.js +87 -0
  682. package/tools/validate-doc-links.js +409 -0
  683. package/tools/validate-file-refs.js +556 -0
  684. package/tools/validate-svg-changes.sh +356 -0
  685. package/tools/xiaoma-npx-wrapper.js +18 -24
  686. package/web-bundles/xmc/agents/analyst.xml +109 -0
  687. package/web-bundles/xmc/agents/architect.xml +101 -0
  688. package/web-bundles/xmc/agents/dev.xml +106 -0
  689. package/web-bundles/xmc/agents/pm.xml +112 -0
  690. package/web-bundles/xmc/agents/qa.xml +126 -0
  691. package/web-bundles/xmc/agents/quick-flow-solo-dev.xml +104 -0
  692. package/web-bundles/xmc/agents/sm.xml +109 -0
  693. package/web-bundles/xmc/agents/ux-designer.xml +100 -0
  694. package/web-bundles/xmc/teams/team-fullstack.xml +1192 -0
  695. package/.claude/agents/tech-translator.md +0 -124
  696. package/.claude/settings.local.json +0 -37
  697. package/.idea/misc.xml +0 -6
  698. package/.xiaoma-core/.coordinator-state.json +0 -19
  699. package/CLAUDE.md +0 -283
  700. package/JAVA-BACKEND-COMMANDS-REFERENCE.md +0 -300
  701. package/JAVA-BACKEND-ITERATION-GUIDE.md +0 -2116
  702. package/common/tasks/create-doc.md +0 -103
  703. package/common/tasks/execute-checklist.md +0 -88
  704. package/common/utils/bmad-doc-template.md +0 -327
  705. package/common/utils/workflow-management.md +0 -71
  706. package/dist/agents/analyst.txt +0 -6308
  707. package/dist/agents/architect.txt +0 -5046
  708. package/dist/agents/automation-orchestrator.txt +0 -396
  709. package/dist/agents/dev.txt +0 -1180
  710. package/dist/agents/full-requirement-orchestrator.txt +0 -505
  711. package/dist/agents/pm.txt +0 -3078
  712. package/dist/agents/po.txt +0 -1358
  713. package/dist/agents/qa.txt +0 -2002
  714. package/dist/agents/sm.txt +0 -3044
  715. package/dist/agents/ux-expert.txt +0 -707
  716. package/dist/agents/workflow-executor.txt +0 -1029
  717. package/dist/agents/workflow-helper.txt +0 -93
  718. package/dist/agents/xiaoma-master.txt +0 -9008
  719. package/dist/agents/xiaoma-orchestrator.txt +0 -1523
  720. package/dist/teams/team-all.txt +0 -23101
  721. package/dist/teams/team-fullstack-with-database.txt +0 -25076
  722. package/dist/teams/team-fullstack.txt +0 -15820
  723. package/dist/teams/team-ide-minimal.txt +0 -8285
  724. package/dist/teams/team-no-ui.txt +0 -14368
  725. package/docs/GUIDING-PRINCIPLES.md +0 -91
  726. package/docs/architecture/workflow-coordinator-implementation.md +0 -1188
  727. package/docs/architecture-sharding-modification.md +0 -623
  728. package/docs/automated-requirements-analysis-outputs.md +0 -896
  729. package/docs/core-architecture.md +0 -219
  730. package/docs/enhanced-ide-development-workflow.md +0 -248
  731. package/docs/prd/workflow-coordinator-prd.md +0 -1214
  732. package/docs/user-guide.md +0 -530
  733. package/docs/versioning-and-releases.md +0 -155
  734. package/docs/versions.md +0 -48
  735. package/docs/working-in-the-brownfield.md +0 -597
  736. package/tools/api-server.js +0 -367
  737. package/tools/builders/web-builder.js +0 -830
  738. package/tools/bump-all-versions.js +0 -133
  739. package/tools/cli.js +0 -157
  740. package/tools/installer/README.md +0 -8
  741. package/tools/installer/bin/xiaoma.js +0 -477
  742. package/tools/installer/config/ide-agent-config.yaml +0 -58
  743. package/tools/installer/config/install.config.yaml +0 -164
  744. package/tools/installer/lib/config-loader.js +0 -286
  745. package/tools/installer/lib/file-manager.js +0 -446
  746. package/tools/installer/lib/ide-base-setup.js +0 -238
  747. package/tools/installer/lib/ide-setup.js +0 -2027
  748. package/tools/installer/lib/installer.js +0 -2333
  749. package/tools/installer/lib/memory-profiler.js +0 -235
  750. package/tools/installer/lib/module-manager.js +0 -116
  751. package/tools/installer/lib/resource-locator.js +0 -334
  752. package/tools/installer/package-lock.json +0 -715
  753. package/tools/installer/package.json +0 -44
  754. package/tools/lib/dependency-resolver.js +0 -186
  755. package/tools/lib/yaml-utils.js +0 -34
  756. package/tools/md-assets/web-agent-startup-instructions.md +0 -39
  757. package/tools/preview-release-notes.js +0 -74
  758. package/tools/setup-hooks.sh +0 -37
  759. package/tools/shared/bannerArt.js +0 -105
  760. package/tools/sync-installer-version.js +0 -41
  761. package/tools/sync-version.sh +0 -23
  762. package/tools/upgraders/v3-to-v4-upgrader.js +0 -753
  763. package/tools/version-bump.js +0 -100
  764. package/tools/workflow-coordinator/README.md +0 -38
  765. package/tools/workflow-coordinator/USAGE.md +0 -548
  766. package/tools/workflow-coordinator/package-lock.json +0 -4868
  767. package/tools/workflow-coordinator/package.json +0 -35
  768. package/tools/workflow-coordinator/src/api/server.js +0 -207
  769. package/tools/workflow-coordinator/src/controller/workflow-controller.js +0 -263
  770. package/tools/workflow-coordinator/src/index.js +0 -113
  771. package/tools/workflow-coordinator/src/parser/workflow-parser.js +0 -144
  772. package/tools/workflow-coordinator/src/utils/state-manager.js +0 -59
  773. package/tools/workflow-coordinator/src/utils/validator.js +0 -86
  774. package/tools/workflow-coordinator/test/integration-test.js +0 -266
  775. package/tools/workflow-coordinator/test/quick-test.js +0 -127
  776. package/xiaoma-core/agent-teams/team-all.yaml +0 -15
  777. package/xiaoma-core/agent-teams/team-fullstack-with-database.yaml +0 -27
  778. package/xiaoma-core/agent-teams/team-fullstack.yaml +0 -19
  779. package/xiaoma-core/agent-teams/team-ide-minimal.yaml +0 -11
  780. package/xiaoma-core/agent-teams/team-no-ui.yaml +0 -14
  781. package/xiaoma-core/agents/analyst.md +0 -91
  782. package/xiaoma-core/agents/architect.md +0 -88
  783. package/xiaoma-core/agents/automated-fix-validator.yaml +0 -579
  784. package/xiaoma-core/agents/automated-quality-validator.yaml +0 -549
  785. package/xiaoma-core/agents/automation-orchestrator.md +0 -353
  786. package/xiaoma-core/agents/dev.md +0 -144
  787. package/xiaoma-core/agents/enhanced-workflow-orchestrator.yaml +0 -304
  788. package/xiaoma-core/agents/full-requirement-orchestrator.md +0 -462
  789. package/xiaoma-core/agents/global-requirements-auditor.yaml +0 -520
  790. package/xiaoma-core/agents/intelligent-template-adapter.yaml +0 -389
  791. package/xiaoma-core/agents/issue-dispatcher.yaml +0 -627
  792. package/xiaoma-core/agents/master-execution-engine.yaml +0 -543
  793. package/xiaoma-core/agents/pm.md +0 -85
  794. package/xiaoma-core/agents/po.md +0 -77
  795. package/xiaoma-core/agents/qa.md +0 -88
  796. package/xiaoma-core/agents/requirements-coverage-auditor.yaml +0 -373
  797. package/xiaoma-core/agents/sm.md +0 -125
  798. package/xiaoma-core/agents/ux-expert.md +0 -67
  799. package/xiaoma-core/agents/workflow-executor.md +0 -1031
  800. package/xiaoma-core/agents/workflow-helper.md +0 -481
  801. package/xiaoma-core/agents/xiaoma-master.md +0 -108
  802. package/xiaoma-core/agents/xiaoma-orchestrator.md +0 -145
  803. package/xiaoma-core/checklists/architect-checklist.md +0 -440
  804. package/xiaoma-core/checklists/change-checklist.md +0 -184
  805. package/xiaoma-core/checklists/dev-completion-checklist.md +0 -324
  806. package/xiaoma-core/checklists/pm-checklist.md +0 -372
  807. package/xiaoma-core/checklists/po-master-checklist.md +0 -434
  808. package/xiaoma-core/checklists/po-story-validation-checklist.md +0 -219
  809. package/xiaoma-core/checklists/qa-approval-checklist.md +0 -393
  810. package/xiaoma-core/checklists/story-dod-checklist.md +0 -96
  811. package/xiaoma-core/checklists/story-draft-checklist.md +0 -155
  812. package/xiaoma-core/core-config.yaml +0 -23
  813. package/xiaoma-core/data/bmad-kb.md +0 -809
  814. package/xiaoma-core/data/brainstorming-techniques.md +0 -38
  815. package/xiaoma-core/data/elicitation-methods.md +0 -156
  816. package/xiaoma-core/data/technical-preferences.md +0 -5
  817. package/xiaoma-core/data/test-levels-framework.md +0 -148
  818. package/xiaoma-core/data/test-priorities-matrix.md +0 -174
  819. package/xiaoma-core/scripts/build-validation/pre-dev-validation.sh +0 -71
  820. package/xiaoma-core/scripts/build-validation/progressive-validation.sh +0 -88
  821. package/xiaoma-core/scripts/build-validation/quick-check.sh +0 -69
  822. package/xiaoma-core/tasks/advanced-elicitation.md +0 -119
  823. package/xiaoma-core/tasks/analyze-existing-database.md +0 -155
  824. package/xiaoma-core/tasks/apply-qa-fixes.md +0 -150
  825. package/xiaoma-core/tasks/automated-story-cycle.md +0 -370
  826. package/xiaoma-core/tasks/batch-story-generation.md +0 -354
  827. package/xiaoma-core/tasks/brownfield-create-epic.md +0 -162
  828. package/xiaoma-core/tasks/brownfield-create-story.md +0 -149
  829. package/xiaoma-core/tasks/correct-course.md +0 -72
  830. package/xiaoma-core/tasks/create-brownfield-story.md +0 -314
  831. package/xiaoma-core/tasks/create-database-design.md +0 -161
  832. package/xiaoma-core/tasks/create-deep-research-prompt.md +0 -280
  833. package/xiaoma-core/tasks/create-enhanced-story-with-database.md +0 -250
  834. package/xiaoma-core/tasks/create-incremental-architecture.md +0 -525
  835. package/xiaoma-core/tasks/create-next-story.md +0 -114
  836. package/xiaoma-core/tasks/create-prd-from-rag.md +0 -435
  837. package/xiaoma-core/tasks/create-story-with-rag.md +0 -559
  838. package/xiaoma-core/tasks/develop-story-with-rag.md +0 -536
  839. package/xiaoma-core/tasks/document-project.md +0 -345
  840. package/xiaoma-core/tasks/facilitate-brainstorming-session.md +0 -138
  841. package/xiaoma-core/tasks/generate-ai-frontend-prompt.md +0 -53
  842. package/xiaoma-core/tasks/generate-database-ddl.md +0 -240
  843. package/xiaoma-core/tasks/generate-database-entities.md +0 -501
  844. package/xiaoma-core/tasks/generate-rag-questions.md +0 -312
  845. package/xiaoma-core/tasks/index-docs.md +0 -175
  846. package/xiaoma-core/tasks/kb-mode-interaction.md +0 -77
  847. package/xiaoma-core/tasks/nfr-assess.md +0 -345
  848. package/xiaoma-core/tasks/project-integration-testing.md +0 -477
  849. package/xiaoma-core/tasks/qa-gate.md +0 -163
  850. package/xiaoma-core/tasks/requirement-analysis-with-rag.md +0 -1318
  851. package/xiaoma-core/tasks/requirements-coverage-audit.md +0 -198
  852. package/xiaoma-core/tasks/review-story.md +0 -316
  853. package/xiaoma-core/tasks/risk-profile.md +0 -355
  854. package/xiaoma-core/tasks/serial-development-orchestration.md +0 -426
  855. package/xiaoma-core/tasks/shard-doc.md +0 -187
  856. package/xiaoma-core/tasks/test-design.md +0 -176
  857. package/xiaoma-core/tasks/trace-requirements.md +0 -266
  858. package/xiaoma-core/tasks/validate-next-story.md +0 -136
  859. package/xiaoma-core/templates/api-design-tmpl.yaml +0 -704
  860. package/xiaoma-core/templates/architecture-tmpl.yaml +0 -650
  861. package/xiaoma-core/templates/brainstorming-output-tmpl.yaml +0 -156
  862. package/xiaoma-core/templates/brownfield-architecture-tmpl.yaml +0 -476
  863. package/xiaoma-core/templates/brownfield-prd-tmpl.yaml +0 -280
  864. package/xiaoma-core/templates/competitor-analysis-tmpl.yaml +0 -336
  865. package/xiaoma-core/templates/database-design-tmpl.yaml +0 -266
  866. package/xiaoma-core/templates/enhanced-story-with-database-tmpl.yaml +0 -428
  867. package/xiaoma-core/templates/front-end-architecture-tmpl.yaml +0 -272
  868. package/xiaoma-core/templates/front-end-spec-tmpl.yaml +0 -354
  869. package/xiaoma-core/templates/fullstack-architecture-tmpl.yaml +0 -925
  870. package/xiaoma-core/templates/global-qa-monitoring-tmpl.yaml +0 -443
  871. package/xiaoma-core/templates/incremental-architecture-tmpl.yaml +0 -601
  872. package/xiaoma-core/templates/market-research-tmpl.yaml +0 -252
  873. package/xiaoma-core/templates/maven-lombok-template.xml +0 -111
  874. package/xiaoma-core/templates/prd-from-rag-tmpl.yaml +0 -410
  875. package/xiaoma-core/templates/prd-tmpl.yaml +0 -202
  876. package/xiaoma-core/templates/project-brief-tmpl.yaml +0 -221
  877. package/xiaoma-core/templates/qa-gate-tmpl.yaml +0 -102
  878. package/xiaoma-core/templates/rag-knowledge-tmpl.yaml +0 -569
  879. package/xiaoma-core/templates/rag-questions-tmpl.yaml +0 -949
  880. package/xiaoma-core/templates/requirements-coverage-audit.yaml +0 -330
  881. package/xiaoma-core/templates/start-enhanced-workflow.yaml +0 -347
  882. package/xiaoma-core/templates/story-tmpl.yaml +0 -137
  883. package/xiaoma-core/templates/story-with-rag-tmpl.yaml +0 -360
  884. package/xiaoma-core/workflows/automated-requirements-analysis.yaml +0 -2149
  885. package/xiaoma-core/workflows/automated-requirements-development.yaml +0 -739
  886. package/xiaoma-core/workflows/automated-story-development.yaml +0 -1264
  887. package/xiaoma-core/workflows/brownfield-fullstack.yaml +0 -298
  888. package/xiaoma-core/workflows/brownfield-service.yaml +0 -188
  889. package/xiaoma-core/workflows/brownfield-ui.yaml +0 -198
  890. package/xiaoma-core/workflows/enhanced-fullstack-with-database.yaml +0 -427
  891. package/xiaoma-core/workflows/enhanced-fullstack-with-qa-loop.yaml +0 -766
  892. package/xiaoma-core/workflows/full-requirement-automation.yaml +0 -1305
  893. package/xiaoma-core/workflows/greenfield-fullstack.yaml +0 -241
  894. package/xiaoma-core/workflows/greenfield-service.yaml +0 -207
  895. package/xiaoma-core/workflows/greenfield-ui.yaml +0 -236
@@ -0,0 +1,1382 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const yaml = require('yaml');
4
+ const prompts = require('../../../lib/prompts');
5
+ const { XmlHandler } = require('../../../lib/xml-handler');
6
+ const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
7
+ const { filterCustomizationData } = require('../../../lib/agent/compiler');
8
+ const { ExternalModuleManager } = require('./external-manager');
9
+ const { XiaoMa_FOLDER_NAME } = require('../ide/shared/path-utils');
10
+
11
+ /**
12
+ * Manages the installation, updating, and removal of XiaoMa modules.
13
+ * Handles module discovery, dependency resolution, configuration processing,
14
+ * and agent file management including XML activation block injection.
15
+ *
16
+ * @class ModuleManager
17
+ * @requires fs-extra
18
+ * @requires yaml
19
+ * @requires prompts
20
+ * @requires XmlHandler
21
+ *
22
+ * @example
23
+ * const manager = new ModuleManager();
24
+ * const modules = await manager.listAvailable();
25
+ * await manager.install('core-module', '/path/to/xiaoma');
26
+ */
27
+ class ModuleManager {
28
+ constructor(options = {}) {
29
+ this.xmlHandler = new XmlHandler();
30
+ this.xiaomaFolderName = XiaoMa_FOLDER_NAME; // Default, can be overridden
31
+ this.customModulePaths = new Map(); // Initialize custom module paths
32
+ this.externalModuleManager = new ExternalModuleManager(); // For external official modules
33
+ }
34
+
35
+ /**
36
+ * Set the xiaoma folder name for placeholder replacement
37
+ * @param {string} xiaomaFolderName - The xiaoma folder name
38
+ */
39
+ setXiaoMaFolderName(xiaomaFolderName) {
40
+ this.xiaomaFolderName = xiaomaFolderName;
41
+ }
42
+
43
+ /**
44
+ * Set the core configuration for access during module installation
45
+ * @param {Object} coreConfig - Core configuration object
46
+ */
47
+ setCoreConfig(coreConfig) {
48
+ this.coreConfig = coreConfig;
49
+ }
50
+
51
+ /**
52
+ * Set custom module paths for priority lookup
53
+ * @param {Map<string, string>} customModulePaths - Map of module ID to source path
54
+ */
55
+ setCustomModulePaths(customModulePaths) {
56
+ this.customModulePaths = customModulePaths;
57
+ }
58
+
59
+ /**
60
+ * Copy a file to the target location
61
+ * @param {string} sourcePath - Source file path
62
+ * @param {string} targetPath - Target file path
63
+ * @param {boolean} overwrite - Whether to overwrite existing files (default: true)
64
+ */
65
+ async copyFileWithPlaceholderReplacement(sourcePath, targetPath, overwrite = true) {
66
+ await fs.copy(sourcePath, targetPath, { overwrite });
67
+ }
68
+
69
+ /**
70
+ * Copy a directory recursively
71
+ * @param {string} sourceDir - Source directory path
72
+ * @param {string} targetDir - Target directory path
73
+ * @param {boolean} overwrite - Whether to overwrite existing files (default: true)
74
+ */
75
+ async copyDirectoryWithPlaceholderReplacement(sourceDir, targetDir, overwrite = true) {
76
+ await fs.ensureDir(targetDir);
77
+ const entries = await fs.readdir(sourceDir, { withFileTypes: true });
78
+
79
+ for (const entry of entries) {
80
+ const sourcePath = path.join(sourceDir, entry.name);
81
+ const targetPath = path.join(targetDir, entry.name);
82
+
83
+ if (entry.isDirectory()) {
84
+ await this.copyDirectoryWithPlaceholderReplacement(sourcePath, targetPath, overwrite);
85
+ } else {
86
+ await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath, overwrite);
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Copy sidecar directory to _xiaoma/_memory location with update-safe handling
93
+ * @param {string} sourceSidecarPath - Source sidecar directory path
94
+ * @param {string} agentName - Name of the agent (for naming)
95
+ * @param {string} xiaomaMemoryPath - This should ALWAYS be _xiaoma/_memory
96
+ * @param {boolean} isUpdate - Whether this is an update (default: false)
97
+ * @param {string} xiaomaDir - XiaoMa installation directory
98
+ * @param {Object} installer - Installer instance for file tracking
99
+ */
100
+ async copySidecarToMemory(sourceSidecarPath, agentName, xiaomaMemoryPath, isUpdate = false, xiaomaDir = null, installer = null) {
101
+ const crypto = require('node:crypto');
102
+ const sidecarTargetDir = path.join(xiaomaMemoryPath, `${agentName}-sidecar`);
103
+
104
+ // Ensure target directory exists
105
+ await fs.ensureDir(xiaomaMemoryPath);
106
+ await fs.ensureDir(sidecarTargetDir);
107
+
108
+ // Get existing files manifest for update checking
109
+ let existingFilesManifest = [];
110
+ if (isUpdate && installer) {
111
+ existingFilesManifest = await installer.readFilesManifest(xiaomaDir);
112
+ }
113
+
114
+ // Build map of existing sidecar files with their hashes
115
+ const existingSidecarFiles = new Map();
116
+ for (const fileEntry of existingFilesManifest) {
117
+ if (fileEntry.path && fileEntry.path.includes(`${agentName}-sidecar/`)) {
118
+ existingSidecarFiles.set(fileEntry.path, fileEntry.hash);
119
+ }
120
+ }
121
+
122
+ // Get all files in source sidecar
123
+ const sourceFiles = await this.getFileList(sourceSidecarPath);
124
+
125
+ for (const file of sourceFiles) {
126
+ const sourceFilePath = path.join(sourceSidecarPath, file);
127
+ const targetFilePath = path.join(sidecarTargetDir, file);
128
+
129
+ // Calculate current source file hash
130
+ const sourceHash = crypto
131
+ .createHash('sha256')
132
+ .update(await fs.readFile(sourceFilePath))
133
+ .digest('hex');
134
+
135
+ // Path relative to xiaoma directory
136
+ const relativeToXiaoMa = path.join('_memory', `${agentName}-sidecar`, file);
137
+
138
+ if (isUpdate && (await fs.pathExists(targetFilePath))) {
139
+ // Calculate current target file hash
140
+ const currentTargetHash = crypto
141
+ .createHash('sha256')
142
+ .update(await fs.readFile(targetFilePath))
143
+ .digest('hex');
144
+
145
+ // Get the last known hash from files-manifest
146
+ const lastKnownHash = existingSidecarFiles.get(relativeToXiaoMa);
147
+
148
+ if (lastKnownHash) {
149
+ // We have a record of this file
150
+ if (currentTargetHash === lastKnownHash) {
151
+ // File hasn't been modified by user, safe to update
152
+ await this.copyFileWithPlaceholderReplacement(sourceFilePath, targetFilePath, true);
153
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
154
+ await prompts.log.message(` Updated sidecar file: ${relativeToXiaoMa}`);
155
+ }
156
+ } else {
157
+ // User has modified the file, preserve it
158
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
159
+ await prompts.log.message(` Preserving user-modified file: ${relativeToXiaoMa}`);
160
+ }
161
+ }
162
+ } else {
163
+ // First time seeing this file in manifest, copy it
164
+ await this.copyFileWithPlaceholderReplacement(sourceFilePath, targetFilePath, true);
165
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
166
+ await prompts.log.message(` Added new sidecar file: ${relativeToXiaoMa}`);
167
+ }
168
+ }
169
+ } else {
170
+ // New installation
171
+ await this.copyFileWithPlaceholderReplacement(sourceFilePath, targetFilePath, true);
172
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
173
+ await prompts.log.message(` Copied sidecar file: ${relativeToXiaoMa}`);
174
+ }
175
+ }
176
+
177
+ // Track the file in the installer's file tracking system
178
+ if (installer && installer.installedFiles) {
179
+ installer.installedFiles.add(targetFilePath);
180
+ }
181
+ }
182
+
183
+ // Return list of files that were processed
184
+ const processedFiles = sourceFiles.map((file) => path.join('_memory', `${agentName}-sidecar`, file));
185
+ return processedFiles;
186
+ }
187
+
188
+ /**
189
+ * List all available modules (excluding core which is always installed)
190
+ * xmc is the only built-in module, directly under src/xmc
191
+ * All other modules come from external-official-modules.yaml
192
+ * @returns {Object} Object with modules array and customModules array
193
+ */
194
+ async listAvailable() {
195
+ const modules = [];
196
+ const customModules = [];
197
+
198
+ // Add built-in xmc module (directly under src/xmc)
199
+ const xmcPath = getSourcePath('xmc');
200
+ if (await fs.pathExists(xmcPath)) {
201
+ const xmcInfo = await this.getModuleInfo(xmcPath, 'xmc', 'src/xmc');
202
+ if (xmcInfo) {
203
+ modules.push(xmcInfo);
204
+ }
205
+ }
206
+
207
+ // Check for cached custom modules in _config/custom/
208
+ if (this.xiaomaDir) {
209
+ const customCacheDir = path.join(this.xiaomaDir, '_config', 'custom');
210
+ if (await fs.pathExists(customCacheDir)) {
211
+ const cacheEntries = await fs.readdir(customCacheDir, { withFileTypes: true });
212
+ for (const entry of cacheEntries) {
213
+ if (entry.isDirectory()) {
214
+ const cachePath = path.join(customCacheDir, entry.name);
215
+ const moduleInfo = await this.getModuleInfo(cachePath, entry.name, '_config/custom');
216
+ if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) {
217
+ moduleInfo.isCustom = true;
218
+ moduleInfo.fromCache = true;
219
+ customModules.push(moduleInfo);
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ return { modules, customModules };
227
+ }
228
+
229
+ /**
230
+ * Get module information from a module path
231
+ * @param {string} modulePath - Path to the module directory
232
+ * @param {string} defaultName - Default name for the module
233
+ * @param {string} sourceDescription - Description of where the module was found
234
+ * @returns {Object|null} Module info or null if not a valid module
235
+ */
236
+ async getModuleInfo(modulePath, defaultName, sourceDescription) {
237
+ // Check for module structure (module.yaml OR custom.yaml)
238
+ const moduleConfigPath = path.join(modulePath, 'module.yaml');
239
+ const rootCustomConfigPath = path.join(modulePath, 'custom.yaml');
240
+ let configPath = null;
241
+
242
+ if (await fs.pathExists(moduleConfigPath)) {
243
+ configPath = moduleConfigPath;
244
+ } else if (await fs.pathExists(rootCustomConfigPath)) {
245
+ configPath = rootCustomConfigPath;
246
+ }
247
+
248
+ // Skip if this doesn't look like a module
249
+ if (!configPath) {
250
+ return null;
251
+ }
252
+
253
+ // Mark as custom if it's using custom.yaml OR if it's outside src/xmc or src/core
254
+ const isCustomSource = sourceDescription !== 'src/xmc' && sourceDescription !== 'src/core' && sourceDescription !== 'src/modules';
255
+ const moduleInfo = {
256
+ id: defaultName,
257
+ path: modulePath,
258
+ name: defaultName
259
+ .split('-')
260
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
261
+ .join(' '),
262
+ description: 'XiaoMa Module',
263
+ version: '5.0.0',
264
+ source: sourceDescription,
265
+ isCustom: configPath === rootCustomConfigPath || isCustomSource,
266
+ };
267
+
268
+ // Read module config for metadata
269
+ try {
270
+ const configContent = await fs.readFile(configPath, 'utf8');
271
+ const config = yaml.parse(configContent);
272
+
273
+ // Use the code property as the id if available
274
+ if (config.code) {
275
+ moduleInfo.id = config.code;
276
+ }
277
+
278
+ moduleInfo.name = config.name || moduleInfo.name;
279
+ moduleInfo.description = config.description || moduleInfo.description;
280
+ moduleInfo.version = config.version || moduleInfo.version;
281
+ moduleInfo.dependencies = config.dependencies || [];
282
+ moduleInfo.defaultSelected = config.default_selected === undefined ? false : config.default_selected;
283
+ } catch (error) {
284
+ await prompts.log.warn(`Failed to read config for ${defaultName}: ${error.message}`);
285
+ }
286
+
287
+ return moduleInfo;
288
+ }
289
+
290
+ /**
291
+ * Find the source path for a module by searching all possible locations
292
+ * @param {string} moduleCode - Code of the module to find (from module.yaml)
293
+ * @returns {string|null} Path to the module source or null if not found
294
+ */
295
+ async findModuleSource(moduleCode, options = {}) {
296
+ const projectRoot = getProjectRoot();
297
+
298
+ // First check custom module paths if they exist
299
+ if (this.customModulePaths && this.customModulePaths.has(moduleCode)) {
300
+ return this.customModulePaths.get(moduleCode);
301
+ }
302
+
303
+ // Check for built-in xmc module (directly under src/xmc)
304
+ if (moduleCode === 'xmc') {
305
+ const xmcPath = getSourcePath('xmc');
306
+ if (await fs.pathExists(xmcPath)) {
307
+ return xmcPath;
308
+ }
309
+ }
310
+
311
+ // Check external official modules
312
+ const externalSource = await this.findExternalModuleSource(moduleCode, options);
313
+ if (externalSource) {
314
+ return externalSource;
315
+ }
316
+
317
+ return null;
318
+ }
319
+
320
+ /**
321
+ * Check if a module is an external official module
322
+ * @param {string} moduleCode - Code of the module to check
323
+ * @returns {boolean} True if the module is external
324
+ */
325
+ async isExternalModule(moduleCode) {
326
+ return await this.externalModuleManager.hasModule(moduleCode);
327
+ }
328
+
329
+ /**
330
+ * Get the cache directory for external modules
331
+ * @returns {string} Path to the external modules cache directory
332
+ */
333
+ getExternalCacheDir() {
334
+ const os = require('node:os');
335
+ const cacheDir = path.join(os.homedir(), '.xiaoma', 'cache', 'external-modules');
336
+ return cacheDir;
337
+ }
338
+
339
+ /**
340
+ * Clone an external module repository to cache
341
+ * @param {string} moduleCode - Code of the external module
342
+ * @returns {string} Path to the cloned repository
343
+ */
344
+ async cloneExternalModule(moduleCode, options = {}) {
345
+ const { execSync } = require('node:child_process');
346
+ const moduleInfo = await this.externalModuleManager.getModuleByCode(moduleCode);
347
+
348
+ if (!moduleInfo) {
349
+ throw new Error(`External module '${moduleCode}' not found in external-official-modules.yaml`);
350
+ }
351
+
352
+ const cacheDir = this.getExternalCacheDir();
353
+ const moduleCacheDir = path.join(cacheDir, moduleCode);
354
+ const silent = options.silent || false;
355
+
356
+ // Create cache directory if it doesn't exist
357
+ await fs.ensureDir(cacheDir);
358
+
359
+ // Helper to create a spinner or a no-op when silent
360
+ const createSpinner = async () => {
361
+ if (silent) {
362
+ return {
363
+ start() {},
364
+ stop() {},
365
+ error() {},
366
+ message() {},
367
+ cancel() {},
368
+ clear() {},
369
+ get isSpinning() {
370
+ return false;
371
+ },
372
+ get isCancelled() {
373
+ return false;
374
+ },
375
+ };
376
+ }
377
+ return await prompts.spinner();
378
+ };
379
+
380
+ // Track if we need to install dependencies
381
+ let needsDependencyInstall = false;
382
+ let wasNewClone = false;
383
+
384
+ // Check if already cloned
385
+ if (await fs.pathExists(moduleCacheDir)) {
386
+ // Try to update if it's a git repo
387
+ const fetchSpinner = await createSpinner();
388
+ fetchSpinner.start(`Fetching ${moduleInfo.name}...`);
389
+ try {
390
+ const currentRef = execSync('git rev-parse HEAD', { cwd: moduleCacheDir, stdio: 'pipe' }).toString().trim();
391
+ // Fetch and reset to remote - works better with shallow clones than pull
392
+ execSync('git fetch origin --depth 1', {
393
+ cwd: moduleCacheDir,
394
+ stdio: ['ignore', 'pipe', 'pipe'],
395
+ env: { ...process.env, GIT_TERMINAL_PROMPT: '0' },
396
+ });
397
+ execSync('git reset --hard origin/HEAD', {
398
+ cwd: moduleCacheDir,
399
+ stdio: ['ignore', 'pipe', 'pipe'],
400
+ env: { ...process.env, GIT_TERMINAL_PROMPT: '0' },
401
+ });
402
+ const newRef = execSync('git rev-parse HEAD', { cwd: moduleCacheDir, stdio: 'pipe' }).toString().trim();
403
+
404
+ fetchSpinner.stop(`Fetched ${moduleInfo.name}`);
405
+ // Force dependency install if we got new code
406
+ if (currentRef !== newRef) {
407
+ needsDependencyInstall = true;
408
+ }
409
+ } catch {
410
+ fetchSpinner.error(`Fetch failed, re-downloading ${moduleInfo.name}`);
411
+ // If update fails, remove and re-clone
412
+ await fs.remove(moduleCacheDir);
413
+ wasNewClone = true;
414
+ }
415
+ } else {
416
+ wasNewClone = true;
417
+ }
418
+
419
+ // Clone if not exists or was removed
420
+ if (wasNewClone) {
421
+ const fetchSpinner = await createSpinner();
422
+ fetchSpinner.start(`Fetching ${moduleInfo.name}...`);
423
+ try {
424
+ execSync(`git clone --depth 1 "${moduleInfo.url}" "${moduleCacheDir}"`, {
425
+ stdio: ['ignore', 'pipe', 'pipe'],
426
+ env: { ...process.env, GIT_TERMINAL_PROMPT: '0' },
427
+ });
428
+ fetchSpinner.stop(`Fetched ${moduleInfo.name}`);
429
+ } catch (error) {
430
+ fetchSpinner.error(`Failed to fetch ${moduleInfo.name}`);
431
+ throw new Error(`Failed to clone external module '${moduleCode}': ${error.message}`);
432
+ }
433
+ }
434
+
435
+ // Install dependencies if package.json exists
436
+ const packageJsonPath = path.join(moduleCacheDir, 'package.json');
437
+ const nodeModulesPath = path.join(moduleCacheDir, 'node_modules');
438
+ if (await fs.pathExists(packageJsonPath)) {
439
+ // Install if node_modules doesn't exist, or if package.json is newer (dependencies changed)
440
+ const nodeModulesMissing = !(await fs.pathExists(nodeModulesPath));
441
+
442
+ // Force install if we updated or cloned new
443
+ if (needsDependencyInstall || wasNewClone || nodeModulesMissing) {
444
+ const installSpinner = await createSpinner();
445
+ installSpinner.start(`Installing dependencies for ${moduleInfo.name}...`);
446
+ try {
447
+ execSync('npm install --omit=dev --no-audit --no-fund --no-progress --legacy-peer-deps', {
448
+ cwd: moduleCacheDir,
449
+ stdio: ['ignore', 'pipe', 'pipe'],
450
+ timeout: 120_000, // 2 minute timeout
451
+ });
452
+ installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`);
453
+ } catch (error) {
454
+ installSpinner.error(`Failed to install dependencies for ${moduleInfo.name}`);
455
+ if (!silent) await prompts.log.warn(` ${error.message}`);
456
+ }
457
+ } else {
458
+ // Check if package.json is newer than node_modules
459
+ let packageJsonNewer = false;
460
+ try {
461
+ const packageStats = await fs.stat(packageJsonPath);
462
+ const nodeModulesStats = await fs.stat(nodeModulesPath);
463
+ packageJsonNewer = packageStats.mtime > nodeModulesStats.mtime;
464
+ } catch {
465
+ // If stat fails, assume we need to install
466
+ packageJsonNewer = true;
467
+ }
468
+
469
+ if (packageJsonNewer) {
470
+ const installSpinner = await createSpinner();
471
+ installSpinner.start(`Installing dependencies for ${moduleInfo.name}...`);
472
+ try {
473
+ execSync('npm install --omit=dev --no-audit --no-fund --no-progress --legacy-peer-deps', {
474
+ cwd: moduleCacheDir,
475
+ stdio: ['ignore', 'pipe', 'pipe'],
476
+ timeout: 120_000, // 2 minute timeout
477
+ });
478
+ installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`);
479
+ } catch (error) {
480
+ installSpinner.error(`Failed to install dependencies for ${moduleInfo.name}`);
481
+ if (!silent) await prompts.log.warn(` ${error.message}`);
482
+ }
483
+ }
484
+ }
485
+ }
486
+
487
+ return moduleCacheDir;
488
+ }
489
+
490
+ /**
491
+ * Find the source path for an external module
492
+ * @param {string} moduleCode - Code of the external module
493
+ * @returns {string|null} Path to the module source or null if not found
494
+ */
495
+ async findExternalModuleSource(moduleCode, options = {}) {
496
+ const moduleInfo = await this.externalModuleManager.getModuleByCode(moduleCode);
497
+
498
+ if (!moduleInfo) {
499
+ return null;
500
+ }
501
+
502
+ // Clone the external module repo
503
+ const cloneDir = await this.cloneExternalModule(moduleCode, options);
504
+
505
+ // The module-definition specifies the path to module.yaml relative to repo root
506
+ // We need to return the directory containing module.yaml
507
+ const moduleDefinitionPath = moduleInfo.moduleDefinition; // e.g., 'src/module.yaml'
508
+ const moduleDir = path.dirname(path.join(cloneDir, moduleDefinitionPath));
509
+
510
+ return moduleDir;
511
+ }
512
+
513
+ /**
514
+ * Install a module
515
+ * @param {string} moduleName - Code of the module to install (from module.yaml)
516
+ * @param {string} xiaomaDir - Target xiaoma directory
517
+ * @param {Function} fileTrackingCallback - Optional callback to track installed files
518
+ * @param {Object} options - Additional installation options
519
+ * @param {Array<string>} options.installedIDEs - Array of IDE codes that were installed
520
+ * @param {Object} options.moduleConfig - Module configuration from config collector
521
+ * @param {Object} options.logger - Logger instance for output
522
+ */
523
+ async install(moduleName, xiaomaDir, fileTrackingCallback = null, options = {}) {
524
+ const sourcePath = await this.findModuleSource(moduleName, { silent: options.silent });
525
+ const targetPath = path.join(xiaomaDir, moduleName);
526
+
527
+ // Check if source module exists
528
+ if (!sourcePath) {
529
+ // Provide a more user-friendly error message
530
+ throw new Error(
531
+ `Source for module '${moduleName}' is not available. It will be retained but cannot be updated without its source files.`,
532
+ );
533
+ }
534
+
535
+ // Check if this is a custom module and read its custom.yaml values
536
+ let customConfig = null;
537
+ const rootCustomConfigPath = path.join(sourcePath, 'custom.yaml');
538
+
539
+ if (await fs.pathExists(rootCustomConfigPath)) {
540
+ try {
541
+ const customContent = await fs.readFile(rootCustomConfigPath, 'utf8');
542
+ customConfig = yaml.parse(customContent);
543
+ } catch (error) {
544
+ await prompts.log.warn(`Failed to read custom.yaml for ${moduleName}: ${error.message}`);
545
+ }
546
+ }
547
+
548
+ // If this is a custom module, merge its values into the module config
549
+ if (customConfig) {
550
+ options.moduleConfig = { ...options.moduleConfig, ...customConfig };
551
+ if (options.logger) {
552
+ await options.logger.log(` Merged custom configuration for ${moduleName}`);
553
+ }
554
+ }
555
+
556
+ // Check if already installed
557
+ if (await fs.pathExists(targetPath)) {
558
+ await fs.remove(targetPath);
559
+ }
560
+
561
+ // Vendor cross-module workflows BEFORE copying
562
+ // This reads source agent.yaml files and copies referenced workflows
563
+ await this.vendorCrossModuleWorkflows(sourcePath, targetPath, moduleName);
564
+
565
+ // Copy module files with filtering
566
+ await this.copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback, options.moduleConfig);
567
+
568
+ // Compile any .agent.yaml files to .md format
569
+ await this.compileModuleAgents(sourcePath, targetPath, moduleName, xiaomaDir, options.installer);
570
+
571
+ // Process agent files to inject activation block
572
+ await this.processAgentFiles(targetPath, moduleName);
573
+
574
+ // Create directories declared in module.yaml (unless explicitly skipped)
575
+ if (!options.skipModuleInstaller) {
576
+ await this.createModuleDirectories(moduleName, xiaomaDir, options);
577
+ }
578
+
579
+ // Capture version info for manifest
580
+ const { Manifest } = require('../core/manifest');
581
+ const manifestObj = new Manifest();
582
+ const versionInfo = await manifestObj.getModuleVersionInfo(moduleName, xiaomaDir, sourcePath);
583
+
584
+ await manifestObj.addModule(xiaomaDir, moduleName, {
585
+ version: versionInfo.version,
586
+ source: versionInfo.source,
587
+ npmPackage: versionInfo.npmPackage,
588
+ repoUrl: versionInfo.repoUrl,
589
+ });
590
+
591
+ return {
592
+ success: true,
593
+ module: moduleName,
594
+ path: targetPath,
595
+ versionInfo,
596
+ };
597
+ }
598
+
599
+ /**
600
+ * Update an existing module
601
+ * @param {string} moduleName - Name of the module to update
602
+ * @param {string} xiaomaDir - Target xiaoma directory
603
+ * @param {boolean} force - Force update (overwrite modifications)
604
+ */
605
+ async update(moduleName, xiaomaDir, force = false, options = {}) {
606
+ const sourcePath = await this.findModuleSource(moduleName);
607
+ const targetPath = path.join(xiaomaDir, moduleName);
608
+
609
+ // Check if source module exists
610
+ if (!sourcePath) {
611
+ throw new Error(`Module '${moduleName}' not found in any source location`);
612
+ }
613
+
614
+ // Check if module is installed
615
+ if (!(await fs.pathExists(targetPath))) {
616
+ throw new Error(`Module '${moduleName}' is not installed`);
617
+ }
618
+
619
+ if (force) {
620
+ // Force update - remove and reinstall
621
+ await fs.remove(targetPath);
622
+ return await this.install(moduleName, xiaomaDir, null, { installer: options.installer });
623
+ } else {
624
+ // Selective update - preserve user modifications
625
+ await this.syncModule(sourcePath, targetPath);
626
+
627
+ // Recompile agents (#1133)
628
+ await this.compileModuleAgents(sourcePath, targetPath, moduleName, xiaomaDir, options.installer);
629
+ await this.processAgentFiles(targetPath, moduleName);
630
+ }
631
+
632
+ return {
633
+ success: true,
634
+ module: moduleName,
635
+ path: targetPath,
636
+ };
637
+ }
638
+
639
+ /**
640
+ * Remove a module
641
+ * @param {string} moduleName - Name of the module to remove
642
+ * @param {string} xiaomaDir - Target xiaoma directory
643
+ */
644
+ async remove(moduleName, xiaomaDir) {
645
+ const targetPath = path.join(xiaomaDir, moduleName);
646
+
647
+ if (!(await fs.pathExists(targetPath))) {
648
+ throw new Error(`Module '${moduleName}' is not installed`);
649
+ }
650
+
651
+ await fs.remove(targetPath);
652
+
653
+ return {
654
+ success: true,
655
+ module: moduleName,
656
+ };
657
+ }
658
+
659
+ /**
660
+ * Check if a module is installed
661
+ * @param {string} moduleName - Name of the module
662
+ * @param {string} xiaomaDir - Target xiaoma directory
663
+ * @returns {boolean} True if module is installed
664
+ */
665
+ async isInstalled(moduleName, xiaomaDir) {
666
+ const targetPath = path.join(xiaomaDir, moduleName);
667
+ return await fs.pathExists(targetPath);
668
+ }
669
+
670
+ /**
671
+ * Get installed module info
672
+ * @param {string} moduleName - Name of the module
673
+ * @param {string} xiaomaDir - Target xiaoma directory
674
+ * @returns {Object|null} Module info or null if not installed
675
+ */
676
+ async getInstalledInfo(moduleName, xiaomaDir) {
677
+ const targetPath = path.join(xiaomaDir, moduleName);
678
+
679
+ if (!(await fs.pathExists(targetPath))) {
680
+ return null;
681
+ }
682
+
683
+ const configPath = path.join(targetPath, 'config.yaml');
684
+ const moduleInfo = {
685
+ id: moduleName,
686
+ path: targetPath,
687
+ installed: true,
688
+ };
689
+
690
+ if (await fs.pathExists(configPath)) {
691
+ try {
692
+ const configContent = await fs.readFile(configPath, 'utf8');
693
+ const config = yaml.parse(configContent);
694
+ Object.assign(moduleInfo, config);
695
+ } catch (error) {
696
+ await prompts.log.warn(`Failed to read installed module config: ${error.message}`);
697
+ }
698
+ }
699
+
700
+ return moduleInfo;
701
+ }
702
+
703
+ /**
704
+ * Copy module with filtering for localskip agents and conditional content
705
+ * @param {string} sourcePath - Source module path
706
+ * @param {string} targetPath - Target module path
707
+ * @param {Function} fileTrackingCallback - Optional callback to track installed files
708
+ * @param {Object} moduleConfig - Module configuration with conditional flags
709
+ */
710
+ async copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback = null, moduleConfig = {}) {
711
+ // Get all files in source
712
+ const sourceFiles = await this.getFileList(sourcePath);
713
+
714
+ for (const file of sourceFiles) {
715
+ // Skip sub-modules directory - these are IDE-specific and handled separately
716
+ if (file.startsWith('sub-modules/')) {
717
+ continue;
718
+ }
719
+
720
+ // Only skip sidecar directories - they are handled separately during agent compilation
721
+ // But still allow other files in agent directories
722
+ const isInAgentDirectory = file.startsWith('agents/');
723
+ const isInSidecarDirectory = path
724
+ .dirname(file)
725
+ .split('/')
726
+ .some((dir) => dir.toLowerCase().endsWith('-sidecar'));
727
+
728
+ if (isInSidecarDirectory) {
729
+ continue;
730
+ }
731
+
732
+ // Skip module.yaml at root - it's only needed at install time
733
+ if (file === 'module.yaml') {
734
+ continue;
735
+ }
736
+
737
+ // Skip module root config.yaml only - generated by config collector with actual values
738
+ // Workflow-level config.yaml (e.g. workflows/orchestrate-story/config.yaml) must be copied
739
+ // for custom modules that use workflow-specific configuration
740
+ if (file === 'config.yaml') {
741
+ continue;
742
+ }
743
+
744
+ // Skip .agent.yaml files - they will be compiled separately
745
+ if (file.endsWith('.agent.yaml')) {
746
+ continue;
747
+ }
748
+
749
+ const sourceFile = path.join(sourcePath, file);
750
+ const targetFile = path.join(targetPath, file);
751
+
752
+ // Check if this is an agent file
753
+ if (file.startsWith('agents/') && file.endsWith('.md')) {
754
+ // Read the file to check for localskip
755
+ const content = await fs.readFile(sourceFile, 'utf8');
756
+
757
+ // Check for localskip="true" in the agent tag
758
+ const agentMatch = content.match(/<agent[^>]*\slocalskip="true"[^>]*>/);
759
+ if (agentMatch) {
760
+ await prompts.log.message(` Skipping web-only agent: ${path.basename(file)}`);
761
+ continue; // Skip this agent
762
+ }
763
+ }
764
+
765
+ // Copy the file with placeholder replacement
766
+ await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile);
767
+
768
+ // Track the file if callback provided
769
+ if (fileTrackingCallback) {
770
+ fileTrackingCallback(targetFile);
771
+ }
772
+ }
773
+ }
774
+
775
+ /**
776
+ * Compile .agent.yaml files to .md format in modules
777
+ * @param {string} sourcePath - Source module path
778
+ * @param {string} targetPath - Target module path
779
+ * @param {string} moduleName - Module name
780
+ * @param {string} xiaomaDir - XiaoMa installation directory
781
+ * @param {Object} installer - Installer instance for file tracking
782
+ */
783
+ async compileModuleAgents(sourcePath, targetPath, moduleName, xiaomaDir, installer = null) {
784
+ const sourceAgentsPath = path.join(sourcePath, 'agents');
785
+ const targetAgentsPath = path.join(targetPath, 'agents');
786
+ const cfgAgentsDir = path.join(xiaomaDir, '_config', 'agents');
787
+
788
+ // Check if agents directory exists in source
789
+ if (!(await fs.pathExists(sourceAgentsPath))) {
790
+ return; // No agents to compile
791
+ }
792
+
793
+ // Get all agent YAML files recursively
794
+ const agentFiles = await this.findAgentFiles(sourceAgentsPath);
795
+
796
+ for (const agentFile of agentFiles) {
797
+ if (!agentFile.endsWith('.agent.yaml')) continue;
798
+
799
+ const relativePath = path.relative(sourceAgentsPath, agentFile).split(path.sep).join('/');
800
+ const targetDir = path.join(targetAgentsPath, path.dirname(relativePath));
801
+
802
+ await fs.ensureDir(targetDir);
803
+
804
+ const agentName = path.basename(agentFile, '.agent.yaml');
805
+ const sourceYamlPath = agentFile;
806
+ const targetMdPath = path.join(targetDir, `${agentName}.md`);
807
+ const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
808
+
809
+ // Read and compile the YAML
810
+ try {
811
+ const yamlContent = await fs.readFile(sourceYamlPath, 'utf8');
812
+ const { compileAgent } = require('../../../lib/agent/compiler');
813
+
814
+ // Create customize template if it doesn't exist
815
+ if (!(await fs.pathExists(customizePath))) {
816
+ const { getSourcePath } = require('../../../lib/project-root');
817
+ const genericTemplatePath = getSourcePath('utility', 'agent-components', 'agent.customize.template.yaml');
818
+ if (await fs.pathExists(genericTemplatePath)) {
819
+ await this.copyFileWithPlaceholderReplacement(genericTemplatePath, customizePath);
820
+ // Only show customize creation in verbose mode
821
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
822
+ await prompts.log.message(` Created customize: ${moduleName}-${agentName}.customize.yaml`);
823
+ }
824
+
825
+ // Store original hash for modification detection
826
+ const crypto = require('node:crypto');
827
+ const customizeContent = await fs.readFile(customizePath, 'utf8');
828
+ const originalHash = crypto.createHash('sha256').update(customizeContent).digest('hex');
829
+
830
+ // Store in main manifest
831
+ const manifestPath = path.join(xiaomaDir, '_config', 'manifest.yaml');
832
+ let manifestData = {};
833
+ if (await fs.pathExists(manifestPath)) {
834
+ const manifestContent = await fs.readFile(manifestPath, 'utf8');
835
+ const yaml = require('yaml');
836
+ manifestData = yaml.parse(manifestContent);
837
+ }
838
+ if (!manifestData.agentCustomizations) {
839
+ manifestData.agentCustomizations = {};
840
+ }
841
+ manifestData.agentCustomizations[path.relative(xiaomaDir, customizePath)] = originalHash;
842
+
843
+ // Write back to manifest
844
+ const yaml = require('yaml');
845
+ // Clean the manifest data to remove any non-serializable values
846
+ const cleanManifestData = structuredClone(manifestData);
847
+
848
+ const updatedContent = yaml.stringify(cleanManifestData, {
849
+ indent: 2,
850
+ lineWidth: 0,
851
+ });
852
+ await fs.writeFile(manifestPath, updatedContent, 'utf8');
853
+ }
854
+ }
855
+
856
+ // Check for customizations and build answers object
857
+ let customizedFields = [];
858
+ let answers = {};
859
+ if (await fs.pathExists(customizePath)) {
860
+ const customizeContent = await fs.readFile(customizePath, 'utf8');
861
+ const customizeData = yaml.parse(customizeContent);
862
+ customizedFields = customizeData.customized_fields || [];
863
+
864
+ // Build answers object from customizations
865
+ if (customizeData.persona) {
866
+ answers.persona = customizeData.persona;
867
+ }
868
+ if (customizeData.agent?.metadata) {
869
+ const filteredMetadata = filterCustomizationData(customizeData.agent.metadata);
870
+ if (Object.keys(filteredMetadata).length > 0) {
871
+ Object.assign(answers, { metadata: filteredMetadata });
872
+ }
873
+ }
874
+ if (customizeData.critical_actions && customizeData.critical_actions.length > 0) {
875
+ answers.critical_actions = customizeData.critical_actions;
876
+ }
877
+ if (customizeData.memories && customizeData.memories.length > 0) {
878
+ answers.memories = customizeData.memories;
879
+ }
880
+ if (customizeData.menu && customizeData.menu.length > 0) {
881
+ answers.menu = customizeData.menu;
882
+ }
883
+ if (customizeData.prompts && customizeData.prompts.length > 0) {
884
+ answers.prompts = customizeData.prompts;
885
+ }
886
+ }
887
+
888
+ // Check if agent has sidecar
889
+ let hasSidecar = false;
890
+ try {
891
+ const agentYaml = yaml.parse(yamlContent);
892
+ hasSidecar = agentYaml?.agent?.metadata?.hasSidecar === true;
893
+ } catch {
894
+ // Continue without sidecar processing
895
+ }
896
+
897
+ // Compile with customizations if any
898
+ const { xml } = await compileAgent(yamlContent, answers, agentName, relativePath, { config: this.coreConfig || {} });
899
+
900
+ // Write the compiled agent
901
+ await fs.writeFile(targetMdPath, xml, 'utf8');
902
+
903
+ // Handle sidecar copying if present
904
+ if (hasSidecar) {
905
+ // Get the agent's directory to look for sidecar
906
+ const agentDir = path.dirname(agentFile);
907
+ const sidecarDirName = `${agentName}-sidecar`;
908
+ const sourceSidecarPath = path.join(agentDir, sidecarDirName);
909
+
910
+ // Check if sidecar directory exists
911
+ if (await fs.pathExists(sourceSidecarPath)) {
912
+ // Memory is always in _xiaoma/_memory
913
+ const xiaomaMemoryPath = path.join(xiaomaDir, '_memory');
914
+
915
+ // Determine if this is an update (by checking if agent already exists)
916
+ const isUpdate = await fs.pathExists(targetMdPath);
917
+
918
+ // Copy sidecar to memory location with update-safe handling
919
+ const copiedFiles = await this.copySidecarToMemory(
920
+ sourceSidecarPath,
921
+ agentName,
922
+ xiaomaMemoryPath,
923
+ isUpdate,
924
+ xiaomaDir,
925
+ installer,
926
+ );
927
+
928
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true' && copiedFiles.length > 0) {
929
+ await prompts.log.message(` Sidecar files processed: ${copiedFiles.length} files`);
930
+ }
931
+ } else if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
932
+ await prompts.log.warn(` Agent marked as having sidecar but ${sidecarDirName} directory not found`);
933
+ }
934
+ }
935
+
936
+ // Copy any non-sidecar files from agent directory (e.g., foo.md)
937
+ const agentDir = path.dirname(agentFile);
938
+ const agentEntries = await fs.readdir(agentDir, { withFileTypes: true });
939
+
940
+ for (const entry of agentEntries) {
941
+ if (entry.isFile() && !entry.name.endsWith('.agent.yaml') && !entry.name.endsWith('.md')) {
942
+ // Copy additional files (like foo.md) to the agent target directory
943
+ const sourceFile = path.join(agentDir, entry.name);
944
+ const targetFile = path.join(targetDir, entry.name);
945
+ await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile);
946
+ }
947
+ }
948
+
949
+ // Only show compilation details in verbose mode
950
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
951
+ await prompts.log.message(
952
+ ` Compiled agent: ${agentName} -> ${path.relative(targetPath, targetMdPath)}${hasSidecar ? ' (with sidecar)' : ''}`,
953
+ );
954
+ }
955
+ } catch (error) {
956
+ await prompts.log.warn(` Failed to compile agent ${agentName}: ${error.message}`);
957
+ }
958
+ }
959
+ }
960
+
961
+ /**
962
+ * Find all .agent.yaml files recursively in a directory
963
+ * @param {string} dir - Directory to search
964
+ * @returns {Array} List of .agent.yaml file paths
965
+ */
966
+ async findAgentFiles(dir) {
967
+ const agentFiles = [];
968
+
969
+ async function searchDirectory(searchDir) {
970
+ const entries = await fs.readdir(searchDir, { withFileTypes: true });
971
+
972
+ for (const entry of entries) {
973
+ const fullPath = path.join(searchDir, entry.name);
974
+
975
+ if (entry.isFile() && entry.name.endsWith('.agent.yaml')) {
976
+ agentFiles.push(fullPath);
977
+ } else if (entry.isDirectory()) {
978
+ await searchDirectory(fullPath);
979
+ }
980
+ }
981
+ }
982
+
983
+ await searchDirectory(dir);
984
+ return agentFiles;
985
+ }
986
+
987
+ /**
988
+ * Process agent files to inject activation block
989
+ * @param {string} modulePath - Path to installed module
990
+ * @param {string} moduleName - Module name
991
+ */
992
+ async processAgentFiles(modulePath, moduleName) {
993
+ // const agentsPath = path.join(modulePath, 'agents');
994
+ // // Check if agents directory exists
995
+ // if (!(await fs.pathExists(agentsPath))) {
996
+ // return; // No agents to process
997
+ // }
998
+ // // Get all agent MD files recursively
999
+ // const agentFiles = await this.findAgentMdFiles(agentsPath);
1000
+ // for (const agentFile of agentFiles) {
1001
+ // if (!agentFile.endsWith('.md')) continue;
1002
+ // let content = await fs.readFile(agentFile, 'utf8');
1003
+ // // Check if content has agent XML and no activation block
1004
+ // if (content.includes('<agent') && !content.includes('<activation')) {
1005
+ // // Inject the activation block using XML handler
1006
+ // content = this.xmlHandler.injectActivationSimple(content);
1007
+ // await fs.writeFile(agentFile, content, 'utf8');
1008
+ // }
1009
+ // }
1010
+ }
1011
+
1012
+ /**
1013
+ * Find all .md agent files recursively in a directory
1014
+ * @param {string} dir - Directory to search
1015
+ * @returns {Array} List of .md agent file paths
1016
+ */
1017
+ async findAgentMdFiles(dir) {
1018
+ const agentFiles = [];
1019
+
1020
+ async function searchDirectory(searchDir) {
1021
+ const entries = await fs.readdir(searchDir, { withFileTypes: true });
1022
+
1023
+ for (const entry of entries) {
1024
+ const fullPath = path.join(searchDir, entry.name);
1025
+
1026
+ if (entry.isFile() && entry.name.endsWith('.md')) {
1027
+ agentFiles.push(fullPath);
1028
+ } else if (entry.isDirectory()) {
1029
+ await searchDirectory(fullPath);
1030
+ }
1031
+ }
1032
+ }
1033
+
1034
+ await searchDirectory(dir);
1035
+ return agentFiles;
1036
+ }
1037
+
1038
+ /**
1039
+ * Vendor cross-module workflows referenced in agent files
1040
+ * Scans SOURCE agent.yaml files for workflow-install and copies workflows to destination
1041
+ * @param {string} sourcePath - Source module path
1042
+ * @param {string} targetPath - Target module path (destination)
1043
+ * @param {string} moduleName - Module name being installed
1044
+ */
1045
+ async vendorCrossModuleWorkflows(sourcePath, targetPath, moduleName) {
1046
+ const sourceAgentsPath = path.join(sourcePath, 'agents');
1047
+
1048
+ // Check if source agents directory exists
1049
+ if (!(await fs.pathExists(sourceAgentsPath))) {
1050
+ return; // No agents to process
1051
+ }
1052
+
1053
+ // Get all agent YAML files from source
1054
+ const agentFiles = await fs.readdir(sourceAgentsPath);
1055
+ const yamlFiles = agentFiles.filter((f) => f.endsWith('.agent.yaml') || f.endsWith('.yaml'));
1056
+
1057
+ if (yamlFiles.length === 0) {
1058
+ return; // No YAML agent files
1059
+ }
1060
+
1061
+ let workflowsVendored = false;
1062
+
1063
+ for (const agentFile of yamlFiles) {
1064
+ const agentPath = path.join(sourceAgentsPath, agentFile);
1065
+ const agentYaml = yaml.parse(await fs.readFile(agentPath, 'utf8'));
1066
+
1067
+ // Check if agent has menu items with workflow-install
1068
+ const menuItems = agentYaml?.agent?.menu || [];
1069
+ const workflowInstallItems = menuItems.filter((item) => item['workflow-install']);
1070
+
1071
+ if (workflowInstallItems.length === 0) {
1072
+ continue; // No workflow-install in this agent
1073
+ }
1074
+
1075
+ if (!workflowsVendored) {
1076
+ await prompts.log.info(`\n Vendoring cross-module workflows for ${moduleName}...`);
1077
+ workflowsVendored = true;
1078
+ }
1079
+
1080
+ await prompts.log.message(` Processing: ${agentFile}`);
1081
+
1082
+ for (const item of workflowInstallItems) {
1083
+ const sourceWorkflowPath = item.exec; // Where to copy FROM
1084
+ const installWorkflowPath = item['workflow-install']; // Where to copy TO
1085
+
1086
+ // Parse SOURCE workflow path
1087
+ // Example: {project-root}/_xiaoma/xmc/workflows/4-implementation/create-story/workflow.md
1088
+ const sourceMatch = sourceWorkflowPath.match(/\{project-root\}\/(?:_xiaoma)\/([^/]+)\/workflows\/(.+)/);
1089
+ if (!sourceMatch) {
1090
+ await prompts.log.warn(` Could not parse workflow path: ${sourceWorkflowPath}`);
1091
+ continue;
1092
+ }
1093
+
1094
+ const [, sourceModule, sourceWorkflowSubPath] = sourceMatch;
1095
+
1096
+ // Parse INSTALL workflow path
1097
+ // Example: {project-root}/_xiaoma/bmgd/workflows/4-production/create-story/workflow.md
1098
+ const installMatch = installWorkflowPath.match(/\{project-root\}\/(?:_xiaoma)\/([^/]+)\/workflows\/(.+)/);
1099
+ if (!installMatch) {
1100
+ await prompts.log.warn(` Could not parse workflow-install path: ${installWorkflowPath}`);
1101
+ continue;
1102
+ }
1103
+
1104
+ const installWorkflowSubPath = installMatch[2];
1105
+
1106
+ const sourceModulePath = getModulePath(sourceModule);
1107
+ const actualSourceWorkflowPath = path.join(sourceModulePath, 'workflows', sourceWorkflowSubPath.replace(/\/workflow\.md$/, ''));
1108
+
1109
+ const actualDestWorkflowPath = path.join(targetPath, 'workflows', installWorkflowSubPath.replace(/\/workflow\.md$/, ''));
1110
+
1111
+ // Check if source workflow exists
1112
+ if (!(await fs.pathExists(actualSourceWorkflowPath))) {
1113
+ await prompts.log.warn(` Source workflow not found: ${actualSourceWorkflowPath}`);
1114
+ continue;
1115
+ }
1116
+
1117
+ // Copy the entire workflow folder
1118
+ await prompts.log.message(
1119
+ ` Vendoring: ${sourceModule}/workflows/${sourceWorkflowSubPath.replace(/\/workflow\.md$/, '')} → ${moduleName}/workflows/${installWorkflowSubPath.replace(/\/workflow\.md$/, '')}`,
1120
+ );
1121
+
1122
+ await fs.ensureDir(path.dirname(actualDestWorkflowPath));
1123
+ // Copy the workflow directory recursively with placeholder replacement
1124
+ await this.copyDirectoryWithPlaceholderReplacement(actualSourceWorkflowPath, actualDestWorkflowPath);
1125
+ }
1126
+ }
1127
+
1128
+ if (workflowsVendored) {
1129
+ await prompts.log.success(` Workflow vendoring complete\n`);
1130
+ }
1131
+ }
1132
+
1133
+ /**
1134
+ * Create directories declared in module.yaml's `directories` key
1135
+ * This replaces the security-risky module installer pattern with declarative config
1136
+ * During updates, if a directory path changed, moves the old directory to the new path
1137
+ * @param {string} moduleName - Name of the module
1138
+ * @param {string} xiaomaDir - Target xiaoma directory
1139
+ * @param {Object} options - Installation options
1140
+ * @param {Object} options.moduleConfig - Module configuration from config collector
1141
+ * @param {Object} options.existingModuleConfig - Previous module config (for detecting path changes during updates)
1142
+ * @param {Object} options.coreConfig - Core configuration
1143
+ * @returns {Promise<{createdDirs: string[], movedDirs: string[], createdWdsFolders: string[]}>} Created directories info
1144
+ */
1145
+ async createModuleDirectories(moduleName, xiaomaDir, options = {}) {
1146
+ const moduleConfig = options.moduleConfig || {};
1147
+ const existingModuleConfig = options.existingModuleConfig || {};
1148
+ const projectRoot = path.dirname(xiaomaDir);
1149
+ const emptyResult = { createdDirs: [], movedDirs: [], createdWdsFolders: [] };
1150
+
1151
+ // Special handling for core module - it's in src/core not src/modules
1152
+ let sourcePath;
1153
+ if (moduleName === 'core') {
1154
+ sourcePath = getSourcePath('core');
1155
+ } else {
1156
+ sourcePath = await this.findModuleSource(moduleName, { silent: true });
1157
+ if (!sourcePath) {
1158
+ return emptyResult; // No source found, skip
1159
+ }
1160
+ }
1161
+
1162
+ // Read module.yaml to find the `directories` key
1163
+ const moduleYamlPath = path.join(sourcePath, 'module.yaml');
1164
+ if (!(await fs.pathExists(moduleYamlPath))) {
1165
+ return emptyResult; // No module.yaml, skip
1166
+ }
1167
+
1168
+ let moduleYaml;
1169
+ try {
1170
+ const yamlContent = await fs.readFile(moduleYamlPath, 'utf8');
1171
+ moduleYaml = yaml.parse(yamlContent);
1172
+ } catch {
1173
+ return emptyResult; // Invalid YAML, skip
1174
+ }
1175
+
1176
+ if (!moduleYaml || !moduleYaml.directories) {
1177
+ return emptyResult; // No directories declared, skip
1178
+ }
1179
+
1180
+ const directories = moduleYaml.directories;
1181
+ const wdsFolders = moduleYaml.wds_folders || [];
1182
+ const createdDirs = [];
1183
+ const movedDirs = [];
1184
+ const createdWdsFolders = [];
1185
+
1186
+ for (const dirRef of directories) {
1187
+ // Parse variable reference like "{design_artifacts}"
1188
+ const varMatch = dirRef.match(/^\{([^}]+)\}$/);
1189
+ if (!varMatch) {
1190
+ // Not a variable reference, skip
1191
+ continue;
1192
+ }
1193
+
1194
+ const configKey = varMatch[1];
1195
+ const dirValue = moduleConfig[configKey];
1196
+ if (!dirValue || typeof dirValue !== 'string') {
1197
+ continue; // No value or not a string, skip
1198
+ }
1199
+
1200
+ // Strip {project-root}/ prefix if present
1201
+ let dirPath = dirValue.replace(/^\{project-root\}\/?/, '');
1202
+
1203
+ // Handle remaining {project-root} anywhere in the path
1204
+ dirPath = dirPath.replaceAll('{project-root}', '');
1205
+
1206
+ // Resolve to absolute path
1207
+ const fullPath = path.join(projectRoot, dirPath);
1208
+
1209
+ // Validate path is within project root (prevent directory traversal)
1210
+ const normalizedPath = path.normalize(fullPath);
1211
+ const normalizedRoot = path.normalize(projectRoot);
1212
+ if (!normalizedPath.startsWith(normalizedRoot + path.sep) && normalizedPath !== normalizedRoot) {
1213
+ const color = await prompts.getColor();
1214
+ await prompts.log.warn(color.yellow(`${configKey} path escapes project root, skipping: ${dirPath}`));
1215
+ continue;
1216
+ }
1217
+
1218
+ // Check if directory path changed from previous config (update/modify scenario)
1219
+ const oldDirValue = existingModuleConfig[configKey];
1220
+ let oldFullPath = null;
1221
+ let oldDirPath = null;
1222
+ if (oldDirValue && typeof oldDirValue === 'string') {
1223
+ // F3: Normalize both values before comparing to avoid false negatives
1224
+ // from trailing slashes, separator differences, or prefix format variations
1225
+ let normalizedOld = oldDirValue.replace(/^\{project-root\}\/?/, '');
1226
+ normalizedOld = path.normalize(normalizedOld.replaceAll('{project-root}', ''));
1227
+ const normalizedNew = path.normalize(dirPath);
1228
+
1229
+ if (normalizedOld !== normalizedNew) {
1230
+ oldDirPath = normalizedOld;
1231
+ oldFullPath = path.join(projectRoot, oldDirPath);
1232
+ const normalizedOldAbsolute = path.normalize(oldFullPath);
1233
+ if (!normalizedOldAbsolute.startsWith(normalizedRoot + path.sep) && normalizedOldAbsolute !== normalizedRoot) {
1234
+ oldFullPath = null; // Old path escapes project root, ignore it
1235
+ }
1236
+
1237
+ // F13: Prevent parent/child move (e.g. docs/planning → docs/planning/v2)
1238
+ if (oldFullPath) {
1239
+ const normalizedNewAbsolute = path.normalize(fullPath);
1240
+ if (
1241
+ normalizedOldAbsolute.startsWith(normalizedNewAbsolute + path.sep) ||
1242
+ normalizedNewAbsolute.startsWith(normalizedOldAbsolute + path.sep)
1243
+ ) {
1244
+ const color = await prompts.getColor();
1245
+ await prompts.log.warn(
1246
+ color.yellow(
1247
+ `${configKey}: cannot move between parent/child paths (${oldDirPath} / ${dirPath}), creating new directory instead`,
1248
+ ),
1249
+ );
1250
+ oldFullPath = null;
1251
+ }
1252
+ }
1253
+ }
1254
+ }
1255
+
1256
+ const dirName = configKey.replaceAll('_', ' ');
1257
+
1258
+ if (oldFullPath && (await fs.pathExists(oldFullPath)) && !(await fs.pathExists(fullPath))) {
1259
+ // Path changed and old dir exists → move old to new location
1260
+ // F1: Use fs.move() instead of fs.rename() for cross-device/volume support
1261
+ // F2: Wrap in try/catch — fallback to creating new dir on failure
1262
+ try {
1263
+ await fs.ensureDir(path.dirname(fullPath));
1264
+ await fs.move(oldFullPath, fullPath);
1265
+ movedDirs.push(`${dirName}: ${oldDirPath} → ${dirPath}`);
1266
+ } catch (moveError) {
1267
+ const color = await prompts.getColor();
1268
+ await prompts.log.warn(
1269
+ color.yellow(
1270
+ `Failed to move ${oldDirPath} → ${dirPath}: ${moveError.message}\n Creating new directory instead. Please move contents from the old directory manually.`,
1271
+ ),
1272
+ );
1273
+ await fs.ensureDir(fullPath);
1274
+ createdDirs.push(`${dirName}: ${dirPath}`);
1275
+ }
1276
+ } else if (oldFullPath && (await fs.pathExists(oldFullPath)) && (await fs.pathExists(fullPath))) {
1277
+ // F5: Both old and new directories exist — warn user about potential orphaned documents
1278
+ const color = await prompts.getColor();
1279
+ await prompts.log.warn(
1280
+ color.yellow(
1281
+ `${dirName}: path changed but both directories exist:\n Old: ${oldDirPath}\n New: ${dirPath}\n Old directory may contain orphaned documents — please review and merge manually.`,
1282
+ ),
1283
+ );
1284
+ } else if (!(await fs.pathExists(fullPath))) {
1285
+ // New directory doesn't exist yet → create it
1286
+ createdDirs.push(`${dirName}: ${dirPath}`);
1287
+ await fs.ensureDir(fullPath);
1288
+ }
1289
+
1290
+ // Create WDS subfolders if this is the design_artifacts directory
1291
+ if (configKey === 'design_artifacts' && wdsFolders.length > 0) {
1292
+ for (const subfolder of wdsFolders) {
1293
+ const subPath = path.join(fullPath, subfolder);
1294
+ if (!(await fs.pathExists(subPath))) {
1295
+ await fs.ensureDir(subPath);
1296
+ createdWdsFolders.push(subfolder);
1297
+ }
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ return { createdDirs, movedDirs, createdWdsFolders };
1303
+ }
1304
+
1305
+ /**
1306
+ * Private: Process module configuration
1307
+ * @param {string} modulePath - Path to installed module
1308
+ * @param {string} moduleName - Module name
1309
+ */
1310
+ async processModuleConfig(modulePath, moduleName) {
1311
+ const configPath = path.join(modulePath, 'config.yaml');
1312
+
1313
+ if (await fs.pathExists(configPath)) {
1314
+ try {
1315
+ let configContent = await fs.readFile(configPath, 'utf8');
1316
+
1317
+ // Replace path placeholders
1318
+ configContent = configContent.replaceAll('{project-root}', `xiaoma/${moduleName}`);
1319
+ configContent = configContent.replaceAll('{module}', moduleName);
1320
+
1321
+ await fs.writeFile(configPath, configContent, 'utf8');
1322
+ } catch (error) {
1323
+ await prompts.log.warn(`Failed to process module config: ${error.message}`);
1324
+ }
1325
+ }
1326
+ }
1327
+
1328
+ /**
1329
+ * Private: Sync module files (preserving user modifications)
1330
+ * @param {string} sourcePath - Source module path
1331
+ * @param {string} targetPath - Target module path
1332
+ */
1333
+ async syncModule(sourcePath, targetPath) {
1334
+ // Get list of all source files
1335
+ const sourceFiles = await this.getFileList(sourcePath);
1336
+
1337
+ for (const file of sourceFiles) {
1338
+ const sourceFile = path.join(sourcePath, file);
1339
+ const targetFile = path.join(targetPath, file);
1340
+
1341
+ // Check if target file exists and has been modified
1342
+ if (await fs.pathExists(targetFile)) {
1343
+ const sourceStats = await fs.stat(sourceFile);
1344
+ const targetStats = await fs.stat(targetFile);
1345
+
1346
+ // Skip if target is newer (user modified)
1347
+ if (targetStats.mtime > sourceStats.mtime) {
1348
+ continue;
1349
+ }
1350
+ }
1351
+
1352
+ // Copy file with placeholder replacement
1353
+ await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile);
1354
+ }
1355
+ }
1356
+
1357
+ /**
1358
+ * Private: Get list of all files in a directory
1359
+ * @param {string} dir - Directory path
1360
+ * @param {string} baseDir - Base directory for relative paths
1361
+ * @returns {Array} List of relative file paths
1362
+ */
1363
+ async getFileList(dir, baseDir = dir) {
1364
+ const files = [];
1365
+ const entries = await fs.readdir(dir, { withFileTypes: true });
1366
+
1367
+ for (const entry of entries) {
1368
+ const fullPath = path.join(dir, entry.name);
1369
+
1370
+ if (entry.isDirectory()) {
1371
+ const subFiles = await this.getFileList(fullPath, baseDir);
1372
+ files.push(...subFiles);
1373
+ } else {
1374
+ files.push(path.relative(baseDir, fullPath));
1375
+ }
1376
+ }
1377
+
1378
+ return files;
1379
+ }
1380
+ }
1381
+
1382
+ module.exports = { ModuleManager };