@zeyue0329/xiaoma-cli 1.0.49 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/quality.yaml +116 -0
- package/.husky/pre-commit +26 -0
- package/.idea/codeStyles/Project.xml +60 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/modules.xml +1 -1
- package/.idea/vcs.xml +0 -1
- package/.idea/workspace.xml +40 -24
- package/.markdownlint-cli2.yaml +41 -0
- package/.prettierignore +12 -0
- package/.vscode/settings.json +96 -0
- package/LICENSE +30 -0
- package/README.md +108 -2
- package/XIAOMA-CLI-GUIDE.md +512 -0
- package/{.idea/XiaoMa-Cli.iml → XiaoMa-Cli.iml} +1 -1
- package/custom/src/agents/commit-poet/commit-poet.agent.yaml +129 -0
- package/custom/src/agents/commit-poet/installation-guide.md +36 -0
- package/custom/src/agents/toolsmith/installation-guide.md +36 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/instructions.md +70 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +111 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +70 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +114 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +134 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +160 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +103 -0
- package/custom/src/agents/toolsmith/toolsmith-sidecar/memories.md +17 -0
- package/custom/src/agents/toolsmith/toolsmith.agent.yaml +108 -0
- package/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
- package/docs/agent-customization-guide.md +208 -0
- package/docs/custom-agent-installation.md +183 -0
- package/docs/document-sharding-guide.md +449 -0
- package/docs/explanation/advanced-elicitation.md +49 -0
- package/docs/explanation/adversarial-review.md +59 -0
- package/docs/explanation/brainstorming.md +33 -0
- package/docs/explanation/established-projects-faq.md +50 -0
- package/docs/explanation/party-mode.md +59 -0
- package/docs/explanation/preventing-agent-conflicts.md +112 -0
- package/docs/explanation/project-context.md +157 -0
- package/docs/explanation/quick-dev-new-preview.md +73 -0
- package/docs/explanation/quick-flow.md +77 -0
- package/docs/explanation/why-solutioning-matters.md +77 -0
- package/docs/how-to/customize-xiaoma.md +172 -0
- package/docs/how-to/established-projects.md +117 -0
- package/docs/how-to/get-answers-about-xiaoma.md +134 -0
- package/docs/how-to/install-xiaoma.md +107 -0
- package/docs/how-to/non-interactive-installation.md +171 -0
- package/docs/how-to/project-context.md +136 -0
- package/docs/how-to/quick-fixes.md +123 -0
- package/docs/how-to/shard-large-documents.md +78 -0
- package/docs/how-to/upgrade-to-v6.md +100 -0
- package/docs/ide-info/auggie.md +31 -0
- package/docs/ide-info/claude-code.md +25 -0
- package/docs/ide-info/cline.md +31 -0
- package/docs/ide-info/codex.md +21 -0
- package/docs/ide-info/crush.md +30 -0
- package/docs/ide-info/cursor.md +25 -0
- package/docs/ide-info/gemini.md +25 -0
- package/docs/ide-info/github-copilot.md +26 -0
- package/docs/ide-info/iflow.md +33 -0
- package/docs/ide-info/kilo.md +24 -0
- package/docs/ide-info/opencode.md +24 -0
- package/docs/ide-info/qwen.md +25 -0
- package/docs/ide-info/roo.md +27 -0
- package/docs/ide-info/rovo-dev.md +388 -0
- package/docs/ide-info/trae.md +25 -0
- package/docs/ide-info/windsurf.md +22 -0
- package/docs/index.md +60 -0
- package/docs/installers-bundlers/ide-injections.md +186 -0
- package/docs/installers-bundlers/installers-modules-platforms-reference.md +379 -0
- package/docs/rag/rag.md +856 -0
- package/docs/reference/agents.md +28 -0
- package/docs/reference/commands.md +145 -0
- package/docs/reference/modules.md +76 -0
- package/docs/reference/testing.md +106 -0
- package/docs/reference/workflow-map.md +89 -0
- package/docs/roadmap.mdx +136 -0
- package/docs/superpowers/plans/2026-03-11-upstream-sync-with-branding.md +586 -0
- package/docs/tutorials/getting-started.md +273 -0
- package/docs/v4-to-v6-upgrade.md +220 -0
- package/docs/v6-open-items.md +17 -0
- package/docs/web-bundles-gemini-gpt-guide.md +468 -0
- package/docs/zh-cn/404.md +9 -0
- package/docs/zh-cn/_STYLE_GUIDE.md +370 -0
- package/docs/zh-cn/explanation/advanced-elicitation.md +62 -0
- package/docs/zh-cn/explanation/adversarial-review.md +71 -0
- package/docs/zh-cn/explanation/brainstorming.md +43 -0
- package/docs/zh-cn/explanation/established-projects-faq.md +60 -0
- package/docs/zh-cn/explanation/party-mode.md +79 -0
- package/docs/zh-cn/explanation/preventing-agent-conflicts.md +137 -0
- package/docs/zh-cn/explanation/project-context.md +176 -0
- package/docs/zh-cn/explanation/quick-flow.md +93 -0
- package/docs/zh-cn/explanation/why-solutioning-matters.md +90 -0
- package/docs/zh-cn/how-to/customize-xiaoma.md +182 -0
- package/docs/zh-cn/how-to/established-projects.md +134 -0
- package/docs/zh-cn/how-to/get-answers-about-xiaoma.md +144 -0
- package/docs/zh-cn/how-to/install-xiaoma.md +105 -0
- package/docs/zh-cn/how-to/non-interactive-installation.md +181 -0
- package/docs/zh-cn/how-to/project-context.md +152 -0
- package/docs/zh-cn/how-to/quick-fixes.md +140 -0
- package/docs/zh-cn/how-to/shard-large-documents.md +86 -0
- package/docs/zh-cn/how-to/upgrade-to-v6.md +120 -0
- package/docs/zh-cn/index.md +69 -0
- package/docs/zh-cn/reference/agents.md +41 -0
- package/docs/zh-cn/reference/commands.md +166 -0
- package/docs/zh-cn/reference/modules.md +94 -0
- package/docs/zh-cn/reference/testing.md +122 -0
- package/docs/zh-cn/reference/workflow-map.md +104 -0
- package/docs/zh-cn/roadmap.mdx +152 -0
- package/docs/zh-cn/tutorials/getting-started.md +300 -0
- package/eslint.config.mjs +144 -0
- package/package.json +56 -58
- package/prettier.config.mjs +32 -0
- package/src/core/_module-installer/install-config.yaml +29 -0
- package/src/core/_module-installer/installer.js +60 -0
- package/src/core/agents/xiaoma-master.agent.yaml +30 -0
- package/src/core/agents/xiaoma-skill-manifest.yaml +3 -0
- package/src/core/agents/xiaoma-web-orchestrator.agent.xml +113 -0
- package/src/core/module-help.csv +10 -0
- package/src/core/module.yaml +25 -0
- package/src/core/resources/excalidraw/README.md +160 -0
- package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/src/core/resources/excalidraw/library-loader.md +50 -0
- package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/src/core/tasks/advanced-elicitation-methods.csv +51 -0
- package/src/core/tasks/advanced-elicitation.xml +116 -0
- package/src/core/tasks/editorial-review-prose.xml +102 -0
- package/src/core/tasks/editorial-review-structure.xml +208 -0
- package/src/core/tasks/help.md +92 -0
- package/src/core/tasks/index-docs.xml +65 -0
- package/src/core/tasks/review-adversarial-general.xml +49 -0
- package/src/core/tasks/review-edge-case-hunter.xml +63 -0
- package/src/core/tasks/shard-doc.xml +108 -0
- package/src/core/tasks/validate-workflow.xml +89 -0
- package/src/core/tasks/workflow.xml +235 -0
- package/src/core/tasks/xiaoma-help/SKILL.md +6 -0
- package/src/core/tasks/xiaoma-help/workflow.md +88 -0
- package/src/core/tasks/xiaoma-help/xiaoma-skill-manifest.yaml +1 -0
- package/src/core/tasks/xiaoma-review-adversarial-general/SKILL.md +6 -0
- package/src/core/tasks/xiaoma-review-adversarial-general/workflow.md +32 -0
- package/src/core/tasks/xiaoma-review-adversarial-general/xiaoma-skill-manifest.yaml +1 -0
- package/src/core/tasks/xiaoma-review-edge-case-hunter/SKILL.md +6 -0
- package/src/core/tasks/xiaoma-review-edge-case-hunter/workflow.md +62 -0
- package/src/core/tasks/xiaoma-review-edge-case-hunter/xiaoma-skill-manifest.yaml +1 -0
- package/src/core/tasks/xiaoma-skill-manifest.yaml +19 -0
- package/src/core/tools/shard-doc.xml +109 -0
- package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/src/core/workflows/advanced-elicitation/workflow.md +138 -0
- package/src/core/workflows/advanced-elicitation/workflow.xml +118 -0
- package/src/core/workflows/advanced-elicitation/xiaoma-skill-manifest.yaml +3 -0
- package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +210 -0
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/src/core/workflows/brainstorming/template.md +15 -0
- package/src/core/workflows/brainstorming/workflow.md +60 -0
- package/src/core/workflows/brainstorming/xiaoma-skill-manifest.yaml +3 -0
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +168 -0
- package/src/core/workflows/party-mode/workflow.md +194 -0
- package/src/core/workflows/party-mode/xiaoma-skill-manifest.yaml +3 -0
- package/src/utility/agent-components/activation-rules.txt +6 -0
- package/src/utility/agent-components/activation-steps.txt +14 -0
- package/src/utility/agent-components/agent-command-header.md +1 -0
- package/src/utility/agent-components/agent.customize.template.yaml +41 -0
- package/src/utility/agent-components/handler-action.txt +4 -0
- package/src/utility/agent-components/handler-data.txt +5 -0
- package/src/utility/agent-components/handler-exec.txt +6 -0
- package/src/utility/agent-components/handler-multi.txt +13 -0
- package/src/utility/agent-components/handler-tmpl.txt +5 -0
- package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
- package/src/utility/agent-components/handler-workflow.txt +10 -0
- package/src/utility/agent-components/menu-handlers.txt +6 -0
- package/src/utility/models/action-command-header.md +0 -0
- package/src/utility/models/agent-activation-ide.xml +51 -0
- package/src/utility/models/agent-activation-web.xml +50 -0
- package/src/utility/models/agent-command-header.md +1 -0
- package/src/utility/models/agent-config-template.md +23 -0
- package/src/utility/models/agent-in-team-activation.xml +3 -0
- package/src/utility/models/fragments/activation-rules.xml +7 -0
- package/src/utility/models/fragments/activation-steps.xml +16 -0
- package/src/utility/models/fragments/handler-action.xml +4 -0
- package/src/utility/models/fragments/handler-data.xml +5 -0
- package/src/utility/models/fragments/handler-exec.xml +6 -0
- package/src/utility/models/fragments/handler-multi.xml +14 -0
- package/src/utility/models/fragments/handler-tmpl.xml +5 -0
- package/src/utility/models/fragments/handler-validate-workflow.xml +7 -0
- package/src/utility/models/fragments/handler-workflow.xml +9 -0
- package/src/utility/models/fragments/menu-handlers.xml +6 -0
- package/src/utility/models/fragments/web-bundle-activation-steps.xml +32 -0
- package/src/utility/templates/agent.customize.template.yaml +42 -0
- package/src/xmc/_module-installer/install-config.yaml +53 -0
- package/src/xmc/_module-installer/installer.js +131 -0
- package/src/xmc/_module-installer/platform-specifics/claude-code.js +35 -0
- package/src/xmc/_module-installer/platform-specifics/windsurf.js +32 -0
- package/src/xmc/agents/analyst.agent.yaml +43 -0
- package/src/xmc/agents/architect.agent.yaml +29 -0
- package/src/xmc/agents/dev.agent.yaml +38 -0
- package/src/xmc/agents/pm.agent.yaml +44 -0
- package/src/xmc/agents/qa.agent.yaml +58 -0
- package/src/xmc/agents/quick-flow-solo-dev.agent.yaml +36 -0
- package/src/xmc/agents/sm.agent.yaml +37 -0
- package/src/xmc/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
- package/src/xmc/agents/tech-writer/tech-writer.agent.yaml +46 -0
- package/src/xmc/agents/tech-writer/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/agents/ux-designer.agent.yaml +27 -0
- package/src/xmc/agents/xiaoma-skill-manifest.yaml +39 -0
- package/src/xmc/data/project-context-template.md +26 -0
- package/src/xmc/module-help.csv +32 -0
- package/src/xmc/module.yaml +50 -0
- package/src/xmc/sub-modules/claude-code/config.yaml +5 -0
- package/src/xmc/sub-modules/claude-code/injections.yaml +242 -0
- package/src/xmc/sub-modules/claude-code/readme.md +87 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/api-documenter.md +102 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/codebase-analyzer.md +82 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/data-analyst.md +101 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-analysis/pattern-detector.md +84 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/dependency-mapper.md +83 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/epic-optimizer.md +81 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/requirements-analyst.md +61 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/technical-decisions-curator.md +168 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/trend-spotter.md +115 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/user-journey-mapper.md +123 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-planning/user-researcher.md +72 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-research/market-researcher.md +51 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-research/tech-debt-auditor.md +106 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-review/document-reviewer.md +102 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-review/technical-evaluator.md +68 -0
- package/src/xmc/sub-modules/claude-code/sub-agents/xiaoma-review/test-coverage-analyzer.md +108 -0
- package/src/xmc/teams/default-party.csv +20 -0
- package/src/xmc/teams/team-fullstack.yaml +12 -0
- package/src/xmc/testarch/knowledge/api-request.md +303 -0
- package/src/xmc/testarch/knowledge/auth-session.md +356 -0
- package/src/xmc/testarch/knowledge/burn-in.md +273 -0
- package/src/xmc/testarch/knowledge/ci-burn-in.md +675 -0
- package/src/xmc/testarch/knowledge/component-tdd.md +486 -0
- package/src/xmc/testarch/knowledge/contract-testing.md +957 -0
- package/src/xmc/testarch/knowledge/data-factories.md +500 -0
- package/src/xmc/testarch/knowledge/email-auth.md +721 -0
- package/src/xmc/testarch/knowledge/error-handling.md +725 -0
- package/src/xmc/testarch/knowledge/feature-flags.md +750 -0
- package/src/xmc/testarch/knowledge/file-utils.md +260 -0
- package/src/xmc/testarch/knowledge/fixture-architecture.md +401 -0
- package/src/xmc/testarch/knowledge/fixtures-composition.md +382 -0
- package/src/xmc/testarch/knowledge/intercept-network-call.md +280 -0
- package/src/xmc/testarch/knowledge/log.md +294 -0
- package/src/xmc/testarch/knowledge/network-error-monitor.md +272 -0
- package/src/xmc/testarch/knowledge/network-first.md +486 -0
- package/src/xmc/testarch/knowledge/network-recorder.md +265 -0
- package/src/xmc/testarch/knowledge/nfr-criteria.md +670 -0
- package/src/xmc/testarch/knowledge/overview.md +284 -0
- package/src/xmc/testarch/knowledge/playwright-config.md +730 -0
- package/src/xmc/testarch/knowledge/probability-impact.md +601 -0
- package/src/xmc/testarch/knowledge/recurse.md +296 -0
- package/src/xmc/testarch/knowledge/risk-governance.md +615 -0
- package/src/xmc/testarch/knowledge/selective-testing.md +732 -0
- package/src/xmc/testarch/knowledge/selector-resilience.md +527 -0
- package/src/xmc/testarch/knowledge/test-healing-patterns.md +644 -0
- package/src/xmc/testarch/knowledge/test-levels-framework.md +473 -0
- package/src/xmc/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/src/xmc/testarch/knowledge/test-quality.md +664 -0
- package/src/xmc/testarch/knowledge/timing-debugging.md +372 -0
- package/src/xmc/testarch/knowledge/visual-debugging.md +524 -0
- package/src/xmc/testarch/tea-index.csv +33 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/workflow.md +57 -0
- package/src/xmc/workflows/1-analysis/create-product-brief/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
- package/src/xmc/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
- package/src/xmc/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/src/xmc/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/src/xmc/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
- package/src/xmc/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +444 -0
- package/src/xmc/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/src/xmc/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/src/xmc/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/src/xmc/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/src/xmc/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/src/xmc/workflows/1-analysis/research/market-steps/step-06-research-completion.md +476 -0
- package/src/xmc/workflows/1-analysis/research/research.template.md +29 -0
- package/src/xmc/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
- package/src/xmc/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
- package/src/xmc/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
- package/src/xmc/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/src/xmc/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +233 -0
- package/src/xmc/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +487 -0
- package/src/xmc/workflows/1-analysis/research/workflow-domain-research.md +54 -0
- package/src/xmc/workflows/1-analysis/research/workflow-market-research.md +54 -0
- package/src/xmc/workflows/1-analysis/research/workflow-technical-research.md +54 -0
- package/src/xmc/workflows/1-analysis/research/xiaoma-skill-manifest.yaml +14 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +15 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +191 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +152 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +224 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +154 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +170 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +226 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +213 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +207 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +226 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +237 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +228 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +231 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +242 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +217 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +124 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +247 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +249 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +253 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +168 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +226 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +231 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +63 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -0
- package/src/xmc/workflows/2-plan-workflows/create-prd/xiaoma-skill-manifest.yaml +14 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/workflow.md +42 -0
- package/src/xmc/workflows/2-plan-workflows/create-ux-design/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +184 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +172 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +173 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +133 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +245 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -0
- package/src/xmc/workflows/3-solutioning/check-implementation-readiness/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +13 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +173 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +329 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/workflow.md +49 -0
- package/src/xmc/workflows/3-solutioning/create-architecture/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -0
- package/src/xmc/workflows/3-solutioning/create-epics-and-stories/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/code-review/checklist.md +23 -0
- package/src/xmc/workflows/4-implementation/code-review/discover-inputs.md +88 -0
- package/src/xmc/workflows/4-implementation/code-review/workflow.md +271 -0
- package/src/xmc/workflows/4-implementation/code-review/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/src/xmc/workflows/4-implementation/correct-course/workflow.md +274 -0
- package/src/xmc/workflows/4-implementation/correct-course/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/create-story/checklist.md +357 -0
- package/src/xmc/workflows/4-implementation/create-story/discover-inputs.md +88 -0
- package/src/xmc/workflows/4-implementation/create-story/template.md +49 -0
- package/src/xmc/workflows/4-implementation/create-story/workflow.md +388 -0
- package/src/xmc/workflows/4-implementation/create-story/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/src/xmc/workflows/4-implementation/dev-story/workflow.md +457 -0
- package/src/xmc/workflows/4-implementation/dev-story/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/retrospective/workflow.md +1485 -0
- package/src/xmc/workflows/4-implementation/retrospective/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/src/xmc/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +56 -0
- package/src/xmc/workflows/4-implementation/sprint-planning/workflow.md +271 -0
- package/src/xmc/workflows/4-implementation/sprint-planning/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/4-implementation/sprint-status/workflow.md +267 -0
- package/src/xmc/workflows/4-implementation/sprint-status/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/document-project/checklist.md +245 -0
- package/src/xmc/workflows/document-project/documentation-requirements.csv +12 -0
- package/src/xmc/workflows/document-project/instructions.md +128 -0
- package/src/xmc/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/src/xmc/workflows/document-project/templates/index-template.md +169 -0
- package/src/xmc/workflows/document-project/templates/project-overview-template.md +103 -0
- package/src/xmc/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/src/xmc/workflows/document-project/templates/source-tree-template.md +135 -0
- package/src/xmc/workflows/document-project/workflow.md +39 -0
- package/src/xmc/workflows/document-project/workflows/deep-dive-instructions.md +297 -0
- package/src/xmc/workflows/document-project/workflows/deep-dive-workflow.md +42 -0
- package/src/xmc/workflows/document-project/workflows/full-scan-instructions.md +1105 -0
- package/src/xmc/workflows/document-project/workflows/full-scan-workflow.md +42 -0
- package/src/xmc/workflows/document-project/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/generate-project-context/project-context-template.md +21 -0
- package/src/xmc/workflows/generate-project-context/steps/step-01-discover.md +184 -0
- package/src/xmc/workflows/generate-project-context/steps/step-02-generate.md +318 -0
- package/src/xmc/workflows/generate-project-context/steps/step-03-complete.md +278 -0
- package/src/xmc/workflows/generate-project-context/workflow.md +49 -0
- package/src/xmc/workflows/generate-project-context/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/qa-generate-e2e-tests/checklist.md +33 -0
- package/src/xmc/workflows/qa-generate-e2e-tests/workflow.md +143 -0
- package/src/xmc/workflows/qa-generate-e2e-tests/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-01-mode-detection.md +174 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-02-context-gathering.md +118 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-03-execute.md +111 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-04-self-check.md +111 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-05-adversarial-review.md +98 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/workflow.md +50 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-dev/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-01-understand.md +189 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-02-investigate.md +143 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-03-generate.md +126 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/steps/step-04-review.md +198 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/workflow.md +79 -0
- package/src/xmc/workflows/xiaoma-quick-flow/quick-spec/xiaoma-skill-manifest.yaml +3 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/SKILL.md +6 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-01-clarify-and-route.md +54 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-02-plan.md +39 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-03-implement.md +35 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-04-review.md +55 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/steps/step-05-present.md +19 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/tech-spec-template.md +90 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/workflow.md +84 -0
- package/src/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/xiaoma-skill-manifest.yaml +1 -0
- package/test/README.md +295 -0
- package/test/adversarial-review-tests/README.md +56 -0
- package/test/adversarial-review-tests/sample-content.md +46 -0
- package/test/adversarial-review-tests/test-cases.yaml +103 -0
- package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
- package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
- package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
- package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
- package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
- package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
- package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
- package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
- package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
- package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
- package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
- package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
- package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
- package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
- package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +23 -0
- package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
- package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
- package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
- package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
- package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
- package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
- package/test/fixtures/file-refs-csv/invalid/all-empty-workflow.csv +3 -0
- package/test/fixtures/file-refs-csv/invalid/empty-data.csv +1 -0
- package/test/fixtures/file-refs-csv/invalid/no-workflow-column.csv +3 -0
- package/test/fixtures/file-refs-csv/invalid/unresolvable-vars.csv +3 -0
- package/test/fixtures/file-refs-csv/valid/core-style.csv +3 -0
- package/test/fixtures/file-refs-csv/valid/minimal.csv +2 -0
- package/test/fixtures/file-refs-csv/valid/xmc-style.csv +3 -0
- package/test/test-agent-schema.js +387 -0
- package/test/test-cli-integration.sh +159 -0
- package/test/test-file-refs-csv.js +133 -0
- package/test/test-install-to-xiaoma.js +154 -0
- package/test/test-installation-components.js +1802 -0
- package/test/test-rehype-plugins.mjs +1050 -0
- package/test/test-workflow-path-regex.js +88 -0
- package/test/unit-test-schema.js +133 -0
- package/tools/build-docs.mjs +464 -0
- package/tools/cli/README.md +60 -0
- package/tools/cli/bundlers/bundle-web.js +179 -0
- package/tools/cli/bundlers/bundlers/bundle-web.js +179 -0
- package/tools/cli/bundlers/bundlers/test-analyst.js +28 -0
- package/tools/cli/bundlers/bundlers/test-bundler.js +119 -0
- package/tools/cli/bundlers/bundlers/web-bundler.js +1754 -0
- package/tools/cli/bundlers/test-analyst.js +28 -0
- package/tools/cli/bundlers/test-bundler.js +119 -0
- package/tools/cli/bundlers/web-bundler.js +1754 -0
- package/tools/cli/commands/agent-install.js +409 -0
- package/tools/cli/commands/build.js +458 -0
- package/tools/cli/commands/cleanup.js +144 -0
- package/tools/cli/commands/install.js +87 -0
- package/tools/cli/commands/list.js +43 -0
- package/tools/cli/commands/status.js +65 -0
- package/tools/cli/commands/uninstall.js +167 -0
- package/tools/cli/commands/update.js +28 -0
- package/tools/cli/external-official-modules.yaml +53 -0
- package/tools/cli/installers/install-messages.yaml +39 -0
- package/tools/cli/installers/lib/core/config-collector.js +1285 -0
- package/tools/cli/installers/lib/core/custom-module-cache.js +260 -0
- package/tools/cli/installers/lib/core/dependency-resolver.js +743 -0
- package/tools/cli/installers/lib/core/detector.js +223 -0
- package/tools/cli/installers/lib/core/ide-config-manager.js +157 -0
- package/tools/cli/installers/lib/core/installer.js +3195 -0
- package/tools/cli/installers/lib/core/manifest-generator.js +1374 -0
- package/tools/cli/installers/lib/core/manifest.js +1038 -0
- package/tools/cli/installers/lib/custom/handler.js +358 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +674 -0
- package/tools/cli/installers/lib/ide/_config-driven.js +1053 -0
- package/tools/cli/installers/lib/ide/antigravity.js +510 -0
- package/tools/cli/installers/lib/ide/auggie.js +232 -0
- package/tools/cli/installers/lib/ide/claude-code.js +512 -0
- package/tools/cli/installers/lib/ide/cline.js +269 -0
- package/tools/cli/installers/lib/ide/codex.js +440 -0
- package/tools/cli/installers/lib/ide/crush.js +287 -0
- package/tools/cli/installers/lib/ide/cursor.js +400 -0
- package/tools/cli/installers/lib/ide/gemini.js +253 -0
- package/tools/cli/installers/lib/ide/github-copilot.js +699 -0
- package/tools/cli/installers/lib/ide/iflow.js +172 -0
- package/tools/cli/installers/lib/ide/kilo.js +269 -0
- package/tools/cli/installers/lib/ide/manager.js +304 -0
- package/tools/cli/installers/lib/ide/opencode.js +257 -0
- package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
- package/tools/cli/installers/lib/ide/platform-codes.yaml +321 -0
- package/tools/cli/installers/lib/ide/qwen.js +372 -0
- package/tools/cli/installers/lib/ide/roo.js +324 -0
- package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
- package/tools/cli/installers/lib/ide/rovodev.js +257 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +181 -0
- package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
- package/tools/cli/installers/lib/ide/shared/path-utils.js +364 -0
- package/tools/cli/installers/lib/ide/shared/skill-manifest.js +90 -0
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +368 -0
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +179 -0
- package/tools/cli/installers/lib/ide/shared/xiaoma-artifacts.js +181 -0
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-task.md +10 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-tool.md +10 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-agent.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-task.toml +11 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-tool.toml +11 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow-yaml.toml +16 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/kiro-agent.md +16 -0
- package/tools/cli/installers/lib/ide/templates/combined/kiro-task.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/kiro-tool.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow-yaml.md +15 -0
- package/tools/cli/installers/lib/ide/templates/combined/kiro-workflow.md +7 -0
- package/tools/cli/installers/lib/ide/templates/combined/opencode-agent.md +15 -0
- package/tools/cli/installers/lib/ide/templates/combined/opencode-task.md +13 -0
- package/tools/cli/installers/lib/ide/templates/combined/opencode-tool.md +13 -0
- package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow-yaml.md +16 -0
- package/tools/cli/installers/lib/ide/templates/combined/opencode-workflow.md +16 -0
- package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
- package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
- package/tools/cli/installers/lib/ide/templates/split/.gitkeep +0 -0
- package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
- package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
- package/tools/cli/installers/lib/ide/trae.js +313 -0
- package/tools/cli/installers/lib/ide/windsurf.js +258 -0
- package/tools/cli/installers/lib/message-loader.js +83 -0
- package/tools/cli/installers/lib/modules/external-manager.js +136 -0
- package/tools/cli/installers/lib/modules/manager.js +1382 -0
- package/tools/cli/lib/activation-builder.js +165 -0
- package/tools/cli/lib/agent/compiler.js +516 -0
- package/tools/cli/lib/agent/installer.js +680 -0
- package/tools/cli/lib/agent/template-engine.js +152 -0
- package/tools/cli/lib/agent-analyzer.js +97 -0
- package/tools/cli/lib/agent-party-generator.js +194 -0
- package/tools/cli/lib/cli-utils.js +182 -0
- package/tools/cli/lib/config.js +213 -0
- package/tools/cli/lib/file-ops.js +204 -0
- package/tools/cli/lib/platform-codes.js +116 -0
- package/tools/cli/lib/project-root.js +77 -0
- package/tools/cli/lib/prompts.js +809 -0
- package/tools/cli/lib/replace-project-root.js +239 -0
- package/tools/cli/lib/ui.js +1940 -0
- package/tools/cli/lib/xml-handler.js +177 -0
- package/tools/cli/lib/xml-to-markdown.js +82 -0
- package/tools/{yaml-format.js → cli/lib/yaml-format.js} +39 -71
- package/tools/cli/lib/yaml-xml-builder.js +570 -0
- package/tools/cli/regenerate-manifests.js +28 -0
- package/tools/cli/test-yaml-builder.js +43 -0
- package/tools/cli/xiaoma-cli.js +106 -0
- package/tools/docs/_prompt-external-modules-page.md +59 -0
- package/tools/docs/fix-refs.md +91 -0
- package/tools/docs/native-skills-migration-checklist.md +281 -0
- package/tools/fix-doc-links.js +285 -0
- package/tools/flattener/aggregate.js +12 -30
- package/tools/flattener/binary.js +43 -46
- package/tools/flattener/discovery.js +15 -23
- package/tools/flattener/files.js +6 -6
- package/tools/flattener/flattener/aggregate.js +76 -0
- package/tools/flattener/flattener/binary.js +80 -0
- package/tools/flattener/flattener/discovery.js +71 -0
- package/tools/flattener/flattener/files.js +35 -0
- package/tools/flattener/flattener/ignoreRules.js +172 -0
- package/tools/flattener/flattener/main.js +483 -0
- package/tools/flattener/flattener/projectRoot.js +201 -0
- package/tools/flattener/flattener/prompts.js +44 -0
- package/tools/flattener/flattener/stats.helpers.js +368 -0
- package/tools/flattener/flattener/stats.js +75 -0
- package/tools/flattener/flattener/test-matrix.js +409 -0
- package/tools/flattener/flattener/xml.js +88 -0
- package/tools/flattener/ignoreRules.js +122 -127
- package/tools/flattener/main.js +140 -330
- package/tools/flattener/projectRoot.js +71 -81
- package/tools/flattener/prompts.js +10 -12
- package/tools/flattener/stats.helpers.js +63 -119
- package/tools/flattener/stats.js +2 -7
- package/tools/flattener/test-matrix.js +169 -228
- package/tools/flattener/xml.js +23 -31
- package/tools/format-workflow-md.js +263 -0
- package/tools/lib/xml-utils.js +13 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/platform-codes.yaml +157 -0
- package/tools/schema/agent.js +489 -0
- package/tools/validate-agent-schema.js +110 -0
- package/tools/validate-bundles.js +87 -0
- package/tools/validate-doc-links.js +409 -0
- package/tools/validate-file-refs.js +556 -0
- package/tools/validate-svg-changes.sh +356 -0
- package/tools/xiaoma-npx-wrapper.js +18 -24
- package/web-bundles/xmc/agents/analyst.xml +109 -0
- package/web-bundles/xmc/agents/architect.xml +101 -0
- package/web-bundles/xmc/agents/dev.xml +106 -0
- package/web-bundles/xmc/agents/pm.xml +112 -0
- package/web-bundles/xmc/agents/qa.xml +126 -0
- package/web-bundles/xmc/agents/quick-flow-solo-dev.xml +104 -0
- package/web-bundles/xmc/agents/sm.xml +109 -0
- package/web-bundles/xmc/agents/ux-designer.xml +100 -0
- package/web-bundles/xmc/teams/team-fullstack.xml +1192 -0
- package/.claude/agents/tech-translator.md +0 -124
- package/.claude/settings.local.json +0 -37
- package/.idea/misc.xml +0 -6
- package/.xiaoma-core/.coordinator-state.json +0 -19
- package/CLAUDE.md +0 -283
- package/JAVA-BACKEND-COMMANDS-REFERENCE.md +0 -300
- package/JAVA-BACKEND-ITERATION-GUIDE.md +0 -2116
- package/common/tasks/create-doc.md +0 -103
- package/common/tasks/execute-checklist.md +0 -88
- package/common/utils/bmad-doc-template.md +0 -327
- package/common/utils/workflow-management.md +0 -71
- package/dist/agents/analyst.txt +0 -6308
- package/dist/agents/architect.txt +0 -5046
- package/dist/agents/automation-orchestrator.txt +0 -396
- package/dist/agents/dev.txt +0 -1180
- package/dist/agents/full-requirement-orchestrator.txt +0 -505
- package/dist/agents/pm.txt +0 -3078
- package/dist/agents/po.txt +0 -1358
- package/dist/agents/qa.txt +0 -2002
- package/dist/agents/sm.txt +0 -3044
- package/dist/agents/ux-expert.txt +0 -707
- package/dist/agents/workflow-executor.txt +0 -1029
- package/dist/agents/workflow-helper.txt +0 -93
- package/dist/agents/xiaoma-master.txt +0 -9008
- package/dist/agents/xiaoma-orchestrator.txt +0 -1523
- package/dist/teams/team-all.txt +0 -23101
- package/dist/teams/team-fullstack-with-database.txt +0 -25076
- package/dist/teams/team-fullstack.txt +0 -15820
- package/dist/teams/team-ide-minimal.txt +0 -8285
- package/dist/teams/team-no-ui.txt +0 -14368
- package/docs/GUIDING-PRINCIPLES.md +0 -91
- package/docs/architecture/workflow-coordinator-implementation.md +0 -1188
- package/docs/architecture-sharding-modification.md +0 -623
- package/docs/automated-requirements-analysis-outputs.md +0 -896
- package/docs/core-architecture.md +0 -219
- package/docs/enhanced-ide-development-workflow.md +0 -248
- package/docs/prd/workflow-coordinator-prd.md +0 -1214
- package/docs/user-guide.md +0 -530
- package/docs/versioning-and-releases.md +0 -155
- package/docs/versions.md +0 -48
- package/docs/working-in-the-brownfield.md +0 -597
- package/tools/api-server.js +0 -367
- package/tools/builders/web-builder.js +0 -830
- package/tools/bump-all-versions.js +0 -133
- package/tools/cli.js +0 -157
- package/tools/installer/README.md +0 -8
- package/tools/installer/bin/xiaoma.js +0 -477
- package/tools/installer/config/ide-agent-config.yaml +0 -58
- package/tools/installer/config/install.config.yaml +0 -164
- package/tools/installer/lib/config-loader.js +0 -286
- package/tools/installer/lib/file-manager.js +0 -446
- package/tools/installer/lib/ide-base-setup.js +0 -238
- package/tools/installer/lib/ide-setup.js +0 -2027
- package/tools/installer/lib/installer.js +0 -2333
- package/tools/installer/lib/memory-profiler.js +0 -235
- package/tools/installer/lib/module-manager.js +0 -116
- package/tools/installer/lib/resource-locator.js +0 -334
- package/tools/installer/package-lock.json +0 -715
- package/tools/installer/package.json +0 -44
- package/tools/lib/dependency-resolver.js +0 -186
- package/tools/lib/yaml-utils.js +0 -34
- package/tools/md-assets/web-agent-startup-instructions.md +0 -39
- package/tools/preview-release-notes.js +0 -74
- package/tools/setup-hooks.sh +0 -37
- package/tools/shared/bannerArt.js +0 -105
- package/tools/sync-installer-version.js +0 -41
- package/tools/sync-version.sh +0 -23
- package/tools/upgraders/v3-to-v4-upgrader.js +0 -753
- package/tools/version-bump.js +0 -100
- package/tools/workflow-coordinator/README.md +0 -38
- package/tools/workflow-coordinator/USAGE.md +0 -548
- package/tools/workflow-coordinator/package-lock.json +0 -4868
- package/tools/workflow-coordinator/package.json +0 -35
- package/tools/workflow-coordinator/src/api/server.js +0 -207
- package/tools/workflow-coordinator/src/controller/workflow-controller.js +0 -263
- package/tools/workflow-coordinator/src/index.js +0 -113
- package/tools/workflow-coordinator/src/parser/workflow-parser.js +0 -144
- package/tools/workflow-coordinator/src/utils/state-manager.js +0 -59
- package/tools/workflow-coordinator/src/utils/validator.js +0 -86
- package/tools/workflow-coordinator/test/integration-test.js +0 -266
- package/tools/workflow-coordinator/test/quick-test.js +0 -127
- package/xiaoma-core/agent-teams/team-all.yaml +0 -15
- package/xiaoma-core/agent-teams/team-fullstack-with-database.yaml +0 -27
- package/xiaoma-core/agent-teams/team-fullstack.yaml +0 -19
- package/xiaoma-core/agent-teams/team-ide-minimal.yaml +0 -11
- package/xiaoma-core/agent-teams/team-no-ui.yaml +0 -14
- package/xiaoma-core/agents/analyst.md +0 -91
- package/xiaoma-core/agents/architect.md +0 -88
- package/xiaoma-core/agents/automated-fix-validator.yaml +0 -579
- package/xiaoma-core/agents/automated-quality-validator.yaml +0 -549
- package/xiaoma-core/agents/automation-orchestrator.md +0 -353
- package/xiaoma-core/agents/dev.md +0 -144
- package/xiaoma-core/agents/enhanced-workflow-orchestrator.yaml +0 -304
- package/xiaoma-core/agents/full-requirement-orchestrator.md +0 -462
- package/xiaoma-core/agents/global-requirements-auditor.yaml +0 -520
- package/xiaoma-core/agents/intelligent-template-adapter.yaml +0 -389
- package/xiaoma-core/agents/issue-dispatcher.yaml +0 -627
- package/xiaoma-core/agents/master-execution-engine.yaml +0 -543
- package/xiaoma-core/agents/pm.md +0 -85
- package/xiaoma-core/agents/po.md +0 -77
- package/xiaoma-core/agents/qa.md +0 -88
- package/xiaoma-core/agents/requirements-coverage-auditor.yaml +0 -373
- package/xiaoma-core/agents/sm.md +0 -125
- package/xiaoma-core/agents/ux-expert.md +0 -67
- package/xiaoma-core/agents/workflow-executor.md +0 -1031
- package/xiaoma-core/agents/workflow-helper.md +0 -481
- package/xiaoma-core/agents/xiaoma-master.md +0 -108
- package/xiaoma-core/agents/xiaoma-orchestrator.md +0 -145
- package/xiaoma-core/checklists/architect-checklist.md +0 -440
- package/xiaoma-core/checklists/change-checklist.md +0 -184
- package/xiaoma-core/checklists/dev-completion-checklist.md +0 -324
- package/xiaoma-core/checklists/pm-checklist.md +0 -372
- package/xiaoma-core/checklists/po-master-checklist.md +0 -434
- package/xiaoma-core/checklists/po-story-validation-checklist.md +0 -219
- package/xiaoma-core/checklists/qa-approval-checklist.md +0 -393
- package/xiaoma-core/checklists/story-dod-checklist.md +0 -96
- package/xiaoma-core/checklists/story-draft-checklist.md +0 -155
- package/xiaoma-core/core-config.yaml +0 -23
- package/xiaoma-core/data/bmad-kb.md +0 -809
- package/xiaoma-core/data/brainstorming-techniques.md +0 -38
- package/xiaoma-core/data/elicitation-methods.md +0 -156
- package/xiaoma-core/data/technical-preferences.md +0 -5
- package/xiaoma-core/data/test-levels-framework.md +0 -148
- package/xiaoma-core/data/test-priorities-matrix.md +0 -174
- package/xiaoma-core/scripts/build-validation/pre-dev-validation.sh +0 -71
- package/xiaoma-core/scripts/build-validation/progressive-validation.sh +0 -88
- package/xiaoma-core/scripts/build-validation/quick-check.sh +0 -69
- package/xiaoma-core/tasks/advanced-elicitation.md +0 -119
- package/xiaoma-core/tasks/analyze-existing-database.md +0 -155
- package/xiaoma-core/tasks/apply-qa-fixes.md +0 -150
- package/xiaoma-core/tasks/automated-story-cycle.md +0 -370
- package/xiaoma-core/tasks/batch-story-generation.md +0 -354
- package/xiaoma-core/tasks/brownfield-create-epic.md +0 -162
- package/xiaoma-core/tasks/brownfield-create-story.md +0 -149
- package/xiaoma-core/tasks/correct-course.md +0 -72
- package/xiaoma-core/tasks/create-brownfield-story.md +0 -314
- package/xiaoma-core/tasks/create-database-design.md +0 -161
- package/xiaoma-core/tasks/create-deep-research-prompt.md +0 -280
- package/xiaoma-core/tasks/create-enhanced-story-with-database.md +0 -250
- package/xiaoma-core/tasks/create-incremental-architecture.md +0 -525
- package/xiaoma-core/tasks/create-next-story.md +0 -114
- package/xiaoma-core/tasks/create-prd-from-rag.md +0 -435
- package/xiaoma-core/tasks/create-story-with-rag.md +0 -559
- package/xiaoma-core/tasks/develop-story-with-rag.md +0 -536
- package/xiaoma-core/tasks/document-project.md +0 -345
- package/xiaoma-core/tasks/facilitate-brainstorming-session.md +0 -138
- package/xiaoma-core/tasks/generate-ai-frontend-prompt.md +0 -53
- package/xiaoma-core/tasks/generate-database-ddl.md +0 -240
- package/xiaoma-core/tasks/generate-database-entities.md +0 -501
- package/xiaoma-core/tasks/generate-rag-questions.md +0 -312
- package/xiaoma-core/tasks/index-docs.md +0 -175
- package/xiaoma-core/tasks/kb-mode-interaction.md +0 -77
- package/xiaoma-core/tasks/nfr-assess.md +0 -345
- package/xiaoma-core/tasks/project-integration-testing.md +0 -477
- package/xiaoma-core/tasks/qa-gate.md +0 -163
- package/xiaoma-core/tasks/requirement-analysis-with-rag.md +0 -1318
- package/xiaoma-core/tasks/requirements-coverage-audit.md +0 -198
- package/xiaoma-core/tasks/review-story.md +0 -316
- package/xiaoma-core/tasks/risk-profile.md +0 -355
- package/xiaoma-core/tasks/serial-development-orchestration.md +0 -426
- package/xiaoma-core/tasks/shard-doc.md +0 -187
- package/xiaoma-core/tasks/test-design.md +0 -176
- package/xiaoma-core/tasks/trace-requirements.md +0 -266
- package/xiaoma-core/tasks/validate-next-story.md +0 -136
- package/xiaoma-core/templates/api-design-tmpl.yaml +0 -704
- package/xiaoma-core/templates/architecture-tmpl.yaml +0 -650
- package/xiaoma-core/templates/brainstorming-output-tmpl.yaml +0 -156
- package/xiaoma-core/templates/brownfield-architecture-tmpl.yaml +0 -476
- package/xiaoma-core/templates/brownfield-prd-tmpl.yaml +0 -280
- package/xiaoma-core/templates/competitor-analysis-tmpl.yaml +0 -336
- package/xiaoma-core/templates/database-design-tmpl.yaml +0 -266
- package/xiaoma-core/templates/enhanced-story-with-database-tmpl.yaml +0 -428
- package/xiaoma-core/templates/front-end-architecture-tmpl.yaml +0 -272
- package/xiaoma-core/templates/front-end-spec-tmpl.yaml +0 -354
- package/xiaoma-core/templates/fullstack-architecture-tmpl.yaml +0 -925
- package/xiaoma-core/templates/global-qa-monitoring-tmpl.yaml +0 -443
- package/xiaoma-core/templates/incremental-architecture-tmpl.yaml +0 -601
- package/xiaoma-core/templates/market-research-tmpl.yaml +0 -252
- package/xiaoma-core/templates/maven-lombok-template.xml +0 -111
- package/xiaoma-core/templates/prd-from-rag-tmpl.yaml +0 -410
- package/xiaoma-core/templates/prd-tmpl.yaml +0 -202
- package/xiaoma-core/templates/project-brief-tmpl.yaml +0 -221
- package/xiaoma-core/templates/qa-gate-tmpl.yaml +0 -102
- package/xiaoma-core/templates/rag-knowledge-tmpl.yaml +0 -569
- package/xiaoma-core/templates/rag-questions-tmpl.yaml +0 -949
- package/xiaoma-core/templates/requirements-coverage-audit.yaml +0 -330
- package/xiaoma-core/templates/start-enhanced-workflow.yaml +0 -347
- package/xiaoma-core/templates/story-tmpl.yaml +0 -137
- package/xiaoma-core/templates/story-with-rag-tmpl.yaml +0 -360
- package/xiaoma-core/workflows/automated-requirements-analysis.yaml +0 -2149
- package/xiaoma-core/workflows/automated-requirements-development.yaml +0 -739
- package/xiaoma-core/workflows/automated-story-development.yaml +0 -1264
- package/xiaoma-core/workflows/brownfield-fullstack.yaml +0 -298
- package/xiaoma-core/workflows/brownfield-service.yaml +0 -188
- package/xiaoma-core/workflows/brownfield-ui.yaml +0 -198
- package/xiaoma-core/workflows/enhanced-fullstack-with-database.yaml +0 -427
- package/xiaoma-core/workflows/enhanced-fullstack-with-qa-loop.yaml +0 -766
- package/xiaoma-core/workflows/full-requirement-automation.yaml +0 -1305
- package/xiaoma-core/workflows/greenfield-fullstack.yaml +0 -241
- package/xiaoma-core/workflows/greenfield-service.yaml +0 -207
- package/xiaoma-core/workflows/greenfield-ui.yaml +0 -236
|
@@ -0,0 +1,1053 @@
|
|
|
1
|
+
const os = require('node:os');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const yaml = require('yaml');
|
|
5
|
+
const { BaseIdeSetup } = require('./_base-ide');
|
|
6
|
+
const prompts = require('../../../lib/prompts');
|
|
7
|
+
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
|
8
|
+
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
|
9
|
+
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
|
10
|
+
const csv = require('csv-parse/sync');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Config-driven IDE setup handler
|
|
14
|
+
*
|
|
15
|
+
* This class provides a standardized way to install XiaoMa artifacts to IDEs
|
|
16
|
+
* based on configuration in platform-codes.yaml. It eliminates the need for
|
|
17
|
+
* individual installer files for each IDE.
|
|
18
|
+
*
|
|
19
|
+
* Features:
|
|
20
|
+
* - Config-driven from platform-codes.yaml
|
|
21
|
+
* - Template-based content generation
|
|
22
|
+
* - Multi-target installation support (e.g., GitHub Copilot)
|
|
23
|
+
* - Artifact type filtering (agents, workflows, tasks, tools)
|
|
24
|
+
*/
|
|
25
|
+
class ConfigDrivenIdeSetup extends BaseIdeSetup {
|
|
26
|
+
constructor(platformCode, platformConfig) {
|
|
27
|
+
super(platformCode, platformConfig.name, platformConfig.preferred);
|
|
28
|
+
this.platformConfig = platformConfig;
|
|
29
|
+
this.installerConfig = platformConfig.installer || null;
|
|
30
|
+
|
|
31
|
+
// Set configDir from target_dir so base-class detect() works
|
|
32
|
+
if (this.installerConfig?.target_dir) {
|
|
33
|
+
this.configDir = this.installerConfig.target_dir;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Detect whether this IDE already has configuration in the project.
|
|
39
|
+
* For skill_format platforms, checks for xiaoma-prefixed entries in target_dir
|
|
40
|
+
* (matching old codex.js behavior) instead of just checking directory existence.
|
|
41
|
+
* @param {string} projectDir - Project directory
|
|
42
|
+
* @returns {Promise<boolean>}
|
|
43
|
+
*/
|
|
44
|
+
async detect(projectDir) {
|
|
45
|
+
if (this.installerConfig?.skill_format && this.configDir) {
|
|
46
|
+
const dir = path.join(projectDir || process.cwd(), this.configDir);
|
|
47
|
+
if (await fs.pathExists(dir)) {
|
|
48
|
+
try {
|
|
49
|
+
const entries = await fs.readdir(dir);
|
|
50
|
+
return entries.some((e) => typeof e === 'string' && e.startsWith('xiaoma'));
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return super.detect(projectDir);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Main setup method - called by IdeManager
|
|
62
|
+
* @param {string} projectDir - Project directory
|
|
63
|
+
* @param {string} xiaomaDir - XiaoMa installation directory
|
|
64
|
+
* @param {Object} options - Setup options
|
|
65
|
+
* @returns {Promise<Object>} Setup result
|
|
66
|
+
*/
|
|
67
|
+
async setup(projectDir, xiaomaDir, options = {}) {
|
|
68
|
+
// Check for XiaoMa files in ancestor directories that would cause duplicates
|
|
69
|
+
if (this.installerConfig?.ancestor_conflict_check) {
|
|
70
|
+
const conflict = await this.findAncestorConflict(projectDir);
|
|
71
|
+
if (conflict) {
|
|
72
|
+
await prompts.log.error(
|
|
73
|
+
`Found existing XiaoMa skills in ancestor installation: ${conflict}\n` +
|
|
74
|
+
` ${this.name} inherits skills from parent directories, so this would cause duplicates.\n` +
|
|
75
|
+
` Please remove the XiaoMa files from that directory first:\n` +
|
|
76
|
+
` rm -rf "${conflict}"/xiaoma*`,
|
|
77
|
+
);
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
reason: 'ancestor-conflict',
|
|
81
|
+
error: `Ancestor conflict: ${conflict}`,
|
|
82
|
+
conflictDir: conflict,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!options.silent) await prompts.log.info(`Setting up ${this.name}...`);
|
|
88
|
+
|
|
89
|
+
// Clean up any old XiaoMa installation first
|
|
90
|
+
await this.cleanup(projectDir, options);
|
|
91
|
+
|
|
92
|
+
if (!this.installerConfig) {
|
|
93
|
+
return { success: false, reason: 'no-config' };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle multi-target installations (e.g., GitHub Copilot)
|
|
97
|
+
if (this.installerConfig.targets) {
|
|
98
|
+
return this.installToMultipleTargets(projectDir, xiaomaDir, this.installerConfig.targets, options);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Handle single-target installations
|
|
102
|
+
if (this.installerConfig.target_dir) {
|
|
103
|
+
return this.installToTarget(projectDir, xiaomaDir, this.installerConfig, options);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { success: false, reason: 'invalid-config' };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Install to a single target directory
|
|
111
|
+
* @param {string} projectDir - Project directory
|
|
112
|
+
* @param {string} xiaomaDir - XiaoMa installation directory
|
|
113
|
+
* @param {Object} config - Installation configuration
|
|
114
|
+
* @param {Object} options - Setup options
|
|
115
|
+
* @returns {Promise<Object>} Installation result
|
|
116
|
+
*/
|
|
117
|
+
async installToTarget(projectDir, xiaomaDir, config, options) {
|
|
118
|
+
const { target_dir, template_type, artifact_types } = config;
|
|
119
|
+
|
|
120
|
+
// Skip targets with explicitly empty artifact_types and no verbatim skills
|
|
121
|
+
// This prevents creating empty directories when no artifacts will be written
|
|
122
|
+
const skipStandardArtifacts = Array.isArray(artifact_types) && artifact_types.length === 0;
|
|
123
|
+
if (skipStandardArtifacts && !config.skill_format) {
|
|
124
|
+
return { success: true, results: { agents: 0, workflows: 0, tasks: 0, tools: 0, skills: 0 } };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const targetPath = path.join(projectDir, target_dir);
|
|
128
|
+
await this.ensureDir(targetPath);
|
|
129
|
+
|
|
130
|
+
const selectedModules = options.selectedModules || [];
|
|
131
|
+
const results = { agents: 0, workflows: 0, tasks: 0, tools: 0, skills: 0 };
|
|
132
|
+
|
|
133
|
+
// Install standard artifacts (agents, workflows, tasks, tools)
|
|
134
|
+
if (!skipStandardArtifacts) {
|
|
135
|
+
// Install agents
|
|
136
|
+
if (!artifact_types || artifact_types.includes('agents')) {
|
|
137
|
+
const agentGen = new AgentCommandGenerator(this.xiaomaFolderName);
|
|
138
|
+
const { artifacts } = await agentGen.collectAgentArtifacts(xiaomaDir, selectedModules);
|
|
139
|
+
results.agents = await this.writeAgentArtifacts(targetPath, artifacts, template_type, config);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Install workflows
|
|
143
|
+
if (!artifact_types || artifact_types.includes('workflows')) {
|
|
144
|
+
const workflowGen = new WorkflowCommandGenerator(this.xiaomaFolderName);
|
|
145
|
+
const { artifacts } = await workflowGen.collectWorkflowArtifacts(xiaomaDir);
|
|
146
|
+
results.workflows = await this.writeWorkflowArtifacts(targetPath, artifacts, template_type, config);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Install tasks and tools using template system (supports TOML for Gemini, MD for others)
|
|
150
|
+
if (!artifact_types || artifact_types.includes('tasks') || artifact_types.includes('tools')) {
|
|
151
|
+
const taskToolGen = new TaskToolCommandGenerator(this.xiaomaFolderName);
|
|
152
|
+
const { artifacts } = await taskToolGen.collectTaskToolArtifacts(xiaomaDir);
|
|
153
|
+
const taskToolResult = await this.writeTaskToolArtifacts(targetPath, artifacts, template_type, config);
|
|
154
|
+
results.tasks = taskToolResult.tasks || 0;
|
|
155
|
+
results.tools = taskToolResult.tools || 0;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Install verbatim skills (type: skill)
|
|
160
|
+
if (config.skill_format) {
|
|
161
|
+
results.skills = await this.installVerbatimSkills(projectDir, xiaomaDir, targetPath, config);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await this.printSummary(results, target_dir, options);
|
|
165
|
+
return { success: true, results };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Install to multiple target directories
|
|
170
|
+
* @param {string} projectDir - Project directory
|
|
171
|
+
* @param {string} xiaomaDir - XiaoMa installation directory
|
|
172
|
+
* @param {Array} targets - Array of target configurations
|
|
173
|
+
* @param {Object} options - Setup options
|
|
174
|
+
* @returns {Promise<Object>} Installation result
|
|
175
|
+
*/
|
|
176
|
+
async installToMultipleTargets(projectDir, xiaomaDir, targets, options) {
|
|
177
|
+
const allResults = { agents: 0, workflows: 0, tasks: 0, tools: 0, skills: 0 };
|
|
178
|
+
|
|
179
|
+
for (const target of targets) {
|
|
180
|
+
const result = await this.installToTarget(projectDir, xiaomaDir, target, options);
|
|
181
|
+
if (result.success) {
|
|
182
|
+
allResults.agents += result.results.agents || 0;
|
|
183
|
+
allResults.workflows += result.results.workflows || 0;
|
|
184
|
+
allResults.tasks += result.results.tasks || 0;
|
|
185
|
+
allResults.tools += result.results.tools || 0;
|
|
186
|
+
allResults.skills += result.results.skills || 0;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return { success: true, results: allResults };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Write agent artifacts to target directory
|
|
195
|
+
* @param {string} targetPath - Target directory path
|
|
196
|
+
* @param {Array} artifacts - Agent artifacts
|
|
197
|
+
* @param {string} templateType - Template type to use
|
|
198
|
+
* @param {Object} config - Installation configuration
|
|
199
|
+
* @returns {Promise<number>} Count of artifacts written
|
|
200
|
+
*/
|
|
201
|
+
async writeAgentArtifacts(targetPath, artifacts, templateType, config = {}) {
|
|
202
|
+
// Try to load platform-specific template, fall back to default-agent
|
|
203
|
+
const { content: template, extension } = await this.loadTemplate(templateType, 'agent', config, 'default-agent');
|
|
204
|
+
let count = 0;
|
|
205
|
+
|
|
206
|
+
for (const artifact of artifacts) {
|
|
207
|
+
const content = this.renderTemplate(template, artifact);
|
|
208
|
+
const filename = this.generateFilename(artifact, 'agent', extension);
|
|
209
|
+
|
|
210
|
+
if (config.skill_format) {
|
|
211
|
+
await this.writeSkillFile(targetPath, artifact, content);
|
|
212
|
+
} else {
|
|
213
|
+
const filePath = path.join(targetPath, filename);
|
|
214
|
+
await this.writeFile(filePath, content);
|
|
215
|
+
}
|
|
216
|
+
count++;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return count;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Write workflow artifacts to target directory
|
|
224
|
+
* @param {string} targetPath - Target directory path
|
|
225
|
+
* @param {Array} artifacts - Workflow artifacts
|
|
226
|
+
* @param {string} templateType - Template type to use
|
|
227
|
+
* @param {Object} config - Installation configuration
|
|
228
|
+
* @returns {Promise<number>} Count of artifacts written
|
|
229
|
+
*/
|
|
230
|
+
async writeWorkflowArtifacts(targetPath, artifacts, templateType, config = {}) {
|
|
231
|
+
let count = 0;
|
|
232
|
+
|
|
233
|
+
for (const artifact of artifacts) {
|
|
234
|
+
if (artifact.type === 'workflow-command') {
|
|
235
|
+
const workflowTemplateType = config.md_workflow_template || `${templateType}-workflow`;
|
|
236
|
+
const { content: template, extension } = await this.loadTemplate(workflowTemplateType, '', config, 'default-workflow');
|
|
237
|
+
const content = this.renderTemplate(template, artifact);
|
|
238
|
+
const filename = this.generateFilename(artifact, 'workflow', extension);
|
|
239
|
+
|
|
240
|
+
if (config.skill_format) {
|
|
241
|
+
await this.writeSkillFile(targetPath, artifact, content);
|
|
242
|
+
} else {
|
|
243
|
+
const filePath = path.join(targetPath, filename);
|
|
244
|
+
await this.writeFile(filePath, content);
|
|
245
|
+
}
|
|
246
|
+
count++;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return count;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Write task/tool artifacts to target directory using templates
|
|
255
|
+
* @param {string} targetPath - Target directory path
|
|
256
|
+
* @param {Array} artifacts - Task/tool artifacts
|
|
257
|
+
* @param {string} templateType - Template type to use
|
|
258
|
+
* @param {Object} config - Installation configuration
|
|
259
|
+
* @returns {Promise<Object>} Counts of tasks and tools written
|
|
260
|
+
*/
|
|
261
|
+
async writeTaskToolArtifacts(targetPath, artifacts, templateType, config = {}) {
|
|
262
|
+
let taskCount = 0;
|
|
263
|
+
let toolCount = 0;
|
|
264
|
+
|
|
265
|
+
// Pre-load templates to avoid repeated file I/O in the loop
|
|
266
|
+
const taskTemplate = await this.loadTemplate(templateType, 'task', config, 'default-task');
|
|
267
|
+
const toolTemplate = await this.loadTemplate(templateType, 'tool', config, 'default-tool');
|
|
268
|
+
|
|
269
|
+
const { artifact_types } = config;
|
|
270
|
+
|
|
271
|
+
for (const artifact of artifacts) {
|
|
272
|
+
if (artifact.type !== 'task' && artifact.type !== 'tool') {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Skip if the specific artifact type is not requested in config
|
|
277
|
+
if (artifact_types) {
|
|
278
|
+
if (artifact.type === 'task' && !artifact_types.includes('tasks')) continue;
|
|
279
|
+
if (artifact.type === 'tool' && !artifact_types.includes('tools')) continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Use pre-loaded template based on artifact type
|
|
283
|
+
const { content: template, extension } = artifact.type === 'task' ? taskTemplate : toolTemplate;
|
|
284
|
+
|
|
285
|
+
const content = this.renderTemplate(template, artifact);
|
|
286
|
+
const filename = this.generateFilename(artifact, artifact.type, extension);
|
|
287
|
+
|
|
288
|
+
if (config.skill_format) {
|
|
289
|
+
await this.writeSkillFile(targetPath, artifact, content);
|
|
290
|
+
} else {
|
|
291
|
+
const filePath = path.join(targetPath, filename);
|
|
292
|
+
await this.writeFile(filePath, content);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (artifact.type === 'task') {
|
|
296
|
+
taskCount++;
|
|
297
|
+
} else {
|
|
298
|
+
toolCount++;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return { tasks: taskCount, tools: toolCount };
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Load template based on type and configuration
|
|
307
|
+
* @param {string} templateType - Template type (claude, windsurf, etc.)
|
|
308
|
+
* @param {string} artifactType - Artifact type (agent, workflow, task, tool)
|
|
309
|
+
* @param {Object} config - Installation configuration
|
|
310
|
+
* @param {string} fallbackTemplateType - Fallback template type if requested template not found
|
|
311
|
+
* @returns {Promise<{content: string, extension: string}>} Template content and extension
|
|
312
|
+
*/
|
|
313
|
+
async loadTemplate(templateType, artifactType, config = {}, fallbackTemplateType = null) {
|
|
314
|
+
const { header_template, body_template } = config;
|
|
315
|
+
|
|
316
|
+
// Check for separate header/body templates
|
|
317
|
+
if (header_template || body_template) {
|
|
318
|
+
const content = await this.loadSplitTemplates(templateType, artifactType, header_template, body_template);
|
|
319
|
+
// Allow config to override extension, default to .md
|
|
320
|
+
const ext = config.extension || '.md';
|
|
321
|
+
const normalizedExt = ext.startsWith('.') ? ext : `.${ext}`;
|
|
322
|
+
return { content, extension: normalizedExt };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Load combined template - try multiple extensions
|
|
326
|
+
// If artifactType is empty, templateType already contains full name (e.g., 'gemini-workflow-yaml')
|
|
327
|
+
const templateBaseName = artifactType ? `${templateType}-${artifactType}` : templateType;
|
|
328
|
+
const templateDir = path.join(__dirname, 'templates', 'combined');
|
|
329
|
+
const extensions = ['.md', '.toml', '.yaml', '.yml'];
|
|
330
|
+
|
|
331
|
+
for (const ext of extensions) {
|
|
332
|
+
const templatePath = path.join(templateDir, templateBaseName + ext);
|
|
333
|
+
if (await fs.pathExists(templatePath)) {
|
|
334
|
+
const content = await fs.readFile(templatePath, 'utf8');
|
|
335
|
+
return { content, extension: ext };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Fall back to default template (if provided)
|
|
340
|
+
if (fallbackTemplateType) {
|
|
341
|
+
for (const ext of extensions) {
|
|
342
|
+
const fallbackPath = path.join(templateDir, `${fallbackTemplateType}${ext}`);
|
|
343
|
+
if (await fs.pathExists(fallbackPath)) {
|
|
344
|
+
const content = await fs.readFile(fallbackPath, 'utf8');
|
|
345
|
+
return { content, extension: ext };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Ultimate fallback - minimal template
|
|
351
|
+
return { content: this.getDefaultTemplate(artifactType), extension: '.md' };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Load split templates (header + body)
|
|
356
|
+
* @param {string} templateType - Template type
|
|
357
|
+
* @param {string} artifactType - Artifact type
|
|
358
|
+
* @param {string} headerTpl - Header template name
|
|
359
|
+
* @param {string} bodyTpl - Body template name
|
|
360
|
+
* @returns {Promise<string>} Combined template content
|
|
361
|
+
*/
|
|
362
|
+
async loadSplitTemplates(templateType, artifactType, headerTpl, bodyTpl) {
|
|
363
|
+
let header = '';
|
|
364
|
+
let body = '';
|
|
365
|
+
|
|
366
|
+
// Load header template
|
|
367
|
+
if (headerTpl) {
|
|
368
|
+
const headerPath = path.join(__dirname, 'templates', 'split', headerTpl);
|
|
369
|
+
if (await fs.pathExists(headerPath)) {
|
|
370
|
+
header = await fs.readFile(headerPath, 'utf8');
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
// Use default header for template type
|
|
374
|
+
const defaultHeaderPath = path.join(__dirname, 'templates', 'split', templateType, 'header.md');
|
|
375
|
+
if (await fs.pathExists(defaultHeaderPath)) {
|
|
376
|
+
header = await fs.readFile(defaultHeaderPath, 'utf8');
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Load body template
|
|
381
|
+
if (bodyTpl) {
|
|
382
|
+
const bodyPath = path.join(__dirname, 'templates', 'split', bodyTpl);
|
|
383
|
+
if (await fs.pathExists(bodyPath)) {
|
|
384
|
+
body = await fs.readFile(bodyPath, 'utf8');
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
// Use default body for template type
|
|
388
|
+
const defaultBodyPath = path.join(__dirname, 'templates', 'split', templateType, 'body.md');
|
|
389
|
+
if (await fs.pathExists(defaultBodyPath)) {
|
|
390
|
+
body = await fs.readFile(defaultBodyPath, 'utf8');
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Combine header and body
|
|
395
|
+
return `${header}\n${body}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Get default minimal template
|
|
400
|
+
* @param {string} artifactType - Artifact type
|
|
401
|
+
* @returns {string} Default template
|
|
402
|
+
*/
|
|
403
|
+
getDefaultTemplate(artifactType) {
|
|
404
|
+
if (artifactType === 'agent') {
|
|
405
|
+
return `---
|
|
406
|
+
name: '{{name}}'
|
|
407
|
+
description: '{{description}}'
|
|
408
|
+
disable-model-invocation: true
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
You must fully embody this agent's persona and follow all activation instructions exactly as specified.
|
|
412
|
+
|
|
413
|
+
<agent-activation CRITICAL="TRUE">
|
|
414
|
+
1. LOAD the FULL agent file from {project-root}/{{xiaomaFolderName}}/{{path}}
|
|
415
|
+
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
416
|
+
3. FOLLOW every step in the <activation> section precisely
|
|
417
|
+
</agent-activation>
|
|
418
|
+
`;
|
|
419
|
+
}
|
|
420
|
+
return `---
|
|
421
|
+
name: '{{name}}'
|
|
422
|
+
description: '{{description}}'
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
# {{name}}
|
|
426
|
+
|
|
427
|
+
LOAD and execute from: {project-root}/{{xiaomaFolderName}}/{{path}}
|
|
428
|
+
`;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Render template with artifact data
|
|
433
|
+
* @param {string} template - Template content
|
|
434
|
+
* @param {Object} artifact - Artifact data
|
|
435
|
+
* @returns {string} Rendered content
|
|
436
|
+
*/
|
|
437
|
+
renderTemplate(template, artifact) {
|
|
438
|
+
// Use the appropriate path property based on artifact type
|
|
439
|
+
let pathToUse = artifact.relativePath || '';
|
|
440
|
+
switch (artifact.type) {
|
|
441
|
+
case 'agent-launcher': {
|
|
442
|
+
pathToUse = artifact.agentPath || artifact.relativePath || '';
|
|
443
|
+
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
case 'workflow-command': {
|
|
447
|
+
pathToUse = artifact.workflowPath || artifact.relativePath || '';
|
|
448
|
+
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
case 'task':
|
|
452
|
+
case 'tool': {
|
|
453
|
+
pathToUse = artifact.path || artifact.relativePath || '';
|
|
454
|
+
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
// No default
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Replace _xiaoma placeholder with actual folder name BEFORE inserting paths,
|
|
461
|
+
// so that paths containing '_xiaoma' are not corrupted by the blanket replacement.
|
|
462
|
+
let rendered = template.replaceAll('_xiaoma', this.xiaomaFolderName);
|
|
463
|
+
|
|
464
|
+
// Replace {{xiaomaFolderName}} placeholder if present
|
|
465
|
+
rendered = rendered.replaceAll('{{xiaomaFolderName}}', this.xiaomaFolderName);
|
|
466
|
+
|
|
467
|
+
rendered = rendered
|
|
468
|
+
.replaceAll('{{name}}', artifact.name || '')
|
|
469
|
+
.replaceAll('{{module}}', artifact.module || 'core')
|
|
470
|
+
.replaceAll('{{path}}', pathToUse)
|
|
471
|
+
.replaceAll('{{description}}', artifact.description || `${artifact.name} ${artifact.type || ''}`)
|
|
472
|
+
.replaceAll('{{workflow_path}}', pathToUse);
|
|
473
|
+
|
|
474
|
+
return rendered;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Write artifact as a skill directory with SKILL.md inside.
|
|
479
|
+
* Writes artifact as a skill directory with SKILL.md inside.
|
|
480
|
+
* @param {string} targetPath - Base skills directory
|
|
481
|
+
* @param {Object} artifact - Artifact data
|
|
482
|
+
* @param {string} content - Rendered template content
|
|
483
|
+
*/
|
|
484
|
+
async writeSkillFile(targetPath, artifact, content) {
|
|
485
|
+
const { resolveSkillName } = require('./shared/path-utils');
|
|
486
|
+
|
|
487
|
+
// Get the skill name (prefers canonicalId, falls back to path-derived) and remove .md
|
|
488
|
+
const flatName = resolveSkillName(artifact);
|
|
489
|
+
const skillName = path.basename(flatName.replace(/\.md$/, ''));
|
|
490
|
+
|
|
491
|
+
if (!skillName) {
|
|
492
|
+
throw new Error(`Cannot derive skill name for artifact: ${artifact.relativePath || JSON.stringify(artifact)}`);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Create skill directory
|
|
496
|
+
const skillDir = path.join(targetPath, skillName);
|
|
497
|
+
await this.ensureDir(skillDir);
|
|
498
|
+
|
|
499
|
+
// Transform content: rewrite frontmatter for skills format
|
|
500
|
+
const skillContent = this.transformToSkillFormat(content, skillName);
|
|
501
|
+
|
|
502
|
+
await this.writeFile(path.join(skillDir, 'SKILL.md'), skillContent);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Transform artifact content to Agent Skills format.
|
|
507
|
+
* Rewrites frontmatter to contain only unquoted name and description.
|
|
508
|
+
* @param {string} content - Original content with YAML frontmatter
|
|
509
|
+
* @param {string} skillName - Skill name (must match directory name)
|
|
510
|
+
* @returns {string} Transformed content
|
|
511
|
+
*/
|
|
512
|
+
transformToSkillFormat(content, skillName) {
|
|
513
|
+
// Normalize line endings
|
|
514
|
+
content = content.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
|
|
515
|
+
|
|
516
|
+
// Parse frontmatter
|
|
517
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
518
|
+
if (!fmMatch) {
|
|
519
|
+
// No frontmatter -- wrap with minimal frontmatter
|
|
520
|
+
const fm = yaml.stringify({ name: skillName, description: skillName }).trimEnd();
|
|
521
|
+
return `---\n${fm}\n---\n\n${content}`;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const frontmatter = fmMatch[1];
|
|
525
|
+
const body = fmMatch[2];
|
|
526
|
+
|
|
527
|
+
// Parse frontmatter with yaml library to extract description
|
|
528
|
+
let description;
|
|
529
|
+
try {
|
|
530
|
+
const parsed = yaml.parse(frontmatter);
|
|
531
|
+
const rawDesc = parsed?.description;
|
|
532
|
+
description = typeof rawDesc === 'string' && rawDesc ? rawDesc : `${skillName} skill`;
|
|
533
|
+
} catch {
|
|
534
|
+
description = `${skillName} skill`;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Build new frontmatter with only name and description, unquoted
|
|
538
|
+
const newFrontmatter = yaml.stringify({ name: skillName, description: String(description) }, { lineWidth: 0 }).trimEnd();
|
|
539
|
+
return `---\n${newFrontmatter}\n---\n${body}`;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Install a custom agent launcher.
|
|
544
|
+
* For skill_format platforms, produces <skillDir>/SKILL.md.
|
|
545
|
+
* For flat platforms, produces a single file in target_dir.
|
|
546
|
+
* @param {string} projectDir - Project directory
|
|
547
|
+
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
|
548
|
+
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
|
549
|
+
* @param {Object} metadata - Agent metadata
|
|
550
|
+
* @returns {Object|null} Info about created file/skill
|
|
551
|
+
*/
|
|
552
|
+
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
|
553
|
+
if (!this.installerConfig?.target_dir) return null;
|
|
554
|
+
|
|
555
|
+
const { customAgentDashName } = require('./shared/path-utils');
|
|
556
|
+
const targetPath = path.join(projectDir, this.installerConfig.target_dir);
|
|
557
|
+
await this.ensureDir(targetPath);
|
|
558
|
+
|
|
559
|
+
// Build artifact to reuse existing template rendering.
|
|
560
|
+
// The default-agent template already includes the _xiaoma/ prefix before {{path}},
|
|
561
|
+
// but agentPath is relative to project root (e.g. "_xiaoma/custom/agents/fred.md").
|
|
562
|
+
// Strip the xiaomaFolderName prefix so the template doesn't produce a double path.
|
|
563
|
+
const xiaomaPrefix = this.xiaomaFolderName + '/';
|
|
564
|
+
const normalizedPath = agentPath.startsWith(xiaomaPrefix) ? agentPath.slice(xiaomaPrefix.length) : agentPath;
|
|
565
|
+
|
|
566
|
+
const artifact = {
|
|
567
|
+
type: 'agent-launcher',
|
|
568
|
+
name: agentName,
|
|
569
|
+
description: metadata?.description || `${agentName} agent`,
|
|
570
|
+
agentPath: normalizedPath,
|
|
571
|
+
relativePath: normalizedPath,
|
|
572
|
+
module: 'custom',
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
const { content: template } = await this.loadTemplate(
|
|
576
|
+
this.installerConfig.template_type || 'default',
|
|
577
|
+
'agent',
|
|
578
|
+
this.installerConfig,
|
|
579
|
+
'default-agent',
|
|
580
|
+
);
|
|
581
|
+
const content = this.renderTemplate(template, artifact);
|
|
582
|
+
|
|
583
|
+
if (this.installerConfig.skill_format) {
|
|
584
|
+
const skillName = customAgentDashName(agentName).replace(/\.md$/, '');
|
|
585
|
+
const skillDir = path.join(targetPath, skillName);
|
|
586
|
+
await this.ensureDir(skillDir);
|
|
587
|
+
const skillContent = this.transformToSkillFormat(content, skillName);
|
|
588
|
+
const skillPath = path.join(skillDir, 'SKILL.md');
|
|
589
|
+
await this.writeFile(skillPath, skillContent);
|
|
590
|
+
return { path: path.relative(projectDir, skillPath), command: `$${skillName}` };
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// Flat file output
|
|
594
|
+
const filename = customAgentDashName(agentName);
|
|
595
|
+
const filePath = path.join(targetPath, filename);
|
|
596
|
+
await this.writeFile(filePath, content);
|
|
597
|
+
return { path: path.relative(projectDir, filePath), command: agentName };
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Generate filename for artifact
|
|
602
|
+
* @param {Object} artifact - Artifact data
|
|
603
|
+
* @param {string} artifactType - Artifact type (agent, workflow, task, tool)
|
|
604
|
+
* @param {string} extension - File extension to use (e.g., '.md', '.toml')
|
|
605
|
+
* @returns {string} Generated filename
|
|
606
|
+
*/
|
|
607
|
+
generateFilename(artifact, artifactType, extension = '.md') {
|
|
608
|
+
const { resolveSkillName } = require('./shared/path-utils');
|
|
609
|
+
|
|
610
|
+
// Reuse central logic to ensure consistent naming conventions
|
|
611
|
+
// Prefers canonicalId from manifest when available, falls back to path-derived name
|
|
612
|
+
const standardName = resolveSkillName(artifact);
|
|
613
|
+
|
|
614
|
+
// Clean up potential double extensions from source files (e.g. .yaml.md, .xml.md -> .md)
|
|
615
|
+
// This handles any extensions that might slip through toDashPath()
|
|
616
|
+
const baseName = standardName.replace(/\.(md|yaml|yml|json|xml|toml)\.md$/i, '.md');
|
|
617
|
+
|
|
618
|
+
// If using default markdown, preserve the xiaoma-agent- prefix for agents
|
|
619
|
+
if (extension === '.md') {
|
|
620
|
+
return baseName;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// For other extensions (e.g., .toml), replace .md extension
|
|
624
|
+
// Note: agent prefix is preserved even with non-markdown extensions
|
|
625
|
+
return baseName.replace(/\.md$/, extension);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Install verbatim skill directories (type: skill entries from skill-manifest.csv).
|
|
630
|
+
* Copies the entire source directory as-is into the IDE skill directory.
|
|
631
|
+
* The source SKILL.md is used directly — no frontmatter transformation or file generation.
|
|
632
|
+
* @param {string} projectDir - Project directory
|
|
633
|
+
* @param {string} xiaomaDir - XiaoMa installation directory
|
|
634
|
+
* @param {string} targetPath - Target skills directory
|
|
635
|
+
* @param {Object} config - Installation configuration
|
|
636
|
+
* @returns {Promise<number>} Count of skills installed
|
|
637
|
+
*/
|
|
638
|
+
async installVerbatimSkills(projectDir, xiaomaDir, targetPath, config) {
|
|
639
|
+
const xiaomaFolderName = path.basename(xiaomaDir);
|
|
640
|
+
const xiaomaPrefix = xiaomaFolderName + '/';
|
|
641
|
+
const csvPath = path.join(xiaomaDir, '_config', 'skill-manifest.csv');
|
|
642
|
+
|
|
643
|
+
if (!(await fs.pathExists(csvPath))) return 0;
|
|
644
|
+
|
|
645
|
+
const csvContent = await fs.readFile(csvPath, 'utf8');
|
|
646
|
+
const records = csv.parse(csvContent, {
|
|
647
|
+
columns: true,
|
|
648
|
+
skip_empty_lines: true,
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
let count = 0;
|
|
652
|
+
|
|
653
|
+
for (const record of records) {
|
|
654
|
+
const canonicalId = record.canonicalId;
|
|
655
|
+
if (!canonicalId) continue;
|
|
656
|
+
|
|
657
|
+
// Derive source directory from path column
|
|
658
|
+
// path is like "_xiaoma/xmc/workflows/xiaoma-quick-flow/xiaoma-quick-dev-new-preview/SKILL.md"
|
|
659
|
+
// Strip xiaomaFolderName prefix and join with xiaomaDir, then get dirname
|
|
660
|
+
const relativePath = record.path.startsWith(xiaomaPrefix) ? record.path.slice(xiaomaPrefix.length) : record.path;
|
|
661
|
+
const sourceFile = path.join(xiaomaDir, relativePath);
|
|
662
|
+
const sourceDir = path.dirname(sourceFile);
|
|
663
|
+
|
|
664
|
+
if (!(await fs.pathExists(sourceDir))) continue;
|
|
665
|
+
|
|
666
|
+
// Clean target before copy to prevent stale files
|
|
667
|
+
const skillDir = path.join(targetPath, canonicalId);
|
|
668
|
+
await fs.remove(skillDir);
|
|
669
|
+
await fs.ensureDir(skillDir);
|
|
670
|
+
|
|
671
|
+
// Copy all skill files, filtering OS/editor artifacts recursively
|
|
672
|
+
const skipPatterns = new Set(['.DS_Store', 'Thumbs.db', 'desktop.ini']);
|
|
673
|
+
const skipSuffixes = ['~', '.swp', '.swo', '.bak'];
|
|
674
|
+
const filter = (src) => {
|
|
675
|
+
const name = path.basename(src);
|
|
676
|
+
if (src === sourceDir) return true;
|
|
677
|
+
if (skipPatterns.has(name)) return false;
|
|
678
|
+
if (name.startsWith('.') && name !== '.gitkeep') return false;
|
|
679
|
+
if (skipSuffixes.some((s) => name.endsWith(s))) return false;
|
|
680
|
+
return true;
|
|
681
|
+
};
|
|
682
|
+
await fs.copy(sourceDir, skillDir, { filter });
|
|
683
|
+
|
|
684
|
+
count++;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Post-install cleanup: remove _xiaoma/ directories for skills with install_to_xiaoma === "false"
|
|
688
|
+
for (const record of records) {
|
|
689
|
+
if (record.install_to_xiaoma === 'false') {
|
|
690
|
+
const relativePath = record.path.startsWith(xiaomaPrefix) ? record.path.slice(xiaomaPrefix.length) : record.path;
|
|
691
|
+
const sourceFile = path.join(xiaomaDir, relativePath);
|
|
692
|
+
const sourceDir = path.dirname(sourceFile);
|
|
693
|
+
if (await fs.pathExists(sourceDir)) {
|
|
694
|
+
await fs.remove(sourceDir);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return count;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Print installation summary
|
|
704
|
+
* @param {Object} results - Installation results
|
|
705
|
+
* @param {string} targetDir - Target directory (relative)
|
|
706
|
+
*/
|
|
707
|
+
async printSummary(results, targetDir, options = {}) {
|
|
708
|
+
if (options.silent) return;
|
|
709
|
+
const parts = [];
|
|
710
|
+
if (results.agents > 0) parts.push(`${results.agents} agents`);
|
|
711
|
+
if (results.workflows > 0) parts.push(`${results.workflows} workflows`);
|
|
712
|
+
if (results.tasks > 0) parts.push(`${results.tasks} tasks`);
|
|
713
|
+
if (results.tools > 0) parts.push(`${results.tools} tools`);
|
|
714
|
+
if (results.skills > 0) parts.push(`${results.skills} skills`);
|
|
715
|
+
await prompts.log.success(`${this.name} configured: ${parts.join(', ')} → ${targetDir}`);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Cleanup IDE configuration
|
|
720
|
+
* @param {string} projectDir - Project directory
|
|
721
|
+
*/
|
|
722
|
+
async cleanup(projectDir, options = {}) {
|
|
723
|
+
// Migrate legacy target directories (e.g. .opencode/agent → .opencode/agents)
|
|
724
|
+
if (this.installerConfig?.legacy_targets) {
|
|
725
|
+
if (!options.silent) await prompts.log.message(' Migrating legacy directories...');
|
|
726
|
+
for (const legacyDir of this.installerConfig.legacy_targets) {
|
|
727
|
+
if (this.isGlobalPath(legacyDir)) {
|
|
728
|
+
await this.warnGlobalLegacy(legacyDir, options);
|
|
729
|
+
} else {
|
|
730
|
+
await this.cleanupTarget(projectDir, legacyDir, options);
|
|
731
|
+
await this.removeEmptyParents(projectDir, legacyDir);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Strip XiaoMa markers from copilot-instructions.md if present
|
|
737
|
+
if (this.name === 'github-copilot') {
|
|
738
|
+
await this.cleanupCopilotInstructions(projectDir, options);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Strip XiaoMa modes from .kilocodemodes if present
|
|
742
|
+
if (this.name === 'kilo') {
|
|
743
|
+
await this.cleanupKiloModes(projectDir, options);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// Strip XiaoMa entries from .rovodev/prompts.yml if present
|
|
747
|
+
if (this.name === 'rovo-dev') {
|
|
748
|
+
await this.cleanupRovoDevPrompts(projectDir, options);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Clean all target directories
|
|
752
|
+
if (this.installerConfig?.targets) {
|
|
753
|
+
const parentDirs = new Set();
|
|
754
|
+
for (const target of this.installerConfig.targets) {
|
|
755
|
+
await this.cleanupTarget(projectDir, target.target_dir, options);
|
|
756
|
+
// Track parent directories for empty-dir cleanup
|
|
757
|
+
const parentDir = path.dirname(target.target_dir);
|
|
758
|
+
if (parentDir && parentDir !== '.') {
|
|
759
|
+
parentDirs.add(parentDir);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
// After all targets cleaned, remove empty parent directories (recursive up to projectDir)
|
|
763
|
+
for (const parentDir of parentDirs) {
|
|
764
|
+
await this.removeEmptyParents(projectDir, parentDir);
|
|
765
|
+
}
|
|
766
|
+
} else if (this.installerConfig?.target_dir) {
|
|
767
|
+
await this.cleanupTarget(projectDir, this.installerConfig.target_dir, options);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Check if a path is global (starts with ~ or is absolute)
|
|
773
|
+
* @param {string} p - Path to check
|
|
774
|
+
* @returns {boolean}
|
|
775
|
+
*/
|
|
776
|
+
isGlobalPath(p) {
|
|
777
|
+
return p.startsWith('~') || path.isAbsolute(p);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Warn about stale XiaoMa files in a global legacy directory (never auto-deletes)
|
|
782
|
+
* @param {string} legacyDir - Legacy directory path (may start with ~)
|
|
783
|
+
* @param {Object} options - Options (silent, etc.)
|
|
784
|
+
*/
|
|
785
|
+
async warnGlobalLegacy(legacyDir, options = {}) {
|
|
786
|
+
try {
|
|
787
|
+
const expanded = legacyDir.startsWith('~/')
|
|
788
|
+
? path.join(os.homedir(), legacyDir.slice(2))
|
|
789
|
+
: legacyDir === '~'
|
|
790
|
+
? os.homedir()
|
|
791
|
+
: legacyDir;
|
|
792
|
+
|
|
793
|
+
if (!(await fs.pathExists(expanded))) return;
|
|
794
|
+
|
|
795
|
+
const entries = await fs.readdir(expanded);
|
|
796
|
+
const xiaomaFiles = entries.filter((e) => typeof e === 'string' && e.startsWith('xiaoma'));
|
|
797
|
+
|
|
798
|
+
if (xiaomaFiles.length > 0 && !options.silent) {
|
|
799
|
+
await prompts.log.warn(`Found ${xiaomaFiles.length} stale XiaoMa file(s) in ${expanded}. Remove manually: rm ${expanded}/xiaoma-*`);
|
|
800
|
+
}
|
|
801
|
+
} catch {
|
|
802
|
+
// Errors reading global paths are silently ignored
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Cleanup a specific target directory
|
|
808
|
+
* @param {string} projectDir - Project directory
|
|
809
|
+
* @param {string} targetDir - Target directory to clean
|
|
810
|
+
*/
|
|
811
|
+
async cleanupTarget(projectDir, targetDir, options = {}) {
|
|
812
|
+
const targetPath = path.join(projectDir, targetDir);
|
|
813
|
+
|
|
814
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// Remove all xiaoma* files
|
|
819
|
+
let entries;
|
|
820
|
+
try {
|
|
821
|
+
entries = await fs.readdir(targetPath);
|
|
822
|
+
} catch {
|
|
823
|
+
// Directory exists but can't be read - skip cleanup
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
if (!entries || !Array.isArray(entries)) {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
let removedCount = 0;
|
|
832
|
+
|
|
833
|
+
for (const entry of entries) {
|
|
834
|
+
if (!entry || typeof entry !== 'string') {
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
if (entry.startsWith('xiaoma') && !entry.startsWith('xiaoma-os-')) {
|
|
838
|
+
const entryPath = path.join(targetPath, entry);
|
|
839
|
+
try {
|
|
840
|
+
await fs.remove(entryPath);
|
|
841
|
+
removedCount++;
|
|
842
|
+
} catch {
|
|
843
|
+
// Skip entries that can't be removed (broken symlinks, permission errors)
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
if (removedCount > 0 && !options.silent) {
|
|
849
|
+
await prompts.log.message(` Cleaned ${removedCount} XiaoMa files from ${targetDir}`);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// Remove empty directory after cleanup
|
|
853
|
+
if (removedCount > 0) {
|
|
854
|
+
try {
|
|
855
|
+
const remaining = await fs.readdir(targetPath);
|
|
856
|
+
if (remaining.length === 0) {
|
|
857
|
+
await fs.remove(targetPath);
|
|
858
|
+
}
|
|
859
|
+
} catch {
|
|
860
|
+
// Directory may already be gone or in use — skip
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Strip XiaoMa-owned content from .github/copilot-instructions.md.
|
|
866
|
+
* The old custom installer injected content between <!-- XiaoMa:START --> and <!-- XiaoMa:END --> markers.
|
|
867
|
+
* Deletes the file if nothing remains. Restores .bak backup if one exists.
|
|
868
|
+
*/
|
|
869
|
+
async cleanupCopilotInstructions(projectDir, options = {}) {
|
|
870
|
+
const filePath = path.join(projectDir, '.github', 'copilot-instructions.md');
|
|
871
|
+
|
|
872
|
+
if (!(await fs.pathExists(filePath))) return;
|
|
873
|
+
|
|
874
|
+
try {
|
|
875
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
876
|
+
const startIdx = content.indexOf('<!-- XiaoMa:START -->');
|
|
877
|
+
const endIdx = content.indexOf('<!-- XiaoMa:END -->');
|
|
878
|
+
|
|
879
|
+
if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) return;
|
|
880
|
+
|
|
881
|
+
const cleaned = content.slice(0, startIdx) + content.slice(endIdx + '<!-- XiaoMa:END -->'.length);
|
|
882
|
+
|
|
883
|
+
if (cleaned.trim().length === 0) {
|
|
884
|
+
await fs.remove(filePath);
|
|
885
|
+
const backupPath = `${filePath}.bak`;
|
|
886
|
+
if (await fs.pathExists(backupPath)) {
|
|
887
|
+
await fs.rename(backupPath, filePath);
|
|
888
|
+
if (!options.silent) await prompts.log.message(' Restored copilot-instructions.md from backup');
|
|
889
|
+
}
|
|
890
|
+
} else {
|
|
891
|
+
await fs.writeFile(filePath, cleaned, 'utf8');
|
|
892
|
+
const backupPath = `${filePath}.bak`;
|
|
893
|
+
if (await fs.pathExists(backupPath)) await fs.remove(backupPath);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
if (!options.silent) await prompts.log.message(' Cleaned XiaoMa markers from copilot-instructions.md');
|
|
897
|
+
} catch {
|
|
898
|
+
if (!options.silent) await prompts.log.warn(' Warning: Could not clean XiaoMa markers from copilot-instructions.md');
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* Strip XiaoMa-owned modes from .kilocodemodes.
|
|
904
|
+
* The old custom kilo.js installer added modes with slug starting with 'xiaoma-'.
|
|
905
|
+
* Parses YAML, filters out XiaoMa modes, rewrites. Leaves file as-is on parse failure.
|
|
906
|
+
*/
|
|
907
|
+
async cleanupKiloModes(projectDir, options = {}) {
|
|
908
|
+
const kiloModesPath = path.join(projectDir, '.kilocodemodes');
|
|
909
|
+
|
|
910
|
+
if (!(await fs.pathExists(kiloModesPath))) return;
|
|
911
|
+
|
|
912
|
+
const content = await fs.readFile(kiloModesPath, 'utf8');
|
|
913
|
+
|
|
914
|
+
let config;
|
|
915
|
+
try {
|
|
916
|
+
config = yaml.parse(content) || {};
|
|
917
|
+
} catch {
|
|
918
|
+
if (!options.silent) await prompts.log.warn(' Warning: Could not parse .kilocodemodes for cleanup');
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
if (!Array.isArray(config.customModes)) return;
|
|
923
|
+
|
|
924
|
+
const originalCount = config.customModes.length;
|
|
925
|
+
config.customModes = config.customModes.filter((mode) => mode && (!mode.slug || !mode.slug.startsWith('xiaoma-')));
|
|
926
|
+
const removedCount = originalCount - config.customModes.length;
|
|
927
|
+
|
|
928
|
+
if (removedCount > 0) {
|
|
929
|
+
try {
|
|
930
|
+
await fs.writeFile(kiloModesPath, yaml.stringify(config, { lineWidth: 0 }));
|
|
931
|
+
if (!options.silent) await prompts.log.message(` Removed ${removedCount} XiaoMa modes from .kilocodemodes`);
|
|
932
|
+
} catch {
|
|
933
|
+
if (!options.silent) await prompts.log.warn(' Warning: Could not write .kilocodemodes during cleanup');
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Strip XiaoMa-owned entries from .rovodev/prompts.yml.
|
|
940
|
+
* The old custom rovodev.js installer registered workflows in prompts.yml.
|
|
941
|
+
* Parses YAML, filters out entries with name starting with 'xiaoma-', rewrites.
|
|
942
|
+
* Removes the file if no entries remain.
|
|
943
|
+
*/
|
|
944
|
+
async cleanupRovoDevPrompts(projectDir, options = {}) {
|
|
945
|
+
const promptsPath = path.join(projectDir, '.rovodev', 'prompts.yml');
|
|
946
|
+
|
|
947
|
+
if (!(await fs.pathExists(promptsPath))) return;
|
|
948
|
+
|
|
949
|
+
const content = await fs.readFile(promptsPath, 'utf8');
|
|
950
|
+
|
|
951
|
+
let config;
|
|
952
|
+
try {
|
|
953
|
+
config = yaml.parse(content) || {};
|
|
954
|
+
} catch {
|
|
955
|
+
if (!options.silent) await prompts.log.warn(' Warning: Could not parse prompts.yml for cleanup');
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
if (!Array.isArray(config.prompts)) return;
|
|
960
|
+
|
|
961
|
+
const originalCount = config.prompts.length;
|
|
962
|
+
config.prompts = config.prompts.filter((entry) => entry && (!entry.name || !entry.name.startsWith('xiaoma-')));
|
|
963
|
+
const removedCount = originalCount - config.prompts.length;
|
|
964
|
+
|
|
965
|
+
if (removedCount > 0) {
|
|
966
|
+
try {
|
|
967
|
+
if (config.prompts.length === 0) {
|
|
968
|
+
await fs.remove(promptsPath);
|
|
969
|
+
} else {
|
|
970
|
+
await fs.writeFile(promptsPath, yaml.stringify(config, { lineWidth: 0 }));
|
|
971
|
+
}
|
|
972
|
+
if (!options.silent) await prompts.log.message(` Removed ${removedCount} XiaoMa entries from prompts.yml`);
|
|
973
|
+
} catch {
|
|
974
|
+
if (!options.silent) await prompts.log.warn(' Warning: Could not write prompts.yml during cleanup');
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Check ancestor directories for existing XiaoMa files in the same target_dir.
|
|
981
|
+
* IDEs like Claude Code inherit commands from parent directories, so an existing
|
|
982
|
+
* installation in an ancestor would cause duplicate commands.
|
|
983
|
+
* @param {string} projectDir - Project directory being installed to
|
|
984
|
+
* @returns {Promise<string|null>} Path to conflicting directory, or null if clean
|
|
985
|
+
*/
|
|
986
|
+
async findAncestorConflict(projectDir) {
|
|
987
|
+
const targetDir = this.installerConfig?.target_dir;
|
|
988
|
+
if (!targetDir) return null;
|
|
989
|
+
|
|
990
|
+
const resolvedProject = await fs.realpath(path.resolve(projectDir));
|
|
991
|
+
let current = path.dirname(resolvedProject);
|
|
992
|
+
const root = path.parse(current).root;
|
|
993
|
+
|
|
994
|
+
while (current !== root && current.length > root.length) {
|
|
995
|
+
const candidatePath = path.join(current, targetDir);
|
|
996
|
+
try {
|
|
997
|
+
if (await fs.pathExists(candidatePath)) {
|
|
998
|
+
const entries = await fs.readdir(candidatePath);
|
|
999
|
+
const hasXiaoMa = entries.some(
|
|
1000
|
+
(e) => typeof e === 'string' && e.toLowerCase().startsWith('xiaoma') && !e.toLowerCase().startsWith('xiaoma-os-'),
|
|
1001
|
+
);
|
|
1002
|
+
if (hasXiaoMa) {
|
|
1003
|
+
return candidatePath;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
} catch {
|
|
1007
|
+
// Can't read directory — skip
|
|
1008
|
+
}
|
|
1009
|
+
current = path.dirname(current);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
return null;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
/**
|
|
1016
|
+
* Walk up ancestor directories from relativeDir toward projectDir, removing each if empty
|
|
1017
|
+
* Stops at projectDir boundary — never removes projectDir itself
|
|
1018
|
+
* @param {string} projectDir - Project root (boundary)
|
|
1019
|
+
* @param {string} relativeDir - Relative directory to start from
|
|
1020
|
+
*/
|
|
1021
|
+
async removeEmptyParents(projectDir, relativeDir) {
|
|
1022
|
+
const resolvedProject = path.resolve(projectDir);
|
|
1023
|
+
let current = relativeDir;
|
|
1024
|
+
let last = null;
|
|
1025
|
+
while (current && current !== '.' && current !== last) {
|
|
1026
|
+
last = current;
|
|
1027
|
+
const fullPath = path.resolve(projectDir, current);
|
|
1028
|
+
// Boundary guard: never traverse outside projectDir
|
|
1029
|
+
if (!fullPath.startsWith(resolvedProject + path.sep) && fullPath !== resolvedProject) break;
|
|
1030
|
+
try {
|
|
1031
|
+
if (!(await fs.pathExists(fullPath))) {
|
|
1032
|
+
// Dir already gone — advance current; last is reset at top of next iteration
|
|
1033
|
+
current = path.dirname(current);
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
const remaining = await fs.readdir(fullPath);
|
|
1037
|
+
if (remaining.length > 0) break;
|
|
1038
|
+
await fs.rmdir(fullPath);
|
|
1039
|
+
} catch (error) {
|
|
1040
|
+
// ENOTEMPTY: TOCTOU race (file added between readdir and rmdir) — skip level, continue upward
|
|
1041
|
+
// ENOENT: dir removed by another process between pathExists and rmdir — skip level, continue upward
|
|
1042
|
+
if (error.code === 'ENOTEMPTY' || error.code === 'ENOENT') {
|
|
1043
|
+
current = path.dirname(current);
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
break; // fatal error (e.g. EACCES) — stop upward walk
|
|
1047
|
+
}
|
|
1048
|
+
current = path.dirname(current);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
module.exports = { ConfigDrivenIdeSetup };
|