@zeyue0329/xiaoma-cli 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (712) hide show
  1. package/package.json +24 -14
  2. package/src/core-skills/module-help.csv +13 -0
  3. package/src/{core → core-skills}/module.yaml +8 -0
  4. package/src/{core/skills/xiaoma-advanced-elicitation/workflow.md → core-skills/xiaoma-advanced-elicitation/SKILL.md} +10 -3
  5. package/src/core-skills/xiaoma-advanced-elicitation/methods.csv +70 -0
  6. package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-03-technique-execution.md +6 -4
  7. package/src/{core/skills → core-skills}/xiaoma-brainstorming/workflow.md +1 -1
  8. package/src/core-skills/xiaoma-customize/SKILL.md +111 -0
  9. package/src/core-skills/xiaoma-customize/scripts/list_customizable_skills.js +172 -0
  10. package/src/{core/skills → core-skills}/xiaoma-distillator/resources/distillate-format-reference.md +1 -1
  11. package/src/{core/skills → core-skills}/xiaoma-distillator/scripts/analyze_sources.py +2 -2
  12. package/src/{core/skills/xiaoma-editorial-review-prose/workflow.md → core-skills/xiaoma-editorial-review-prose/SKILL.md} +5 -0
  13. package/src/{core/skills/xiaoma-editorial-review-structure/workflow.md → core-skills/xiaoma-editorial-review-structure/SKILL.md} +5 -0
  14. package/src/core-skills/xiaoma-help/SKILL.md +75 -0
  15. package/src/{core/skills/xiaoma-index-docs/workflow.md → core-skills/xiaoma-index-docs/SKILL.md} +5 -0
  16. package/src/core-skills/xiaoma-party-mode/SKILL.md +128 -0
  17. package/src/{core/skills/xiaoma-review-adversarial-general/workflow.md → core-skills/xiaoma-review-adversarial-general/SKILL.md} +5 -0
  18. package/src/{core/skills/xiaoma-review-edge-case-hunter/workflow.md → core-skills/xiaoma-review-edge-case-hunter/SKILL.md} +5 -0
  19. package/src/{core/skills/xiaoma-shard-doc/workflow.md → core-skills/xiaoma-shard-doc/SKILL.md} +5 -0
  20. package/src/core-skills/xiaoma-spec/SKILL.md +129 -0
  21. package/src/core-skills/xiaoma-spec/assets/headless-schemas.md +33 -0
  22. package/src/core-skills/xiaoma-spec/assets/spec-template.md +49 -0
  23. package/src/core-skills/xiaoma-spec/customize.toml +53 -0
  24. package/src/scripts/resolve_config.js +163 -0
  25. package/src/scripts/resolve_customization.js +188 -0
  26. package/src/scripts/toml.js +338 -0
  27. package/src/xmc-skills/1-analysis/research/xiaoma-domain-research/SKILL.md +96 -0
  28. package/src/xmc-skills/1-analysis/research/xiaoma-domain-research/customize.toml +41 -0
  29. package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-06-research-synthesis.md +6 -0
  30. package/src/xmc-skills/1-analysis/research/xiaoma-market-research/SKILL.md +96 -0
  31. package/src/xmc-skills/1-analysis/research/xiaoma-market-research/customize.toml +41 -0
  32. package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-06-research-completion.md +6 -0
  33. package/src/xmc-skills/1-analysis/research/xiaoma-technical-research/SKILL.md +96 -0
  34. package/src/xmc-skills/1-analysis/research/xiaoma-technical-research/customize.toml +41 -0
  35. package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-06-research-synthesis.md +6 -0
  36. package/src/xmc-skills/1-analysis/xiaoma-agent-analyst/SKILL.md +76 -0
  37. package/src/xmc-skills/1-analysis/xiaoma-agent-analyst/customize.toml +90 -0
  38. package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/SKILL.md +76 -0
  39. package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/customize.toml +81 -0
  40. package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/explain-concept.md +20 -0
  41. package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/mermaid-gen.md +20 -0
  42. package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/validate-doc.md +19 -0
  43. package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/write-document.md +20 -0
  44. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/checklist.md +5 -2
  45. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-01-init-and-validate.md +18 -1
  46. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-02-requirements-analysis.md +3 -1
  47. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-03-architecture-analysis.md +5 -3
  48. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-04-create-prd.md +12 -14
  49. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-05-validate-prd.md +18 -15
  50. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-06-create-epics.md +9 -5
  51. package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-07-create-architecture.md +10 -7
  52. package/src/xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline/steps/step-08-finalize.md +184 -0
  53. package/src/xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline/workflow.md +140 -0
  54. package/src/xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline/xiaoma-skill-manifest.yaml +24 -0
  55. package/src/xmc-skills/1-analysis/xiaoma-document-project/SKILL.md +62 -0
  56. package/src/xmc-skills/1-analysis/xiaoma-document-project/customize.toml +41 -0
  57. package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/deep-dive-instructions.md +1 -0
  58. package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/full-scan-instructions.md +1 -0
  59. package/src/xmc-skills/1-analysis/xiaoma-prfaq/SKILL.md +135 -0
  60. package/src/xmc-skills/1-analysis/xiaoma-prfaq/agents/artifact-analyzer.md +60 -0
  61. package/src/xmc-skills/1-analysis/xiaoma-prfaq/agents/web-researcher.md +49 -0
  62. package/src/xmc-skills/1-analysis/xiaoma-prfaq/assets/prfaq-template.md +62 -0
  63. package/src/xmc-skills/1-analysis/xiaoma-prfaq/customize.toml +41 -0
  64. package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/customer-faq.md +55 -0
  65. package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/internal-faq.md +51 -0
  66. package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/press-release.md +60 -0
  67. package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/verdict.md +83 -0
  68. package/src/xmc-skills/1-analysis/xiaoma-prfaq/xiaoma-manifest.json +16 -0
  69. package/src/xmc-skills/1-analysis/xiaoma-product-brief/SKILL.md +91 -0
  70. package/src/xmc-skills/1-analysis/xiaoma-product-brief/assets/brief-template.md +41 -0
  71. package/src/xmc-skills/1-analysis/xiaoma-product-brief/customize.toml +99 -0
  72. package/src/xmc-skills/2-plan-workflows/xiaoma-agent-pm/SKILL.md +76 -0
  73. package/src/xmc-skills/2-plan-workflows/xiaoma-agent-pm/customize.toml +75 -0
  74. package/src/xmc-skills/2-plan-workflows/xiaoma-agent-ux-designer/SKILL.md +76 -0
  75. package/src/xmc-skills/2-plan-workflows/xiaoma-agent-ux-designer/customize.toml +60 -0
  76. package/src/xmc-skills/2-plan-workflows/xiaoma-create-prd/SKILL.md +30 -0
  77. package/src/xmc-skills/2-plan-workflows/xiaoma-create-prd/customize.toml +41 -0
  78. package/src/xmc-skills/2-plan-workflows/xiaoma-edit-prd/SKILL.md +30 -0
  79. package/src/xmc-skills/2-plan-workflows/xiaoma-edit-prd/customize.toml +42 -0
  80. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/SKILL.md +92 -0
  81. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/headless-schemas.md +76 -0
  82. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/prd-template.md +165 -0
  83. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/prd-validation-checklist.md +217 -0
  84. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/validation-report-template.html +325 -0
  85. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/customize.toml +147 -0
  86. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/references/headless.md +39 -0
  87. package/src/xmc-skills/2-plan-workflows/xiaoma-prd/references/validate.md +97 -0
  88. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/SKILL.md +90 -0
  89. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/color-themes.md +9 -0
  90. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-directions.md +9 -0
  91. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-example-editorial.md +158 -0
  92. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-example-mobile.md +93 -0
  93. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-example-shadcn.md +109 -0
  94. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/excalidraw-wireframe.md +19 -0
  95. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/experience-example-mobile.md +112 -0
  96. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/experience-example-shadcn.md +133 -0
  97. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/headless-schemas.md +84 -0
  98. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/key-screens.md +29 -0
  99. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/validation-report-template.html +319 -0
  100. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/customize.toml +100 -0
  101. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/creative-tools.md +19 -0
  102. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/design-md-spec.md +50 -0
  103. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/headless.md +37 -0
  104. package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/validate.md +115 -0
  105. package/src/xmc-skills/2-plan-workflows/xiaoma-validate-prd/SKILL.md +30 -0
  106. package/src/xmc-skills/2-plan-workflows/xiaoma-validate-prd/customize.toml +31 -0
  107. package/src/xmc-skills/3-solutioning/xiaoma-agent-architect/SKILL.md +76 -0
  108. package/src/xmc-skills/3-solutioning/xiaoma-agent-architect/customize.toml +65 -0
  109. package/src/xmc-skills/3-solutioning/xiaoma-check-implementation-readiness/SKILL.md +91 -0
  110. package/src/xmc-skills/3-solutioning/xiaoma-check-implementation-readiness/customize.toml +41 -0
  111. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-01-document-discovery.md +1 -1
  112. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-02-prd-analysis.md +1 -1
  113. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +1 -1
  114. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-06-final-assessment.md +6 -0
  115. package/src/xmc-skills/3-solutioning/xiaoma-create-architecture/SKILL.md +74 -0
  116. package/src/xmc-skills/3-solutioning/xiaoma-create-architecture/customize.toml +41 -0
  117. package/src/xmc-skills/3-solutioning/xiaoma-create-architecture/references/headless.md +37 -0
  118. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-07-validation.md +23 -21
  119. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-08-complete.md +6 -0
  120. package/src/xmc-skills/3-solutioning/xiaoma-create-epics-and-stories/SKILL.md +93 -0
  121. package/src/xmc-skills/3-solutioning/xiaoma-create-epics-and-stories/customize.toml +41 -0
  122. package/src/xmc-skills/3-solutioning/xiaoma-create-epics-and-stories/references/headless.md +35 -0
  123. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-02-design-epics.md +34 -4
  124. package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-04-final-validation.md +12 -0
  125. package/src/xmc-skills/3-solutioning/xiaoma-generate-project-context/SKILL.md +81 -0
  126. package/src/xmc-skills/3-solutioning/xiaoma-generate-project-context/customize.toml +41 -0
  127. package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/steps/step-03-complete.md +6 -0
  128. package/src/xmc-skills/4-implementation/xiaoma-agent-dev/SKILL.md +76 -0
  129. package/src/xmc-skills/4-implementation/xiaoma-agent-dev/customize.toml +131 -0
  130. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/checklist.md +29 -0
  131. package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/steps/step-01-init-and-validate.md +16 -8
  132. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-02-create-story.md +111 -0
  133. package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/steps/step-03-validate-story.md +4 -2
  134. package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/steps/step-04-develop-story.md +10 -6
  135. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-05-code-review.md +99 -0
  136. package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/steps/step-06-test-story.md +25 -12
  137. package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/steps/step-07-fix-and-retest.md +28 -13
  138. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-08-complete-story.md +174 -0
  139. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-09-finalize.md +145 -0
  140. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/workflow.md +127 -0
  141. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/xiaoma-skill-manifest.yaml +27 -0
  142. package/src/{xmc/workflows/4-implementation/auto-story-pipeline-batch → xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch}/SKILL.md +2 -2
  143. package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch/checklist.md +45 -0
  144. package/src/{xmc/workflows/4-implementation/auto-story-pipeline-batch → xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch}/workflow.md +150 -7
  145. package/src/{xmc/workflows/4-implementation/auto-story-pipeline-batch → xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch}/xiaoma-skill-manifest.yaml +2 -2
  146. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/SKILL.md +68 -0
  147. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/customize.toml +41 -0
  148. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/generate-trail.md +38 -0
  149. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-01-orientation.md +105 -0
  150. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-02-walkthrough.md +89 -0
  151. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-03-detail-pass.md +106 -0
  152. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-04-testing.md +74 -0
  153. package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-05-wrapup.md +30 -0
  154. package/src/xmc-skills/4-implementation/xiaoma-code-review/SKILL.md +90 -0
  155. package/src/xmc-skills/4-implementation/xiaoma-code-review/customize.toml +41 -0
  156. package/src/xmc-skills/4-implementation/xiaoma-code-review/steps/step-01-gather-context.md +85 -0
  157. package/src/xmc-skills/4-implementation/xiaoma-code-review/steps/step-02-review.md +35 -0
  158. package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-code-review/steps/step-03-triage.md +7 -8
  159. package/src/xmc-skills/4-implementation/xiaoma-code-review/steps/step-04-present.md +132 -0
  160. package/src/{xmc/workflows/4-implementation/xiaoma-correct-course/workflow.md → xmc-skills/4-implementation/xiaoma-correct-course/SKILL.md} +65 -31
  161. package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-correct-course/checklist.md +2 -2
  162. package/src/xmc-skills/4-implementation/xiaoma-correct-course/customize.toml +41 -0
  163. package/src/{xmc/workflows/4-implementation/xiaoma-create-story/workflow.md → xmc-skills/4-implementation/xiaoma-create-story/SKILL.md} +60 -11
  164. package/src/xmc-skills/4-implementation/xiaoma-create-story/customize.toml +41 -0
  165. package/src/xmc-skills/4-implementation/xiaoma-create-story/references/headless.md +32 -0
  166. package/src/{xmc/workflows/4-implementation/xiaoma-dev-story/workflow.md → xmc-skills/4-implementation/xiaoma-dev-story/SKILL.md} +70 -20
  167. package/src/xmc-skills/4-implementation/xiaoma-dev-story/customize.toml +41 -0
  168. package/src/xmc-skills/4-implementation/xiaoma-investigate/SKILL.md +196 -0
  169. package/src/xmc-skills/4-implementation/xiaoma-investigate/customize.toml +62 -0
  170. package/src/xmc-skills/4-implementation/xiaoma-investigate/references/case-file-template.md +127 -0
  171. package/src/{xmc/workflows/xiaoma-qa-generate-e2e-tests/workflow.md → xmc-skills/4-implementation/xiaoma-qa-generate-e2e-tests/SKILL.md} +51 -23
  172. package/src/{xmc/workflows → xmc-skills/4-implementation}/xiaoma-qa-generate-e2e-tests/checklist.md +1 -5
  173. package/src/xmc-skills/4-implementation/xiaoma-qa-generate-e2e-tests/customize.toml +41 -0
  174. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/SKILL.md +111 -0
  175. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/compile-epic-context.md +62 -0
  176. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/customize.toml +41 -0
  177. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/spec-template.md +88 -0
  178. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-01-clarify-and-route.md +100 -0
  179. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-02-plan.md +47 -0
  180. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-03-implement.md +41 -0
  181. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-04-review.md +50 -0
  182. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-05-present.md +78 -0
  183. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-oneshot.md +71 -0
  184. package/src/xmc-skills/4-implementation/xiaoma-quick-dev/sync-sprint-status.md +19 -0
  185. package/src/{xmc/workflows/4-implementation/xiaoma-retrospective/workflow.md → xmc-skills/4-implementation/xiaoma-retrospective/SKILL.md} +185 -152
  186. package/src/xmc-skills/4-implementation/xiaoma-retrospective/customize.toml +41 -0
  187. package/src/{xmc/workflows/4-implementation/xiaoma-sprint-planning/workflow.md → xmc-skills/4-implementation/xiaoma-sprint-planning/SKILL.md} +59 -15
  188. package/src/xmc-skills/4-implementation/xiaoma-sprint-planning/customize.toml +41 -0
  189. package/src/xmc-skills/4-implementation/xiaoma-sprint-planning/references/headless.md +28 -0
  190. package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-sprint-planning/sprint-status-template.yaml +3 -3
  191. package/src/{xmc/workflows/4-implementation/xiaoma-sprint-status/workflow.md → xmc-skills/4-implementation/xiaoma-sprint-status/SKILL.md} +57 -20
  192. package/src/xmc-skills/4-implementation/xiaoma-sprint-status/customize.toml +41 -0
  193. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/checklist.md +6 -0
  194. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/steps/step-01-init-and-validate.md +28 -4
  195. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/steps/step-02-run-requirements-pipeline.md +2 -1
  196. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/steps/step-03-bridge-sprint-planning.md +63 -9
  197. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/steps/step-04-run-story-pipeline.md +2 -1
  198. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/steps/step-05-finalize.md +30 -3
  199. package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/workflow.md +7 -8
  200. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/checklist.md +4 -0
  201. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/steps/step-01-init-and-validate.md +8 -7
  202. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/steps/step-02-create-epics.md +3 -2
  203. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/steps/step-03-bridge-sprint-planning.md +68 -14
  204. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/steps/step-04-batch-create-stories.md +6 -5
  205. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/steps/step-05-finalize.md +48 -8
  206. package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/workflow.md +7 -8
  207. package/src/xmc-skills/module-help.csv +32 -0
  208. package/src/xmc-skills/module.yaml +95 -0
  209. package/src/xpm-skills/module-help.csv +3 -0
  210. package/src/xpm-skills/module.yaml +36 -0
  211. package/src/xpm-skills/xiaoma-agent-patent-advisor/SKILL.md +75 -0
  212. package/src/xpm-skills/xiaoma-agent-patent-advisor/customize.toml +46 -0
  213. package/src/xpm-skills/xiaoma-patent-mining/SKILL.md +6 -0
  214. package/src/xpm-skills/xiaoma-patent-mining/steps/step-01-project-analysis.md +65 -0
  215. package/src/xpm-skills/xiaoma-patent-mining/steps/step-02-patent-mining.md +87 -0
  216. package/src/xpm-skills/xiaoma-patent-mining/steps/step-03-disclosure-writing.md +110 -0
  217. package/src/xpm-skills/xiaoma-patent-mining/steps/step-04-ai-taste-removal.md +85 -0
  218. package/src/xpm-skills/xiaoma-patent-mining/steps/step-05-docx-generation.md +111 -0
  219. package/src/xpm-skills/xiaoma-patent-mining/workflow.md +94 -0
  220. package/tools/format-workflow-md.js +263 -0
  221. package/tools/{cli → installer}/README.md +2 -2
  222. package/tools/installer/cli-utils.js +57 -0
  223. package/tools/installer/commands/install.js +146 -0
  224. package/tools/{cli → installer}/commands/status.js +15 -7
  225. package/tools/{cli → installer}/commands/uninstall.js +7 -7
  226. package/tools/installer/core/config.js +73 -0
  227. package/tools/installer/core/existing-install.js +121 -0
  228. package/tools/installer/core/install-paths.js +132 -0
  229. package/tools/installer/core/installer.js +1624 -0
  230. package/tools/installer/core/legacy-warnings.js +156 -0
  231. package/tools/installer/core/manifest-generator.js +859 -0
  232. package/tools/installer/core/manifest.js +434 -0
  233. package/tools/{cli/lib → installer}/file-ops.js +1 -1
  234. package/tools/installer/fs-native.js +116 -0
  235. package/tools/installer/ide/_config-driven.js +972 -0
  236. package/tools/{cli/installers/lib → installer}/ide/manager.js +82 -62
  237. package/tools/installer/ide/platform-codes.js +80 -0
  238. package/tools/installer/ide/platform-codes.yaml +322 -0
  239. package/tools/installer/ide/shared/installed-skills.js +50 -0
  240. package/tools/{cli/installers/lib → installer}/ide/shared/path-utils.js +0 -145
  241. package/tools/{cli/installers/lib → installer}/ide/shared/skill-manifest.js +3 -36
  242. package/tools/installer/list-options.js +210 -0
  243. package/tools/{cli/installers/lib → installer}/message-loader.js +3 -3
  244. package/tools/installer/modules/channel-plan.js +203 -0
  245. package/tools/installer/modules/channel-resolver.js +241 -0
  246. package/tools/installer/modules/custom-module-manager.js +912 -0
  247. package/tools/installer/modules/external-manager.js +533 -0
  248. package/tools/installer/modules/module-help-schema.js +13 -0
  249. package/tools/{cli/installers/lib/core/config-collector.js → installer/modules/official-modules.js} +1052 -110
  250. package/tools/installer/modules/plugin-resolver.js +398 -0
  251. package/tools/installer/modules/version-resolver.js +336 -0
  252. package/tools/installer/project-root.js +230 -0
  253. package/tools/{cli/lib → installer}/prompts.js +143 -100
  254. package/tools/installer/set-overrides.js +330 -0
  255. package/tools/installer/ui.js +2078 -0
  256. package/tools/{cli → installer}/xiaoma-cli.js +9 -10
  257. package/tools/{cli/lib → installer}/yaml-format.js +1 -1
  258. package/tools/migrate-custom-module-paths.js +124 -0
  259. package/tools/schema/step.js +855 -0
  260. package/tools/skill-validator.md +323 -0
  261. package/tools/validate-file-refs.js +566 -0
  262. package/tools/validate-frontmatter-prose-routing.js +334 -0
  263. package/tools/validate-skills.js +702 -0
  264. package/tools/validate-step-schemas.js +401 -0
  265. package/tools/validate-svg-changes.sh +1 -1
  266. package/tools/validate-trigger-column-vs-emits.js +375 -0
  267. package/tools/validate-warnings-samples.js +261 -0
  268. package/tools/xiaoma/rebrand.mjs +0 -0
  269. package/tools/xiaoma-npx-wrapper.js +2 -2
  270. package/.playwright-cli/console-2026-05-13T06-36-26-793Z.log +0 -2
  271. package/.playwright-cli/page-2026-05-13T06-36-27-725Z.yml +0 -1
  272. package/CLAUDE.md +0 -111
  273. package/README.md +0 -128
  274. package/XiaoMa-CLI-2026H2-/350/277/255/344/273/243/350/247/204/345/210/222.pptx +0 -0
  275. package/demo/xiaoma-bug-circle-resolve/SKILL.md +0 -6
  276. package/demo/xiaoma-bug-circle-resolve/workflow.md +0 -254
  277. package/demo/xiaoma-bug-resolve/SKILL.md +0 -6
  278. package/demo/xiaoma-bug-resolve/workflow.md +0 -269
  279. package/demo/xiaoma-prd-saas-zh/README.md +0 -57
  280. package/demo/xiaoma-prd-saas-zh/domain-research.md +0 -128
  281. package/demo/xiaoma-prd-saas-zh/epics.md +0 -303
  282. package/demo/xiaoma-prd-saas-zh/market-research-2026-q1.md +0 -183
  283. package/demo/xiaoma-prd-saas-zh/prd-bad-examples.md +0 -268
  284. package/demo/xiaoma-prd-saas-zh/prd.md +0 -409
  285. package/demo/xiaoma-prd-saas-zh/product-brief.md +0 -97
  286. package/demo/xiaoma-prd-saas-zh/validation-report.md +0 -279
  287. package/docs/roadshow/01-/351/241/271/347/233/256/346/246/202/350/247/210/344/270/216/346/236/266/346/236/204.md +0 -189
  288. package/docs/roadshow/02-/346/231/272/350/203/275/344/275/223/347/263/273/347/273/237/350/257/246/350/247/243.md +0 -464
  289. package/docs/roadshow/03-/346/231/272/350/203/275/344/275/223/344/272/244/344/272/222/346/265/201/347/250/213/345/233/276.md +0 -334
  290. package/docs/roadshow/04-/345/267/245/344/275/234/346/265/201/346/211/247/350/241/214/350/257/246/350/247/243.md +0 -1038
  291. package/docs/roadshow/05-/346/212/200/346/234/257/345/256/236/347/216/260/344/270/216/345/210/233/346/226/260/344/272/256/347/202/271.md +0 -205
  292. package/docs/roadshow/06-/350/267/257/346/274/224/346/200/273/347/273/223/344/270/216/346/274/224/347/244/272/345/273/272/350/256/256.md +0 -167
  293. package/media/doc1_fig1.png +0 -0
  294. package/media/doc1_fig2.png +0 -0
  295. package/media/doc1_fig3.png +0 -0
  296. package/media/doc1_fig4.png +0 -0
  297. package/media/doc2_fig1.png +0 -0
  298. package/media/doc2_fig2.png +0 -0
  299. package/media/doc2_fig3.png +0 -0
  300. package/media/doc2_fig4.png +0 -0
  301. package/media/doc3_fig1.png +0 -0
  302. package/media/doc3_fig2.png +0 -0
  303. package/media/doc3_fig3.png +0 -0
  304. package/media/doc3_fig4.png +0 -0
  305. package/media/doc4_fig1.png +0 -0
  306. package/media/doc4_fig2.png +0 -0
  307. package/media/doc4_fig3.png +0 -0
  308. package/media/doc5_fig1.png +0 -0
  309. package/media/doc5_fig2.png +0 -0
  310. package/media/doc5_fig3.png +0 -0
  311. package/patent-disclosure-optimized/SKILL.md +0 -416
  312. package/src/core/module-help.csv +0 -11
  313. package/src/core/skills/xiaoma-advanced-elicitation/SKILL.md +0 -6
  314. package/src/core/skills/xiaoma-advanced-elicitation/methods.csv +0 -51
  315. package/src/core/skills/xiaoma-editorial-review-prose/SKILL.md +0 -6
  316. package/src/core/skills/xiaoma-editorial-review-structure/SKILL.md +0 -6
  317. package/src/core/skills/xiaoma-help/SKILL.md +0 -6
  318. package/src/core/skills/xiaoma-help/workflow.md +0 -88
  319. package/src/core/skills/xiaoma-help/xiaoma-skill-manifest.yaml +0 -1
  320. package/src/core/skills/xiaoma-index-docs/SKILL.md +0 -6
  321. package/src/core/skills/xiaoma-index-docs/xiaoma-skill-manifest.yaml +0 -1
  322. package/src/core/skills/xiaoma-party-mode/SKILL.md +0 -6
  323. package/src/core/skills/xiaoma-party-mode/steps/step-01-agent-loading.md +0 -138
  324. package/src/core/skills/xiaoma-party-mode/steps/step-02-discussion-orchestration.md +0 -187
  325. package/src/core/skills/xiaoma-party-mode/steps/step-03-graceful-exit.md +0 -167
  326. package/src/core/skills/xiaoma-party-mode/workflow.md +0 -190
  327. package/src/core/skills/xiaoma-party-mode/xiaoma-skill-manifest.yaml +0 -1
  328. package/src/core/skills/xiaoma-review-adversarial-general/SKILL.md +0 -6
  329. package/src/core/skills/xiaoma-review-adversarial-general/xiaoma-skill-manifest.yaml +0 -1
  330. package/src/core/skills/xiaoma-review-edge-case-hunter/SKILL.md +0 -6
  331. package/src/core/skills/xiaoma-review-edge-case-hunter/xiaoma-skill-manifest.yaml +0 -1
  332. package/src/core/skills/xiaoma-shard-doc/SKILL.md +0 -6
  333. package/src/core/skills/xiaoma-shard-doc/xiaoma-skill-manifest.yaml +0 -1
  334. package/src/core/tasks/xiaoma-create-prd/SKILL.md +0 -6
  335. package/src/core/tasks/xiaoma-create-prd/data/prd-purpose.md +0 -354
  336. package/src/core/tasks/xiaoma-create-prd/data/upstream-input-contract.md +0 -168
  337. package/src/core/tasks/xiaoma-create-prd/steps-c/step-01-init.md +0 -178
  338. package/src/core/tasks/xiaoma-create-prd/steps-c/step-01b-continue.md +0 -161
  339. package/src/core/tasks/xiaoma-create-prd/steps-c/step-02-discovery.md +0 -208
  340. package/src/core/tasks/xiaoma-create-prd/steps-c/step-02b-vision.md +0 -142
  341. package/src/core/tasks/xiaoma-create-prd/steps-c/step-02c-executive-summary.md +0 -158
  342. package/src/core/tasks/xiaoma-create-prd/steps-c/step-03-success.md +0 -214
  343. package/src/core/tasks/xiaoma-create-prd/steps-c/step-04-journeys.md +0 -201
  344. package/src/core/tasks/xiaoma-create-prd/steps-c/step-05-domain.md +0 -194
  345. package/src/core/tasks/xiaoma-create-prd/steps-c/step-06-innovation.md +0 -211
  346. package/src/core/tasks/xiaoma-create-prd/steps-c/step-07-project-type.md +0 -222
  347. package/src/core/tasks/xiaoma-create-prd/steps-c/step-08-scoping.md +0 -216
  348. package/src/core/tasks/xiaoma-create-prd/steps-c/step-09-functional.md +0 -219
  349. package/src/core/tasks/xiaoma-create-prd/steps-c/step-10-nonfunctional.md +0 -230
  350. package/src/core/tasks/xiaoma-create-prd/steps-c/step-11-polish.md +0 -221
  351. package/src/core/tasks/xiaoma-create-prd/steps-c/step-12-complete.md +0 -115
  352. package/src/core/tasks/xiaoma-create-prd/templates/prd-skeleton-reference.md +0 -428
  353. package/src/core/tasks/xiaoma-create-prd/templates/prd-template.md +0 -108
  354. package/src/core/tasks/xiaoma-create-prd/workflow.md +0 -62
  355. package/src/core/tasks/xiaoma-create-prd/xiaoma-skill-manifest.yaml +0 -1
  356. package/src/utility/agent-components/activation-rules.txt +0 -6
  357. package/src/utility/agent-components/activation-steps.txt +0 -14
  358. package/src/utility/agent-components/agent-command-header.md +0 -1
  359. package/src/utility/agent-components/agent.customize.template.yaml +0 -41
  360. package/src/utility/agent-components/handler-action.txt +0 -4
  361. package/src/utility/agent-components/handler-data.txt +0 -5
  362. package/src/utility/agent-components/handler-exec.txt +0 -6
  363. package/src/utility/agent-components/handler-multi.txt +0 -13
  364. package/src/utility/agent-components/handler-tmpl.txt +0 -5
  365. package/src/utility/agent-components/menu-handlers.txt +0 -6
  366. package/src/xmc/agents/analyst.agent.yaml +0 -47
  367. package/src/xmc/agents/architect.agent.yaml +0 -29
  368. package/src/xmc/agents/dev.agent.yaml +0 -38
  369. package/src/xmc/agents/pm.agent.yaml +0 -44
  370. package/src/xmc/agents/qa.agent.yaml +0 -58
  371. package/src/xmc/agents/quick-flow-solo-dev.agent.yaml +0 -36
  372. package/src/xmc/agents/sm.agent.yaml +0 -53
  373. package/src/xmc/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +0 -224
  374. package/src/xmc/agents/tech-writer/tech-writer.agent.yaml +0 -46
  375. package/src/xmc/agents/tech-writer/xiaoma-skill-manifest.yaml +0 -3
  376. package/src/xmc/agents/ux-designer.agent.yaml +0 -27
  377. package/src/xmc/agents/xiaoma-skill-manifest.yaml +0 -39
  378. package/src/xmc/data/project-context-template.md +0 -26
  379. package/src/xmc/module-help.csv +0 -32
  380. package/src/xmc/module.yaml +0 -50
  381. package/src/xmc/teams/default-party.csv +0 -20
  382. package/src/xmc/teams/team-fullstack.yaml +0 -12
  383. package/src/xmc/workflows/1-analysis/auto-requirements-pipeline/steps/step-08-finalize.md +0 -124
  384. package/src/xmc/workflows/1-analysis/auto-requirements-pipeline/workflow.md +0 -107
  385. package/src/xmc/workflows/1-analysis/auto-requirements-pipeline/xiaoma-skill-manifest.yaml +0 -3
  386. package/src/xmc/workflows/1-analysis/research/market-steps/step-01-init.md +0 -182
  387. package/src/xmc/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +0 -237
  388. package/src/xmc/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +0 -249
  389. package/src/xmc/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +0 -259
  390. package/src/xmc/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +0 -177
  391. package/src/xmc/workflows/1-analysis/research/market-steps/step-06-research-completion.md +0 -476
  392. package/src/xmc/workflows/1-analysis/research/xiaoma-domain-research/SKILL.md +0 -6
  393. package/src/xmc/workflows/1-analysis/research/xiaoma-domain-research/workflow.md +0 -49
  394. package/src/xmc/workflows/1-analysis/research/xiaoma-domain-research/xiaoma-skill-manifest.yaml +0 -1
  395. package/src/xmc/workflows/1-analysis/research/xiaoma-market-research/SKILL.md +0 -6
  396. package/src/xmc/workflows/1-analysis/research/xiaoma-market-research/workflow.md +0 -49
  397. package/src/xmc/workflows/1-analysis/research/xiaoma-market-research/xiaoma-skill-manifest.yaml +0 -1
  398. package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/SKILL.md +0 -6
  399. package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/research.template.md +0 -29
  400. package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/workflow.md +0 -50
  401. package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/xiaoma-skill-manifest.yaml +0 -1
  402. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/SKILL.md +0 -6
  403. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/product-brief.template.md +0 -10
  404. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-01-init.md +0 -170
  405. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-01b-continue.md +0 -158
  406. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-02-vision.md +0 -193
  407. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-03-users.md +0 -196
  408. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-04-metrics.md +0 -199
  409. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-05-scope.md +0 -213
  410. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-06-complete.md +0 -159
  411. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/workflow.md +0 -55
  412. package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/xiaoma-skill-manifest.yaml +0 -1
  413. package/src/xmc/workflows/1-analysis/xiaoma-product-brief-preview/xiaoma-skill-manifest.yaml +0 -1
  414. package/src/xmc/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +0 -15
  415. package/src/xmc/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +0 -197
  416. package/src/xmc/workflows/2-plan-workflows/create-prd/data/project-types.csv +0 -11
  417. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +0 -224
  418. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +0 -191
  419. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +0 -209
  420. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +0 -174
  421. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -214
  422. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +0 -228
  423. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +0 -217
  424. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -205
  425. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -243
  426. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +0 -263
  427. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +0 -209
  428. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -264
  429. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +0 -242
  430. package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +0 -232
  431. package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +0 -65
  432. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/SKILL.md +0 -6
  433. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-01-init.md +0 -135
  434. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-01b-continue.md +0 -127
  435. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-02-discovery.md +0 -190
  436. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-03-core-experience.md +0 -217
  437. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-04-emotional-response.md +0 -220
  438. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-05-inspiration.md +0 -235
  439. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-06-design-system.md +0 -253
  440. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-07-defining-experience.md +0 -255
  441. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-08-visual-foundation.md +0 -225
  442. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-09-design-directions.md +0 -225
  443. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-10-user-journeys.md +0 -242
  444. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-11-component-strategy.md +0 -249
  445. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-12-ux-patterns.md +0 -238
  446. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-13-responsive-accessibility.md +0 -265
  447. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-14-complete.md +0 -171
  448. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/ux-design-template.md +0 -13
  449. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/workflow.md +0 -36
  450. package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/xiaoma-skill-manifest.yaml +0 -1
  451. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/SKILL.md +0 -6
  452. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-01-discovery.md +0 -242
  453. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-01b-legacy-conversion.md +0 -204
  454. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-02-review.md +0 -245
  455. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-03-edit.md +0 -250
  456. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-04-complete.md +0 -165
  457. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/workflow.md +0 -63
  458. package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/xiaoma-skill-manifest.yaml +0 -1
  459. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/SKILL.md +0 -6
  460. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/domain-complexity.csv +0 -15
  461. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/prd-purpose.md +0 -197
  462. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/prd-quality-rubric.csv +0 -14
  463. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/project-types.csv +0 -11
  464. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-01-discovery.md +0 -221
  465. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-02-format-detection.md +0 -188
  466. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-02b-parity-check.md +0 -206
  467. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-03-density-validation.md +0 -171
  468. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -211
  469. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-05-measurability-validation.md +0 -225
  470. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-06-traceability-validation.md +0 -214
  471. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -202
  472. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -240
  473. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-09-project-type-validation.md +0 -260
  474. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-10-smart-validation.md +0 -206
  475. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -261
  476. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-12-completeness-validation.md +0 -239
  477. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-13-report-complete.md +0 -229
  478. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/workflow.md +0 -62
  479. package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/xiaoma-skill-manifest.yaml +0 -1
  480. package/src/xmc/workflows/3-solutioning/xiaoma-check-implementation-readiness/SKILL.md +0 -6
  481. package/src/xmc/workflows/3-solutioning/xiaoma-check-implementation-readiness/workflow.md +0 -49
  482. package/src/xmc/workflows/3-solutioning/xiaoma-check-implementation-readiness/xiaoma-skill-manifest.yaml +0 -1
  483. package/src/xmc/workflows/3-solutioning/xiaoma-create-architecture/SKILL.md +0 -6
  484. package/src/xmc/workflows/3-solutioning/xiaoma-create-architecture/workflow.md +0 -38
  485. package/src/xmc/workflows/3-solutioning/xiaoma-create-architecture/xiaoma-skill-manifest.yaml +0 -1
  486. package/src/xmc/workflows/3-solutioning/xiaoma-create-epics-and-stories/SKILL.md +0 -6
  487. package/src/xmc/workflows/3-solutioning/xiaoma-create-epics-and-stories/workflow.md +0 -53
  488. package/src/xmc/workflows/3-solutioning/xiaoma-create-epics-and-stories/xiaoma-skill-manifest.yaml +0 -1
  489. package/src/xmc/workflows/4-implementation/auto-story-pipeline/checklist.md +0 -22
  490. package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-02-create-story.md +0 -102
  491. package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-05-code-review.md +0 -95
  492. package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-08-complete-story.md +0 -114
  493. package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-09-finalize.md +0 -69
  494. package/src/xmc/workflows/4-implementation/auto-story-pipeline/workflow.md +0 -89
  495. package/src/xmc/workflows/4-implementation/auto-story-pipeline/xiaoma-skill-manifest.yaml +0 -3
  496. package/src/xmc/workflows/4-implementation/xiaoma-code-review/SKILL.md +0 -6
  497. package/src/xmc/workflows/4-implementation/xiaoma-code-review/checklist.md +0 -23
  498. package/src/xmc/workflows/4-implementation/xiaoma-code-review/steps/step-01-gather-context.md +0 -61
  499. package/src/xmc/workflows/4-implementation/xiaoma-code-review/steps/step-02-review.md +0 -41
  500. package/src/xmc/workflows/4-implementation/xiaoma-code-review/steps/step-04-present.md +0 -38
  501. package/src/xmc/workflows/4-implementation/xiaoma-code-review/workflow.md +0 -54
  502. package/src/xmc/workflows/4-implementation/xiaoma-code-review/xiaoma-skill-manifest.yaml +0 -1
  503. package/src/xmc/workflows/4-implementation/xiaoma-correct-course/SKILL.md +0 -6
  504. package/src/xmc/workflows/4-implementation/xiaoma-correct-course/xiaoma-skill-manifest.yaml +0 -1
  505. package/src/xmc/workflows/4-implementation/xiaoma-create-story/SKILL.md +0 -6
  506. package/src/xmc/workflows/4-implementation/xiaoma-create-story/discover-inputs.md +0 -88
  507. package/src/xmc/workflows/4-implementation/xiaoma-create-story/xiaoma-skill-manifest.yaml +0 -1
  508. package/src/xmc/workflows/4-implementation/xiaoma-dev-story/SKILL.md +0 -6
  509. package/src/xmc/workflows/4-implementation/xiaoma-dev-story/xiaoma-skill-manifest.yaml +0 -1
  510. package/src/xmc/workflows/4-implementation/xiaoma-retrospective/SKILL.md +0 -6
  511. package/src/xmc/workflows/4-implementation/xiaoma-retrospective/xiaoma-skill-manifest.yaml +0 -1
  512. package/src/xmc/workflows/4-implementation/xiaoma-sprint-planning/SKILL.md +0 -6
  513. package/src/xmc/workflows/4-implementation/xiaoma-sprint-planning/xiaoma-skill-manifest.yaml +0 -1
  514. package/src/xmc/workflows/4-implementation/xiaoma-sprint-status/SKILL.md +0 -6
  515. package/src/xmc/workflows/4-implementation/xiaoma-sprint-status/xiaoma-skill-manifest.yaml +0 -1
  516. package/src/xmc/workflows/xiaoma-document-project/SKILL.md +0 -6
  517. package/src/xmc/workflows/xiaoma-document-project/workflow.md +0 -27
  518. package/src/xmc/workflows/xiaoma-document-project/xiaoma-skill-manifest.yaml +0 -1
  519. package/src/xmc/workflows/xiaoma-generate-project-context/SKILL.md +0 -6
  520. package/src/xmc/workflows/xiaoma-generate-project-context/workflow.md +0 -43
  521. package/src/xmc/workflows/xiaoma-generate-project-context/xiaoma-skill-manifest.yaml +0 -1
  522. package/src/xmc/workflows/xiaoma-qa-generate-e2e-tests/SKILL.md +0 -6
  523. package/src/xmc/workflows/xiaoma-qa-generate-e2e-tests/xiaoma-skill-manifest.yaml +0 -1
  524. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/SKILL.md +0 -6
  525. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-01-mode-detection.md +0 -169
  526. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-02-context-gathering.md +0 -114
  527. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-03-execute.md +0 -107
  528. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-04-self-check.md +0 -107
  529. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-05-adversarial-review.md +0 -94
  530. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-06-resolve-findings.md +0 -144
  531. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/workflow.md +0 -38
  532. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/xiaoma-skill-manifest.yaml +0 -1
  533. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/xiaoma-skill-manifest.yaml +0 -1
  534. package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-spec/xiaoma-skill-manifest.yaml +0 -1
  535. package/tools/cli/commands/install.js +0 -87
  536. package/tools/cli/external-official-modules.yaml +0 -4
  537. package/tools/cli/installers/lib/core/custom-module-cache.js +0 -260
  538. package/tools/cli/installers/lib/core/dependency-resolver.js +0 -743
  539. package/tools/cli/installers/lib/core/detector.js +0 -223
  540. package/tools/cli/installers/lib/core/ide-config-manager.js +0 -157
  541. package/tools/cli/installers/lib/core/installer.js +0 -3212
  542. package/tools/cli/installers/lib/core/manifest-generator.js +0 -1374
  543. package/tools/cli/installers/lib/core/manifest.js +0 -1040
  544. package/tools/cli/installers/lib/custom/handler.js +0 -358
  545. package/tools/cli/installers/lib/ide/_base-ide.js +0 -673
  546. package/tools/cli/installers/lib/ide/_config-driven.js +0 -1058
  547. package/tools/cli/installers/lib/ide/platform-codes.js +0 -100
  548. package/tools/cli/installers/lib/ide/platform-codes.yaml +0 -321
  549. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +0 -181
  550. package/tools/cli/installers/lib/ide/shared/module-injections.js +0 -136
  551. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +0 -368
  552. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +0 -179
  553. package/tools/cli/installers/lib/ide/shared/xiaoma-artifacts.js +0 -181
  554. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +0 -14
  555. package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +0 -8
  556. package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +0 -15
  557. package/tools/cli/installers/lib/ide/templates/combined/default-task.md +0 -10
  558. package/tools/cli/installers/lib/ide/templates/combined/default-tool.md +0 -10
  559. package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +0 -6
  560. package/tools/cli/installers/lib/ide/templates/combined/gemini-agent.toml +0 -14
  561. package/tools/cli/installers/lib/ide/templates/combined/gemini-task.toml +0 -11
  562. package/tools/cli/installers/lib/ide/templates/combined/gemini-tool.toml +0 -11
  563. package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow-yaml.toml +0 -16
  564. package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow.toml +0 -14
  565. package/tools/cli/installers/lib/ide/templates/combined/kiro-agent.md +0 -16
  566. package/tools/cli/installers/lib/ide/templates/combined/kiro-task.md +0 -9
  567. package/tools/cli/installers/lib/ide/templates/combined/kiro-tool.md +0 -9
  568. package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow.md +0 -7
  569. package/tools/cli/installers/lib/ide/templates/combined/opencode-agent.md +0 -15
  570. package/tools/cli/installers/lib/ide/templates/combined/opencode-task.md +0 -13
  571. package/tools/cli/installers/lib/ide/templates/combined/opencode-tool.md +0 -13
  572. package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow-yaml.md +0 -16
  573. package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow.md +0 -16
  574. package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +0 -9
  575. package/tools/cli/installers/lib/ide/templates/combined/trae.md +0 -9
  576. package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +0 -10
  577. package/tools/cli/installers/lib/ide/templates/split/.gitkeep +0 -0
  578. package/tools/cli/installers/lib/modules/external-manager.js +0 -136
  579. package/tools/cli/installers/lib/modules/manager.js +0 -1382
  580. package/tools/cli/lib/activation-builder.js +0 -165
  581. package/tools/cli/lib/agent/compiler.js +0 -516
  582. package/tools/cli/lib/agent/installer.js +0 -680
  583. package/tools/cli/lib/agent/template-engine.js +0 -152
  584. package/tools/cli/lib/agent-analyzer.js +0 -97
  585. package/tools/cli/lib/agent-party-generator.js +0 -194
  586. package/tools/cli/lib/cli-utils.js +0 -182
  587. package/tools/cli/lib/config.js +0 -213
  588. package/tools/cli/lib/platform-codes.js +0 -116
  589. package/tools/cli/lib/project-root.js +0 -77
  590. package/tools/cli/lib/ui.js +0 -1960
  591. package/tools/cli/lib/xml-handler.js +0 -177
  592. package/tools/cli/lib/xml-to-markdown.js +0 -82
  593. package/tools/cli/lib/yaml-xml-builder.js +0 -570
  594. package/tools/platform-codes.yaml +0 -157
  595. package/tools/schema/agent.js +0 -489
  596. package//344/270/223/345/210/251/344/272/244/345/272/225/344/271/246_1_/351/235/242/345/220/221AI/346/231/272/350/203/275/344/275/223/347/232/204/345/244/232/351/200/232/351/201/223/344/276/235/350/265/226_20260318.md +0 -483
  597. package//344/270/223/345/210/251/344/272/244/345/272/225/344/271/246_2_/345/237/272/344/272/216/351/205/215/347/275/256/351/251/261/345/212/250/347/232/204/350/267/250/345/271/263/345/217/260IDE/346/231/272/350/203/275_20260318.md +0 -592
  598. package//344/270/223/345/210/251/344/272/244/345/272/225/344/271/246_3_AI/346/231/272/350/203/275/344/275/223/345/243/260/346/230/216/345/274/217/345/256/232/344/271/211/347/232/204/347/274/226/350/257/221/346/265/201/346/260/264_20260318.md +0 -624
  599. package//344/270/223/345/210/251/344/272/244/345/272/225/344/271/246_4_/345/237/272/344/272/216/345/223/210/345/270/214/346/214/207/347/272/271/347/232/204/346/231/272/350/203/275/344/275/223/351/231/204/345/261/236/350/265/204/346/272/220/351/200/211_20260318.md +0 -628
  600. package//344/270/223/345/210/251/344/272/244/345/272/225/344/271/246_5_AI/346/231/272/350/203/275/344/275/223/350/247/246/345/217/221/346/214/207/344/273/244/347/232/204/345/244/215/345/220/210/346/240/274/345/274/217/346/240/241_20260318.md +0 -652
  601. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/SKILL.md +0 -0
  602. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/brain-methods.csv +0 -0
  603. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-01-session-setup.md +0 -0
  604. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-01b-continue.md +0 -0
  605. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02a-user-selected.md +0 -0
  606. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02b-ai-recommended.md +0 -0
  607. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02c-random-selection.md +0 -0
  608. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02d-progressive-flow.md +0 -0
  609. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-04-idea-organization.md +0 -0
  610. /package/src/{core/skills → core-skills}/xiaoma-brainstorming/template.md +0 -0
  611. /package/src/{core/skills → core-skills}/xiaoma-distillator/SKILL.md +0 -0
  612. /package/src/{core/skills → core-skills}/xiaoma-distillator/agents/distillate-compressor.md +0 -0
  613. /package/src/{core/skills → core-skills}/xiaoma-distillator/agents/round-trip-reconstructor.md +0 -0
  614. /package/src/{core/skills → core-skills}/xiaoma-distillator/resources/compression-rules.md +0 -0
  615. /package/src/{core/skills → core-skills}/xiaoma-distillator/resources/splitting-strategy.md +0 -0
  616. /package/src/{core/skills → core-skills}/xiaoma-distillator/scripts/tests/test_analyze_sources.py +0 -0
  617. /package/src/{core/skills → core-skills}/xiaoma-distillator/xiaoma-skill-manifest.yaml +0 -0
  618. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-01-init.md +0 -0
  619. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-02-domain-analysis.md +0 -0
  620. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-03-competitive-landscape.md +0 -0
  621. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-04-regulatory-focus.md +0 -0
  622. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-05-technical-trends.md +0 -0
  623. /package/src/{xmc/workflows/1-analysis/research → xmc-skills/1-analysis/research/xiaoma-domain-research}/research.template.md +0 -0
  624. /package/src/{xmc/workflows/1-analysis/research/xiaoma-domain-research → xmc-skills/1-analysis/research/xiaoma-market-research}/research.template.md +0 -0
  625. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-01-init.md +0 -0
  626. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-02-customer-behavior.md +0 -0
  627. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-03-customer-pain-points.md +0 -0
  628. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-04-customer-decisions.md +0 -0
  629. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-05-competitive-analysis.md +0 -0
  630. /package/src/{xmc/workflows/1-analysis/research/xiaoma-market-research → xmc-skills/1-analysis/research/xiaoma-technical-research}/research.template.md +0 -0
  631. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-01-init.md +0 -0
  632. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-02-technical-overview.md +0 -0
  633. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-03-integration-patterns.md +0 -0
  634. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-04-architectural-patterns.md +0 -0
  635. /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-05-implementation-research.md +0 -0
  636. /package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/SKILL.md +0 -0
  637. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/checklist.md +0 -0
  638. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/documentation-requirements.csv +0 -0
  639. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/instructions.md +0 -0
  640. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/deep-dive-template.md +0 -0
  641. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/index-template.md +0 -0
  642. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/project-overview-template.md +0 -0
  643. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/project-scan-report-schema.json +0 -0
  644. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/source-tree-template.md +0 -0
  645. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/deep-dive-workflow.md +0 -0
  646. /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/full-scan-workflow.md +0 -0
  647. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/SKILL.md +0 -0
  648. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/artifact-analyzer.md +0 -0
  649. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/opportunity-reviewer.md +0 -0
  650. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/skeptic-reviewer.md +0 -0
  651. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/web-researcher.md +0 -0
  652. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/contextual-discovery.md +0 -0
  653. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/draft-and-review.md +0 -0
  654. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/finalize.md +0 -0
  655. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/guided-elicitation.md +0 -0
  656. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/resources/brief-template.md +0 -0
  657. /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/xiaoma-manifest.json +0 -0
  658. /package/src/{core/skills/xiaoma-advanced-elicitation → xmc-skills/1-analysis/xiaoma-product-brief-preview}/xiaoma-skill-manifest.yaml +0 -0
  659. /package/src/{core/tasks/xiaoma-create-prd/data → xmc-skills/2-plan-workflows/xiaoma-prd/assets}/domain-complexity.csv +0 -0
  660. /package/src/{core/tasks/xiaoma-create-prd/data → xmc-skills/2-plan-workflows/xiaoma-prd/assets}/project-types.csv +0 -0
  661. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-04-ux-alignment.md +0 -0
  662. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-05-epic-quality-review.md +0 -0
  663. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/templates/readiness-report-template.md +0 -0
  664. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/architecture-decision-template.md +0 -0
  665. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/data/domain-complexity.csv +0 -0
  666. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/data/project-types.csv +0 -0
  667. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-01-init.md +0 -0
  668. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-01b-continue.md +0 -0
  669. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-02-context.md +0 -0
  670. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-03-starter.md +0 -0
  671. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-04-decisions.md +0 -0
  672. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-05-patterns.md +0 -0
  673. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-06-structure.md +0 -0
  674. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-01-validate-prerequisites.md +0 -0
  675. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-03-create-stories.md +0 -0
  676. /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/templates/epics-template.md +0 -0
  677. /package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/project-context-template.md +0 -0
  678. /package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/steps/step-01-discover.md +0 -0
  679. /package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/steps/step-02-generate.md +0 -0
  680. /package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/SKILL.md +0 -0
  681. /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-create-story/checklist.md +0 -0
  682. /package/src/{xmc/workflows/4-implementation/xiaoma-code-review → xmc-skills/4-implementation/xiaoma-create-story}/discover-inputs.md +0 -0
  683. /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-create-story/template.md +0 -0
  684. /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-dev-story/checklist.md +0 -0
  685. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/SKILL.md +0 -0
  686. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-01-clarify-and-route.md +0 -0
  687. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-02-plan.md +0 -0
  688. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-03-implement.md +0 -0
  689. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-04-review.md +0 -0
  690. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-05-present.md +0 -0
  691. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/tech-spec-template.md +0 -0
  692. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/workflow.md +0 -0
  693. /package/src/{core/skills/xiaoma-brainstorming → xmc-skills/4-implementation/xiaoma-quick-dev-new-preview}/xiaoma-skill-manifest.yaml +0 -0
  694. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/SKILL.md +0 -0
  695. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-01-understand.md +0 -0
  696. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-02-investigate.md +0 -0
  697. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-03-generate.md +0 -0
  698. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-04-review.md +0 -0
  699. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/tech-spec-template.md +0 -0
  700. /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/workflow.md +0 -0
  701. /package/src/{core/skills/xiaoma-editorial-review-prose → xmc-skills/4-implementation/xiaoma-quick-spec}/xiaoma-skill-manifest.yaml +0 -0
  702. /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-sprint-planning/checklist.md +0 -0
  703. /package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/SKILL.md +0 -0
  704. /package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/xiaoma-skill-manifest.yaml +0 -0
  705. /package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/SKILL.md +0 -0
  706. /package/src/{xmc/workflows/5-full-pipeline/auto-prd-to-stories → xmc-skills/5-full-pipeline/xiaoma-auto-prd-to-stories}/xiaoma-skill-manifest.yaml +0 -0
  707. /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/references/disclosure-template.md +0 -0
  708. /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/references/docx-format-spec.md +0 -0
  709. /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/references/mining-principles.md +0 -0
  710. /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/scripts/md2docx.js +0 -0
  711. /package/src/{core/skills/xiaoma-editorial-review-structure → xpm-skills/xiaoma-patent-mining}/xiaoma-skill-manifest.yaml +0 -0
  712. /package/tools/{cli/installers → installer}/install-messages.yaml +0 -0
@@ -0,0 +1,1624 @@
1
+ const path = require('node:path');
2
+ const fs = require('../fs-native');
3
+ const { Manifest } = require('./manifest');
4
+ const { OfficialModules } = require('../modules/official-modules');
5
+ const { IdeManager } = require('../ide/manager');
6
+ const { FileOps } = require('../file-ops');
7
+ const { Config } = require('./config');
8
+ const { getProjectRoot, getSourcePath } = require('../project-root');
9
+ const { ManifestGenerator } = require('./manifest-generator');
10
+ const prompts = require('../prompts');
11
+ const { XiaoMa_FOLDER_NAME } = require('../ide/shared/path-utils');
12
+ const { InstallPaths } = require('./install-paths');
13
+ const { ExternalModuleManager } = require('../modules/external-manager');
14
+ const { resolveModuleVersion } = require('../modules/version-resolver');
15
+ const { MODULE_HELP_CSV_HEADER } = require('../modules/module-help-schema');
16
+
17
+ const { ExistingInstall } = require('./existing-install');
18
+ const { warnPreNativeSkillsLegacy } = require('./legacy-warnings');
19
+
20
+ class Installer {
21
+ constructor() {
22
+ this.externalModuleManager = new ExternalModuleManager();
23
+ this.manifest = new Manifest();
24
+ this.ideManager = new IdeManager();
25
+ this.fileOps = new FileOps();
26
+ this.installedFiles = new Set(); // Track all installed files
27
+ this.xiaomaFolderName = XiaoMa_FOLDER_NAME;
28
+ }
29
+
30
+ /**
31
+ * Main installation method
32
+ * @param {Object} config - Installation configuration
33
+ * @param {string} config.directory - Target directory
34
+ * @param {string[]} config.modules - Modules to install (including 'core')
35
+ * @param {string[]} config.ides - IDEs to configure
36
+ */
37
+ async install(originalConfig) {
38
+ let updateState = null;
39
+
40
+ try {
41
+ const config = Config.build(originalConfig);
42
+ const paths = await InstallPaths.create(config);
43
+ const officialModules = await OfficialModules.build(config, paths);
44
+ const existingInstall = await ExistingInstall.detect(paths.xiaomaDir);
45
+
46
+ try {
47
+ await warnPreNativeSkillsLegacy({
48
+ projectRoot: paths.projectRoot,
49
+ existingVersion: existingInstall.installed ? existingInstall.version : null,
50
+ });
51
+ } catch (error) {
52
+ // Legacy-dir scan is informational; never let it abort install.
53
+ await prompts.log.warn(`Warning: Could not check for legacy XiaoMa entries: ${error.message}`);
54
+ }
55
+
56
+ if (existingInstall.installed) {
57
+ await this._removeDeselectedModules(existingInstall, config, paths, originalConfig._preserveModules || []);
58
+ updateState = await this._prepareUpdateState(paths, config, existingInstall, officialModules);
59
+ await this._removeDeselectedIdes(existingInstall, config, paths);
60
+ }
61
+
62
+ await this._validateIdeSelection(config);
63
+
64
+ // Capture pre-install module versions for from→to display
65
+ const preInstallVersions = new Map();
66
+ if (existingInstall.installed) {
67
+ const existingModules = await this.manifest.getAllModuleVersions(paths.xiaomaDir);
68
+ for (const mod of existingModules) {
69
+ if (mod.name && mod.version) {
70
+ preInstallVersions.set(mod.name, mod.version);
71
+ }
72
+ }
73
+ }
74
+
75
+ // Results collector for consolidated summary
76
+ const results = [];
77
+ const addResult = (step, status, detail = '', meta = {}) => results.push({ step, status, detail, ...meta });
78
+
79
+ // Capture previously installed skill rows before they get overwritten
80
+ const preservedModules = originalConfig._preserveModules || [];
81
+ const previousSkillManifestRows = await this._readSkillManifestRows(paths.xiaomaDir);
82
+ const previousSkillIds = this._getPreviousSkillIdsForCleanup(previousSkillManifestRows, preservedModules);
83
+
84
+ const allModules = config.modules || [];
85
+
86
+ await this._installAndConfigure(
87
+ config,
88
+ originalConfig,
89
+ paths,
90
+ allModules,
91
+ allModules,
92
+ addResult,
93
+ officialModules,
94
+ previousSkillManifestRows,
95
+ );
96
+
97
+ await this._setupIdes(config, allModules, paths, addResult, previousSkillIds);
98
+
99
+ // Skills are now in IDE directories — remove redundant copies from _xiaoma/.
100
+ // Also cleans up skill dirs left by older installer versions.
101
+ await this._cleanupSkillDirs(paths.xiaomaDir);
102
+
103
+ const restoreResult = await this._restoreUserFiles(paths, updateState);
104
+
105
+ // Render consolidated summary
106
+ await this.renderInstallSummary(results, {
107
+ xiaomaDir: paths.xiaomaDir,
108
+ modules: config.modules,
109
+ ides: config.ides,
110
+ customFiles: restoreResult.customFiles.length > 0 ? restoreResult.customFiles : undefined,
111
+ modifiedFiles: restoreResult.modifiedFiles.length > 0 ? restoreResult.modifiedFiles : undefined,
112
+ preInstallVersions,
113
+ });
114
+
115
+ return {
116
+ success: true,
117
+ path: paths.xiaomaDir,
118
+ modules: config.modules,
119
+ ides: config.ides,
120
+ projectDir: paths.projectRoot,
121
+ };
122
+ } catch (error) {
123
+ await prompts.log.error('Installation failed');
124
+
125
+ // Clean up any temp backup directories that were created before the failure
126
+ try {
127
+ if (updateState?.tempBackupDir && (await fs.pathExists(updateState.tempBackupDir))) {
128
+ await fs.remove(updateState.tempBackupDir);
129
+ }
130
+ if (updateState?.tempModifiedBackupDir && (await fs.pathExists(updateState.tempModifiedBackupDir))) {
131
+ await fs.remove(updateState.tempModifiedBackupDir);
132
+ }
133
+ } catch {
134
+ // Best-effort cleanup — don't mask the original error
135
+ }
136
+
137
+ throw error;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Remove modules that were previously installed but are no longer selected.
143
+ * No confirmation — the user's module selection is the decision.
144
+ */
145
+ async _removeDeselectedModules(existingInstall, config, paths, preservedModules = []) {
146
+ const previouslyInstalled = new Set(existingInstall.moduleIds);
147
+ const newlySelected = new Set(config.modules || []);
148
+ const preserved = new Set(preservedModules);
149
+ const toRemove = [...previouslyInstalled].filter((m) => !newlySelected.has(m) && m !== 'core' && !preserved.has(m));
150
+
151
+ for (const moduleId of toRemove) {
152
+ const modulePath = paths.moduleDir(moduleId);
153
+ try {
154
+ if (await fs.pathExists(modulePath)) {
155
+ await fs.remove(modulePath);
156
+ }
157
+ } catch (error) {
158
+ await prompts.log.warn(`Warning: Failed to remove ${moduleId}: ${error.message}`);
159
+ }
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Fail fast if all selected IDEs are suspended.
165
+ */
166
+ async _validateIdeSelection(config) {
167
+ if (!config.ides || config.ides.length === 0) return;
168
+
169
+ await this.ideManager.ensureInitialized();
170
+ const suspendedIdes = config.ides.filter((ide) => {
171
+ const handler = this.ideManager.handlers.get(ide);
172
+ return handler?.platformConfig?.suspended;
173
+ });
174
+
175
+ if (suspendedIdes.length > 0 && suspendedIdes.length === config.ides.length) {
176
+ for (const ide of suspendedIdes) {
177
+ const handler = this.ideManager.handlers.get(ide);
178
+ await prompts.log.error(`${handler.displayName || ide}: ${handler.platformConfig.suspended}`);
179
+ }
180
+ throw new Error(
181
+ `All selected tool(s) are suspended: ${suspendedIdes.join(', ')}. Installation aborted to prevent upgrading _xiaoma/ without a working IDE configuration.`,
182
+ );
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Remove IDEs that were previously installed but are no longer selected.
188
+ * No confirmation — the user's IDE selection is the decision.
189
+ */
190
+ async _removeDeselectedIdes(existingInstall, config, paths) {
191
+ const previouslyInstalled = new Set(existingInstall.ides);
192
+ const newlySelected = new Set(config.ides || []);
193
+ const toRemove = [...previouslyInstalled].filter((ide) => !newlySelected.has(ide));
194
+
195
+ if (toRemove.length === 0) return;
196
+
197
+ // Pass the newly-selected list as remainingIdes so cleanupByList skips
198
+ // target_dir wipes for IDEs whose directory is still owned by a peer
199
+ // (e.g. removing 'cursor' while 'gemini' remains — both share .agents/skills).
200
+ const results = await this.ideManager.cleanupByList(paths.projectRoot, toRemove, {
201
+ remainingIdes: [...newlySelected],
202
+ });
203
+
204
+ for (const result of results || []) {
205
+ if (result && result.success === false) {
206
+ await prompts.log.warn(`Warning: Failed to remove ${result.ide}: ${result.error || 'unknown error'}`);
207
+ }
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Install modules, create directories, generate configs and manifests.
213
+ */
214
+ async _installAndConfigure(
215
+ config,
216
+ originalConfig,
217
+ paths,
218
+ officialModuleIds,
219
+ allModules,
220
+ addResult,
221
+ officialModules,
222
+ previousSkillManifestRows = [],
223
+ ) {
224
+ const isQuickUpdate = config.isQuickUpdate();
225
+ const moduleConfigs = officialModules.moduleConfigs;
226
+
227
+ const dirResults = { createdDirs: [], movedDirs: [], createdWdsFolders: [] };
228
+
229
+ const installTasks = [];
230
+
231
+ installTasks.push({
232
+ title: 'Installing shared scripts',
233
+ task: async () => {
234
+ await this._installSharedScripts(paths);
235
+ addResult('Shared scripts', 'ok');
236
+ return 'Shared scripts installed';
237
+ },
238
+ });
239
+
240
+ if (allModules.length > 0) {
241
+ installTasks.push({
242
+ title: isQuickUpdate ? `Updating ${allModules.length} module(s)` : `Installing ${allModules.length} module(s)`,
243
+ task: async (message) => {
244
+ const installedModuleNames = new Set();
245
+
246
+ await this._installOfficialModules(config, paths, officialModuleIds, addResult, isQuickUpdate, officialModules, {
247
+ message,
248
+ installedModuleNames,
249
+ });
250
+
251
+ return `${allModules.length} module(s) ${isQuickUpdate ? 'updated' : 'installed'}`;
252
+ },
253
+ });
254
+ }
255
+
256
+ installTasks.push({
257
+ title: 'Creating module directories',
258
+ task: async (message) => {
259
+ const verboseMode = process.env.XiaoMa_VERBOSE_INSTALL === 'true' || config.verbose;
260
+ const moduleLogger = {
261
+ log: async (msg) => (verboseMode ? await prompts.log.message(msg) : undefined),
262
+ error: async (msg) => await prompts.log.error(msg),
263
+ warn: async (msg) => await prompts.log.warn(msg),
264
+ };
265
+
266
+ if (config.modules && config.modules.length > 0) {
267
+ for (const moduleName of config.modules) {
268
+ message(`Setting up ${moduleName}...`);
269
+ const result = await officialModules.createModuleDirectories(moduleName, paths.xiaomaDir, {
270
+ installedIDEs: config.ides || [],
271
+ moduleConfig: moduleConfigs[moduleName] || {},
272
+ existingModuleConfig: officialModules.existingConfig?.[moduleName] || {},
273
+ coreConfig: moduleConfigs.core || {},
274
+ logger: moduleLogger,
275
+ silent: true,
276
+ });
277
+ if (result) {
278
+ dirResults.createdDirs.push(...result.createdDirs);
279
+ dirResults.movedDirs.push(...(result.movedDirs || []));
280
+ dirResults.createdWdsFolders.push(...result.createdWdsFolders);
281
+ }
282
+ }
283
+ }
284
+
285
+ addResult('Module directories', 'ok');
286
+ return 'Module directories created';
287
+ },
288
+ });
289
+
290
+ const configTask = {
291
+ title: 'Generating configurations',
292
+ task: async (message) => {
293
+ await this.generateModuleConfigs(paths.xiaomaDir, moduleConfigs);
294
+ addResult('Configurations', 'ok', 'generated');
295
+
296
+ this.installedFiles.add(paths.manifestFile());
297
+ this.installedFiles.add(paths.centralConfig());
298
+ this.installedFiles.add(paths.centralUserConfig());
299
+
300
+ message('Generating manifests...');
301
+ const manifestGen = new ManifestGenerator();
302
+ const preservedModules = originalConfig._preserveModules || [];
303
+
304
+ const allModulesForManifest = config.isQuickUpdate()
305
+ ? originalConfig._existingModules || allModules || []
306
+ : preservedModules.length > 0
307
+ ? [...allModules, ...preservedModules]
308
+ : allModules || [];
309
+
310
+ let modulesForCsvPreserve;
311
+ if (config.isQuickUpdate()) {
312
+ modulesForCsvPreserve = originalConfig._existingModules || allModules || [];
313
+ } else {
314
+ modulesForCsvPreserve = preservedModules.length > 0 ? [...allModules, ...preservedModules] : allModules;
315
+ }
316
+
317
+ await this._trackPreservedModuleFiles(paths.xiaomaDir, preservedModules);
318
+
319
+ await manifestGen.generateManifests(paths.xiaomaDir, allModulesForManifest, [...this.installedFiles], {
320
+ ides: config.ides || [],
321
+ preservedModules: modulesForCsvPreserve,
322
+ moduleConfigs,
323
+ });
324
+ await this._appendPreservedSkillManifestRows(paths.xiaomaDir, previousSkillManifestRows, preservedModules);
325
+
326
+ // Apply post-install --set TOML patches. Runs after writeCentralConfig
327
+ // (inside generateManifests above) so the patch operates on the
328
+ // freshly written `_xiaoma/config.toml` / `_xiaoma/config.user.toml`.
329
+ // See `tools/installer/set-overrides.js` for routing rules.
330
+ if (config.setOverrides && Object.keys(config.setOverrides).length > 0) {
331
+ const { applySetOverrides } = require('../set-overrides');
332
+ const applied = await applySetOverrides(config.setOverrides, paths.xiaomaDir);
333
+ if (applied.length > 0) {
334
+ const summary = applied.map((a) => `${a.module}.${a.key} → ${a.file}`).join(', ');
335
+ await prompts.log.info(`Applied --set overrides: ${summary}`);
336
+ }
337
+ }
338
+
339
+ message('Generating help catalog...');
340
+ await this.mergeModuleHelpCatalogs(paths.xiaomaDir, manifestGen.agents);
341
+ addResult('Help catalog', 'ok');
342
+
343
+ return 'Configurations generated';
344
+ },
345
+ };
346
+ installTasks.push(configTask);
347
+
348
+ // Run install + dirs first, then render dir output, then run config generation
349
+ const mainTasks = installTasks.filter((t) => t !== configTask);
350
+ await prompts.tasks(mainTasks);
351
+
352
+ const color = await prompts.getColor();
353
+ if (dirResults.movedDirs.length > 0) {
354
+ const lines = dirResults.movedDirs.map((d) => ` ${d}`).join('\n');
355
+ await prompts.log.message(color.cyan(`Moved directories:\n${lines}`));
356
+ }
357
+ if (dirResults.createdDirs.length > 0) {
358
+ const lines = dirResults.createdDirs.map((d) => ` ${d}`).join('\n');
359
+ await prompts.log.message(color.yellow(`Created directories:\n${lines}`));
360
+ }
361
+ if (dirResults.createdWdsFolders.length > 0) {
362
+ const lines = dirResults.createdWdsFolders.map((f) => color.dim(` \u2713 ${f}/`)).join('\n');
363
+ await prompts.log.message(color.cyan(`Created WDS folder structure:\n${lines}`));
364
+ }
365
+
366
+ await prompts.tasks([configTask]);
367
+ }
368
+
369
+ /**
370
+ * Set up IDE integrations for each selected IDE.
371
+ */
372
+ async _setupIdes(config, allModules, paths, addResult, previousSkillIds = new Set()) {
373
+ if (config.skipIde || !config.ides || config.ides.length === 0) return;
374
+
375
+ await this.ideManager.ensureInitialized();
376
+ const validIdes = config.ides.filter((ide) => ide && typeof ide === 'string');
377
+
378
+ if (validIdes.length === 0) {
379
+ addResult('IDE configuration', 'warn', 'no valid IDEs selected');
380
+ return;
381
+ }
382
+
383
+ const setupResults = await this.ideManager.setupBatch(validIdes, paths.projectRoot, paths.xiaomaDir, {
384
+ selectedModules: allModules || [],
385
+ verbose: config.verbose,
386
+ previousSkillIds,
387
+ });
388
+
389
+ for (const setupResult of setupResults) {
390
+ const ide = setupResult.ide;
391
+ if (setupResult.success) {
392
+ addResult(ide, 'ok', setupResult.detail || '');
393
+ } else {
394
+ addResult(ide, 'error', setupResult.error || 'failed');
395
+ }
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Remove skill directories from _xiaoma/ after IDE installation.
401
+ * Skills are self-contained in IDE directories, so _xiaoma/ only needs
402
+ * module-level files (config.yaml, _config/, etc.).
403
+ * Also cleans up skill dirs left by older installer versions.
404
+ * @param {string} xiaomaDir - XiaoMa installation directory
405
+ */
406
+ async _cleanupSkillDirs(xiaomaDir) {
407
+ const csv = require('csv-parse/sync');
408
+ const csvPath = path.join(xiaomaDir, '_config', 'skill-manifest.csv');
409
+ if (!(await fs.pathExists(csvPath))) return;
410
+
411
+ const csvContent = await fs.readFile(csvPath, 'utf8');
412
+ const records = csv.parse(csvContent, { columns: true, skip_empty_lines: true });
413
+ const xiaomaFolderName = path.basename(xiaomaDir);
414
+ const xiaomaPrefix = xiaomaFolderName + '/';
415
+
416
+ for (const record of records) {
417
+ if (!record.path) continue;
418
+ const relativePath = record.path.startsWith(xiaomaPrefix) ? record.path.slice(xiaomaPrefix.length) : record.path;
419
+ const sourceDir = path.dirname(path.join(xiaomaDir, relativePath));
420
+ if (await fs.pathExists(sourceDir)) {
421
+ await fs.remove(sourceDir);
422
+ }
423
+ }
424
+ }
425
+
426
+ async _readSkillManifestRows(xiaomaDir) {
427
+ const csvPath = path.join(xiaomaDir, '_config', 'skill-manifest.csv');
428
+ if (!(await fs.pathExists(csvPath))) return [];
429
+
430
+ try {
431
+ const csvParse = require('csv-parse/sync');
432
+ const content = await fs.readFile(csvPath, 'utf8');
433
+ return csvParse.parse(content, { columns: true, skip_empty_lines: true });
434
+ } catch (error) {
435
+ await prompts.log.warn(`Failed to parse skill-manifest.csv: ${error.message}`);
436
+ return [];
437
+ }
438
+ }
439
+
440
+ _getPreviousSkillIdsForCleanup(previousRows, preservedModules = []) {
441
+ const preservedModuleSet = new Set(preservedModules || []);
442
+ const ids = new Set();
443
+ for (const row of previousRows || []) {
444
+ if (row.canonicalId && !preservedModuleSet.has(row.module)) {
445
+ ids.add(row.canonicalId);
446
+ }
447
+ }
448
+ return ids;
449
+ }
450
+
451
+ async _appendPreservedSkillManifestRows(xiaomaDir, previousRows, preservedModules = []) {
452
+ if (!previousRows || previousRows.length === 0 || preservedModules.length === 0) return;
453
+
454
+ const preservedModuleSet = new Set(preservedModules);
455
+ const rowsToPreserve = previousRows.filter((row) => row.canonicalId && row.module && preservedModuleSet.has(row.module));
456
+ if (rowsToPreserve.length === 0) return;
457
+
458
+ const csvPath = path.join(xiaomaDir, '_config', 'skill-manifest.csv');
459
+ if (!(await fs.pathExists(csvPath))) return;
460
+
461
+ const currentRows = await this._readSkillManifestRows(xiaomaDir);
462
+ const activeIds = new Set(currentRows.map((row) => row.canonicalId).filter(Boolean));
463
+ const appendedRows = [];
464
+
465
+ for (const row of rowsToPreserve) {
466
+ if (activeIds.has(row.canonicalId)) continue;
467
+ activeIds.add(row.canonicalId);
468
+ appendedRows.push(
469
+ [row.canonicalId, row.name || row.canonicalId, row.description || '', row.module, row.path || '']
470
+ .map((field) => this.escapeCSVField(field))
471
+ .join(','),
472
+ );
473
+ }
474
+
475
+ if (appendedRows.length === 0) return;
476
+
477
+ const currentContent = await fs.readFile(csvPath, 'utf8');
478
+ const prefix = currentContent.endsWith('\n') ? currentContent : `${currentContent}\n`;
479
+ await fs.writeFile(csvPath, prefix + appendedRows.join('\n') + '\n', 'utf8');
480
+ }
481
+
482
+ /**
483
+ * Restore custom and modified files that were backed up before the update.
484
+ * No-op for fresh installs (updateState is null).
485
+ * @param {Object} paths - InstallPaths instance
486
+ * @param {Object|null} updateState - From _prepareUpdateState, or null for fresh installs
487
+ * @returns {Object} { customFiles, modifiedFiles } — lists of restored files
488
+ */
489
+ async _restoreUserFiles(paths, updateState) {
490
+ const noFiles = { customFiles: [], modifiedFiles: [] };
491
+
492
+ if (!updateState || (updateState.customFiles.length === 0 && updateState.modifiedFiles.length === 0)) {
493
+ return noFiles;
494
+ }
495
+
496
+ let restoredCustomFiles = [];
497
+ let restoredModifiedFiles = [];
498
+
499
+ await prompts.tasks([
500
+ {
501
+ title: 'Finalizing installation',
502
+ task: async (message) => {
503
+ if (updateState.customFiles.length > 0) {
504
+ message(`Restoring ${updateState.customFiles.length} custom files...`);
505
+
506
+ for (const originalPath of updateState.customFiles) {
507
+ const relativePath = path.relative(paths.xiaomaDir, originalPath);
508
+ const backupPath = path.join(updateState.tempBackupDir, relativePath);
509
+
510
+ if (await fs.pathExists(backupPath)) {
511
+ await fs.ensureDir(path.dirname(originalPath));
512
+ await fs.copy(backupPath, originalPath, { overwrite: true });
513
+ }
514
+ }
515
+
516
+ if (updateState.tempBackupDir && (await fs.pathExists(updateState.tempBackupDir))) {
517
+ await fs.remove(updateState.tempBackupDir);
518
+ }
519
+
520
+ restoredCustomFiles = updateState.customFiles;
521
+ }
522
+
523
+ if (updateState.modifiedFiles.length > 0) {
524
+ restoredModifiedFiles = updateState.modifiedFiles;
525
+
526
+ if (updateState.tempModifiedBackupDir && (await fs.pathExists(updateState.tempModifiedBackupDir))) {
527
+ message(`Restoring ${restoredModifiedFiles.length} modified files as .bak...`);
528
+
529
+ for (const modifiedFile of restoredModifiedFiles) {
530
+ const relativePath = path.relative(paths.xiaomaDir, modifiedFile.path);
531
+ const tempBackupPath = path.join(updateState.tempModifiedBackupDir, relativePath);
532
+ const bakPath = modifiedFile.path + '.bak';
533
+
534
+ if (await fs.pathExists(tempBackupPath)) {
535
+ await fs.ensureDir(path.dirname(bakPath));
536
+ await fs.copy(tempBackupPath, bakPath, { overwrite: true });
537
+ }
538
+ }
539
+
540
+ await fs.remove(updateState.tempModifiedBackupDir);
541
+ }
542
+ }
543
+
544
+ return 'Installation finalized';
545
+ },
546
+ },
547
+ ]);
548
+
549
+ return { customFiles: restoredCustomFiles, modifiedFiles: restoredModifiedFiles };
550
+ }
551
+
552
+ /**
553
+ * Common update preparation: detect files, preserve core config, back up.
554
+ * @param {Object} paths - InstallPaths instance
555
+ * @param {Object} config - Clean config (may have coreConfig updated)
556
+ * @param {Object} existingInstall - Detection result
557
+ * @param {Object} officialModules - OfficialModules instance
558
+ * @returns {Object} Update state: { customFiles, modifiedFiles, tempBackupDir, tempModifiedBackupDir }
559
+ */
560
+ async _prepareUpdateState(paths, config, existingInstall, officialModules) {
561
+ // Detect custom and modified files BEFORE updating (compare current files vs files-manifest.csv)
562
+ const existingFilesManifest = await this.readFilesManifest(paths.xiaomaDir);
563
+ const { customFiles, modifiedFiles } = await this.detectCustomFiles(paths.xiaomaDir, existingFilesManifest);
564
+
565
+ // Preserve existing core configuration during updates
566
+ // (no-op for quick-update which already has core config from collectModuleConfigQuick)
567
+ const coreConfigPath = paths.moduleConfig('core');
568
+ if ((await fs.pathExists(coreConfigPath)) && (!config.coreConfig || Object.keys(config.coreConfig).length === 0)) {
569
+ try {
570
+ const yaml = require('yaml');
571
+ const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
572
+ const existingCoreConfig = yaml.parse(coreConfigContent);
573
+
574
+ config.coreConfig = existingCoreConfig;
575
+ officialModules.moduleConfigs.core = existingCoreConfig;
576
+ } catch (error) {
577
+ await prompts.log.warn(`Warning: Could not read existing core config: ${error.message}`);
578
+ }
579
+ }
580
+
581
+ const backupDirs = await this._backupUserFiles(paths, customFiles, modifiedFiles);
582
+
583
+ return {
584
+ customFiles,
585
+ modifiedFiles,
586
+ tempBackupDir: backupDirs.tempBackupDir,
587
+ tempModifiedBackupDir: backupDirs.tempModifiedBackupDir,
588
+ };
589
+ }
590
+
591
+ /**
592
+ * Back up custom and modified files to temp directories before overwriting.
593
+ * Returns the temp directory paths (or undefined if no files to back up).
594
+ * @param {Object} paths - InstallPaths instance
595
+ * @param {string[]} customFiles - Absolute paths of custom (user-added) files
596
+ * @param {Object[]} modifiedFiles - Array of { path, relativePath } for modified files
597
+ * @returns {Object} { tempBackupDir, tempModifiedBackupDir } — undefined if no files
598
+ */
599
+ async _backupUserFiles(paths, customFiles, modifiedFiles) {
600
+ let tempBackupDir;
601
+ let tempModifiedBackupDir;
602
+
603
+ if (customFiles.length > 0) {
604
+ tempBackupDir = path.join(paths.projectRoot, '_xiaoma-custom-backup-temp');
605
+ await fs.ensureDir(tempBackupDir);
606
+
607
+ for (const customFile of customFiles) {
608
+ const relativePath = path.relative(paths.xiaomaDir, customFile);
609
+ const backupPath = path.join(tempBackupDir, relativePath);
610
+ await fs.ensureDir(path.dirname(backupPath));
611
+ await fs.copy(customFile, backupPath);
612
+ }
613
+ }
614
+
615
+ if (modifiedFiles.length > 0) {
616
+ tempModifiedBackupDir = path.join(paths.projectRoot, '_xiaoma-modified-backup-temp');
617
+ await fs.ensureDir(tempModifiedBackupDir);
618
+
619
+ for (const modifiedFile of modifiedFiles) {
620
+ const relativePath = path.relative(paths.xiaomaDir, modifiedFile.path);
621
+ const tempBackupPath = path.join(tempModifiedBackupDir, relativePath);
622
+ await fs.ensureDir(path.dirname(tempBackupPath));
623
+ await fs.copy(modifiedFile.path, tempBackupPath, { overwrite: true });
624
+ }
625
+ }
626
+
627
+ return { tempBackupDir, tempModifiedBackupDir };
628
+ }
629
+
630
+ /**
631
+ * Sync src/scripts/* → _xiaoma/scripts/ so shared Python scripts
632
+ * (e.g. resolve_customization.js) are available at install time.
633
+ * Wipes the destination first so files removed or renamed in source
634
+ * don't linger and get recorded as installed. Also seeds
635
+ * _xiaoma/custom/.gitignore on fresh installs so *.user.toml overrides
636
+ * stay out of version control.
637
+ */
638
+ async _installSharedScripts(paths) {
639
+ const srcScriptsDir = path.join(paths.srcDir, 'src', 'scripts');
640
+ if (!(await fs.pathExists(srcScriptsDir))) {
641
+ throw new Error(`Shared scripts source directory not found: ${srcScriptsDir}`);
642
+ }
643
+
644
+ await fs.remove(paths.scriptsDir);
645
+ await fs.ensureDir(paths.scriptsDir);
646
+ await fs.copy(srcScriptsDir, paths.scriptsDir, { overwrite: true });
647
+ await this._trackFilesRecursive(paths.scriptsDir);
648
+
649
+ const customGitignore = path.join(paths.customDir, '.gitignore');
650
+ if (!(await fs.pathExists(customGitignore))) {
651
+ await fs.writeFile(customGitignore, '*.user.toml\n', 'utf8');
652
+ this.installedFiles.add(customGitignore);
653
+ }
654
+ }
655
+
656
+ async _trackFilesRecursive(dir) {
657
+ const entries = await fs.readdir(dir, { withFileTypes: true });
658
+ for (const entry of entries) {
659
+ const full = path.join(dir, entry.name);
660
+ if (entry.isDirectory()) {
661
+ await this._trackFilesRecursive(full);
662
+ } else if (entry.isFile()) {
663
+ this.installedFiles.add(full);
664
+ }
665
+ }
666
+ }
667
+
668
+ async _trackPreservedModuleFiles(xiaomaDir, preservedModules = []) {
669
+ for (const moduleName of preservedModules) {
670
+ const modulePath = path.join(xiaomaDir, moduleName);
671
+ if (await fs.pathExists(modulePath)) {
672
+ await this._trackFilesRecursive(modulePath);
673
+ }
674
+ }
675
+ }
676
+
677
+ /**
678
+ * Install official (non-custom) modules.
679
+ * @param {Object} config - Installation configuration
680
+ * @param {Object} paths - InstallPaths instance
681
+ * @param {string[]} officialModuleIds - Official module IDs to install
682
+ * @param {Function} addResult - Callback to record installation results
683
+ * @param {boolean} isQuickUpdate - Whether this is a quick update
684
+ * @param {Object} ctx - Shared context: { message, installedModuleNames }
685
+ */
686
+ async _installOfficialModules(config, paths, officialModuleIds, addResult, isQuickUpdate, officialModules, ctx) {
687
+ const { message, installedModuleNames } = ctx;
688
+ const { CustomModuleManager } = require('../modules/custom-module-manager');
689
+
690
+ for (const moduleName of officialModuleIds) {
691
+ if (installedModuleNames.has(moduleName)) continue;
692
+ installedModuleNames.add(moduleName);
693
+
694
+ message(`${isQuickUpdate ? 'Updating' : 'Installing'} ${moduleName}...`);
695
+
696
+ const moduleConfig = officialModules.moduleConfigs[moduleName] || {};
697
+ const installResult = await officialModules.install(
698
+ moduleName,
699
+ paths.xiaomaDir,
700
+ (filePath) => {
701
+ this.installedFiles.add(filePath);
702
+ },
703
+ {
704
+ skipModuleInstaller: true,
705
+ moduleConfig: moduleConfig,
706
+ installer: this,
707
+ silent: true,
708
+ channelOptions: config.channelOptions,
709
+ },
710
+ );
711
+
712
+ // Get display name from source module.yaml and resolve the freshest version metadata we can find locally.
713
+ const sourcePath = await officialModules.findModuleSource(moduleName, {
714
+ silent: true,
715
+ channelOptions: config.channelOptions,
716
+ });
717
+ const moduleInfo = sourcePath ? await officialModules.getModuleInfo(sourcePath, moduleName, '') : null;
718
+ const displayName = moduleInfo?.name || moduleName;
719
+
720
+ const resolution = officialModules.externalModuleManager.getResolution(moduleName);
721
+ const cachedResolution = CustomModuleManager._resolutionCache.get(moduleName);
722
+ const versionInfo = await resolveModuleVersion(moduleName, {
723
+ moduleSourcePath: sourcePath,
724
+ fallbackVersion: resolution?.version || cachedResolution?.version,
725
+ marketplacePluginNames: cachedResolution?.pluginName ? [cachedResolution.pluginName] : [],
726
+ });
727
+ // Prefer the git tag recorded by the resolution (e.g. "v1.7.0") over
728
+ // the on-disk package.json (which may be ahead of the released tag).
729
+ const version = resolution?.version || versionInfo.version || '';
730
+ addResult(displayName, 'ok', '', {
731
+ moduleCode: moduleName,
732
+ newVersion: version,
733
+ newChannel: resolution?.channel || null,
734
+ newSha: resolution?.sha || null,
735
+ });
736
+ }
737
+ }
738
+
739
+ /**
740
+ * Read files-manifest.csv
741
+ * @param {string} xiaomaDir - XiaoMa installation directory
742
+ * @returns {Array} Array of file entries from files-manifest.csv
743
+ */
744
+ async readFilesManifest(xiaomaDir) {
745
+ const filesManifestPath = path.join(xiaomaDir, '_config', 'files-manifest.csv');
746
+ if (!(await fs.pathExists(filesManifestPath))) {
747
+ return [];
748
+ }
749
+
750
+ try {
751
+ const content = await fs.readFile(filesManifestPath, 'utf8');
752
+ const lines = content.split('\n');
753
+ const files = [];
754
+
755
+ for (let i = 1; i < lines.length; i++) {
756
+ // Skip header
757
+ const line = lines[i].trim();
758
+ if (!line) continue;
759
+
760
+ // Parse CSV line properly handling quoted values
761
+ const parts = [];
762
+ let current = '';
763
+ let inQuotes = false;
764
+
765
+ for (const char of line) {
766
+ if (char === '"') {
767
+ inQuotes = !inQuotes;
768
+ } else if (char === ',' && !inQuotes) {
769
+ parts.push(current);
770
+ current = '';
771
+ } else {
772
+ current += char;
773
+ }
774
+ }
775
+ parts.push(current); // Add last part
776
+
777
+ if (parts.length >= 4) {
778
+ files.push({
779
+ type: parts[0],
780
+ name: parts[1],
781
+ module: parts[2],
782
+ path: parts[3],
783
+ hash: parts[4] || null, // Hash may not exist in old manifests
784
+ });
785
+ }
786
+ }
787
+
788
+ return files;
789
+ } catch (error) {
790
+ await prompts.log.warn('Could not read files-manifest.csv: ' + error.message);
791
+ return [];
792
+ }
793
+ }
794
+
795
+ /**
796
+ * Detect custom and modified files
797
+ * @param {string} xiaomaDir - XiaoMa installation directory
798
+ * @param {Array} existingFilesManifest - Previous files from files-manifest.csv
799
+ * @returns {Object} Object with customFiles and modifiedFiles arrays
800
+ */
801
+ async detectCustomFiles(xiaomaDir, existingFilesManifest) {
802
+ const customFiles = [];
803
+ const modifiedFiles = [];
804
+
805
+ // Memory subtrees (v6.1: _xiaoma/_memory, current: _xiaoma/memory) hold
806
+ // per-user runtime data generated by agents with sidecars. These files
807
+ // aren't installer-managed and must never be reported as "custom" or
808
+ // "modified" — they're user state, not user overrides.
809
+ const xiaomaMemoryPaths = ['_memory', 'memory'];
810
+
811
+ // Check if the manifest has hashes - if not, we can't detect modifications
812
+ let manifestHasHashes = false;
813
+ if (existingFilesManifest && existingFilesManifest.length > 0) {
814
+ manifestHasHashes = existingFilesManifest.some((f) => f.hash);
815
+ }
816
+
817
+ // Build map of previously installed files from files-manifest.csv with their hashes
818
+ const installedFilesMap = new Map();
819
+ for (const fileEntry of existingFilesManifest) {
820
+ if (fileEntry.path) {
821
+ const absolutePath = path.join(xiaomaDir, fileEntry.path);
822
+ installedFilesMap.set(path.normalize(absolutePath), {
823
+ hash: fileEntry.hash,
824
+ relativePath: fileEntry.path,
825
+ });
826
+ }
827
+ }
828
+
829
+ // Recursively scan xiaomaDir for all files
830
+ const scanDirectory = async (dir) => {
831
+ try {
832
+ const entries = await fs.readdir(dir, { withFileTypes: true });
833
+ for (const entry of entries) {
834
+ const fullPath = path.join(dir, entry.name);
835
+
836
+ if (entry.isDirectory()) {
837
+ // Skip certain directories
838
+ if (entry.name === 'node_modules' || entry.name === '.git') {
839
+ continue;
840
+ }
841
+ await scanDirectory(fullPath);
842
+ } else if (entry.isFile()) {
843
+ const normalizedPath = path.normalize(fullPath);
844
+ const fileInfo = installedFilesMap.get(normalizedPath);
845
+
846
+ // Skip certain system files that are auto-generated
847
+ const relativePath = path.relative(xiaomaDir, fullPath);
848
+ const fileName = path.basename(fullPath);
849
+
850
+ // Skip _config directory EXCEPT for modified agent customizations
851
+ if (relativePath.startsWith('_config/') || relativePath.startsWith('_config\\')) {
852
+ // Special handling for .customize.yaml files - only preserve if modified
853
+ if (relativePath.includes('/agents/') && fileName.endsWith('.customize.yaml')) {
854
+ // Check if the customization file has been modified from manifest
855
+ const manifestPath = path.join(xiaomaDir, '_config', 'manifest.yaml');
856
+ if (await fs.pathExists(manifestPath)) {
857
+ const crypto = require('node:crypto');
858
+ const currentContent = await fs.readFile(fullPath, 'utf8');
859
+ const currentHash = crypto.createHash('sha256').update(currentContent).digest('hex');
860
+
861
+ const yaml = require('yaml');
862
+ const manifestContent = await fs.readFile(manifestPath, 'utf8');
863
+ const manifestData = yaml.parse(manifestContent);
864
+ const originalHash = manifestData.agentCustomizations?.[relativePath];
865
+
866
+ // Only add to customFiles if hash differs (user modified)
867
+ if (originalHash && currentHash !== originalHash) {
868
+ customFiles.push(fullPath);
869
+ }
870
+ }
871
+ }
872
+ continue;
873
+ }
874
+
875
+ if (xiaomaMemoryPaths.some((mp) => relativePath === mp || relativePath.startsWith(mp + '/'))) {
876
+ continue;
877
+ }
878
+
879
+ // Skip config.yaml files - these are regenerated on each install/update
880
+ if (fileName === 'config.yaml') {
881
+ continue;
882
+ }
883
+
884
+ if (!fileInfo) {
885
+ // File not in manifest = custom file
886
+ // EXCEPT: Agent .md files in module folders are generated files, not custom
887
+ // Only treat .md files under _config/agents/ as custom
888
+ if (!(fileName.endsWith('.md') && relativePath.includes('/agents/') && !relativePath.startsWith('_config/'))) {
889
+ customFiles.push(fullPath);
890
+ }
891
+ } else if (manifestHasHashes && fileInfo.hash) {
892
+ // File in manifest with hash - check if it was modified
893
+ const currentHash = await this.manifest.calculateFileHash(fullPath);
894
+ if (currentHash && currentHash !== fileInfo.hash) {
895
+ // Hash changed = file was modified
896
+ modifiedFiles.push({
897
+ path: fullPath,
898
+ relativePath: fileInfo.relativePath,
899
+ });
900
+ }
901
+ }
902
+ }
903
+ }
904
+ } catch {
905
+ // Ignore errors scanning directories
906
+ }
907
+ };
908
+
909
+ await scanDirectory(xiaomaDir);
910
+ return { customFiles, modifiedFiles };
911
+ }
912
+
913
+ /**
914
+ * Generate clean config.yaml files for each installed module
915
+ * @param {string} xiaomaDir - XiaoMa installation directory
916
+ * @param {Object} moduleConfigs - Collected configuration values
917
+ */
918
+ async generateModuleConfigs(xiaomaDir, moduleConfigs) {
919
+ const yaml = require('yaml');
920
+
921
+ // Extract core config values to share with other modules
922
+ const coreConfig = moduleConfigs.core || {};
923
+
924
+ // Get all installed module directories
925
+ const entries = await fs.readdir(xiaomaDir, { withFileTypes: true });
926
+ const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']);
927
+ const installedModules = entries.filter((entry) => entry.isDirectory() && !nonModuleDirs.has(entry.name)).map((entry) => entry.name);
928
+
929
+ // Generate config.yaml for each installed module
930
+ for (const moduleName of installedModules) {
931
+ const modulePath = path.join(xiaomaDir, moduleName);
932
+
933
+ // Get module-specific config or use empty object if none
934
+ const config = moduleConfigs[moduleName] || {};
935
+
936
+ if (await fs.pathExists(modulePath)) {
937
+ const configPath = path.join(modulePath, 'config.yaml');
938
+
939
+ // Create header
940
+ const packageJson = require(path.join(getProjectRoot(), 'package.json'));
941
+ const header = `# ${moduleName.toUpperCase()} Module Configuration
942
+ # Generated by XiaoMa installer
943
+ # Version: ${packageJson.version}
944
+ # Date: ${new Date().toISOString()}
945
+
946
+ `;
947
+
948
+ // For non-core modules, add core config values directly
949
+ let finalConfig = { ...config };
950
+ let coreSection = '';
951
+
952
+ if (moduleName !== 'core' && coreConfig && Object.keys(coreConfig).length > 0) {
953
+ // Add core values directly to the module config
954
+ // These will be available for reference in the module
955
+ finalConfig = {
956
+ ...config,
957
+ ...coreConfig, // Spread core config values directly into the module config
958
+ };
959
+
960
+ // Create a comment section to identify core values
961
+ coreSection = '\n# Core Configuration Values\n';
962
+ }
963
+
964
+ // Clean the config to remove any non-serializable values (like functions)
965
+ const cleanConfig = structuredClone(finalConfig);
966
+
967
+ // Convert config to YAML
968
+ let yamlContent = yaml.stringify(cleanConfig, {
969
+ indent: 2,
970
+ lineWidth: 0,
971
+ minContentWidth: 0,
972
+ });
973
+
974
+ // If we have core values, reorganize the YAML to group them with their comment
975
+ if (coreSection && moduleName !== 'core') {
976
+ // Split the YAML into lines
977
+ const lines = yamlContent.split('\n');
978
+ const moduleConfigLines = [];
979
+ const coreConfigLines = [];
980
+
981
+ // Separate module-specific and core config lines
982
+ for (const line of lines) {
983
+ const key = line.split(':')[0].trim();
984
+ if (Object.prototype.hasOwnProperty.call(coreConfig, key)) {
985
+ coreConfigLines.push(line);
986
+ } else {
987
+ moduleConfigLines.push(line);
988
+ }
989
+ }
990
+
991
+ // Rebuild YAML with module config first, then core config with comment
992
+ yamlContent = moduleConfigLines.join('\n');
993
+ if (coreConfigLines.length > 0) {
994
+ yamlContent += coreSection + coreConfigLines.join('\n');
995
+ }
996
+ }
997
+
998
+ // Write the clean config file with POSIX-compliant final newline
999
+ const content = header + yamlContent;
1000
+ await fs.writeFile(configPath, content.endsWith('\n') ? content : content + '\n', 'utf8');
1001
+
1002
+ // Track the config file in installedFiles
1003
+ this.installedFiles.add(configPath);
1004
+ }
1005
+ }
1006
+ }
1007
+
1008
+ /**
1009
+ * Merge all module-help.csv files into a single xiaoma-help.csv.
1010
+ * Scans all installed modules for module-help.csv and merges them.
1011
+ * Output preserves the source schema verbatim — see schema below.
1012
+ * @param {string} xiaomaDir - XiaoMa installation directory
1013
+ * @param {Array<Object>} _agentEntries - Unused; retained for call-site compatibility
1014
+ */
1015
+ async mergeModuleHelpCatalogs(xiaomaDir, _agentEntries = []) {
1016
+ const allRows = [];
1017
+ const headerRow = MODULE_HELP_CSV_HEADER;
1018
+ const COLUMN_COUNT = 13;
1019
+ const PHASE_INDEX = 7;
1020
+
1021
+ // Get all installed module directories
1022
+ const entries = await fs.readdir(xiaomaDir, { withFileTypes: true });
1023
+ const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']);
1024
+ const installedModules = entries.filter((entry) => entry.isDirectory() && !nonModuleDirs.has(entry.name)).map((entry) => entry.name);
1025
+
1026
+ // Add core module to scan (it's installed at root level as _config, but we check src/core-skills)
1027
+ const coreModulePath = getSourcePath('core-skills');
1028
+ const modulePaths = new Map();
1029
+
1030
+ // Map all module source paths
1031
+ if (await fs.pathExists(coreModulePath)) {
1032
+ modulePaths.set('core', coreModulePath);
1033
+ }
1034
+
1035
+ // Map installed module paths
1036
+ for (const moduleName of installedModules) {
1037
+ const modulePath = path.join(xiaomaDir, moduleName);
1038
+ modulePaths.set(moduleName, modulePath);
1039
+ }
1040
+
1041
+ // Scan each module for module-help.csv
1042
+ for (const [moduleName, modulePath] of modulePaths) {
1043
+ const helpFilePath = path.join(modulePath, 'module-help.csv');
1044
+
1045
+ if (await fs.pathExists(helpFilePath)) {
1046
+ try {
1047
+ const content = await fs.readFile(helpFilePath, 'utf8');
1048
+ const lines = content.split('\n').filter((line) => line.trim() && !line.startsWith('#'));
1049
+
1050
+ let headerWarned = false;
1051
+ for (const line of lines) {
1052
+ // Header row: warn on drift from canonical schema, then skip.
1053
+ // Data rows are loaded positionally regardless, so the warning
1054
+ // is advisory — the maintainer should rename their columns.
1055
+ if (line.startsWith('module,')) {
1056
+ if (!headerWarned && line.trim() !== headerRow) {
1057
+ await prompts.log.warn(
1058
+ ` ${moduleName}/module-help.csv header does not match canonical schema. ` +
1059
+ `Expected: ${headerRow} | Found: ${line.trim()} | Data loaded positionally.`,
1060
+ );
1061
+ headerWarned = true;
1062
+ }
1063
+ continue;
1064
+ }
1065
+
1066
+ // Parse the line - handle quoted fields with commas
1067
+ const columns = this.parseCSVLine(line);
1068
+ if (columns.length < COLUMN_COUNT - 1) continue;
1069
+
1070
+ // Pad short rows; truncate over-long rows
1071
+ const padded = columns.slice(0, COLUMN_COUNT);
1072
+ while (padded.length < COLUMN_COUNT) padded.push('');
1073
+
1074
+ // If module column is empty, fill with this module's name
1075
+ // (core stays empty so its rows render as universal tools)
1076
+ if ((!padded[0] || padded[0].trim() === '') && moduleName !== 'core') {
1077
+ padded[0] = moduleName;
1078
+ }
1079
+
1080
+ allRows.push(padded.map((c) => this.escapeCSVField(c)).join(','));
1081
+ }
1082
+
1083
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
1084
+ await prompts.log.message(` Merged module-help from: ${moduleName}`);
1085
+ }
1086
+ } catch (error) {
1087
+ await prompts.log.warn(` Warning: Failed to read module-help.csv from ${moduleName}: ${error.message}`);
1088
+ }
1089
+ } else if (moduleName !== 'core') {
1090
+ // Non-core modules that ship no module-help.csv are silently invisible in
1091
+ // the merged xiaoma-help catalog. Surface it so the gap is caught at install
1092
+ // time rather than discovered when a user can't find the module's skills.
1093
+ await prompts.log.warn(` ${moduleName}: no module-help.csv — its skills will not appear in the xiaoma-help catalog.`);
1094
+ }
1095
+ }
1096
+
1097
+ // Sort by module, then phase. Stable sort preserves authored order within a phase.
1098
+ const decorated = allRows.map((row, index) => ({ row, index, cols: this.parseCSVLine(row) }));
1099
+ decorated.sort((a, b) => {
1100
+ const moduleA = (a.cols[0] || '').toLowerCase();
1101
+ const moduleB = (b.cols[0] || '').toLowerCase();
1102
+ if (moduleA !== moduleB) return moduleA.localeCompare(moduleB);
1103
+
1104
+ const phaseA = a.cols[PHASE_INDEX] || '';
1105
+ const phaseB = b.cols[PHASE_INDEX] || '';
1106
+ if (phaseA !== phaseB) return phaseA.localeCompare(phaseB);
1107
+
1108
+ return a.index - b.index;
1109
+ });
1110
+ const sortedRows = decorated.map((d) => d.row);
1111
+
1112
+ // Write merged catalog
1113
+ const outputDir = path.join(xiaomaDir, '_config');
1114
+ await fs.ensureDir(outputDir);
1115
+ const outputPath = path.join(outputDir, 'xiaoma-help.csv');
1116
+
1117
+ const mergedContent = [headerRow, ...sortedRows].join('\n');
1118
+ await fs.writeFile(outputPath, mergedContent, 'utf8');
1119
+
1120
+ // Track the installed file
1121
+ this.installedFiles.add(outputPath);
1122
+
1123
+ if (process.env.XiaoMa_VERBOSE_INSTALL === 'true') {
1124
+ await prompts.log.message(` Generated xiaoma-help.csv: ${sortedRows.length} workflows`);
1125
+ }
1126
+ }
1127
+
1128
+ /**
1129
+ * Render a consolidated install summary using prompts.note()
1130
+ * @param {Array} results - Array of {step, status: 'ok'|'error'|'warn', detail}
1131
+ * @param {Object} context - {xiaomaDir, modules, ides, customFiles, modifiedFiles}
1132
+ */
1133
+ async renderInstallSummary(results, context = {}) {
1134
+ const color = await prompts.getColor();
1135
+ const selectedIdes = new Set((context.ides || []).map((ide) => String(ide).toLowerCase()));
1136
+
1137
+ // Build step lines with status indicators
1138
+ const preVersions = context.preInstallVersions || new Map();
1139
+ const lines = [];
1140
+ for (const r of results) {
1141
+ const stepLabel = r.step;
1142
+
1143
+ let icon;
1144
+ if (r.status === 'ok') {
1145
+ icon = color.green('\u2713');
1146
+ } else if (r.status === 'warn') {
1147
+ icon = color.yellow('!');
1148
+ } else {
1149
+ icon = color.red('\u2717');
1150
+ }
1151
+
1152
+ // Build version detail for module results
1153
+ let detail = '';
1154
+ if (r.moduleCode && r.newVersion) {
1155
+ const oldVersion = preVersions.get(r.moduleCode);
1156
+ // Format a version label for display:
1157
+ // "main" → "main @ <short-sha>" (next channel shows what SHA landed)
1158
+ // "v1.7.0" or "1.7.0" → "v1.7.0" (prefix 'v' when missing)
1159
+ // anything else (legacy strings) → as-is
1160
+ const fmt = (v, sha) => {
1161
+ if (typeof v !== 'string' || !v) return '';
1162
+ if (v === 'main' || v === 'HEAD') return sha ? `main @ ${sha.slice(0, 7)}` : 'main';
1163
+ if (/^v?\d+\.\d+\.\d+/.test(v)) return v.startsWith('v') ? v : `v${v}`;
1164
+ return v;
1165
+ };
1166
+ const newV = fmt(r.newVersion, r.newSha);
1167
+ // 'main'/'HEAD' strings only identify the channel, not the commit, so
1168
+ // we can't assert "no change" without comparing SHAs — and preVersions
1169
+ // doesn't carry the old SHA. Render these as a refresh instead of a
1170
+ // false-negative "no change".
1171
+ const isMainLike = oldVersion === 'main' || oldVersion === 'HEAD';
1172
+ if (oldVersion && oldVersion === r.newVersion && !isMainLike) {
1173
+ detail = ` (${newV}, no change)`;
1174
+ } else if (oldVersion && isMainLike) {
1175
+ detail = ` (${newV}, refreshed)`;
1176
+ } else if (oldVersion) {
1177
+ detail = ` (${fmt(oldVersion, r.newSha)} → ${newV})`;
1178
+ } else {
1179
+ detail = ` (${newV}, installed)`;
1180
+ }
1181
+ } else if (r.detail) {
1182
+ detail = ` (${r.detail})`;
1183
+ }
1184
+ lines.push(` ${icon} ${stepLabel}${detail}`);
1185
+ }
1186
+
1187
+ if ((context.ides || []).length === 0) {
1188
+ lines.push(` ${color.green('\u2713')} No IDE selected (installed in _xiaoma only)`);
1189
+ }
1190
+
1191
+ // Context and warnings
1192
+ lines.push('');
1193
+ if (context.xiaomaDir) {
1194
+ lines.push(` Installed to: ${context.xiaomaDir}`);
1195
+ }
1196
+ if (context.customFiles && context.customFiles.length > 0) {
1197
+ lines.push(` ${color.cyan(`Custom files preserved: ${context.customFiles.length}`)}`);
1198
+ }
1199
+ if (context.modifiedFiles && context.modifiedFiles.length > 0) {
1200
+ lines.push(` ${color.yellow(`Modified files backed up (.bak): ${context.modifiedFiles.length}`)}`);
1201
+ }
1202
+
1203
+ // Next steps
1204
+ lines.push(
1205
+ '',
1206
+ ' Get started:',
1207
+ ` 1. Launch your AI agent from your project folder`,
1208
+ ` 2. Not sure what to do? Invoke the ${color.cyan('xiaoma-help')} skill and ask it what to do!`,
1209
+ );
1210
+
1211
+ await prompts.box(lines.join('\n'), 'XiaoMa is ready to use!', {
1212
+ rounded: true,
1213
+ formatBorder: color.green,
1214
+ });
1215
+ }
1216
+
1217
+ /**
1218
+ * Quick update method - preserves all settings and only prompts for new config fields
1219
+ * @param {Object} config - Configuration with directory
1220
+ * @returns {Object} Update result
1221
+ */
1222
+ async quickUpdate(config) {
1223
+ const projectDir = path.resolve(config.directory);
1224
+ const { xiaomaDir } = await this.findXiaomaDir(projectDir);
1225
+
1226
+ // Check if xiaoma directory exists
1227
+ if (!(await fs.pathExists(xiaomaDir))) {
1228
+ throw new Error(`XiaoMa not installed at ${xiaomaDir}. Use regular install for first-time setup.`);
1229
+ }
1230
+
1231
+ // Detect existing installation
1232
+ const existingInstall = await ExistingInstall.detect(xiaomaDir);
1233
+ const installedModules = existingInstall.moduleIds;
1234
+ const configuredIdes = existingInstall.ides;
1235
+ const projectRoot = path.dirname(xiaomaDir);
1236
+
1237
+ // Get available modules (what we have source for)
1238
+ const availableModulesData = await new OfficialModules().listAvailable();
1239
+ const availableModules = [...availableModulesData.modules];
1240
+
1241
+ // Add external official modules to available modules
1242
+ const externalModules = await this.externalModuleManager.listAvailable();
1243
+ for (const externalModule of externalModules) {
1244
+ if (installedModules.includes(externalModule.code) && !availableModules.some((m) => m.id === externalModule.code)) {
1245
+ availableModules.push({
1246
+ id: externalModule.code,
1247
+ name: externalModule.name,
1248
+ isExternal: true,
1249
+ fromExternal: true,
1250
+ });
1251
+ }
1252
+ }
1253
+
1254
+ // Add installed custom modules to available modules
1255
+ const { CustomModuleManager } = require('../modules/custom-module-manager');
1256
+ const customMgr = new CustomModuleManager();
1257
+ for (const moduleId of installedModules) {
1258
+ if (!availableModules.some((m) => m.id === moduleId)) {
1259
+ const customSource = await customMgr.findModuleSourceByCode(moduleId, { xiaomaDir });
1260
+ if (customSource) {
1261
+ availableModules.push({
1262
+ id: moduleId,
1263
+ name: moduleId,
1264
+ isExternal: true,
1265
+ fromCustom: true,
1266
+ });
1267
+ }
1268
+ }
1269
+ }
1270
+
1271
+ const availableModuleIds = new Set(availableModules.map((m) => m.id));
1272
+
1273
+ // Only update modules that are BOTH installed AND available (we have source for)
1274
+ const modulesToUpdate = installedModules.filter((id) => availableModuleIds.has(id));
1275
+ const skippedModules = installedModules.filter((id) => !availableModuleIds.has(id));
1276
+
1277
+ if (skippedModules.length > 0) {
1278
+ await prompts.log.warn(`Skipping ${skippedModules.length} module(s) - no source available: ${skippedModules.join(', ')}`);
1279
+ }
1280
+
1281
+ // Build channel options from the existing manifest FIRST so the config
1282
+ // collector below (which triggers external-module clones via
1283
+ // findModuleSource) knows each module's recorded channel and doesn't
1284
+ // silently redecide it. Without this, modules previously on 'next' or
1285
+ // 'pinned' would trigger a stable-channel tag lookup at config-collection
1286
+ // time, burning GitHub API quota and potentially failing.
1287
+ const manifestData = await this.manifest.read(xiaomaDir);
1288
+ const channelOptions = { global: null, nextSet: new Set(), pins: new Map(), warnings: [] };
1289
+ if (manifestData?.modulesDetailed) {
1290
+ const { fetchStableTags, classifyUpgrade, parseGitHubRepo } = require('../modules/channel-resolver');
1291
+ for (const entry of manifestData.modulesDetailed) {
1292
+ if (!entry?.name || !entry?.channel) continue;
1293
+ if (entry.channel === 'pinned' && entry.version) {
1294
+ channelOptions.pins.set(entry.name, entry.version);
1295
+ continue;
1296
+ }
1297
+ if (entry.channel === 'next') {
1298
+ channelOptions.nextSet.add(entry.name);
1299
+ continue;
1300
+ }
1301
+ // Stable: classify the available upgrade. Patches and minors fall
1302
+ // through (stable default picks up the top tag). A major upgrade
1303
+ // requires opt-in, so under quick-update's non-interactive semantics
1304
+ // we pin to the current version to prevent a silent breaking jump.
1305
+ if (entry.channel === 'stable' && entry.version && entry.repoUrl) {
1306
+ const parsed = parseGitHubRepo(entry.repoUrl);
1307
+ if (!parsed) continue;
1308
+ try {
1309
+ const tags = await fetchStableTags(parsed.owner, parsed.repo);
1310
+ if (tags.length === 0) continue;
1311
+ const topTag = tags[0].tag;
1312
+ const cls = classifyUpgrade(entry.version, topTag);
1313
+ if (cls === 'major') {
1314
+ channelOptions.pins.set(entry.name, entry.version);
1315
+ await prompts.log.warn(
1316
+ `${entry.name} ${entry.version} → ${topTag} is a new major release; staying on ${entry.version}. ` +
1317
+ `Run \`xiaoma install\` (Modify) with \`--pin ${entry.name}=${topTag}\` to accept.`,
1318
+ );
1319
+ }
1320
+ } catch (error) {
1321
+ // Tag lookup failed (offline, rate-limited). Stay on the current
1322
+ // version rather than guessing — the existing cache is already
1323
+ // at that ref, so re-using it keeps the install stable.
1324
+ channelOptions.pins.set(entry.name, entry.version);
1325
+ await prompts.log.warn(`Could not check ${entry.name} for updates (${error.message}); staying on ${entry.version}.`);
1326
+ }
1327
+ }
1328
+ }
1329
+ }
1330
+
1331
+ // Load existing configs and collect new fields (if any)
1332
+ await prompts.log.info('Checking for new configuration options...');
1333
+ const quickModules = new OfficialModules({ channelOptions });
1334
+ await quickModules.loadExistingConfig(projectDir);
1335
+
1336
+ let promptedForNewFields = false;
1337
+
1338
+ const corePrompted = await quickModules.collectModuleConfigQuick('core', projectDir, true);
1339
+ if (corePrompted) {
1340
+ promptedForNewFields = true;
1341
+ }
1342
+
1343
+ for (const moduleName of modulesToUpdate) {
1344
+ if (moduleName === 'core') continue; // Already collected above
1345
+ const modulePrompted = await quickModules.collectModuleConfigQuick(moduleName, projectDir, true);
1346
+ if (modulePrompted) {
1347
+ promptedForNewFields = true;
1348
+ }
1349
+ }
1350
+
1351
+ if (!promptedForNewFields) {
1352
+ await prompts.log.success('All configuration is up to date, no new options to configure');
1353
+ }
1354
+
1355
+ quickModules.collectedConfig._meta = {
1356
+ version: require(path.join(getProjectRoot(), 'package.json')).version,
1357
+ installDate: new Date().toISOString(),
1358
+ lastModified: new Date().toISOString(),
1359
+ };
1360
+
1361
+ // Build config and delegate to install()
1362
+ const installConfig = {
1363
+ directory: projectDir,
1364
+ modules: modulesToUpdate,
1365
+ ides: configuredIdes,
1366
+ coreConfig: quickModules.collectedConfig.core,
1367
+ moduleConfigs: quickModules.collectedConfig,
1368
+ // Forward `--set` overrides so the post-install patch step
1369
+ // (`applySetOverrides`) runs at the end of quick-update too. The
1370
+ // installer.install path applies them after writeCentralConfig.
1371
+ setOverrides: config.setOverrides || {},
1372
+ actionType: 'install',
1373
+ _quickUpdate: true,
1374
+ _preserveModules: skippedModules,
1375
+ _existingModules: installedModules,
1376
+ channelOptions,
1377
+ };
1378
+
1379
+ await this.install(installConfig);
1380
+
1381
+ return {
1382
+ success: true,
1383
+ moduleCount: modulesToUpdate.length,
1384
+ hadNewFields: promptedForNewFields,
1385
+ modules: modulesToUpdate,
1386
+ skippedModules: skippedModules,
1387
+ ides: configuredIdes,
1388
+ };
1389
+ }
1390
+
1391
+ /**
1392
+ * Uninstall XiaoMa with selective removal options
1393
+ * @param {string} directory - Project directory
1394
+ * @param {Object} options - Uninstall options
1395
+ * @param {boolean} [options.removeModules=true] - Remove _xiaoma/ directory
1396
+ * @param {boolean} [options.removeIdeConfigs=true] - Remove IDE configurations
1397
+ * @param {boolean} [options.removeOutputFolder=false] - Remove user artifacts output folder
1398
+ * @returns {Object} Result with success status and removed components
1399
+ */
1400
+ async uninstall(directory, options = {}) {
1401
+ const projectDir = path.resolve(directory);
1402
+ const { xiaomaDir } = await this.findXiaomaDir(projectDir);
1403
+
1404
+ if (!(await fs.pathExists(xiaomaDir))) {
1405
+ return { success: false, reason: 'not-installed' };
1406
+ }
1407
+
1408
+ // 1. DETECT: Read state BEFORE deleting anything
1409
+ const existingInstall = await ExistingInstall.detect(xiaomaDir);
1410
+ const outputFolder = await this._readOutputFolder(xiaomaDir);
1411
+
1412
+ const removed = { modules: false, ideConfigs: false, outputFolder: false };
1413
+
1414
+ // 2. IDE CLEANUP (before _xiaoma/ deletion so configs are accessible)
1415
+ if (options.removeIdeConfigs !== false) {
1416
+ await this.uninstallIdeConfigs(projectDir, existingInstall, { silent: options.silent });
1417
+ removed.ideConfigs = true;
1418
+ }
1419
+
1420
+ // 3. OUTPUT FOLDER (only if explicitly requested)
1421
+ if (options.removeOutputFolder === true && outputFolder) {
1422
+ removed.outputFolder = await this.uninstallOutputFolder(projectDir, outputFolder);
1423
+ }
1424
+
1425
+ // 4. XiaoMa DIRECTORY (last, after everything that needs it)
1426
+ if (options.removeModules !== false) {
1427
+ removed.modules = await this.uninstallModules(projectDir);
1428
+ }
1429
+
1430
+ return { success: true, removed, version: existingInstall.installed ? existingInstall.version : null };
1431
+ }
1432
+
1433
+ /**
1434
+ * Uninstall IDE configurations only
1435
+ * @param {string} projectDir - Project directory
1436
+ * @param {Object} existingInstall - Detection result from detector.detect()
1437
+ * @param {Object} [options] - Options (e.g. { silent: true })
1438
+ * @returns {Promise<Object>} Results from IDE cleanup
1439
+ */
1440
+ async uninstallIdeConfigs(projectDir, existingInstall, options = {}) {
1441
+ await this.ideManager.ensureInitialized();
1442
+ const cleanupOptions = { isUninstall: true, silent: options.silent };
1443
+ const ideList = existingInstall.ides;
1444
+ if (ideList.length > 0) {
1445
+ return this.ideManager.cleanupByList(projectDir, ideList, cleanupOptions);
1446
+ }
1447
+ return this.ideManager.cleanup(projectDir, cleanupOptions);
1448
+ }
1449
+
1450
+ /**
1451
+ * Remove user artifacts output folder
1452
+ * @param {string} projectDir - Project directory
1453
+ * @param {string} outputFolder - Output folder name (relative)
1454
+ * @returns {Promise<boolean>} Whether the folder was removed
1455
+ */
1456
+ async uninstallOutputFolder(projectDir, outputFolder) {
1457
+ if (!outputFolder) return false;
1458
+ const resolvedProject = path.resolve(projectDir);
1459
+ const outputPath = path.resolve(resolvedProject, outputFolder);
1460
+ if (!outputPath.startsWith(resolvedProject + path.sep)) {
1461
+ return false;
1462
+ }
1463
+ if (await fs.pathExists(outputPath)) {
1464
+ await fs.remove(outputPath);
1465
+ return true;
1466
+ }
1467
+ return false;
1468
+ }
1469
+
1470
+ /**
1471
+ * Remove the _xiaoma/ directory
1472
+ * @param {string} projectDir - Project directory
1473
+ * @returns {Promise<boolean>} Whether the directory was removed
1474
+ */
1475
+ async uninstallModules(projectDir) {
1476
+ const { xiaomaDir } = await this.findXiaomaDir(projectDir);
1477
+ if (await fs.pathExists(xiaomaDir)) {
1478
+ await fs.remove(xiaomaDir);
1479
+ return true;
1480
+ }
1481
+ return false;
1482
+ }
1483
+
1484
+ /**
1485
+ * Get installation status
1486
+ */
1487
+ async getStatus(directory) {
1488
+ const projectDir = path.resolve(directory);
1489
+ const { xiaomaDir } = await this.findXiaomaDir(projectDir);
1490
+ return await ExistingInstall.detect(xiaomaDir);
1491
+ }
1492
+
1493
+ /**
1494
+ * Get available modules
1495
+ */
1496
+ async getAvailableModules() {
1497
+ return await new OfficialModules().listAvailable();
1498
+ }
1499
+
1500
+ /**
1501
+ * Get the configured output folder name for a project
1502
+ * Resolves xiaomaDir internally from projectDir
1503
+ * @param {string} projectDir - Project directory
1504
+ * @returns {string} Output folder name (relative, default: '_xiaoma-output')
1505
+ */
1506
+ async getOutputFolder(projectDir) {
1507
+ const { xiaomaDir } = await this.findXiaomaDir(projectDir);
1508
+ return this._readOutputFolder(xiaomaDir);
1509
+ }
1510
+
1511
+ /**
1512
+ * Find the xiaoma installation directory in a project
1513
+ * Always uses the standard _xiaoma folder name
1514
+ * @param {string} projectDir - Project directory
1515
+ * @returns {Promise<Object>} { xiaomaDir: string }
1516
+ */
1517
+ async findXiaomaDir(projectDir) {
1518
+ const xiaomaDir = path.join(projectDir, XiaoMa_FOLDER_NAME);
1519
+ return { xiaomaDir };
1520
+ }
1521
+
1522
+ /**
1523
+ * Read the output_folder setting from module config files
1524
+ * Checks xmc/config.yaml first, then other module configs
1525
+ * @param {string} xiaomaDir - XiaoMa installation directory
1526
+ * @returns {string} Output folder path or default
1527
+ */
1528
+ async _readOutputFolder(xiaomaDir) {
1529
+ const yaml = require('yaml');
1530
+
1531
+ // Check xmc/config.yaml first (most common)
1532
+ const xmcConfigPath = path.join(xiaomaDir, 'xmc', 'config.yaml');
1533
+ if (await fs.pathExists(xmcConfigPath)) {
1534
+ try {
1535
+ const content = await fs.readFile(xmcConfigPath, 'utf8');
1536
+ const config = yaml.parse(content);
1537
+ if (config && config.output_folder) {
1538
+ // Strip {project-root}/ prefix if present
1539
+ return config.output_folder.replace(/^\{project-root\}[/\\]/, '');
1540
+ }
1541
+ } catch {
1542
+ // Fall through to other modules
1543
+ }
1544
+ }
1545
+
1546
+ // Scan other module config.yaml files
1547
+ try {
1548
+ const entries = await fs.readdir(xiaomaDir, { withFileTypes: true });
1549
+ for (const entry of entries) {
1550
+ if (!entry.isDirectory() || entry.name === 'xmc' || entry.name.startsWith('_')) continue;
1551
+ const configPath = path.join(xiaomaDir, entry.name, 'config.yaml');
1552
+ if (await fs.pathExists(configPath)) {
1553
+ try {
1554
+ const content = await fs.readFile(configPath, 'utf8');
1555
+ const config = yaml.parse(content);
1556
+ if (config && config.output_folder) {
1557
+ return config.output_folder.replace(/^\{project-root\}[/\\]/, '');
1558
+ }
1559
+ } catch {
1560
+ // Continue scanning
1561
+ }
1562
+ }
1563
+ }
1564
+ } catch {
1565
+ // Directory scan failed
1566
+ }
1567
+
1568
+ // Default fallback
1569
+ return '_xiaoma-output';
1570
+ }
1571
+
1572
+ /**
1573
+ * Parse a CSV line, handling quoted fields
1574
+ * @param {string} line - CSV line to parse
1575
+ * @returns {Array} Array of field values
1576
+ */
1577
+ parseCSVLine(line) {
1578
+ const result = [];
1579
+ let current = '';
1580
+ let inQuotes = false;
1581
+
1582
+ for (let i = 0; i < line.length; i++) {
1583
+ const char = line[i];
1584
+ const nextChar = line[i + 1];
1585
+
1586
+ if (char === '"') {
1587
+ if (inQuotes && nextChar === '"') {
1588
+ // Escaped quote
1589
+ current += '"';
1590
+ i++; // Skip next quote
1591
+ } else {
1592
+ // Toggle quote mode
1593
+ inQuotes = !inQuotes;
1594
+ }
1595
+ } else if (char === ',' && !inQuotes) {
1596
+ result.push(current);
1597
+ current = '';
1598
+ } else {
1599
+ current += char;
1600
+ }
1601
+ }
1602
+ result.push(current);
1603
+ return result;
1604
+ }
1605
+
1606
+ /**
1607
+ * Escape a CSV field if it contains special characters
1608
+ * @param {string} field - Field value to escape
1609
+ * @returns {string} Escaped field
1610
+ */
1611
+ escapeCSVField(field) {
1612
+ if (field === null || field === undefined) {
1613
+ return '';
1614
+ }
1615
+ const str = String(field);
1616
+ // If field contains comma, quote, or newline, wrap in quotes and escape inner quotes
1617
+ if (str.includes(',') || str.includes('"') || str.includes('\n')) {
1618
+ return `"${str.replaceAll('"', '""')}"`;
1619
+ }
1620
+ return str;
1621
+ }
1622
+ }
1623
+
1624
+ module.exports = { Installer };