@zeyue0329/xiaoma-cli 1.13.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +24 -14
- package/src/core-skills/module-help.csv +13 -0
- package/src/{core → core-skills}/module.yaml +8 -0
- package/src/{core/skills/xiaoma-advanced-elicitation/workflow.md → core-skills/xiaoma-advanced-elicitation/SKILL.md} +10 -3
- package/src/core-skills/xiaoma-advanced-elicitation/methods.csv +70 -0
- package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-03-technique-execution.md +6 -4
- package/src/{core/skills → core-skills}/xiaoma-brainstorming/workflow.md +1 -1
- package/src/core-skills/xiaoma-customize/SKILL.md +111 -0
- package/src/core-skills/xiaoma-customize/scripts/list_customizable_skills.js +172 -0
- package/src/{core/skills → core-skills}/xiaoma-distillator/resources/distillate-format-reference.md +1 -1
- package/src/{core/skills → core-skills}/xiaoma-distillator/scripts/analyze_sources.py +2 -2
- package/src/{core/skills/xiaoma-editorial-review-prose/workflow.md → core-skills/xiaoma-editorial-review-prose/SKILL.md} +5 -0
- package/src/{core/skills/xiaoma-editorial-review-structure/workflow.md → core-skills/xiaoma-editorial-review-structure/SKILL.md} +5 -0
- package/src/core-skills/xiaoma-help/SKILL.md +75 -0
- package/src/{core/skills/xiaoma-index-docs/workflow.md → core-skills/xiaoma-index-docs/SKILL.md} +5 -0
- package/src/core-skills/xiaoma-party-mode/SKILL.md +128 -0
- package/src/{core/skills/xiaoma-review-adversarial-general/workflow.md → core-skills/xiaoma-review-adversarial-general/SKILL.md} +5 -0
- package/src/{core/skills/xiaoma-review-edge-case-hunter/workflow.md → core-skills/xiaoma-review-edge-case-hunter/SKILL.md} +5 -0
- package/src/{core/skills/xiaoma-shard-doc/workflow.md → core-skills/xiaoma-shard-doc/SKILL.md} +5 -0
- package/src/core-skills/xiaoma-spec/SKILL.md +129 -0
- package/src/core-skills/xiaoma-spec/assets/headless-schemas.md +33 -0
- package/src/core-skills/xiaoma-spec/assets/spec-template.md +49 -0
- package/src/core-skills/xiaoma-spec/customize.toml +53 -0
- package/src/scripts/resolve_config.js +163 -0
- package/src/scripts/resolve_customization.js +188 -0
- package/src/scripts/toml.js +338 -0
- package/src/xmc-skills/1-analysis/research/xiaoma-domain-research/SKILL.md +96 -0
- package/src/xmc-skills/1-analysis/research/xiaoma-domain-research/customize.toml +41 -0
- package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-06-research-synthesis.md +6 -0
- package/src/xmc-skills/1-analysis/research/xiaoma-market-research/SKILL.md +96 -0
- package/src/xmc-skills/1-analysis/research/xiaoma-market-research/customize.toml +41 -0
- package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-06-research-completion.md +6 -0
- package/src/xmc-skills/1-analysis/research/xiaoma-technical-research/SKILL.md +96 -0
- package/src/xmc-skills/1-analysis/research/xiaoma-technical-research/customize.toml +41 -0
- package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-06-research-synthesis.md +6 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-analyst/SKILL.md +76 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-analyst/customize.toml +90 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/SKILL.md +76 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/customize.toml +81 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/explain-concept.md +20 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/mermaid-gen.md +20 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/validate-doc.md +19 -0
- package/src/xmc-skills/1-analysis/xiaoma-agent-tech-writer/write-document.md +20 -0
- package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/checklist.md +5 -2
- 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
- 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
- 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
- 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
- package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/steps/step-05-validate-prd.md +20 -15
- 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
- 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
- package/src/xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline/steps/step-08-finalize.md +184 -0
- package/src/xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline/workflow.md +140 -0
- package/src/xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline/xiaoma-skill-manifest.yaml +24 -0
- package/src/xmc-skills/1-analysis/xiaoma-document-project/SKILL.md +62 -0
- package/src/xmc-skills/1-analysis/xiaoma-document-project/customize.toml +41 -0
- package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/deep-dive-instructions.md +1 -0
- package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/full-scan-instructions.md +1 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/SKILL.md +135 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/agents/artifact-analyzer.md +60 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/agents/web-researcher.md +49 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/assets/prfaq-template.md +62 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/customize.toml +41 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/customer-faq.md +55 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/internal-faq.md +51 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/press-release.md +60 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/references/verdict.md +83 -0
- package/src/xmc-skills/1-analysis/xiaoma-prfaq/xiaoma-manifest.json +16 -0
- package/src/xmc-skills/1-analysis/xiaoma-product-brief/SKILL.md +91 -0
- package/src/xmc-skills/1-analysis/xiaoma-product-brief/assets/brief-template.md +41 -0
- package/src/xmc-skills/1-analysis/xiaoma-product-brief/customize.toml +99 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-agent-pm/SKILL.md +76 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-agent-pm/customize.toml +75 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-agent-ux-designer/SKILL.md +76 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-agent-ux-designer/customize.toml +60 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-create-prd/SKILL.md +30 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-create-prd/customize.toml +41 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-edit-prd/SKILL.md +30 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-edit-prd/customize.toml +42 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/SKILL.md +92 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/headless-schemas.md +76 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/prd-template.md +165 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/prd-validation-checklist.md +217 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/assets/validation-report-template.html +325 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/customize.toml +147 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/references/headless.md +39 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-prd/references/validate.md +97 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/SKILL.md +90 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/color-themes.md +9 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-directions.md +9 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-example-editorial.md +158 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-example-mobile.md +93 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/design-example-shadcn.md +109 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/excalidraw-wireframe.md +19 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/experience-example-mobile.md +112 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/experience-example-shadcn.md +133 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/headless-schemas.md +84 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/key-screens.md +29 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/assets/validation-report-template.html +319 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/customize.toml +100 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/creative-tools.md +19 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/design-md-spec.md +50 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/headless.md +37 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-ux/references/validate.md +115 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-validate-prd/SKILL.md +30 -0
- package/src/xmc-skills/2-plan-workflows/xiaoma-validate-prd/customize.toml +31 -0
- package/src/xmc-skills/3-solutioning/xiaoma-agent-architect/SKILL.md +76 -0
- package/src/xmc-skills/3-solutioning/xiaoma-agent-architect/customize.toml +65 -0
- package/src/xmc-skills/3-solutioning/xiaoma-check-implementation-readiness/SKILL.md +91 -0
- package/src/xmc-skills/3-solutioning/xiaoma-check-implementation-readiness/customize.toml +41 -0
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-01-document-discovery.md +1 -1
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-02-prd-analysis.md +1 -1
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +1 -1
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-06-final-assessment.md +6 -0
- package/src/xmc-skills/3-solutioning/xiaoma-create-architecture/SKILL.md +74 -0
- package/src/xmc-skills/3-solutioning/xiaoma-create-architecture/customize.toml +41 -0
- package/src/xmc-skills/3-solutioning/xiaoma-create-architecture/references/headless.md +37 -0
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-07-validation.md +23 -21
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-08-complete.md +6 -0
- package/src/xmc-skills/3-solutioning/xiaoma-create-epics-and-stories/SKILL.md +93 -0
- package/src/xmc-skills/3-solutioning/xiaoma-create-epics-and-stories/customize.toml +41 -0
- package/src/xmc-skills/3-solutioning/xiaoma-create-epics-and-stories/references/headless.md +35 -0
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-02-design-epics.md +34 -4
- package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-04-final-validation.md +12 -0
- package/src/xmc-skills/3-solutioning/xiaoma-generate-project-context/SKILL.md +81 -0
- package/src/xmc-skills/3-solutioning/xiaoma-generate-project-context/customize.toml +41 -0
- package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/steps/step-03-complete.md +6 -0
- package/src/xmc-skills/4-implementation/xiaoma-agent-dev/SKILL.md +76 -0
- package/src/xmc-skills/4-implementation/xiaoma-agent-dev/customize.toml +131 -0
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/checklist.md +29 -0
- 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
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-02-create-story.md +111 -0
- 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
- 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
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-05-code-review.md +99 -0
- 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
- 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
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-08-complete-story.md +174 -0
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/steps/step-09-finalize.md +145 -0
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/workflow.md +127 -0
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline/xiaoma-skill-manifest.yaml +27 -0
- package/src/{xmc/workflows/4-implementation/auto-story-pipeline-batch → xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch}/SKILL.md +2 -2
- package/src/xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch/checklist.md +45 -0
- package/src/{xmc/workflows/4-implementation/auto-story-pipeline-batch → xmc-skills/4-implementation/xiaoma-auto-story-pipeline-batch}/workflow.md +152 -9
- 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
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/SKILL.md +68 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/generate-trail.md +38 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-01-orientation.md +105 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-02-walkthrough.md +89 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-03-detail-pass.md +106 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-04-testing.md +74 -0
- package/src/xmc-skills/4-implementation/xiaoma-checkpoint-preview/step-05-wrapup.md +30 -0
- package/src/xmc-skills/4-implementation/xiaoma-code-review/SKILL.md +90 -0
- package/src/xmc-skills/4-implementation/xiaoma-code-review/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-code-review/steps/step-01-gather-context.md +85 -0
- package/src/xmc-skills/4-implementation/xiaoma-code-review/steps/step-02-review.md +35 -0
- package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-code-review/steps/step-03-triage.md +7 -8
- package/src/xmc-skills/4-implementation/xiaoma-code-review/steps/step-04-present.md +132 -0
- package/src/{xmc/workflows/4-implementation/xiaoma-correct-course/workflow.md → xmc-skills/4-implementation/xiaoma-correct-course/SKILL.md} +65 -31
- package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-correct-course/checklist.md +2 -2
- package/src/xmc-skills/4-implementation/xiaoma-correct-course/customize.toml +41 -0
- package/src/{xmc/workflows/4-implementation/xiaoma-create-story/workflow.md → xmc-skills/4-implementation/xiaoma-create-story/SKILL.md} +60 -11
- package/src/xmc-skills/4-implementation/xiaoma-create-story/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-create-story/references/headless.md +32 -0
- package/src/{xmc/workflows/4-implementation/xiaoma-dev-story/workflow.md → xmc-skills/4-implementation/xiaoma-dev-story/SKILL.md} +70 -20
- package/src/xmc-skills/4-implementation/xiaoma-dev-story/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-investigate/SKILL.md +196 -0
- package/src/xmc-skills/4-implementation/xiaoma-investigate/customize.toml +62 -0
- package/src/xmc-skills/4-implementation/xiaoma-investigate/references/case-file-template.md +127 -0
- package/src/{xmc/workflows/xiaoma-qa-generate-e2e-tests/workflow.md → xmc-skills/4-implementation/xiaoma-qa-generate-e2e-tests/SKILL.md} +51 -23
- package/src/{xmc/workflows → xmc-skills/4-implementation}/xiaoma-qa-generate-e2e-tests/checklist.md +1 -5
- package/src/xmc-skills/4-implementation/xiaoma-qa-generate-e2e-tests/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/SKILL.md +111 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/compile-epic-context.md +62 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/spec-template.md +88 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-01-clarify-and-route.md +100 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-02-plan.md +47 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-03-implement.md +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-04-review.md +50 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-05-present.md +78 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/step-oneshot.md +71 -0
- package/src/xmc-skills/4-implementation/xiaoma-quick-dev/sync-sprint-status.md +19 -0
- package/src/{xmc/workflows/4-implementation/xiaoma-retrospective/workflow.md → xmc-skills/4-implementation/xiaoma-retrospective/SKILL.md} +185 -152
- package/src/xmc-skills/4-implementation/xiaoma-retrospective/customize.toml +41 -0
- package/src/{xmc/workflows/4-implementation/xiaoma-sprint-planning/workflow.md → xmc-skills/4-implementation/xiaoma-sprint-planning/SKILL.md} +59 -15
- package/src/xmc-skills/4-implementation/xiaoma-sprint-planning/customize.toml +41 -0
- package/src/xmc-skills/4-implementation/xiaoma-sprint-planning/references/headless.md +28 -0
- package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-sprint-planning/sprint-status-template.yaml +3 -3
- package/src/{xmc/workflows/4-implementation/xiaoma-sprint-status/workflow.md → xmc-skills/4-implementation/xiaoma-sprint-status/SKILL.md} +57 -20
- package/src/xmc-skills/4-implementation/xiaoma-sprint-status/customize.toml +41 -0
- package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/checklist.md +6 -0
- 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
- 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
- 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
- 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
- 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
- package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/workflow.md +7 -8
- 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
- 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
- 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
- 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
- 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 +9 -7
- 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
- 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
- package/src/xmc-skills/module-help.csv +32 -0
- package/src/xmc-skills/module.yaml +95 -0
- package/src/xpm-skills/module-help.csv +3 -0
- package/src/xpm-skills/module.yaml +36 -0
- package/src/xpm-skills/xiaoma-agent-patent-advisor/SKILL.md +75 -0
- package/src/xpm-skills/xiaoma-agent-patent-advisor/customize.toml +46 -0
- package/src/xpm-skills/xiaoma-patent-mining/SKILL.md +6 -0
- package/src/xpm-skills/xiaoma-patent-mining/steps/step-01-project-analysis.md +65 -0
- package/src/xpm-skills/xiaoma-patent-mining/steps/step-02-patent-mining.md +87 -0
- package/src/xpm-skills/xiaoma-patent-mining/steps/step-03-disclosure-writing.md +110 -0
- package/src/xpm-skills/xiaoma-patent-mining/steps/step-04-ai-taste-removal.md +85 -0
- package/src/xpm-skills/xiaoma-patent-mining/steps/step-05-docx-generation.md +111 -0
- package/src/xpm-skills/xiaoma-patent-mining/workflow.md +94 -0
- package/tools/format-workflow-md.js +263 -0
- package/tools/{cli → installer}/README.md +2 -2
- package/tools/installer/cli-utils.js +57 -0
- package/tools/installer/commands/install.js +146 -0
- package/tools/{cli → installer}/commands/status.js +15 -7
- package/tools/{cli → installer}/commands/uninstall.js +7 -7
- package/tools/installer/core/config.js +73 -0
- package/tools/installer/core/existing-install.js +121 -0
- package/tools/installer/core/install-paths.js +132 -0
- package/tools/installer/core/installer.js +1624 -0
- package/tools/installer/core/legacy-warnings.js +156 -0
- package/tools/installer/core/manifest-generator.js +859 -0
- package/tools/installer/core/manifest.js +434 -0
- package/tools/{cli/lib → installer}/file-ops.js +1 -1
- package/tools/installer/fs-native.js +116 -0
- package/tools/installer/ide/_config-driven.js +972 -0
- package/tools/{cli/installers/lib → installer}/ide/manager.js +82 -62
- package/tools/installer/ide/platform-codes.js +80 -0
- package/tools/installer/ide/platform-codes.yaml +322 -0
- package/tools/installer/ide/shared/installed-skills.js +50 -0
- package/tools/{cli/installers/lib → installer}/ide/shared/path-utils.js +0 -145
- package/tools/{cli/installers/lib → installer}/ide/shared/skill-manifest.js +3 -36
- package/tools/installer/list-options.js +210 -0
- package/tools/{cli/installers/lib → installer}/message-loader.js +3 -3
- package/tools/installer/modules/channel-plan.js +203 -0
- package/tools/installer/modules/channel-resolver.js +241 -0
- package/tools/installer/modules/custom-module-manager.js +912 -0
- package/tools/installer/modules/external-manager.js +533 -0
- package/tools/installer/modules/module-help-schema.js +13 -0
- package/tools/{cli/installers/lib/core/config-collector.js → installer/modules/official-modules.js} +1052 -110
- package/tools/installer/modules/plugin-resolver.js +398 -0
- package/tools/installer/modules/version-resolver.js +336 -0
- package/tools/installer/project-root.js +230 -0
- package/tools/{cli/lib → installer}/prompts.js +143 -100
- package/tools/installer/set-overrides.js +367 -0
- package/tools/installer/ui.js +2078 -0
- package/tools/{cli → installer}/xiaoma-cli.js +9 -10
- package/tools/{cli/lib → installer}/yaml-format.js +1 -1
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/schema/step.js +855 -0
- package/tools/skill-validator.md +323 -0
- package/tools/validate-file-refs.js +566 -0
- package/tools/validate-frontmatter-prose-routing.js +334 -0
- package/tools/validate-skills.js +702 -0
- package/tools/validate-step-schemas.js +401 -0
- package/tools/validate-svg-changes.sh +1 -1
- package/tools/validate-trigger-column-vs-emits.js +375 -0
- package/tools/validate-warnings-samples.js +261 -0
- package/tools/xiaoma/rebrand.mjs +0 -0
- package/tools/xiaoma-npx-wrapper.js +2 -2
- package/.playwright-cli/console-2026-05-13T06-36-26-793Z.log +0 -2
- package/.playwright-cli/page-2026-05-13T06-36-27-725Z.yml +0 -1
- package/CLAUDE.md +0 -111
- package/README.md +0 -128
- package/XiaoMa-CLI-2026H2-/350/277/255/344/273/243/350/247/204/345/210/222.pptx +0 -0
- package/demo/xiaoma-bug-circle-resolve/SKILL.md +0 -6
- package/demo/xiaoma-bug-circle-resolve/workflow.md +0 -254
- package/demo/xiaoma-bug-resolve/SKILL.md +0 -6
- package/demo/xiaoma-bug-resolve/workflow.md +0 -269
- package/demo/xiaoma-prd-saas-zh/README.md +0 -57
- package/demo/xiaoma-prd-saas-zh/domain-research.md +0 -128
- package/demo/xiaoma-prd-saas-zh/epics.md +0 -303
- package/demo/xiaoma-prd-saas-zh/market-research-2026-q1.md +0 -183
- package/demo/xiaoma-prd-saas-zh/prd-bad-examples.md +0 -268
- package/demo/xiaoma-prd-saas-zh/prd.md +0 -409
- package/demo/xiaoma-prd-saas-zh/product-brief.md +0 -97
- package/demo/xiaoma-prd-saas-zh/validation-report.md +0 -279
- 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
- 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
- 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
- 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
- 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
- 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
- package/media/doc1_fig1.png +0 -0
- package/media/doc1_fig2.png +0 -0
- package/media/doc1_fig3.png +0 -0
- package/media/doc1_fig4.png +0 -0
- package/media/doc2_fig1.png +0 -0
- package/media/doc2_fig2.png +0 -0
- package/media/doc2_fig3.png +0 -0
- package/media/doc2_fig4.png +0 -0
- package/media/doc3_fig1.png +0 -0
- package/media/doc3_fig2.png +0 -0
- package/media/doc3_fig3.png +0 -0
- package/media/doc3_fig4.png +0 -0
- package/media/doc4_fig1.png +0 -0
- package/media/doc4_fig2.png +0 -0
- package/media/doc4_fig3.png +0 -0
- package/media/doc5_fig1.png +0 -0
- package/media/doc5_fig2.png +0 -0
- package/media/doc5_fig3.png +0 -0
- package/patent-disclosure-optimized/SKILL.md +0 -416
- package/src/core/module-help.csv +0 -11
- package/src/core/skills/xiaoma-advanced-elicitation/SKILL.md +0 -6
- package/src/core/skills/xiaoma-advanced-elicitation/methods.csv +0 -51
- package/src/core/skills/xiaoma-editorial-review-prose/SKILL.md +0 -6
- package/src/core/skills/xiaoma-editorial-review-structure/SKILL.md +0 -6
- package/src/core/skills/xiaoma-help/SKILL.md +0 -6
- package/src/core/skills/xiaoma-help/workflow.md +0 -88
- package/src/core/skills/xiaoma-help/xiaoma-skill-manifest.yaml +0 -1
- package/src/core/skills/xiaoma-index-docs/SKILL.md +0 -6
- package/src/core/skills/xiaoma-index-docs/xiaoma-skill-manifest.yaml +0 -1
- package/src/core/skills/xiaoma-party-mode/SKILL.md +0 -6
- package/src/core/skills/xiaoma-party-mode/steps/step-01-agent-loading.md +0 -138
- package/src/core/skills/xiaoma-party-mode/steps/step-02-discussion-orchestration.md +0 -187
- package/src/core/skills/xiaoma-party-mode/steps/step-03-graceful-exit.md +0 -167
- package/src/core/skills/xiaoma-party-mode/workflow.md +0 -190
- package/src/core/skills/xiaoma-party-mode/xiaoma-skill-manifest.yaml +0 -1
- package/src/core/skills/xiaoma-review-adversarial-general/SKILL.md +0 -6
- package/src/core/skills/xiaoma-review-adversarial-general/xiaoma-skill-manifest.yaml +0 -1
- package/src/core/skills/xiaoma-review-edge-case-hunter/SKILL.md +0 -6
- package/src/core/skills/xiaoma-review-edge-case-hunter/xiaoma-skill-manifest.yaml +0 -1
- package/src/core/skills/xiaoma-shard-doc/SKILL.md +0 -6
- package/src/core/skills/xiaoma-shard-doc/xiaoma-skill-manifest.yaml +0 -1
- package/src/core/tasks/xiaoma-create-prd/SKILL.md +0 -6
- package/src/core/tasks/xiaoma-create-prd/data/prd-purpose.md +0 -354
- package/src/core/tasks/xiaoma-create-prd/data/upstream-input-contract.md +0 -168
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-01-init.md +0 -178
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-01b-continue.md +0 -161
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-02-discovery.md +0 -208
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-02b-vision.md +0 -142
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-02c-executive-summary.md +0 -158
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-03-success.md +0 -214
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-04-journeys.md +0 -201
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-05-domain.md +0 -194
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-06-innovation.md +0 -211
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-07-project-type.md +0 -222
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-08-scoping.md +0 -216
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-09-functional.md +0 -219
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-10-nonfunctional.md +0 -230
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-11-polish.md +0 -221
- package/src/core/tasks/xiaoma-create-prd/steps-c/step-12-complete.md +0 -115
- package/src/core/tasks/xiaoma-create-prd/templates/prd-skeleton-reference.md +0 -428
- package/src/core/tasks/xiaoma-create-prd/templates/prd-template.md +0 -108
- package/src/core/tasks/xiaoma-create-prd/workflow.md +0 -62
- package/src/core/tasks/xiaoma-create-prd/xiaoma-skill-manifest.yaml +0 -1
- package/src/utility/agent-components/activation-rules.txt +0 -6
- package/src/utility/agent-components/activation-steps.txt +0 -14
- package/src/utility/agent-components/agent-command-header.md +0 -1
- package/src/utility/agent-components/agent.customize.template.yaml +0 -41
- package/src/utility/agent-components/handler-action.txt +0 -4
- package/src/utility/agent-components/handler-data.txt +0 -5
- package/src/utility/agent-components/handler-exec.txt +0 -6
- package/src/utility/agent-components/handler-multi.txt +0 -13
- package/src/utility/agent-components/handler-tmpl.txt +0 -5
- package/src/utility/agent-components/menu-handlers.txt +0 -6
- package/src/xmc/agents/analyst.agent.yaml +0 -47
- package/src/xmc/agents/architect.agent.yaml +0 -29
- package/src/xmc/agents/dev.agent.yaml +0 -38
- package/src/xmc/agents/pm.agent.yaml +0 -44
- package/src/xmc/agents/qa.agent.yaml +0 -58
- package/src/xmc/agents/quick-flow-solo-dev.agent.yaml +0 -36
- package/src/xmc/agents/sm.agent.yaml +0 -53
- package/src/xmc/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +0 -224
- package/src/xmc/agents/tech-writer/tech-writer.agent.yaml +0 -46
- package/src/xmc/agents/tech-writer/xiaoma-skill-manifest.yaml +0 -3
- package/src/xmc/agents/ux-designer.agent.yaml +0 -27
- package/src/xmc/agents/xiaoma-skill-manifest.yaml +0 -39
- package/src/xmc/data/project-context-template.md +0 -26
- package/src/xmc/module-help.csv +0 -32
- package/src/xmc/module.yaml +0 -50
- package/src/xmc/teams/default-party.csv +0 -20
- package/src/xmc/teams/team-fullstack.yaml +0 -12
- package/src/xmc/workflows/1-analysis/auto-requirements-pipeline/steps/step-08-finalize.md +0 -124
- package/src/xmc/workflows/1-analysis/auto-requirements-pipeline/workflow.md +0 -107
- package/src/xmc/workflows/1-analysis/auto-requirements-pipeline/xiaoma-skill-manifest.yaml +0 -3
- package/src/xmc/workflows/1-analysis/research/market-steps/step-01-init.md +0 -182
- package/src/xmc/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +0 -237
- package/src/xmc/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +0 -249
- package/src/xmc/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +0 -259
- package/src/xmc/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +0 -177
- package/src/xmc/workflows/1-analysis/research/market-steps/step-06-research-completion.md +0 -476
- package/src/xmc/workflows/1-analysis/research/xiaoma-domain-research/SKILL.md +0 -6
- package/src/xmc/workflows/1-analysis/research/xiaoma-domain-research/workflow.md +0 -49
- package/src/xmc/workflows/1-analysis/research/xiaoma-domain-research/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/1-analysis/research/xiaoma-market-research/SKILL.md +0 -6
- package/src/xmc/workflows/1-analysis/research/xiaoma-market-research/workflow.md +0 -49
- package/src/xmc/workflows/1-analysis/research/xiaoma-market-research/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/SKILL.md +0 -6
- package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/research.template.md +0 -29
- package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/workflow.md +0 -50
- package/src/xmc/workflows/1-analysis/research/xiaoma-technical-research/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/SKILL.md +0 -6
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/product-brief.template.md +0 -10
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-01-init.md +0 -170
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-01b-continue.md +0 -158
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-02-vision.md +0 -193
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-03-users.md +0 -196
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-04-metrics.md +0 -199
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-05-scope.md +0 -213
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/steps/step-06-complete.md +0 -159
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/workflow.md +0 -55
- package/src/xmc/workflows/1-analysis/xiaoma-create-product-brief/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/1-analysis/xiaoma-product-brief-preview/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +0 -15
- package/src/xmc/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +0 -197
- package/src/xmc/workflows/2-plan-workflows/create-prd/data/project-types.csv +0 -11
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +0 -224
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +0 -191
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +0 -209
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +0 -174
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -214
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +0 -228
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +0 -217
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -205
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -243
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +0 -263
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +0 -209
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -264
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +0 -242
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +0 -232
- package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +0 -65
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/SKILL.md +0 -6
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-01-init.md +0 -135
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-01b-continue.md +0 -127
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-02-discovery.md +0 -190
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-03-core-experience.md +0 -217
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-04-emotional-response.md +0 -220
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-05-inspiration.md +0 -235
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-06-design-system.md +0 -253
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-07-defining-experience.md +0 -255
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-08-visual-foundation.md +0 -225
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-09-design-directions.md +0 -225
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-10-user-journeys.md +0 -242
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-11-component-strategy.md +0 -249
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-12-ux-patterns.md +0 -238
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-13-responsive-accessibility.md +0 -265
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/steps/step-14-complete.md +0 -171
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/ux-design-template.md +0 -13
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/workflow.md +0 -36
- package/src/xmc/workflows/2-plan-workflows/xiaoma-create-ux-design/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/SKILL.md +0 -6
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-01-discovery.md +0 -242
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-01b-legacy-conversion.md +0 -204
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-02-review.md +0 -245
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-03-edit.md +0 -250
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/steps-e/step-e-04-complete.md +0 -165
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/workflow.md +0 -63
- package/src/xmc/workflows/2-plan-workflows/xiaoma-edit-prd/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/SKILL.md +0 -6
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/domain-complexity.csv +0 -15
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/prd-purpose.md +0 -197
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/prd-quality-rubric.csv +0 -14
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/data/project-types.csv +0 -11
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-01-discovery.md +0 -221
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-02-format-detection.md +0 -188
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-02b-parity-check.md +0 -206
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-03-density-validation.md +0 -171
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -211
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-05-measurability-validation.md +0 -225
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-06-traceability-validation.md +0 -214
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -202
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -240
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-09-project-type-validation.md +0 -260
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-10-smart-validation.md +0 -206
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -261
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-12-completeness-validation.md +0 -239
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/steps-v/step-v-13-report-complete.md +0 -229
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/workflow.md +0 -62
- package/src/xmc/workflows/2-plan-workflows/xiaoma-validate-prd/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/3-solutioning/xiaoma-check-implementation-readiness/SKILL.md +0 -6
- package/src/xmc/workflows/3-solutioning/xiaoma-check-implementation-readiness/workflow.md +0 -49
- package/src/xmc/workflows/3-solutioning/xiaoma-check-implementation-readiness/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/3-solutioning/xiaoma-create-architecture/SKILL.md +0 -6
- package/src/xmc/workflows/3-solutioning/xiaoma-create-architecture/workflow.md +0 -38
- package/src/xmc/workflows/3-solutioning/xiaoma-create-architecture/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/3-solutioning/xiaoma-create-epics-and-stories/SKILL.md +0 -6
- package/src/xmc/workflows/3-solutioning/xiaoma-create-epics-and-stories/workflow.md +0 -53
- package/src/xmc/workflows/3-solutioning/xiaoma-create-epics-and-stories/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/checklist.md +0 -22
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-02-create-story.md +0 -102
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-05-code-review.md +0 -95
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-08-complete-story.md +0 -114
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/steps/step-09-finalize.md +0 -69
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/workflow.md +0 -89
- package/src/xmc/workflows/4-implementation/auto-story-pipeline/xiaoma-skill-manifest.yaml +0 -3
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/checklist.md +0 -23
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/steps/step-01-gather-context.md +0 -61
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/steps/step-02-review.md +0 -41
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/steps/step-04-present.md +0 -38
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/workflow.md +0 -54
- package/src/xmc/workflows/4-implementation/xiaoma-code-review/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/xiaoma-correct-course/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-correct-course/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/xiaoma-create-story/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-create-story/discover-inputs.md +0 -88
- package/src/xmc/workflows/4-implementation/xiaoma-create-story/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/xiaoma-dev-story/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-dev-story/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/xiaoma-retrospective/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-retrospective/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/xiaoma-sprint-planning/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-sprint-planning/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/4-implementation/xiaoma-sprint-status/SKILL.md +0 -6
- package/src/xmc/workflows/4-implementation/xiaoma-sprint-status/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/xiaoma-document-project/SKILL.md +0 -6
- package/src/xmc/workflows/xiaoma-document-project/workflow.md +0 -27
- package/src/xmc/workflows/xiaoma-document-project/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/xiaoma-generate-project-context/SKILL.md +0 -6
- package/src/xmc/workflows/xiaoma-generate-project-context/workflow.md +0 -43
- package/src/xmc/workflows/xiaoma-generate-project-context/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/xiaoma-qa-generate-e2e-tests/SKILL.md +0 -6
- package/src/xmc/workflows/xiaoma-qa-generate-e2e-tests/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/SKILL.md +0 -6
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-01-mode-detection.md +0 -169
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-02-context-gathering.md +0 -114
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-03-execute.md +0 -107
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-04-self-check.md +0 -107
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-05-adversarial-review.md +0 -94
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/steps/step-06-resolve-findings.md +0 -144
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/workflow.md +0 -38
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/xiaoma-skill-manifest.yaml +0 -1
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-spec/xiaoma-skill-manifest.yaml +0 -1
- package/tools/cli/commands/install.js +0 -87
- package/tools/cli/external-official-modules.yaml +0 -4
- package/tools/cli/installers/lib/core/custom-module-cache.js +0 -260
- package/tools/cli/installers/lib/core/dependency-resolver.js +0 -743
- package/tools/cli/installers/lib/core/detector.js +0 -223
- package/tools/cli/installers/lib/core/ide-config-manager.js +0 -157
- package/tools/cli/installers/lib/core/installer.js +0 -3212
- package/tools/cli/installers/lib/core/manifest-generator.js +0 -1374
- package/tools/cli/installers/lib/core/manifest.js +0 -1040
- package/tools/cli/installers/lib/custom/handler.js +0 -358
- package/tools/cli/installers/lib/ide/_base-ide.js +0 -673
- package/tools/cli/installers/lib/ide/_config-driven.js +0 -1058
- package/tools/cli/installers/lib/ide/platform-codes.js +0 -100
- package/tools/cli/installers/lib/ide/platform-codes.yaml +0 -321
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +0 -181
- package/tools/cli/installers/lib/ide/shared/module-injections.js +0 -136
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +0 -368
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +0 -179
- package/tools/cli/installers/lib/ide/shared/xiaoma-artifacts.js +0 -181
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +0 -14
- package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +0 -8
- package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +0 -15
- package/tools/cli/installers/lib/ide/templates/combined/default-task.md +0 -10
- package/tools/cli/installers/lib/ide/templates/combined/default-tool.md +0 -10
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +0 -6
- package/tools/cli/installers/lib/ide/templates/combined/gemini-agent.toml +0 -14
- package/tools/cli/installers/lib/ide/templates/combined/gemini-task.toml +0 -11
- package/tools/cli/installers/lib/ide/templates/combined/gemini-tool.toml +0 -11
- package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow-yaml.toml +0 -16
- package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow.toml +0 -14
- package/tools/cli/installers/lib/ide/templates/combined/kiro-agent.md +0 -16
- package/tools/cli/installers/lib/ide/templates/combined/kiro-task.md +0 -9
- package/tools/cli/installers/lib/ide/templates/combined/kiro-tool.md +0 -9
- package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow.md +0 -7
- package/tools/cli/installers/lib/ide/templates/combined/opencode-agent.md +0 -15
- package/tools/cli/installers/lib/ide/templates/combined/opencode-task.md +0 -13
- package/tools/cli/installers/lib/ide/templates/combined/opencode-tool.md +0 -13
- package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow-yaml.md +0 -16
- package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow.md +0 -16
- package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +0 -9
- package/tools/cli/installers/lib/ide/templates/combined/trae.md +0 -9
- package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +0 -10
- package/tools/cli/installers/lib/ide/templates/split/.gitkeep +0 -0
- package/tools/cli/installers/lib/modules/external-manager.js +0 -136
- package/tools/cli/installers/lib/modules/manager.js +0 -1382
- package/tools/cli/lib/activation-builder.js +0 -165
- package/tools/cli/lib/agent/compiler.js +0 -516
- package/tools/cli/lib/agent/installer.js +0 -680
- package/tools/cli/lib/agent/template-engine.js +0 -152
- package/tools/cli/lib/agent-analyzer.js +0 -97
- package/tools/cli/lib/agent-party-generator.js +0 -194
- package/tools/cli/lib/cli-utils.js +0 -182
- package/tools/cli/lib/config.js +0 -213
- package/tools/cli/lib/platform-codes.js +0 -116
- package/tools/cli/lib/project-root.js +0 -77
- package/tools/cli/lib/ui.js +0 -1960
- package/tools/cli/lib/xml-handler.js +0 -177
- package/tools/cli/lib/xml-to-markdown.js +0 -82
- package/tools/cli/lib/yaml-xml-builder.js +0 -570
- package/tools/platform-codes.yaml +0 -157
- package/tools/schema/agent.js +0 -489
- 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
- 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
- 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
- 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
- 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
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/SKILL.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/brain-methods.csv +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-01-session-setup.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-01b-continue.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02a-user-selected.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02b-ai-recommended.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02c-random-selection.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-02d-progressive-flow.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/steps/step-04-idea-organization.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-brainstorming/template.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/SKILL.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/agents/distillate-compressor.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/agents/round-trip-reconstructor.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/resources/compression-rules.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/resources/splitting-strategy.md +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/scripts/tests/test_analyze_sources.py +0 -0
- /package/src/{core/skills → core-skills}/xiaoma-distillator/xiaoma-skill-manifest.yaml +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-01-init.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-02-domain-analysis.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-03-competitive-landscape.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-04-regulatory-focus.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-domain-research/domain-steps/step-05-technical-trends.md +0 -0
- /package/src/{xmc/workflows/1-analysis/research → xmc-skills/1-analysis/research/xiaoma-domain-research}/research.template.md +0 -0
- /package/src/{xmc/workflows/1-analysis/research/xiaoma-domain-research → xmc-skills/1-analysis/research/xiaoma-market-research}/research.template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-01-init.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-02-customer-behavior.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-03-customer-pain-points.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-04-customer-decisions.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-market-research/steps/step-05-competitive-analysis.md +0 -0
- /package/src/{xmc/workflows/1-analysis/research/xiaoma-market-research → xmc-skills/1-analysis/research/xiaoma-technical-research}/research.template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-01-init.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-02-technical-overview.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-03-integration-patterns.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-04-architectural-patterns.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/research/xiaoma-technical-research/technical-steps/step-05-implementation-research.md +0 -0
- /package/src/{xmc/workflows/1-analysis/auto-requirements-pipeline → xmc-skills/1-analysis/xiaoma-auto-requirements-pipeline}/SKILL.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/checklist.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/documentation-requirements.csv +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/instructions.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/deep-dive-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/index-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/project-overview-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/project-scan-report-schema.json +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/templates/source-tree-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/deep-dive-workflow.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/1-analysis}/xiaoma-document-project/workflows/full-scan-workflow.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/SKILL.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/artifact-analyzer.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/opportunity-reviewer.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/skeptic-reviewer.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/agents/web-researcher.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/contextual-discovery.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/draft-and-review.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/finalize.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/prompts/guided-elicitation.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/resources/brief-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/1-analysis/xiaoma-product-brief-preview/xiaoma-manifest.json +0 -0
- /package/src/{core/skills/xiaoma-advanced-elicitation → xmc-skills/1-analysis/xiaoma-product-brief-preview}/xiaoma-skill-manifest.yaml +0 -0
- /package/src/{core/tasks/xiaoma-create-prd/data → xmc-skills/2-plan-workflows/xiaoma-prd/assets}/domain-complexity.csv +0 -0
- /package/src/{core/tasks/xiaoma-create-prd/data → xmc-skills/2-plan-workflows/xiaoma-prd/assets}/project-types.csv +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-04-ux-alignment.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/steps/step-05-epic-quality-review.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-check-implementation-readiness/templates/readiness-report-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/architecture-decision-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/data/domain-complexity.csv +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/data/project-types.csv +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-01-init.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-01b-continue.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-02-context.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-03-starter.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-04-decisions.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-05-patterns.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-architecture/steps/step-06-structure.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-01-validate-prerequisites.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/steps/step-03-create-stories.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/3-solutioning/xiaoma-create-epics-and-stories/templates/epics-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/project-context-template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/steps/step-01-discover.md +0 -0
- /package/src/{xmc/workflows → xmc-skills/3-solutioning}/xiaoma-generate-project-context/steps/step-02-generate.md +0 -0
- /package/src/{xmc/workflows/4-implementation/auto-story-pipeline → xmc-skills/4-implementation/xiaoma-auto-story-pipeline}/SKILL.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-create-story/checklist.md +0 -0
- /package/src/{xmc/workflows/4-implementation/xiaoma-code-review → xmc-skills/4-implementation/xiaoma-create-story}/discover-inputs.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-create-story/template.md +0 -0
- /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-dev-story/checklist.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/SKILL.md +0 -0
- /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
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-02-plan.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-03-implement.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-04-review.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/steps/step-05-present.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/tech-spec-template.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-dev-new-preview/workflow.md +0 -0
- /package/src/{core/skills/xiaoma-brainstorming → xmc-skills/4-implementation/xiaoma-quick-dev-new-preview}/xiaoma-skill-manifest.yaml +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/SKILL.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-01-understand.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-02-investigate.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-03-generate.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/steps/step-04-review.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/tech-spec-template.md +0 -0
- /package/src/{xmc/workflows/xiaoma-quick-flow → xmc-skills/4-implementation}/xiaoma-quick-spec/workflow.md +0 -0
- /package/src/{core/skills/xiaoma-editorial-review-prose → xmc-skills/4-implementation/xiaoma-quick-spec}/xiaoma-skill-manifest.yaml +0 -0
- /package/src/{xmc/workflows → xmc-skills}/4-implementation/xiaoma-sprint-planning/checklist.md +0 -0
- /package/src/{xmc/workflows/5-full-pipeline/auto-full-pipeline → xmc-skills/5-full-pipeline/xiaoma-auto-full-pipeline}/SKILL.md +0 -0
- /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
- /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
- /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
- /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/references/disclosure-template.md +0 -0
- /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/references/docx-format-spec.md +0 -0
- /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/references/mining-principles.md +0 -0
- /package/{patent-disclosure-optimized → src/xpm-skills/xiaoma-patent-mining}/scripts/md2docx.js +0 -0
- /package/src/{core/skills/xiaoma-editorial-review-structure → xpm-skills/xiaoma-patent-mining}/xiaoma-skill-manifest.yaml +0 -0
- /package/tools/{cli/installers → installer}/install-messages.yaml +0 -0
package/tools/{cli/installers/lib/core/config-collector.js → installer/modules/official-modules.js}
RENAMED
|
@@ -1,30 +1,783 @@
|
|
|
1
1
|
const path = require('node:path');
|
|
2
|
-
const fs = require('fs-
|
|
2
|
+
const fs = require('../fs-native');
|
|
3
3
|
const yaml = require('yaml');
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const prompts = require('../prompts');
|
|
5
|
+
const { getProjectRoot, getSourcePath, getModulePath } = require('../project-root');
|
|
6
|
+
const { CLIUtils } = require('../cli-utils');
|
|
7
|
+
const { ExternalModuleManager } = require('./external-manager');
|
|
8
|
+
|
|
9
|
+
class OfficialModules {
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.externalModuleManager = new ExternalModuleManager();
|
|
12
|
+
// Config collection state (merged from ConfigCollector)
|
|
10
13
|
this.collectedConfig = {};
|
|
11
|
-
this.
|
|
14
|
+
this._existingConfig = null;
|
|
15
|
+
// Tracked during interactive config collection so {directory_name}
|
|
16
|
+
// placeholder defaults can be resolved in buildQuestion().
|
|
12
17
|
this.currentProjectDir = null;
|
|
13
|
-
|
|
18
|
+
// Install-time channel flag state. Set by Config.build once, then used as
|
|
19
|
+
// the default for every findModuleSource/cloneExternalModule call so that
|
|
20
|
+
// pre-install config collection and the install step agree on which ref
|
|
21
|
+
// to clone.
|
|
22
|
+
this.channelOptions = options.channelOptions || null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Module configurations collected during install.
|
|
27
|
+
*/
|
|
28
|
+
get moduleConfigs() {
|
|
29
|
+
return this.collectedConfig;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Existing module configurations read from a previous installation.
|
|
34
|
+
*/
|
|
35
|
+
get existingConfig() {
|
|
36
|
+
return this._existingConfig;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Build a configured OfficialModules instance from install config.
|
|
41
|
+
* @param {Object} config - Clean install config (from Config.build)
|
|
42
|
+
* @param {Object} paths - InstallPaths instance
|
|
43
|
+
* @returns {OfficialModules}
|
|
44
|
+
*/
|
|
45
|
+
static async build(config, paths) {
|
|
46
|
+
const instance = new OfficialModules({ channelOptions: config.channelOptions });
|
|
47
|
+
|
|
48
|
+
// Pre-collected by UI or quickUpdate — store and load existing for path-change detection
|
|
49
|
+
if (config.moduleConfigs) {
|
|
50
|
+
instance.collectedConfig = config.moduleConfigs;
|
|
51
|
+
await instance.loadExistingConfig(paths.projectRoot);
|
|
52
|
+
return instance;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Headless collection (--yes flag from CLI without UI, tests)
|
|
56
|
+
if (config.hasCoreConfig()) {
|
|
57
|
+
instance.collectedConfig.core = config.coreConfig;
|
|
58
|
+
instance.allAnswers = {};
|
|
59
|
+
for (const [key, value] of Object.entries(config.coreConfig)) {
|
|
60
|
+
instance.allAnswers[`core_${key}`] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const toCollect = config.hasCoreConfig() ? config.modules.filter((m) => m !== 'core') : [...config.modules];
|
|
65
|
+
|
|
66
|
+
await instance.collectAllConfigurations(toCollect, paths.projectRoot, {
|
|
67
|
+
skipPrompts: config.skipPrompts,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return instance;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Copy a file to the target location
|
|
75
|
+
* @param {string} sourcePath - Source file path
|
|
76
|
+
* @param {string} targetPath - Target file path
|
|
77
|
+
* @param {boolean} overwrite - Whether to overwrite existing files (default: true)
|
|
78
|
+
*/
|
|
79
|
+
async copyFile(sourcePath, targetPath, overwrite = true) {
|
|
80
|
+
await fs.copy(sourcePath, targetPath, { overwrite });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Copy a directory recursively
|
|
85
|
+
* @param {string} sourceDir - Source directory path
|
|
86
|
+
* @param {string} targetDir - Target directory path
|
|
87
|
+
* @param {boolean} overwrite - Whether to overwrite existing files (default: true)
|
|
88
|
+
*/
|
|
89
|
+
async copyDirectory(sourceDir, targetDir, overwrite = true) {
|
|
90
|
+
await fs.ensureDir(targetDir);
|
|
91
|
+
const entries = await fs.readdir(sourceDir, { withFileTypes: true });
|
|
92
|
+
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
95
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
96
|
+
|
|
97
|
+
if (entry.isDirectory()) {
|
|
98
|
+
await this.copyDirectory(sourcePath, targetPath, overwrite);
|
|
99
|
+
} else {
|
|
100
|
+
await this.copyFile(sourcePath, targetPath, overwrite);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* List all available built-in modules (core and xmc).
|
|
107
|
+
* All other modules come from external-official-modules.yaml
|
|
108
|
+
* @returns {Object} Object with modules array
|
|
109
|
+
*/
|
|
110
|
+
async listAvailable() {
|
|
111
|
+
const modules = [];
|
|
112
|
+
|
|
113
|
+
// Add built-in core module (directly under src/core-skills)
|
|
114
|
+
const corePath = getSourcePath('core-skills');
|
|
115
|
+
if (await fs.pathExists(corePath)) {
|
|
116
|
+
const coreInfo = await this.getModuleInfo(corePath, 'core', 'src/core-skills');
|
|
117
|
+
if (coreInfo) {
|
|
118
|
+
modules.push(coreInfo);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Add built-in xmc module (directly under src/xmc-skills)
|
|
123
|
+
const xmcPath = getSourcePath('xmc-skills');
|
|
124
|
+
if (await fs.pathExists(xmcPath)) {
|
|
125
|
+
const xmcInfo = await this.getModuleInfo(xmcPath, 'xmc', 'src/xmc-skills');
|
|
126
|
+
if (xmcInfo) {
|
|
127
|
+
modules.push(xmcInfo);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Add built-in xpm module (directly under src/xpm-skills) — opt-in (default_selected: false)
|
|
132
|
+
const xpmPath = getSourcePath('xpm-skills');
|
|
133
|
+
if (await fs.pathExists(xpmPath)) {
|
|
134
|
+
const xpmInfo = await this.getModuleInfo(xpmPath, 'xpm', 'src/xpm-skills');
|
|
135
|
+
if (xpmInfo) {
|
|
136
|
+
modules.push(xpmInfo);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return { modules };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get module information from a module path
|
|
145
|
+
* @param {string} modulePath - Path to the module directory
|
|
146
|
+
* @param {string} defaultName - Default name for the module
|
|
147
|
+
* @param {string} sourceDescription - Description of where the module was found
|
|
148
|
+
* @returns {Object|null} Module info or null if not a valid module
|
|
149
|
+
*/
|
|
150
|
+
async getModuleInfo(modulePath, defaultName, sourceDescription) {
|
|
151
|
+
const moduleConfigPath = path.join(modulePath, 'module.yaml');
|
|
152
|
+
|
|
153
|
+
if (!(await fs.pathExists(moduleConfigPath))) {
|
|
154
|
+
// Check resolution cache for strategy 5 modules (no module.yaml on disk)
|
|
155
|
+
const { CustomModuleManager } = require('./custom-module-manager');
|
|
156
|
+
const customMgr = new CustomModuleManager();
|
|
157
|
+
const resolved = customMgr.getResolution(defaultName);
|
|
158
|
+
if (resolved && resolved.synthesizedModuleYaml) {
|
|
159
|
+
return {
|
|
160
|
+
id: resolved.code,
|
|
161
|
+
path: modulePath,
|
|
162
|
+
name: resolved.name,
|
|
163
|
+
description: resolved.description,
|
|
164
|
+
version: resolved.version || '1.0.0',
|
|
165
|
+
source: sourceDescription,
|
|
166
|
+
dependencies: [],
|
|
167
|
+
defaultSelected: false,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const moduleInfo = {
|
|
174
|
+
id: defaultName,
|
|
175
|
+
path: modulePath,
|
|
176
|
+
name: defaultName
|
|
177
|
+
.split('-')
|
|
178
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
179
|
+
.join(' '),
|
|
180
|
+
description: 'XiaoMa Module',
|
|
181
|
+
version: '5.0.0',
|
|
182
|
+
source: sourceDescription,
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Read module config for metadata
|
|
186
|
+
try {
|
|
187
|
+
const configContent = await fs.readFile(moduleConfigPath, 'utf8');
|
|
188
|
+
const config = yaml.parse(configContent);
|
|
189
|
+
|
|
190
|
+
// Use the code property as the id if available
|
|
191
|
+
if (config.code) {
|
|
192
|
+
moduleInfo.id = config.code;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
moduleInfo.name = config.name || moduleInfo.name;
|
|
196
|
+
moduleInfo.description = config.description || moduleInfo.description;
|
|
197
|
+
moduleInfo.version = config.version || moduleInfo.version;
|
|
198
|
+
moduleInfo.dependencies = config.dependencies || [];
|
|
199
|
+
moduleInfo.defaultSelected = config.default_selected === undefined ? false : config.default_selected;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
await prompts.log.warn(`Failed to read config for ${defaultName}: ${error.message}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return moduleInfo;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Find the source path for a module by searching all possible locations
|
|
209
|
+
* @param {string} moduleCode - Code of the module to find (from module.yaml)
|
|
210
|
+
* @returns {string|null} Path to the module source or null if not found
|
|
211
|
+
*/
|
|
212
|
+
async findModuleSource(moduleCode, options = {}) {
|
|
213
|
+
// Inherit channelOptions from the install-scoped instance when the caller
|
|
214
|
+
// didn't pass one explicitly. Keeps pre-install config collection and the
|
|
215
|
+
// actual install step looking at the same git ref.
|
|
216
|
+
if (options.channelOptions === undefined && this.channelOptions) {
|
|
217
|
+
options = { ...options, channelOptions: this.channelOptions };
|
|
218
|
+
}
|
|
219
|
+
const projectRoot = getProjectRoot();
|
|
220
|
+
|
|
221
|
+
// Check for core module (directly under src/core-skills)
|
|
222
|
+
if (moduleCode === 'core') {
|
|
223
|
+
const corePath = getSourcePath('core-skills');
|
|
224
|
+
if (await fs.pathExists(corePath)) {
|
|
225
|
+
return corePath;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Check for built-in xmc module (directly under src/xmc-skills)
|
|
230
|
+
if (moduleCode === 'xmc') {
|
|
231
|
+
const xmcPath = getSourcePath('xmc-skills');
|
|
232
|
+
if (await fs.pathExists(xmcPath)) {
|
|
233
|
+
return xmcPath;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Check for built-in xpm module (directly under src/xpm-skills)
|
|
238
|
+
if (moduleCode === 'xpm') {
|
|
239
|
+
const xpmPath = getSourcePath('xpm-skills');
|
|
240
|
+
if (await fs.pathExists(xpmPath)) {
|
|
241
|
+
return xpmPath;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Check external official modules (pass channelOptions so channel plan applies)
|
|
246
|
+
const externalSource = await this.externalModuleManager.findExternalModuleSource(moduleCode, options);
|
|
247
|
+
if (externalSource) {
|
|
248
|
+
return externalSource;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Check custom modules (from user-provided URLs, already cloned to cache)
|
|
252
|
+
const { CustomModuleManager } = require('./custom-module-manager');
|
|
253
|
+
const customMgr = new CustomModuleManager();
|
|
254
|
+
const customSource = await customMgr.findModuleSourceByCode(moduleCode, options);
|
|
255
|
+
if (customSource) {
|
|
256
|
+
return customSource;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Install a module
|
|
264
|
+
* @param {string} moduleName - Code of the module to install (from module.yaml)
|
|
265
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
266
|
+
* @param {Function} fileTrackingCallback - Optional callback to track installed files
|
|
267
|
+
* @param {Object} options - Additional installation options
|
|
268
|
+
* @param {Array<string>} options.installedIDEs - Array of IDE codes that were installed
|
|
269
|
+
* @param {Object} options.moduleConfig - Module configuration from config collector
|
|
270
|
+
* @param {Object} options.logger - Logger instance for output
|
|
271
|
+
*/
|
|
272
|
+
async install(moduleName, xiaomaDir, fileTrackingCallback = null, options = {}) {
|
|
273
|
+
// Check if this module has a plugin resolution (custom marketplace install)
|
|
274
|
+
const { CustomModuleManager } = require('./custom-module-manager');
|
|
275
|
+
const customMgr = new CustomModuleManager();
|
|
276
|
+
const resolved = customMgr.getResolution(moduleName);
|
|
277
|
+
if (resolved) {
|
|
278
|
+
return this.installFromResolution(resolved, xiaomaDir, fileTrackingCallback, options);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const sourcePath = await this.findModuleSource(moduleName, {
|
|
282
|
+
silent: options.silent,
|
|
283
|
+
channelOptions: options.channelOptions,
|
|
284
|
+
});
|
|
285
|
+
const targetPath = path.join(xiaomaDir, moduleName);
|
|
286
|
+
|
|
287
|
+
if (!sourcePath) {
|
|
288
|
+
throw new Error(
|
|
289
|
+
`Source for module '${moduleName}' is not available. It will be retained but cannot be updated without its source files.`,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (await fs.pathExists(targetPath)) {
|
|
294
|
+
await fs.remove(targetPath);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
await this.copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback, options.moduleConfig);
|
|
298
|
+
|
|
299
|
+
if (!options.skipModuleInstaller) {
|
|
300
|
+
await this.createModuleDirectories(moduleName, xiaomaDir, options);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const { Manifest } = require('../core/manifest');
|
|
304
|
+
const manifestObj = new Manifest();
|
|
305
|
+
const versionInfo = await manifestObj.getModuleVersionInfo(moduleName, xiaomaDir, sourcePath);
|
|
306
|
+
|
|
307
|
+
// Pick up channel resolution recorded by the external manager (the only
|
|
308
|
+
// manager that does pre-clone resolution now that community is retired).
|
|
309
|
+
const resolution = this.externalModuleManager.getResolution(moduleName);
|
|
310
|
+
|
|
311
|
+
await manifestObj.addModule(xiaomaDir, moduleName, {
|
|
312
|
+
version: resolution?.version || versionInfo.version,
|
|
313
|
+
source: versionInfo.source,
|
|
314
|
+
npmPackage: versionInfo.npmPackage,
|
|
315
|
+
repoUrl: versionInfo.repoUrl,
|
|
316
|
+
channel: resolution?.channel,
|
|
317
|
+
sha: resolution?.sha,
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
return { success: true, module: moduleName, path: targetPath, versionInfo };
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Install a module from a PluginResolver resolution result.
|
|
325
|
+
* Copies specific skill directories and places module-help.csv at the target root.
|
|
326
|
+
* @param {Object} resolved - ResolvedModule from PluginResolver
|
|
327
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
328
|
+
* @param {Function} fileTrackingCallback - Optional callback to track installed files
|
|
329
|
+
* @param {Object} options - Installation options
|
|
330
|
+
*/
|
|
331
|
+
async installFromResolution(resolved, xiaomaDir, fileTrackingCallback = null, options = {}) {
|
|
332
|
+
const targetPath = path.join(xiaomaDir, resolved.code);
|
|
333
|
+
|
|
334
|
+
if (await fs.pathExists(targetPath)) {
|
|
335
|
+
await fs.remove(targetPath);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
await fs.ensureDir(targetPath);
|
|
339
|
+
|
|
340
|
+
// Copy each skill directory, flattened by leaf name
|
|
341
|
+
for (const skillPath of resolved.skillPaths) {
|
|
342
|
+
const skillDirName = path.basename(skillPath);
|
|
343
|
+
const skillTarget = path.join(targetPath, skillDirName);
|
|
344
|
+
await this.copyModuleWithFiltering(skillPath, skillTarget, fileTrackingCallback, options.moduleConfig);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Place module-help.csv at the module root
|
|
348
|
+
if (resolved.moduleHelpCsvPath) {
|
|
349
|
+
// Strategies 1-4: copy the existing file
|
|
350
|
+
const helpTarget = path.join(targetPath, 'module-help.csv');
|
|
351
|
+
await fs.copy(resolved.moduleHelpCsvPath, helpTarget, { overwrite: true });
|
|
352
|
+
if (fileTrackingCallback) fileTrackingCallback(helpTarget);
|
|
353
|
+
} else if (resolved.synthesizedHelpCsv) {
|
|
354
|
+
// Strategy 5: write synthesized content
|
|
355
|
+
const helpTarget = path.join(targetPath, 'module-help.csv');
|
|
356
|
+
await fs.writeFile(helpTarget, resolved.synthesizedHelpCsv, 'utf8');
|
|
357
|
+
if (fileTrackingCallback) fileTrackingCallback(helpTarget);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Create directories declared in module.yaml (strategies 1-4 may have these)
|
|
361
|
+
if (!options.skipModuleInstaller) {
|
|
362
|
+
await this.createModuleDirectories(resolved.code, xiaomaDir, options);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Update manifest. For custom-source installs we derive channel from the
|
|
366
|
+
// cloneRef (present → pinned, absent → next; local paths have no channel).
|
|
367
|
+
const { Manifest } = require('../core/manifest');
|
|
368
|
+
const manifestObj = new Manifest();
|
|
369
|
+
|
|
370
|
+
const hasGitClone = !!resolved.repoUrl;
|
|
371
|
+
const manifestEntry = {
|
|
372
|
+
version: resolved.cloneRef || (hasGitClone ? 'main' : resolved.version || null),
|
|
373
|
+
source: 'custom',
|
|
374
|
+
npmPackage: null,
|
|
375
|
+
repoUrl: resolved.repoUrl || null,
|
|
376
|
+
};
|
|
377
|
+
if (hasGitClone) {
|
|
378
|
+
manifestEntry.channel = resolved.cloneRef ? 'pinned' : 'next';
|
|
379
|
+
if (resolved.cloneSha) manifestEntry.sha = resolved.cloneSha;
|
|
380
|
+
if (resolved.rawInput) manifestEntry.rawSource = resolved.rawInput;
|
|
381
|
+
}
|
|
382
|
+
if (resolved.localPath) manifestEntry.localPath = resolved.localPath;
|
|
383
|
+
await manifestObj.addModule(xiaomaDir, resolved.code, manifestEntry);
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
success: true,
|
|
387
|
+
module: resolved.code,
|
|
388
|
+
path: targetPath,
|
|
389
|
+
// Mirror the manifestEntry.version precedence above so downstream summary
|
|
390
|
+
// lines show the same string we just wrote to disk (custom git-backed
|
|
391
|
+
// installs show the cloned ref or 'main').
|
|
392
|
+
versionInfo: {
|
|
393
|
+
version: resolved.cloneRef || (hasGitClone ? 'main' : resolved.version || ''),
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Update an existing module
|
|
400
|
+
* @param {string} moduleName - Name of the module to update
|
|
401
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
402
|
+
*/
|
|
403
|
+
async update(moduleName, xiaomaDir) {
|
|
404
|
+
const sourcePath = await this.findModuleSource(moduleName);
|
|
405
|
+
const targetPath = path.join(xiaomaDir, moduleName);
|
|
406
|
+
|
|
407
|
+
if (!sourcePath) {
|
|
408
|
+
throw new Error(`Module '${moduleName}' not found in any source location`);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
412
|
+
throw new Error(`Module '${moduleName}' is not installed`);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
await this.syncModule(sourcePath, targetPath);
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
success: true,
|
|
419
|
+
module: moduleName,
|
|
420
|
+
path: targetPath,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Remove a module
|
|
426
|
+
* @param {string} moduleName - Name of the module to remove
|
|
427
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
428
|
+
*/
|
|
429
|
+
async remove(moduleName, xiaomaDir) {
|
|
430
|
+
const targetPath = path.join(xiaomaDir, moduleName);
|
|
431
|
+
|
|
432
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
433
|
+
throw new Error(`Module '${moduleName}' is not installed`);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
await fs.remove(targetPath);
|
|
437
|
+
|
|
438
|
+
return {
|
|
439
|
+
success: true,
|
|
440
|
+
module: moduleName,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Check if a module is installed
|
|
446
|
+
* @param {string} moduleName - Name of the module
|
|
447
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
448
|
+
* @returns {boolean} True if module is installed
|
|
449
|
+
*/
|
|
450
|
+
async isInstalled(moduleName, xiaomaDir) {
|
|
451
|
+
const targetPath = path.join(xiaomaDir, moduleName);
|
|
452
|
+
return await fs.pathExists(targetPath);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Get installed module info
|
|
457
|
+
* @param {string} moduleName - Name of the module
|
|
458
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
459
|
+
* @returns {Object|null} Module info or null if not installed
|
|
460
|
+
*/
|
|
461
|
+
async getInstalledInfo(moduleName, xiaomaDir) {
|
|
462
|
+
const targetPath = path.join(xiaomaDir, moduleName);
|
|
463
|
+
|
|
464
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const configPath = path.join(targetPath, 'config.yaml');
|
|
469
|
+
const moduleInfo = {
|
|
470
|
+
id: moduleName,
|
|
471
|
+
path: targetPath,
|
|
472
|
+
installed: true,
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
if (await fs.pathExists(configPath)) {
|
|
476
|
+
try {
|
|
477
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
478
|
+
const config = yaml.parse(configContent);
|
|
479
|
+
Object.assign(moduleInfo, config);
|
|
480
|
+
} catch (error) {
|
|
481
|
+
await prompts.log.warn(`Failed to read installed module config: ${error.message}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return moduleInfo;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Copy module with filtering for localskip agents and conditional content
|
|
490
|
+
* @param {string} sourcePath - Source module path
|
|
491
|
+
* @param {string} targetPath - Target module path
|
|
492
|
+
* @param {Function} fileTrackingCallback - Optional callback to track installed files
|
|
493
|
+
* @param {Object} moduleConfig - Module configuration with conditional flags
|
|
494
|
+
*/
|
|
495
|
+
async copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback = null, moduleConfig = {}) {
|
|
496
|
+
// Get all files in source
|
|
497
|
+
const sourceFiles = await this.getFileList(sourcePath);
|
|
498
|
+
|
|
499
|
+
for (const file of sourceFiles) {
|
|
500
|
+
// Skip sub-modules directory - these are IDE-specific and handled separately
|
|
501
|
+
if (file.startsWith('sub-modules/')) {
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Skip sidecar directories - these contain agent-specific assets not needed at install time
|
|
506
|
+
const isInSidecarDirectory = path
|
|
507
|
+
.dirname(file)
|
|
508
|
+
.split('/')
|
|
509
|
+
.some((dir) => dir.toLowerCase().endsWith('-sidecar'));
|
|
510
|
+
|
|
511
|
+
if (isInSidecarDirectory) {
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Skip module.yaml at root - it's only needed at install time
|
|
516
|
+
if (file === 'module.yaml') {
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Skip module root config.yaml only - generated by config collector with actual values
|
|
521
|
+
// Workflow-level config.yaml (e.g. workflows/orchestrate-story/config.yaml) must be copied
|
|
522
|
+
// for custom modules that use workflow-specific configuration
|
|
523
|
+
if (file === 'config.yaml') {
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const sourceFile = path.join(sourcePath, file);
|
|
528
|
+
const targetFile = path.join(targetPath, file);
|
|
529
|
+
|
|
530
|
+
// Check if this is an agent file
|
|
531
|
+
if (file.startsWith('agents/') && file.endsWith('.md')) {
|
|
532
|
+
// Read the file to check for localskip
|
|
533
|
+
const content = await fs.readFile(sourceFile, 'utf8');
|
|
534
|
+
|
|
535
|
+
// Check for localskip="true" in the agent tag
|
|
536
|
+
const agentMatch = content.match(/<agent[^>]*\slocalskip="true"[^>]*>/);
|
|
537
|
+
if (agentMatch) {
|
|
538
|
+
await prompts.log.message(` Skipping web-only agent: ${path.basename(file)}`);
|
|
539
|
+
continue; // Skip this agent
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Copy the file with placeholder replacement
|
|
544
|
+
await this.copyFile(sourceFile, targetFile);
|
|
545
|
+
|
|
546
|
+
// Track the file if callback provided
|
|
547
|
+
if (fileTrackingCallback) {
|
|
548
|
+
fileTrackingCallback(targetFile);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Create directories declared in module.yaml's `directories` key
|
|
555
|
+
* This replaces the security-risky module installer pattern with declarative config
|
|
556
|
+
* During updates, if a directory path changed, moves the old directory to the new path
|
|
557
|
+
* @param {string} moduleName - Name of the module
|
|
558
|
+
* @param {string} xiaomaDir - Target xiaoma directory
|
|
559
|
+
* @param {Object} options - Installation options
|
|
560
|
+
* @param {Object} options.moduleConfig - Module configuration from config collector
|
|
561
|
+
* @param {Object} options.existingModuleConfig - Previous module config (for detecting path changes during updates)
|
|
562
|
+
* @param {Object} options.coreConfig - Core configuration
|
|
563
|
+
* @returns {Promise<{createdDirs: string[], movedDirs: string[], createdWdsFolders: string[]}>} Created directories info
|
|
564
|
+
*/
|
|
565
|
+
async createModuleDirectories(moduleName, xiaomaDir, options = {}) {
|
|
566
|
+
const moduleConfig = options.moduleConfig || {};
|
|
567
|
+
const existingModuleConfig = options.existingModuleConfig || {};
|
|
568
|
+
const projectRoot = path.dirname(xiaomaDir);
|
|
569
|
+
const emptyResult = { createdDirs: [], movedDirs: [], createdWdsFolders: [] };
|
|
570
|
+
|
|
571
|
+
// Special handling for core module - it's in src/core-skills not src/modules
|
|
572
|
+
let sourcePath;
|
|
573
|
+
if (moduleName === 'core') {
|
|
574
|
+
sourcePath = getSourcePath('core-skills');
|
|
575
|
+
} else {
|
|
576
|
+
sourcePath = await this.findModuleSource(moduleName, { silent: true });
|
|
577
|
+
if (!sourcePath) {
|
|
578
|
+
return emptyResult; // No source found, skip
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Read module.yaml to find the `directories` key
|
|
583
|
+
const moduleYamlPath = path.join(sourcePath, 'module.yaml');
|
|
584
|
+
if (!(await fs.pathExists(moduleYamlPath))) {
|
|
585
|
+
return emptyResult; // No module.yaml, skip
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
let moduleYaml;
|
|
589
|
+
try {
|
|
590
|
+
const yamlContent = await fs.readFile(moduleYamlPath, 'utf8');
|
|
591
|
+
moduleYaml = yaml.parse(yamlContent);
|
|
592
|
+
} catch (error) {
|
|
593
|
+
await prompts.log.warn(`Invalid module.yaml for ${moduleName}: ${error.message}`);
|
|
594
|
+
return emptyResult;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (!moduleYaml || !moduleYaml.directories) {
|
|
598
|
+
return emptyResult; // No directories declared, skip
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
const directories = moduleYaml.directories;
|
|
602
|
+
const wdsFolders = moduleYaml.wds_folders || [];
|
|
603
|
+
const createdDirs = [];
|
|
604
|
+
const movedDirs = [];
|
|
605
|
+
const createdWdsFolders = [];
|
|
606
|
+
|
|
607
|
+
for (const dirRef of directories) {
|
|
608
|
+
// Parse variable reference like "{design_artifacts}"
|
|
609
|
+
const varMatch = dirRef.match(/^\{([^}]+)\}$/);
|
|
610
|
+
if (!varMatch) {
|
|
611
|
+
// Not a variable reference, skip
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const configKey = varMatch[1];
|
|
616
|
+
const dirValue = moduleConfig[configKey];
|
|
617
|
+
if (!dirValue || typeof dirValue !== 'string') {
|
|
618
|
+
continue; // No value or not a string, skip
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// Strip {project-root}/ prefix if present
|
|
622
|
+
let dirPath = dirValue.replace(/^\{project-root\}\/?/, '');
|
|
623
|
+
|
|
624
|
+
// Handle remaining {project-root} anywhere in the path
|
|
625
|
+
dirPath = dirPath.replaceAll('{project-root}', '');
|
|
626
|
+
|
|
627
|
+
// Resolve to absolute path
|
|
628
|
+
const fullPath = path.join(projectRoot, dirPath);
|
|
629
|
+
|
|
630
|
+
// Validate path is within project root (prevent directory traversal)
|
|
631
|
+
const normalizedPath = path.normalize(fullPath);
|
|
632
|
+
const normalizedRoot = path.normalize(projectRoot);
|
|
633
|
+
if (!normalizedPath.startsWith(normalizedRoot + path.sep) && normalizedPath !== normalizedRoot) {
|
|
634
|
+
const color = await prompts.getColor();
|
|
635
|
+
await prompts.log.warn(color.yellow(`${configKey} path escapes project root, skipping: ${dirPath}`));
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// Check if directory path changed from previous config (update/modify scenario)
|
|
640
|
+
const oldDirValue = existingModuleConfig[configKey];
|
|
641
|
+
let oldFullPath = null;
|
|
642
|
+
let oldDirPath = null;
|
|
643
|
+
if (oldDirValue && typeof oldDirValue === 'string') {
|
|
644
|
+
// F3: Normalize both values before comparing to avoid false negatives
|
|
645
|
+
// from trailing slashes, separator differences, or prefix format variations
|
|
646
|
+
let normalizedOld = oldDirValue.replace(/^\{project-root\}\/?/, '');
|
|
647
|
+
normalizedOld = path.normalize(normalizedOld.replaceAll('{project-root}', ''));
|
|
648
|
+
const normalizedNew = path.normalize(dirPath);
|
|
649
|
+
|
|
650
|
+
if (normalizedOld !== normalizedNew) {
|
|
651
|
+
oldDirPath = normalizedOld;
|
|
652
|
+
oldFullPath = path.join(projectRoot, oldDirPath);
|
|
653
|
+
const normalizedOldAbsolute = path.normalize(oldFullPath);
|
|
654
|
+
if (!normalizedOldAbsolute.startsWith(normalizedRoot + path.sep) && normalizedOldAbsolute !== normalizedRoot) {
|
|
655
|
+
oldFullPath = null; // Old path escapes project root, ignore it
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// F13: Prevent parent/child move (e.g. docs/planning → docs/planning/v2)
|
|
659
|
+
if (oldFullPath) {
|
|
660
|
+
const normalizedNewAbsolute = path.normalize(fullPath);
|
|
661
|
+
if (
|
|
662
|
+
normalizedOldAbsolute.startsWith(normalizedNewAbsolute + path.sep) ||
|
|
663
|
+
normalizedNewAbsolute.startsWith(normalizedOldAbsolute + path.sep)
|
|
664
|
+
) {
|
|
665
|
+
const color = await prompts.getColor();
|
|
666
|
+
await prompts.log.warn(
|
|
667
|
+
color.yellow(
|
|
668
|
+
`${configKey}: cannot move between parent/child paths (${oldDirPath} / ${dirPath}), creating new directory instead`,
|
|
669
|
+
),
|
|
670
|
+
);
|
|
671
|
+
oldFullPath = null;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const dirName = configKey.replaceAll('_', ' ');
|
|
678
|
+
|
|
679
|
+
if (oldFullPath && (await fs.pathExists(oldFullPath)) && !(await fs.pathExists(fullPath))) {
|
|
680
|
+
// Path changed and old dir exists → move old to new location
|
|
681
|
+
// F1: Use fs.move() instead of fs.rename() for cross-device/volume support
|
|
682
|
+
// F2: Wrap in try/catch — fallback to creating new dir on failure
|
|
683
|
+
try {
|
|
684
|
+
await fs.ensureDir(path.dirname(fullPath));
|
|
685
|
+
await fs.move(oldFullPath, fullPath);
|
|
686
|
+
movedDirs.push(`${dirName}: ${oldDirPath} → ${dirPath}`);
|
|
687
|
+
} catch (moveError) {
|
|
688
|
+
const color = await prompts.getColor();
|
|
689
|
+
await prompts.log.warn(
|
|
690
|
+
color.yellow(
|
|
691
|
+
`Failed to move ${oldDirPath} → ${dirPath}: ${moveError.message}\n Creating new directory instead. Please move contents from the old directory manually.`,
|
|
692
|
+
),
|
|
693
|
+
);
|
|
694
|
+
await fs.ensureDir(fullPath);
|
|
695
|
+
createdDirs.push(`${dirName}: ${dirPath}`);
|
|
696
|
+
}
|
|
697
|
+
} else if (oldFullPath && (await fs.pathExists(oldFullPath)) && (await fs.pathExists(fullPath))) {
|
|
698
|
+
// F5: Both old and new directories exist — warn user about potential orphaned documents
|
|
699
|
+
const color = await prompts.getColor();
|
|
700
|
+
await prompts.log.warn(
|
|
701
|
+
color.yellow(
|
|
702
|
+
`${dirName}: path changed but both directories exist:\n Old: ${oldDirPath}\n New: ${dirPath}\n Old directory may contain orphaned documents — please review and merge manually.`,
|
|
703
|
+
),
|
|
704
|
+
);
|
|
705
|
+
} else if (!(await fs.pathExists(fullPath))) {
|
|
706
|
+
// New directory doesn't exist yet → create it
|
|
707
|
+
createdDirs.push(`${dirName}: ${dirPath}`);
|
|
708
|
+
await fs.ensureDir(fullPath);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Create WDS subfolders if this is the design_artifacts directory
|
|
712
|
+
if (configKey === 'design_artifacts' && wdsFolders.length > 0) {
|
|
713
|
+
for (const subfolder of wdsFolders) {
|
|
714
|
+
const subPath = path.join(fullPath, subfolder);
|
|
715
|
+
if (!(await fs.pathExists(subPath))) {
|
|
716
|
+
await fs.ensureDir(subPath);
|
|
717
|
+
createdWdsFolders.push(subfolder);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return { createdDirs, movedDirs, createdWdsFolders };
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Private: Sync module files (preserving user modifications)
|
|
728
|
+
* @param {string} sourcePath - Source module path
|
|
729
|
+
* @param {string} targetPath - Target module path
|
|
730
|
+
*/
|
|
731
|
+
async syncModule(sourcePath, targetPath) {
|
|
732
|
+
// Get list of all source files
|
|
733
|
+
const sourceFiles = await this.getFileList(sourcePath);
|
|
734
|
+
|
|
735
|
+
for (const file of sourceFiles) {
|
|
736
|
+
const sourceFile = path.join(sourcePath, file);
|
|
737
|
+
const targetFile = path.join(targetPath, file);
|
|
738
|
+
|
|
739
|
+
// Check if target file exists and has been modified
|
|
740
|
+
if (await fs.pathExists(targetFile)) {
|
|
741
|
+
const sourceStats = await fs.stat(sourceFile);
|
|
742
|
+
const targetStats = await fs.stat(targetFile);
|
|
743
|
+
|
|
744
|
+
// Skip if target is newer (user modified)
|
|
745
|
+
if (targetStats.mtime > sourceStats.mtime) {
|
|
746
|
+
continue;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// Copy file with placeholder replacement
|
|
751
|
+
await this.copyFile(sourceFile, targetFile);
|
|
752
|
+
}
|
|
14
753
|
}
|
|
15
754
|
|
|
16
755
|
/**
|
|
17
|
-
* Get
|
|
18
|
-
* @
|
|
756
|
+
* Private: Get list of all files in a directory
|
|
757
|
+
* @param {string} dir - Directory path
|
|
758
|
+
* @param {string} baseDir - Base directory for relative paths
|
|
759
|
+
* @returns {Array} List of relative file paths
|
|
19
760
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
761
|
+
async getFileList(dir, baseDir = dir) {
|
|
762
|
+
const files = [];
|
|
763
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
764
|
+
|
|
765
|
+
for (const entry of entries) {
|
|
766
|
+
const fullPath = path.join(dir, entry.name);
|
|
767
|
+
|
|
768
|
+
if (entry.isDirectory()) {
|
|
769
|
+
const subFiles = await this.getFileList(fullPath, baseDir);
|
|
770
|
+
files.push(...subFiles);
|
|
771
|
+
} else {
|
|
772
|
+
files.push(path.relative(baseDir, fullPath));
|
|
773
|
+
}
|
|
24
774
|
}
|
|
25
|
-
|
|
775
|
+
|
|
776
|
+
return files;
|
|
26
777
|
}
|
|
27
778
|
|
|
779
|
+
// ─── Config collection methods (merged from ConfigCollector) ───
|
|
780
|
+
|
|
28
781
|
/**
|
|
29
782
|
* Find the xiaoma installation directory in a project
|
|
30
783
|
* V6+ installations can use ANY folder name but ALWAYS have _config/manifest.yaml
|
|
@@ -95,7 +848,7 @@ class ConfigCollector {
|
|
|
95
848
|
* @param {string} projectDir - Target project directory
|
|
96
849
|
*/
|
|
97
850
|
async loadExistingConfig(projectDir) {
|
|
98
|
-
this.
|
|
851
|
+
this._existingConfig = {};
|
|
99
852
|
|
|
100
853
|
// Check if project directory exists first
|
|
101
854
|
if (!(await fs.pathExists(projectDir))) {
|
|
@@ -110,15 +863,39 @@ class ConfigCollector {
|
|
|
110
863
|
return false;
|
|
111
864
|
}
|
|
112
865
|
|
|
113
|
-
//
|
|
114
|
-
//
|
|
866
|
+
// Primary source: installer-written config.toml + config.user.toml (v6+).
|
|
867
|
+
// Both files together hold all install answers; config.user.toml carries
|
|
868
|
+
// user-scoped keys like user_name that would otherwise be re-prompted on
|
|
869
|
+
// every reinstall.
|
|
115
870
|
let foundAny = false;
|
|
116
|
-
const
|
|
871
|
+
for (const fileName of ['config.toml', 'config.user.toml']) {
|
|
872
|
+
const tomlPath = path.join(xiaomaDir, fileName);
|
|
873
|
+
if (!(await fs.pathExists(tomlPath))) continue;
|
|
874
|
+
try {
|
|
875
|
+
const content = await fs.readFile(tomlPath, 'utf8');
|
|
876
|
+
const parsed = parseCentralToml(content);
|
|
877
|
+
for (const [section, values] of Object.entries(parsed)) {
|
|
878
|
+
if (values && typeof values === 'object' && !Array.isArray(values)) {
|
|
879
|
+
if (!this._existingConfig[section]) this._existingConfig[section] = {};
|
|
880
|
+
Object.assign(this._existingConfig[section], values);
|
|
881
|
+
foundAny = true;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
} catch {
|
|
885
|
+
// Ignore parse errors
|
|
886
|
+
}
|
|
887
|
+
}
|
|
117
888
|
|
|
889
|
+
if (foundAny) {
|
|
890
|
+
return true;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Fallback: legacy per-module config.yaml files (pre-v6 installations).
|
|
894
|
+
const entries = await fs.readdir(xiaomaDir, { withFileTypes: true });
|
|
895
|
+
const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']);
|
|
118
896
|
for (const entry of entries) {
|
|
119
897
|
if (entry.isDirectory()) {
|
|
120
|
-
|
|
121
|
-
if (entry.name === '_config' || entry.name === '_memory') {
|
|
898
|
+
if (nonModuleDirs.has(entry.name)) {
|
|
122
899
|
continue;
|
|
123
900
|
}
|
|
124
901
|
|
|
@@ -128,8 +905,11 @@ class ConfigCollector {
|
|
|
128
905
|
try {
|
|
129
906
|
const content = await fs.readFile(moduleConfigPath, 'utf8');
|
|
130
907
|
const moduleConfig = yaml.parse(content);
|
|
131
|
-
|
|
132
|
-
|
|
908
|
+
// Only keep plain object parses. A corrupt config.yaml that parses
|
|
909
|
+
// to a scalar or array would crash later code that does `key in cfg`
|
|
910
|
+
// / `Object.keys(cfg)`; treat it the same as a parse error.
|
|
911
|
+
if (moduleConfig && typeof moduleConfig === 'object' && !Array.isArray(moduleConfig)) {
|
|
912
|
+
this._existingConfig[entry.name] = moduleConfig;
|
|
133
913
|
foundAny = true;
|
|
134
914
|
}
|
|
135
915
|
} catch {
|
|
@@ -139,9 +919,58 @@ class ConfigCollector {
|
|
|
139
919
|
}
|
|
140
920
|
}
|
|
141
921
|
|
|
922
|
+
if (foundAny) {
|
|
923
|
+
await this._hoistCoreKeysFromLegacyModuleConfigs();
|
|
924
|
+
}
|
|
925
|
+
|
|
142
926
|
return foundAny;
|
|
143
927
|
}
|
|
144
928
|
|
|
929
|
+
/**
|
|
930
|
+
* Migrate prior answers when a key has moved from a non-core module to core
|
|
931
|
+
* (e.g. project_name moving from xmc to core in #2279). Without this, the
|
|
932
|
+
* partition logic in writeCentralConfig drops the value from the xmc bucket
|
|
933
|
+
* (because it's now a core key) without re-homing it under [core], so the
|
|
934
|
+
* user's prior answer silently disappears on the next install/quick-update.
|
|
935
|
+
*/
|
|
936
|
+
async _hoistCoreKeysFromLegacyModuleConfigs() {
|
|
937
|
+
const coreSchemaPath = path.join(getSourcePath(), 'core-skills', 'module.yaml');
|
|
938
|
+
if (!(await fs.pathExists(coreSchemaPath))) return;
|
|
939
|
+
|
|
940
|
+
let coreSchema;
|
|
941
|
+
try {
|
|
942
|
+
coreSchema = yaml.parse(await fs.readFile(coreSchemaPath, 'utf8'));
|
|
943
|
+
} catch {
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
if (!coreSchema || typeof coreSchema !== 'object') return;
|
|
947
|
+
|
|
948
|
+
const coreKeys = new Set(
|
|
949
|
+
Object.entries(coreSchema)
|
|
950
|
+
.filter(([, v]) => v && typeof v === 'object' && 'prompt' in v)
|
|
951
|
+
.map(([k]) => k),
|
|
952
|
+
);
|
|
953
|
+
if (coreKeys.size === 0) return;
|
|
954
|
+
|
|
955
|
+
// Belt-and-suspenders: loadExistingConfig already filters non-object parses,
|
|
956
|
+
// but anyone calling _hoistCoreKeysFromLegacyModuleConfigs in isolation (or
|
|
957
|
+
// future code paths populating _existingConfig directly) shouldn't be able
|
|
958
|
+
// to crash this with a scalar / array.
|
|
959
|
+
const existingCore = this._existingConfig.core;
|
|
960
|
+
this._existingConfig.core = existingCore && typeof existingCore === 'object' && !Array.isArray(existingCore) ? existingCore : {};
|
|
961
|
+
|
|
962
|
+
for (const [moduleName, cfg] of Object.entries(this._existingConfig)) {
|
|
963
|
+
if (moduleName === 'core' || !cfg || typeof cfg !== 'object' || Array.isArray(cfg)) continue;
|
|
964
|
+
for (const key of Object.keys(cfg)) {
|
|
965
|
+
if (!coreKeys.has(key)) continue;
|
|
966
|
+
if (!(key in this._existingConfig.core)) {
|
|
967
|
+
this._existingConfig.core[key] = cfg[key];
|
|
968
|
+
}
|
|
969
|
+
delete cfg[key];
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
145
974
|
/**
|
|
146
975
|
* Pre-scan module schemas to gather metadata for the configuration gateway prompt.
|
|
147
976
|
* Returns info about which modules have configurable options.
|
|
@@ -153,20 +982,15 @@ class ConfigCollector {
|
|
|
153
982
|
const results = [];
|
|
154
983
|
|
|
155
984
|
for (const moduleName of modules) {
|
|
156
|
-
// Resolve module.yaml path -
|
|
985
|
+
// Resolve module.yaml path - standard location first, then OfficialModules search
|
|
157
986
|
let moduleConfigPath = null;
|
|
158
|
-
const
|
|
159
|
-
if (
|
|
160
|
-
moduleConfigPath =
|
|
987
|
+
const standardPath = path.join(getModulePath(moduleName), 'module.yaml');
|
|
988
|
+
if (await fs.pathExists(standardPath)) {
|
|
989
|
+
moduleConfigPath = standardPath;
|
|
161
990
|
} else {
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
moduleConfigPath =
|
|
165
|
-
} else {
|
|
166
|
-
const moduleSourcePath = await this._getModuleManager().findModuleSource(moduleName, { silent: true });
|
|
167
|
-
if (moduleSourcePath) {
|
|
168
|
-
moduleConfigPath = path.join(moduleSourcePath, 'module.yaml');
|
|
169
|
-
}
|
|
991
|
+
const moduleSourcePath = await this.findModuleSource(moduleName, { silent: true });
|
|
992
|
+
if (moduleSourcePath) {
|
|
993
|
+
moduleConfigPath = path.join(moduleSourcePath, 'module.yaml');
|
|
170
994
|
}
|
|
171
995
|
}
|
|
172
996
|
|
|
@@ -211,12 +1035,9 @@ class ConfigCollector {
|
|
|
211
1035
|
* @param {Array} modules - List of modules to configure (including 'core')
|
|
212
1036
|
* @param {string} projectDir - Target project directory
|
|
213
1037
|
* @param {Object} options - Additional options
|
|
214
|
-
* @param {Map} options.customModulePaths - Map of module ID to source path for custom modules
|
|
215
1038
|
* @param {boolean} options.skipPrompts - Skip prompts and use defaults (for --yes flag)
|
|
216
1039
|
*/
|
|
217
1040
|
async collectAllConfigurations(modules, projectDir, options = {}) {
|
|
218
|
-
// Store custom module paths for use in collectModuleConfig
|
|
219
|
-
this.customModulePaths = options.customModulePaths || new Map();
|
|
220
1041
|
this.skipPrompts = options.skipPrompts || false;
|
|
221
1042
|
this.modulesToCustomize = undefined;
|
|
222
1043
|
await this.loadExistingConfig(projectDir);
|
|
@@ -347,9 +1168,8 @@ class ConfigCollector {
|
|
|
347
1168
|
*/
|
|
348
1169
|
async collectModuleConfigQuick(moduleName, projectDir, silentMode = true) {
|
|
349
1170
|
this.currentProjectDir = projectDir;
|
|
350
|
-
|
|
351
1171
|
// Load existing config if not already loaded
|
|
352
|
-
if (!this.
|
|
1172
|
+
if (!this._existingConfig) {
|
|
353
1173
|
await this.loadExistingConfig(projectDir);
|
|
354
1174
|
}
|
|
355
1175
|
|
|
@@ -364,43 +1184,25 @@ class ConfigCollector {
|
|
|
364
1184
|
|
|
365
1185
|
// If not found in src/modules, we need to find it by searching the project
|
|
366
1186
|
if (!(await fs.pathExists(moduleConfigPath))) {
|
|
367
|
-
const moduleSourcePath = await this.
|
|
1187
|
+
const moduleSourcePath = await this.findModuleSource(moduleName, { silent: true });
|
|
368
1188
|
|
|
369
1189
|
if (moduleSourcePath) {
|
|
370
1190
|
moduleConfigPath = path.join(moduleSourcePath, 'module.yaml');
|
|
371
1191
|
}
|
|
372
1192
|
}
|
|
373
1193
|
|
|
374
|
-
|
|
375
|
-
let isCustomModule = false;
|
|
376
|
-
|
|
377
|
-
if (await fs.pathExists(moduleConfigPath)) {
|
|
378
|
-
configPath = moduleConfigPath;
|
|
379
|
-
} else {
|
|
380
|
-
// Check if this is a custom module with custom.yaml
|
|
381
|
-
const moduleSourcePath = await this._getModuleManager().findModuleSource(moduleName, { silent: true });
|
|
382
|
-
|
|
383
|
-
if (moduleSourcePath) {
|
|
384
|
-
const rootCustomConfigPath = path.join(moduleSourcePath, 'custom.yaml');
|
|
385
|
-
|
|
386
|
-
if (await fs.pathExists(rootCustomConfigPath)) {
|
|
387
|
-
isCustomModule = true;
|
|
388
|
-
// For custom modules, we don't have an install-config schema, so just use existing values
|
|
389
|
-
// The custom.yaml values will be loaded and merged during installation
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
1194
|
+
if (!(await fs.pathExists(moduleConfigPath))) {
|
|
393
1195
|
// No config schema for this module - use existing values
|
|
394
|
-
if (this.
|
|
1196
|
+
if (this._existingConfig && this._existingConfig[moduleName]) {
|
|
395
1197
|
if (!this.collectedConfig[moduleName]) {
|
|
396
1198
|
this.collectedConfig[moduleName] = {};
|
|
397
1199
|
}
|
|
398
|
-
this.collectedConfig[moduleName] = { ...this.
|
|
1200
|
+
this.collectedConfig[moduleName] = { ...this._existingConfig[moduleName] };
|
|
399
1201
|
}
|
|
400
1202
|
return false;
|
|
401
1203
|
}
|
|
402
1204
|
|
|
403
|
-
const configContent = await fs.readFile(
|
|
1205
|
+
const configContent = await fs.readFile(moduleConfigPath, 'utf8');
|
|
404
1206
|
const moduleConfig = yaml.parse(configContent);
|
|
405
1207
|
|
|
406
1208
|
if (!moduleConfig) {
|
|
@@ -409,7 +1211,7 @@ class ConfigCollector {
|
|
|
409
1211
|
|
|
410
1212
|
// Compare schema with existing config to find new/missing fields
|
|
411
1213
|
const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt');
|
|
412
|
-
const existingKeys = this.
|
|
1214
|
+
const existingKeys = this._existingConfig && this._existingConfig[moduleName] ? Object.keys(this._existingConfig[moduleName]) : [];
|
|
413
1215
|
|
|
414
1216
|
// Check if this module has no configuration keys at all (like CIS)
|
|
415
1217
|
// Filter out metadata fields and only count actual config objects
|
|
@@ -440,11 +1242,11 @@ class ConfigCollector {
|
|
|
440
1242
|
|
|
441
1243
|
// If in silent mode and no new keys (neither interactive nor static), use existing config and skip prompts
|
|
442
1244
|
if (silentMode && newKeys.length === 0 && newStaticKeys.length === 0) {
|
|
443
|
-
if (this.
|
|
1245
|
+
if (this._existingConfig && this._existingConfig[moduleName]) {
|
|
444
1246
|
if (!this.collectedConfig[moduleName]) {
|
|
445
1247
|
this.collectedConfig[moduleName] = {};
|
|
446
1248
|
}
|
|
447
|
-
this.collectedConfig[moduleName] = { ...this.
|
|
1249
|
+
this.collectedConfig[moduleName] = { ...this._existingConfig[moduleName] };
|
|
448
1250
|
|
|
449
1251
|
// Special handling for user_name: ensure it has a value
|
|
450
1252
|
if (
|
|
@@ -455,7 +1257,7 @@ class ConfigCollector {
|
|
|
455
1257
|
}
|
|
456
1258
|
|
|
457
1259
|
// Also populate allAnswers for cross-referencing
|
|
458
|
-
for (const [key, value] of Object.entries(this.
|
|
1260
|
+
for (const [key, value] of Object.entries(this._existingConfig[moduleName])) {
|
|
459
1261
|
// Ensure user_name is properly set in allAnswers too
|
|
460
1262
|
let finalValue = value;
|
|
461
1263
|
if (moduleName === 'core' && key === 'user_name' && (!value || value === '[USER_NAME]')) {
|
|
@@ -501,7 +1303,13 @@ class ConfigCollector {
|
|
|
501
1303
|
// Collect all answers (static + prompted)
|
|
502
1304
|
let allAnswers = { ...staticAnswers };
|
|
503
1305
|
|
|
504
|
-
if (questions.length > 0) {
|
|
1306
|
+
if (questions.length > 0 && silentMode) {
|
|
1307
|
+
// In silent mode (quick update), use defaults for new fields instead of prompting
|
|
1308
|
+
for (const q of questions) {
|
|
1309
|
+
allAnswers[q.name] = typeof q.default === 'function' ? q.default({}) : q.default;
|
|
1310
|
+
}
|
|
1311
|
+
await prompts.log.message(` \u2713 ${moduleName.toUpperCase()} module configured with defaults`);
|
|
1312
|
+
} else if (questions.length > 0) {
|
|
505
1313
|
// Only show header if we actually have questions
|
|
506
1314
|
await CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader);
|
|
507
1315
|
await prompts.log.message('');
|
|
@@ -519,8 +1327,8 @@ class ConfigCollector {
|
|
|
519
1327
|
|
|
520
1328
|
// Process all answers (both static and prompted)
|
|
521
1329
|
// First, copy existing config to preserve values that aren't being updated
|
|
522
|
-
if (this.
|
|
523
|
-
this.collectedConfig[moduleName] = { ...this.
|
|
1330
|
+
if (this._existingConfig && this._existingConfig[moduleName]) {
|
|
1331
|
+
this.collectedConfig[moduleName] = { ...this._existingConfig[moduleName] };
|
|
524
1332
|
} else {
|
|
525
1333
|
this.collectedConfig[moduleName] = {};
|
|
526
1334
|
}
|
|
@@ -545,11 +1353,11 @@ class ConfigCollector {
|
|
|
545
1353
|
}
|
|
546
1354
|
|
|
547
1355
|
// Copy over existing values for fields that weren't prompted
|
|
548
|
-
if (this.
|
|
1356
|
+
if (this._existingConfig && this._existingConfig[moduleName]) {
|
|
549
1357
|
if (!this.collectedConfig[moduleName]) {
|
|
550
1358
|
this.collectedConfig[moduleName] = {};
|
|
551
1359
|
}
|
|
552
|
-
for (const [key, value] of Object.entries(this.
|
|
1360
|
+
for (const [key, value] of Object.entries(this._existingConfig[moduleName])) {
|
|
553
1361
|
if (!this.collectedConfig[moduleName][key]) {
|
|
554
1362
|
this.collectedConfig[moduleName][key] = value;
|
|
555
1363
|
this.allAnswers[`${moduleName}_${key}`] = value;
|
|
@@ -652,7 +1460,7 @@ class ConfigCollector {
|
|
|
652
1460
|
async collectModuleConfig(moduleName, projectDir, skipLoadExisting = false, skipCompletion = false) {
|
|
653
1461
|
this.currentProjectDir = projectDir;
|
|
654
1462
|
// Load existing config if needed and not already loaded
|
|
655
|
-
if (!skipLoadExisting && !this.
|
|
1463
|
+
if (!skipLoadExisting && !this._existingConfig) {
|
|
656
1464
|
await this.loadExistingConfig(projectDir);
|
|
657
1465
|
}
|
|
658
1466
|
|
|
@@ -661,20 +1469,11 @@ class ConfigCollector {
|
|
|
661
1469
|
this.allAnswers = {};
|
|
662
1470
|
}
|
|
663
1471
|
// Load module's config
|
|
664
|
-
|
|
665
|
-
let moduleConfigPath = null;
|
|
666
|
-
|
|
667
|
-
if (this.customModulePaths && this.customModulePaths.has(moduleName)) {
|
|
668
|
-
const customPath = this.customModulePaths.get(moduleName);
|
|
669
|
-
moduleConfigPath = path.join(customPath, 'module.yaml');
|
|
670
|
-
} else {
|
|
671
|
-
// Try the standard src/modules location
|
|
672
|
-
moduleConfigPath = path.join(getModulePath(moduleName), 'module.yaml');
|
|
673
|
-
}
|
|
1472
|
+
let moduleConfigPath = path.join(getModulePath(moduleName), 'module.yaml');
|
|
674
1473
|
|
|
675
1474
|
// If not found in src/modules or custom paths, search the project
|
|
676
1475
|
if (!(await fs.pathExists(moduleConfigPath))) {
|
|
677
|
-
const moduleSourcePath = await this.
|
|
1476
|
+
const moduleSourcePath = await this.findModuleSource(moduleName, { silent: true });
|
|
678
1477
|
|
|
679
1478
|
if (moduleSourcePath) {
|
|
680
1479
|
moduleConfigPath = path.join(moduleSourcePath, 'module.yaml');
|
|
@@ -954,29 +1753,121 @@ class ConfigCollector {
|
|
|
954
1753
|
return match;
|
|
955
1754
|
}
|
|
956
1755
|
|
|
957
|
-
|
|
958
|
-
let configValue = this.allAnswers[configKey] || this.allAnswers[`core_${configKey}`];
|
|
1756
|
+
const configValue = this.resolveConfigValue(configKey, currentModule, moduleConfig);
|
|
959
1757
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1758
|
+
return configValue || match;
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
/**
|
|
1763
|
+
* Clean a stored path-like value for prompt display/input reuse.
|
|
1764
|
+
* @param {*} value - Stored value
|
|
1765
|
+
* @returns {*} Cleaned value
|
|
1766
|
+
*/
|
|
1767
|
+
cleanPromptValue(value) {
|
|
1768
|
+
if (typeof value === 'string' && value.startsWith('{project-root}/')) {
|
|
1769
|
+
return value.replace('{project-root}/', '');
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
return value;
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
/**
|
|
1776
|
+
* Resolve a config key from answers, collected config, existing config, or schema defaults.
|
|
1777
|
+
* @param {string} configKey - Config key to resolve
|
|
1778
|
+
* @param {string} currentModule - Current module name
|
|
1779
|
+
* @param {Object} moduleConfig - Current module config schema
|
|
1780
|
+
* @returns {*} Resolved value
|
|
1781
|
+
*/
|
|
1782
|
+
resolveConfigValue(configKey, currentModule = null, moduleConfig = null) {
|
|
1783
|
+
// Look for the config value in allAnswers (already answered questions)
|
|
1784
|
+
let configValue = this.allAnswers?.[configKey] || this.allAnswers?.[`core_${configKey}`];
|
|
1785
|
+
|
|
1786
|
+
if (!configValue && this.allAnswers) {
|
|
1787
|
+
for (const [answerKey, answerValue] of Object.entries(this.allAnswers)) {
|
|
1788
|
+
if (answerKey.endsWith(`_${configKey}`)) {
|
|
1789
|
+
configValue = answerValue;
|
|
1790
|
+
break;
|
|
967
1791
|
}
|
|
968
1792
|
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
// Prefer the current module's persisted value when re-prompting an existing install
|
|
1796
|
+
if (!configValue && currentModule && this._existingConfig?.[currentModule]?.[configKey] !== undefined) {
|
|
1797
|
+
configValue = this._existingConfig[currentModule][configKey];
|
|
1798
|
+
}
|
|
969
1799
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
if (
|
|
974
|
-
configValue =
|
|
1800
|
+
// Check in already collected config
|
|
1801
|
+
if (!configValue) {
|
|
1802
|
+
for (const mod of Object.keys(this.collectedConfig)) {
|
|
1803
|
+
if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) {
|
|
1804
|
+
configValue = this.collectedConfig[mod][configKey];
|
|
1805
|
+
break;
|
|
975
1806
|
}
|
|
976
1807
|
}
|
|
1808
|
+
}
|
|
977
1809
|
|
|
978
|
-
|
|
979
|
-
|
|
1810
|
+
// Fall back to other existing module config values
|
|
1811
|
+
if (!configValue && this._existingConfig) {
|
|
1812
|
+
for (const mod of Object.keys(this._existingConfig)) {
|
|
1813
|
+
if (mod !== '_meta' && this._existingConfig[mod] && this._existingConfig[mod][configKey]) {
|
|
1814
|
+
configValue = this._existingConfig[mod][configKey];
|
|
1815
|
+
break;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
// If still not found and we're in the same module, use the default from the config schema
|
|
1821
|
+
if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) {
|
|
1822
|
+
const referencedItem = moduleConfig[configKey];
|
|
1823
|
+
if (referencedItem && referencedItem.default !== undefined) {
|
|
1824
|
+
configValue = referencedItem.default;
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
return this.cleanPromptValue(configValue);
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
/**
|
|
1832
|
+
* Convert an existing stored value back into the prompt-facing value for templated fields.
|
|
1833
|
+
* For example, "{test_artifacts}/{value}" + "_xiaoma-output/test-artifacts/test-design"
|
|
1834
|
+
* becomes "test-design" so the template is not applied twice on modify.
|
|
1835
|
+
* @param {*} existingValue - Stored config value
|
|
1836
|
+
* @param {string} moduleName - Module name
|
|
1837
|
+
* @param {Object} item - Config item definition
|
|
1838
|
+
* @param {Object} moduleConfig - Current module config schema
|
|
1839
|
+
* @returns {*} Prompt-facing default value
|
|
1840
|
+
*/
|
|
1841
|
+
normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig = null) {
|
|
1842
|
+
const cleanedValue = this.cleanPromptValue(existingValue);
|
|
1843
|
+
|
|
1844
|
+
if (typeof cleanedValue !== 'string' || typeof item?.result !== 'string' || !item.result.includes('{value}')) {
|
|
1845
|
+
return cleanedValue;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
const [prefixTemplate = '', suffixTemplate = ''] = item.result.split('{value}');
|
|
1849
|
+
const prefix = this.cleanPromptValue(this.replacePlaceholders(prefixTemplate, moduleName, moduleConfig));
|
|
1850
|
+
const suffix = this.cleanPromptValue(this.replacePlaceholders(suffixTemplate, moduleName, moduleConfig));
|
|
1851
|
+
|
|
1852
|
+
if ((prefix && !cleanedValue.startsWith(prefix)) || (suffix && !cleanedValue.endsWith(suffix))) {
|
|
1853
|
+
return cleanedValue;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
const startIndex = prefix.length;
|
|
1857
|
+
const endIndex = suffix ? cleanedValue.length - suffix.length : cleanedValue.length;
|
|
1858
|
+
if (endIndex < startIndex) {
|
|
1859
|
+
return cleanedValue;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
let promptValue = cleanedValue.slice(startIndex, endIndex);
|
|
1863
|
+
if (promptValue.startsWith('/')) {
|
|
1864
|
+
promptValue = promptValue.slice(1);
|
|
1865
|
+
}
|
|
1866
|
+
if (promptValue.endsWith('/')) {
|
|
1867
|
+
promptValue = promptValue.slice(0, -1);
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
return promptValue || cleanedValue;
|
|
980
1871
|
}
|
|
981
1872
|
|
|
982
1873
|
/**
|
|
@@ -991,14 +1882,9 @@ class ConfigCollector {
|
|
|
991
1882
|
|
|
992
1883
|
// Check for existing value
|
|
993
1884
|
let existingValue = null;
|
|
994
|
-
if (this.
|
|
995
|
-
existingValue = this.
|
|
996
|
-
|
|
997
|
-
// Clean up existing value - remove {project-root}/ prefix if present
|
|
998
|
-
// This prevents duplication when the result template adds it back
|
|
999
|
-
if (typeof existingValue === 'string' && existingValue.startsWith('{project-root}/')) {
|
|
1000
|
-
existingValue = existingValue.replace('{project-root}/', '');
|
|
1001
|
-
}
|
|
1885
|
+
if (this._existingConfig && this._existingConfig[moduleName]) {
|
|
1886
|
+
existingValue = this._existingConfig[moduleName][key];
|
|
1887
|
+
existingValue = this.normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig);
|
|
1002
1888
|
}
|
|
1003
1889
|
|
|
1004
1890
|
// Special handling for user_name: default to system user
|
|
@@ -1282,4 +2168,60 @@ class ConfigCollector {
|
|
|
1282
2168
|
}
|
|
1283
2169
|
}
|
|
1284
2170
|
|
|
1285
|
-
|
|
2171
|
+
/**
|
|
2172
|
+
* Parse a config.toml or config.user.toml written by writeCentralConfig.
|
|
2173
|
+
* Only handles the subset of TOML the installer produces: [core],
|
|
2174
|
+
* [modules.<code>], string/bool/number scalar values. [agents.*] and other
|
|
2175
|
+
* sections are ignored. Returns a plain object keyed by section name where
|
|
2176
|
+
* module sections use the bare code (e.g. "xmc"), not the full "modules.xmc".
|
|
2177
|
+
*/
|
|
2178
|
+
function parseCentralToml(content) {
|
|
2179
|
+
const result = {};
|
|
2180
|
+
let currentSection = null;
|
|
2181
|
+
|
|
2182
|
+
for (const rawLine of content.split('\n')) {
|
|
2183
|
+
const line = rawLine.trim();
|
|
2184
|
+
if (!line || line.startsWith('#')) continue;
|
|
2185
|
+
|
|
2186
|
+
const sectionMatch = line.match(/^\[([^\]]+)\]\s*$/);
|
|
2187
|
+
if (sectionMatch) {
|
|
2188
|
+
const name = sectionMatch[1];
|
|
2189
|
+
if (name === 'core') {
|
|
2190
|
+
currentSection = 'core';
|
|
2191
|
+
} else if (name.startsWith('modules.')) {
|
|
2192
|
+
currentSection = name.slice('modules.'.length);
|
|
2193
|
+
} else {
|
|
2194
|
+
currentSection = null;
|
|
2195
|
+
}
|
|
2196
|
+
if (currentSection && !result[currentSection]) {
|
|
2197
|
+
result[currentSection] = {};
|
|
2198
|
+
}
|
|
2199
|
+
continue;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
if (!currentSection) continue;
|
|
2203
|
+
|
|
2204
|
+
const kvMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/);
|
|
2205
|
+
if (!kvMatch) continue;
|
|
2206
|
+
|
|
2207
|
+
const key = kvMatch[1];
|
|
2208
|
+
const raw = kvMatch[2].trim();
|
|
2209
|
+
let value;
|
|
2210
|
+
if (raw.startsWith('"') && raw.endsWith('"')) {
|
|
2211
|
+
value = raw.slice(1, -1).replaceAll(/\\(["\\nrbt])/g, (_, c) => ({ '"': '"', '\\': '\\', n: '\n', r: '\r', b: '\b', t: '\t' })[c]);
|
|
2212
|
+
} else if (raw === 'true') {
|
|
2213
|
+
value = true;
|
|
2214
|
+
} else if (raw === 'false') {
|
|
2215
|
+
value = false;
|
|
2216
|
+
} else if (raw !== '' && !isNaN(raw)) {
|
|
2217
|
+
value = Number(raw);
|
|
2218
|
+
} else {
|
|
2219
|
+
value = raw;
|
|
2220
|
+
}
|
|
2221
|
+
result[currentSection][key] = value;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
return result;
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
module.exports = { OfficialModules };
|