drt-method 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +45 -0
- package/GETTING-STARTED.md +269 -0
- package/README.md +233 -0
- package/drt-method-1.0.0.tgz +0 -0
- package/drt-modules.yaml +1 -0
- package/package.json +51 -0
- package/scripts/install-from-github.ps1 +22 -0
- package/scripts/install-from-github.sh +17 -0
- package/src/core-skills/drt-advanced-elicitation/SKILL.md +142 -0
- package/src/core-skills/drt-advanced-elicitation/methods.csv +72 -0
- package/src/core-skills/drt-brainstorming/SKILL.md +80 -0
- package/src/core-skills/drt-brainstorming/assets/brain-icons.json +166 -0
- package/src/core-skills/drt-brainstorming/assets/brain-methods.csv +109 -0
- package/src/core-skills/drt-brainstorming/assets/brain-selector.html +326 -0
- package/src/core-skills/drt-brainstorming/customize.toml +84 -0
- package/src/core-skills/drt-brainstorming/references/converge.md +24 -0
- package/src/core-skills/drt-brainstorming/references/finalize.md +26 -0
- package/src/core-skills/drt-brainstorming/references/headless.md +54 -0
- package/src/core-skills/drt-brainstorming/references/in-chat-techniques.md +18 -0
- package/src/core-skills/drt-brainstorming/references/mode-autonomous.md +10 -0
- package/src/core-skills/drt-brainstorming/references/mode-facilitator.md +11 -0
- package/src/core-skills/drt-brainstorming/references/mode-partner.md +16 -0
- package/src/core-skills/drt-brainstorming/references/resume.md +5 -0
- package/src/core-skills/drt-brainstorming/scripts/brain.py +740 -0
- package/src/core-skills/drt-customize/SKILL.md +111 -0
- package/src/core-skills/drt-customize/scripts/list_customizable_skills.py +231 -0
- package/src/core-skills/drt-editorial-review-prose/SKILL.md +86 -0
- package/src/core-skills/drt-editorial-review-structure/SKILL.md +179 -0
- package/src/core-skills/drt-forge-idea/SKILL.md +107 -0
- package/src/core-skills/drt-forge-idea/customize.toml +42 -0
- package/src/core-skills/drt-forge-idea/scripts/resolve_personas.py +270 -0
- package/src/core-skills/drt-help/SKILL.md +75 -0
- package/src/core-skills/drt-index-docs/SKILL.md +66 -0
- package/src/core-skills/drt-party-mode/SKILL.md +60 -0
- package/src/core-skills/drt-party-mode/customize.toml +211 -0
- package/src/core-skills/drt-party-mode/references/create-party.md +70 -0
- package/src/core-skills/drt-party-mode/references/mode-agent-team.md +13 -0
- package/src/core-skills/drt-party-mode/references/mode-auto.md +13 -0
- package/src/core-skills/drt-party-mode/references/mode-subagent.md +31 -0
- package/src/core-skills/drt-party-mode/references/party-memory.md +51 -0
- package/src/core-skills/drt-party-mode/scripts/resolve_party.py +272 -0
- package/src/core-skills/drt-review-adversarial-general/SKILL.md +37 -0
- package/src/core-skills/drt-review-edge-case-hunter/SKILL.md +73 -0
- package/src/core-skills/drt-review-edge-case-hunter/references/deletion-check.md +14 -0
- package/src/core-skills/drt-review-verification-gap/SKILL.md +106 -0
- package/src/core-skills/drt-shard-doc/SKILL.md +105 -0
- package/src/core-skills/drt-spec/SKILL.md +160 -0
- package/src/core-skills/drt-spec/assets/headless-schemas.md +33 -0
- package/src/core-skills/drt-spec/assets/spec-template.md +49 -0
- package/src/core-skills/drt-spec/assets/stories-schema.md +44 -0
- package/src/core-skills/drt-spec/customize.toml +53 -0
- package/src/core-skills/module-help.csv +14 -0
- package/src/core-skills/module.yaml +33 -0
- package/src/drt-skills/1-analysis/drt-agent-analyst/SKILL.md +76 -0
- package/src/drt-skills/1-analysis/drt-agent-analyst/customize.toml +90 -0
- package/src/drt-skills/1-analysis/drt-agent-tech-writer/SKILL.md +76 -0
- package/src/drt-skills/1-analysis/drt-agent-tech-writer/customize.toml +81 -0
- package/src/drt-skills/1-analysis/drt-agent-tech-writer/explain-concept.md +20 -0
- package/src/drt-skills/1-analysis/drt-agent-tech-writer/mermaid-gen.md +20 -0
- package/src/drt-skills/1-analysis/drt-agent-tech-writer/validate-doc.md +19 -0
- package/src/drt-skills/1-analysis/drt-agent-tech-writer/write-document.md +20 -0
- package/src/drt-skills/1-analysis/drt-document-project/SKILL.md +62 -0
- package/src/drt-skills/1-analysis/drt-document-project/checklist.md +245 -0
- package/src/drt-skills/1-analysis/drt-document-project/customize.toml +41 -0
- package/src/drt-skills/1-analysis/drt-document-project/documentation-requirements.csv +12 -0
- package/src/drt-skills/1-analysis/drt-document-project/instructions.md +128 -0
- package/src/drt-skills/1-analysis/drt-document-project/templates/deep-dive-template.md +345 -0
- package/src/drt-skills/1-analysis/drt-document-project/templates/index-template.md +169 -0
- package/src/drt-skills/1-analysis/drt-document-project/templates/project-overview-template.md +103 -0
- package/src/drt-skills/1-analysis/drt-document-project/templates/project-scan-report-schema.json +160 -0
- package/src/drt-skills/1-analysis/drt-document-project/templates/source-tree-template.md +135 -0
- package/src/drt-skills/1-analysis/drt-document-project/workflows/deep-dive-instructions.md +300 -0
- package/src/drt-skills/1-analysis/drt-document-project/workflows/deep-dive-workflow.md +34 -0
- package/src/drt-skills/1-analysis/drt-document-project/workflows/full-scan-instructions.md +1111 -0
- package/src/drt-skills/1-analysis/drt-document-project/workflows/full-scan-workflow.md +34 -0
- package/src/drt-skills/1-analysis/drt-prfaq/SKILL.md +135 -0
- package/src/drt-skills/1-analysis/drt-prfaq/agents/artifact-analyzer.md +60 -0
- package/src/drt-skills/1-analysis/drt-prfaq/agents/web-researcher.md +49 -0
- package/src/drt-skills/1-analysis/drt-prfaq/assets/prfaq-template.md +62 -0
- package/src/drt-skills/1-analysis/drt-prfaq/bmad-manifest.json +16 -0
- package/src/drt-skills/1-analysis/drt-prfaq/customize.toml +41 -0
- package/src/drt-skills/1-analysis/drt-prfaq/references/customer-faq.md +55 -0
- package/src/drt-skills/1-analysis/drt-prfaq/references/internal-faq.md +51 -0
- package/src/drt-skills/1-analysis/drt-prfaq/references/press-release.md +60 -0
- package/src/drt-skills/1-analysis/drt-prfaq/references/verdict.md +83 -0
- package/src/drt-skills/1-analysis/drt-product-brief/SKILL.md +91 -0
- package/src/drt-skills/1-analysis/drt-product-brief/assets/brief-template.md +41 -0
- package/src/drt-skills/1-analysis/drt-product-brief/customize.toml +99 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/SKILL.md +96 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/customize.toml +41 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-01-init.md +137 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-02-domain-analysis.md +229 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-05-technical-trends.md +234 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-06-research-synthesis.md +450 -0
- package/src/drt-skills/1-analysis/research/drt-domain-research/research.template.md +29 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/SKILL.md +96 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/customize.toml +41 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/research.template.md +29 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-01-init.md +184 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-02-customer-behavior.md +239 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-03-customer-pain-points.md +251 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-04-customer-decisions.md +261 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-05-competitive-analysis.md +173 -0
- package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-06-research-completion.md +484 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/SKILL.md +96 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/customize.toml +41 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/research.template.md +29 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-01-init.md +137 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-02-technical-overview.md +239 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-03-integration-patterns.md +248 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-05-implementation-research.md +233 -0
- package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-06-research-synthesis.md +493 -0
- package/src/drt-skills/2-plan-workflows/drt-agent-pm/SKILL.md +76 -0
- package/src/drt-skills/2-plan-workflows/drt-agent-pm/customize.toml +75 -0
- package/src/drt-skills/2-plan-workflows/drt-agent-ux-designer/SKILL.md +76 -0
- package/src/drt-skills/2-plan-workflows/drt-agent-ux-designer/customize.toml +60 -0
- package/src/drt-skills/2-plan-workflows/drt-create-prd/SKILL.md +30 -0
- package/src/drt-skills/2-plan-workflows/drt-create-prd/customize.toml +41 -0
- package/src/drt-skills/2-plan-workflows/drt-edit-prd/SKILL.md +30 -0
- package/src/drt-skills/2-plan-workflows/drt-edit-prd/customize.toml +42 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/SKILL.md +92 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/assets/headless-schemas.md +76 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/assets/prd-template.md +165 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/assets/prd-validation-checklist.md +135 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/assets/validation-report-template.html +325 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/customize.toml +147 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/references/headless.md +39 -0
- package/src/drt-skills/2-plan-workflows/drt-prd/references/validate.md +97 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/SKILL.md +90 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/color-themes.md +9 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-directions.md +9 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-example-editorial.md +158 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-example-mobile.md +93 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-example-shadcn.md +109 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/excalidraw-wireframe.md +19 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/experience-example-mobile.md +112 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/experience-example-shadcn.md +133 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/headless-schemas.md +84 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/key-screens.md +29 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/assets/validation-report-template.html +319 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/customize.toml +100 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/references/creative-tools.md +19 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/references/design-md-spec.md +50 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/references/headless.md +37 -0
- package/src/drt-skills/2-plan-workflows/drt-ux/references/validate.md +115 -0
- package/src/drt-skills/2-plan-workflows/drt-validate-prd/SKILL.md +30 -0
- package/src/drt-skills/2-plan-workflows/drt-validate-prd/customize.toml +42 -0
- package/src/drt-skills/3-solutioning/drt-agent-architect/SKILL.md +76 -0
- package/src/drt-skills/3-solutioning/drt-agent-architect/customize.toml +65 -0
- package/src/drt-skills/3-solutioning/drt-architecture/SKILL.md +85 -0
- package/src/drt-skills/3-solutioning/drt-architecture/assets/spine-template.md +79 -0
- package/src/drt-skills/3-solutioning/drt-architecture/customize.toml +100 -0
- package/src/drt-skills/3-solutioning/drt-architecture/references/headless.md +26 -0
- package/src/drt-skills/3-solutioning/drt-architecture/references/reviewer-gate.md +13 -0
- package/src/drt-skills/3-solutioning/drt-architecture/scripts/lint_spine.py +257 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/SKILL.md +91 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/customize.toml +41 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-01-document-discovery.md +179 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-02-prd-analysis.md +168 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +169 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-04-ux-alignment.md +129 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-05-epic-quality-review.md +241 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-06-final-assessment.md +132 -0
- package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/drt-skills/3-solutioning/drt-create-architecture/SKILL.md +30 -0
- package/src/drt-skills/3-solutioning/drt-create-architecture/customize.toml +41 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/SKILL.md +93 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/customize.toml +41 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-01-validate-prerequisites.md +263 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-02-design-epics.md +242 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-04-final-validation.md +143 -0
- package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/templates/epics-template.md +61 -0
- package/src/drt-skills/3-solutioning/drt-generate-project-context/SKILL.md +81 -0
- package/src/drt-skills/3-solutioning/drt-generate-project-context/customize.toml +41 -0
- package/src/drt-skills/3-solutioning/drt-generate-project-context/project-context-template.md +21 -0
- package/src/drt-skills/3-solutioning/drt-generate-project-context/steps/step-01-discover.md +186 -0
- package/src/drt-skills/3-solutioning/drt-generate-project-context/steps/step-02-generate.md +321 -0
- package/src/drt-skills/3-solutioning/drt-generate-project-context/steps/step-03-complete.md +284 -0
- package/src/drt-skills/4-implementation/drt-agent-dev/SKILL.md +76 -0
- package/src/drt-skills/4-implementation/drt-agent-dev/customize.toml +95 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/SKILL.md +68 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/generate-trail.md +38 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-01-orientation.md +105 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-02-walkthrough.md +89 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-03-detail-pass.md +106 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-04-testing.md +74 -0
- package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-05-wrapup.md +30 -0
- package/src/drt-skills/4-implementation/drt-code-review/SKILL.md +90 -0
- package/src/drt-skills/4-implementation/drt-code-review/customize.toml +93 -0
- package/src/drt-skills/4-implementation/drt-code-review/steps/step-01-gather-context.md +84 -0
- package/src/drt-skills/4-implementation/drt-code-review/steps/step-02-review.md +32 -0
- package/src/drt-skills/4-implementation/drt-code-review/steps/step-03-triage.md +50 -0
- package/src/drt-skills/4-implementation/drt-code-review/steps/step-04-present.md +132 -0
- package/src/drt-skills/4-implementation/drt-correct-course/SKILL.md +301 -0
- package/src/drt-skills/4-implementation/drt-correct-course/checklist.md +288 -0
- package/src/drt-skills/4-implementation/drt-correct-course/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-create-story/SKILL.md +432 -0
- package/src/drt-skills/4-implementation/drt-create-story/checklist.md +357 -0
- package/src/drt-skills/4-implementation/drt-create-story/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-create-story/discover-inputs.md +88 -0
- package/src/drt-skills/4-implementation/drt-create-story/template.md +49 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/SKILL.md +123 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/compile-epic-context.md +62 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/customize.toml +108 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/spec-template.md +98 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/step-01-clarify-and-route.md +84 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/step-02-plan.md +31 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/step-03-implement.md +42 -0
- package/src/drt-skills/4-implementation/drt-dev-auto/step-04-review.md +95 -0
- package/src/drt-skills/4-implementation/drt-dev-story/SKILL.md +500 -0
- package/src/drt-skills/4-implementation/drt-dev-story/checklist.md +80 -0
- package/src/drt-skills/4-implementation/drt-dev-story/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-implement-task/SKILL.md +101 -0
- package/src/drt-skills/4-implementation/drt-implement-task/assets/task-spec-template.md +60 -0
- package/src/drt-skills/4-implementation/drt-implement-task/customize.toml +17 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-01-gather-intent.md +42 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-02-plan-and-approve.md +43 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-03-confirm-dependencies.md +38 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-04-implement.md +42 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-05-qc-test.md +31 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-06-quality-review.md +30 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-07-fix-findings.md +33 -0
- package/src/drt-skills/4-implementation/drt-implement-task/steps/step-08-complete.md +35 -0
- package/src/drt-skills/4-implementation/drt-qa-generate-e2e-tests/SKILL.md +176 -0
- package/src/drt-skills/4-implementation/drt-qa-generate-e2e-tests/checklist.md +33 -0
- package/src/drt-skills/4-implementation/drt-qa-generate-e2e-tests/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/SKILL.md +13 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/compile-epic-context.md +62 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/customize.toml +83 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/render.js +206 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/spec-template.md +89 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/step-01-clarify-and-route.md +103 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/step-02-plan.md +47 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/step-03-implement.md +45 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/step-04-review.md +55 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/step-05-present.md +78 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/step-oneshot.md +78 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/sync-sprint-status.md +19 -0
- package/src/drt-skills/4-implementation/drt-quick-dev/workflow.md +85 -0
- package/src/drt-skills/4-implementation/drt-retrospective/SKILL.md +1527 -0
- package/src/drt-skills/4-implementation/drt-retrospective/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-sprint-planning/SKILL.md +319 -0
- package/src/drt-skills/4-implementation/drt-sprint-planning/checklist.md +34 -0
- package/src/drt-skills/4-implementation/drt-sprint-planning/customize.toml +41 -0
- package/src/drt-skills/4-implementation/drt-sprint-planning/sprint-status-template.yaml +69 -0
- package/src/drt-skills/4-implementation/drt-sprint-status/SKILL.md +311 -0
- package/src/drt-skills/4-implementation/drt-sprint-status/customize.toml +41 -0
- package/src/drt-skills/module-help.csv +32 -0
- package/src/drt-skills/module.yaml +95 -0
- package/src/scripts/lib/load-toml.js +43 -0
- package/src/scripts/lib/merge-utils.js +89 -0
- package/src/scripts/memlog.js +184 -0
- package/src/scripts/package.json +7 -0
- package/src/scripts/resolve-config.js +56 -0
- package/src/scripts/resolve-customization.js +77 -0
- package/tools/installer/cli-utils.js +53 -0
- package/tools/installer/commands/install.js +149 -0
- package/tools/installer/commands/status.js +65 -0
- package/tools/installer/commands/uninstall.js +167 -0
- package/tools/installer/core/config.js +73 -0
- package/tools/installer/core/existing-install.js +121 -0
- package/tools/installer/core/install-paths.js +132 -0
- package/tools/installer/core/installer.js +1762 -0
- package/tools/installer/core/legacy-warnings.js +151 -0
- package/tools/installer/core/manifest-generator.js +859 -0
- package/tools/installer/core/manifest.js +433 -0
- package/tools/installer/core/uv-check.js +97 -0
- package/tools/installer/core/wsl-node-check.js +109 -0
- package/tools/installer/drt-cli.js +104 -0
- package/tools/installer/file-ops.js +204 -0
- package/tools/installer/fs-native.js +116 -0
- package/tools/installer/ide/_config-driven.js +972 -0
- package/tools/installer/ide/manager.js +324 -0
- package/tools/installer/ide/platform-codes.js +80 -0
- package/tools/installer/ide/platform-codes.yaml +343 -0
- package/tools/installer/ide/shared/installed-skills.js +50 -0
- package/tools/installer/ide/shared/path-utils.js +217 -0
- package/tools/installer/ide/shared/skill-manifest.js +57 -0
- package/tools/installer/install-messages.yaml +29 -0
- package/tools/installer/list-options.js +210 -0
- package/tools/installer/message-loader.js +83 -0
- package/tools/installer/modules/channel-plan.js +203 -0
- package/tools/installer/modules/channel-resolver.js +241 -0
- package/tools/installer/modules/custom-module-manager.js +918 -0
- package/tools/installer/modules/external-manager.js +667 -0
- package/tools/installer/modules/module-help-schema.js +13 -0
- package/tools/installer/modules/official-modules.js +2257 -0
- package/tools/installer/modules/plugin-resolver.js +398 -0
- package/tools/installer/modules/version-resolver.js +336 -0
- package/tools/installer/project-root.js +224 -0
- package/tools/installer/prompts.js +852 -0
- package/tools/installer/set-overrides.js +330 -0
- package/tools/installer/ui.js +2090 -0
- package/tools/installer/yaml-format.js +245 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const semver = require('semver');
|
|
3
|
+
const yaml = require('yaml');
|
|
4
|
+
const fs = require('../fs-native');
|
|
5
|
+
const { getExternalModuleCachePath, getModulePath, resolveInstalledModuleYaml } = require('../project-root');
|
|
6
|
+
|
|
7
|
+
const DEFAULT_PARENT_DEPTH = 8;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a module version from authoritative on-disk metadata.
|
|
11
|
+
* Preference order:
|
|
12
|
+
* 1. package.json nearest the module source/cache root
|
|
13
|
+
* 2. module.yaml in the module source directory
|
|
14
|
+
* 3. .claude-plugin/marketplace.json
|
|
15
|
+
* 4. caller-provided fallback version
|
|
16
|
+
*
|
|
17
|
+
* @param {string} moduleName - Module code/name
|
|
18
|
+
* @param {Object} [options]
|
|
19
|
+
* @param {string} [options.moduleSourcePath] - Directory containing module.yaml
|
|
20
|
+
* @param {string} [options.fallbackVersion] - Final fallback when no metadata is found
|
|
21
|
+
* @param {string[]} [options.marketplacePluginNames] - Preferred marketplace plugin names
|
|
22
|
+
* @returns {Promise<{version: string|null, source: string|null, path: string|null}>}
|
|
23
|
+
*/
|
|
24
|
+
async function resolveModuleVersion(moduleName, options = {}) {
|
|
25
|
+
const moduleSourcePath = await normalizeDirectoryPath(options.moduleSourcePath);
|
|
26
|
+
const packageJsonPath = await findPackageJsonPath(moduleName, moduleSourcePath);
|
|
27
|
+
|
|
28
|
+
if (packageJsonPath) {
|
|
29
|
+
const packageVersion = await readPackageJsonVersion(packageJsonPath);
|
|
30
|
+
if (packageVersion) {
|
|
31
|
+
return {
|
|
32
|
+
version: packageVersion,
|
|
33
|
+
source: 'package.json',
|
|
34
|
+
path: packageJsonPath,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const moduleYamlPath = await findModuleYamlPath(moduleName, moduleSourcePath);
|
|
40
|
+
if (moduleYamlPath) {
|
|
41
|
+
const moduleVersion = await readModuleYamlVersion(moduleYamlPath);
|
|
42
|
+
if (moduleVersion) {
|
|
43
|
+
return {
|
|
44
|
+
version: moduleVersion,
|
|
45
|
+
source: 'module.yaml',
|
|
46
|
+
path: moduleYamlPath,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const marketplaceVersion = await findMarketplaceVersion(moduleName, moduleSourcePath, options.marketplacePluginNames || []);
|
|
52
|
+
if (marketplaceVersion) {
|
|
53
|
+
return marketplaceVersion;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const fallbackVersion = normalizeVersion(options.fallbackVersion);
|
|
57
|
+
if (fallbackVersion) {
|
|
58
|
+
return {
|
|
59
|
+
version: fallbackVersion,
|
|
60
|
+
source: 'fallback',
|
|
61
|
+
path: null,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
version: null,
|
|
67
|
+
source: null,
|
|
68
|
+
path: null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function findPackageJsonPath(moduleName, moduleSourcePath) {
|
|
73
|
+
const roots = await buildSearchRoots(moduleName, moduleSourcePath);
|
|
74
|
+
|
|
75
|
+
for (const root of roots) {
|
|
76
|
+
const packageJsonPath = await findNearestUpwardFile(root.searchDir, 'package.json', { boundaryDir: root.boundaryDir });
|
|
77
|
+
if (packageJsonPath) {
|
|
78
|
+
return packageJsonPath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function findModuleYamlPath(moduleName, moduleSourcePath) {
|
|
86
|
+
if (moduleSourcePath) {
|
|
87
|
+
const directModuleYamlPath = path.join(moduleSourcePath, 'module.yaml');
|
|
88
|
+
if (await fs.pathExists(directModuleYamlPath)) {
|
|
89
|
+
return directModuleYamlPath;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return resolveInstalledModuleYaml(moduleName);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function findMarketplaceVersion(moduleName, moduleSourcePath, marketplacePluginNames) {
|
|
97
|
+
const roots = await buildSearchRoots(moduleName, moduleSourcePath);
|
|
98
|
+
|
|
99
|
+
for (const root of roots) {
|
|
100
|
+
const marketplacePath = await findNearestUpwardFile(root.searchDir, path.join('.claude-plugin', 'marketplace.json'), {
|
|
101
|
+
boundaryDir: root.boundaryDir,
|
|
102
|
+
});
|
|
103
|
+
if (!marketplacePath) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const data = await readJsonFile(marketplacePath);
|
|
108
|
+
if (!data) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const version = extractMarketplaceVersion(data, moduleName, marketplacePluginNames);
|
|
113
|
+
if (version) {
|
|
114
|
+
return {
|
|
115
|
+
version,
|
|
116
|
+
source: 'marketplace.json',
|
|
117
|
+
path: marketplacePath,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function buildSearchRoots(moduleName, moduleSourcePath) {
|
|
126
|
+
const roots = [];
|
|
127
|
+
const seen = new Set();
|
|
128
|
+
|
|
129
|
+
const addRoot = async (candidate) => {
|
|
130
|
+
const normalized = await normalizeExistingDirectory(candidate);
|
|
131
|
+
if (!normalized || seen.has(normalized)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
seen.add(normalized);
|
|
136
|
+
roots.push({
|
|
137
|
+
searchDir: normalized,
|
|
138
|
+
boundaryDir: await findSearchBoundary(normalized),
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
await addRoot(moduleSourcePath);
|
|
143
|
+
|
|
144
|
+
if (moduleName === 'core' || moduleName === 'drt') {
|
|
145
|
+
await addRoot(getModulePath(moduleName));
|
|
146
|
+
} else {
|
|
147
|
+
await addRoot(getExternalModuleCachePath(moduleName));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return roots;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function findNearestUpwardFile(startDir, relativeFilePath, options = {}) {
|
|
154
|
+
const normalizedStartDir = await normalizeExistingDirectory(startDir);
|
|
155
|
+
if (!normalizedStartDir) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const maxDepth = options.maxDepth ?? DEFAULT_PARENT_DEPTH;
|
|
160
|
+
const normalizedBoundaryDir = await normalizeDirectoryPath(options.boundaryDir);
|
|
161
|
+
let currentDir = normalizedStartDir;
|
|
162
|
+
for (let depth = 0; depth <= maxDepth; depth++) {
|
|
163
|
+
const candidate = path.join(currentDir, relativeFilePath);
|
|
164
|
+
if (await fs.pathExists(candidate)) {
|
|
165
|
+
return candidate;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (normalizedBoundaryDir && currentDir === normalizedBoundaryDir) {
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const parentDir = path.dirname(currentDir);
|
|
173
|
+
if (parentDir === currentDir) {
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
currentDir = parentDir;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function findSearchBoundary(startDir) {
|
|
183
|
+
const normalizedStartDir = await normalizeExistingDirectory(startDir);
|
|
184
|
+
if (!normalizedStartDir) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let currentDir = normalizedStartDir;
|
|
189
|
+
for (let depth = 0; depth <= DEFAULT_PARENT_DEPTH; depth++) {
|
|
190
|
+
if (
|
|
191
|
+
(await fs.pathExists(path.join(currentDir, 'package.json'))) ||
|
|
192
|
+
(await fs.pathExists(path.join(currentDir, '.claude-plugin', 'marketplace.json'))) ||
|
|
193
|
+
(await fs.pathExists(path.join(currentDir, '.git')))
|
|
194
|
+
) {
|
|
195
|
+
return currentDir;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const parentDir = path.dirname(currentDir);
|
|
199
|
+
if (parentDir === currentDir) {
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
currentDir = parentDir;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return normalizedStartDir;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function normalizeDirectoryPath(candidate) {
|
|
209
|
+
if (!candidate) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const resolvedPath = path.resolve(candidate);
|
|
214
|
+
try {
|
|
215
|
+
const stats = await fs.stat(resolvedPath);
|
|
216
|
+
return stats.isDirectory() ? resolvedPath : path.dirname(resolvedPath);
|
|
217
|
+
} catch {
|
|
218
|
+
return resolvedPath;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function normalizeExistingDirectory(candidate) {
|
|
223
|
+
const normalized = await normalizeDirectoryPath(candidate);
|
|
224
|
+
if (!normalized) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!(await fs.pathExists(normalized))) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return normalized;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async function readPackageJsonVersion(packageJsonPath) {
|
|
236
|
+
const data = await readJsonFile(packageJsonPath);
|
|
237
|
+
return normalizeVersion(data?.version);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async function readModuleYamlVersion(moduleYamlPath) {
|
|
241
|
+
try {
|
|
242
|
+
const content = await fs.readFile(moduleYamlPath, 'utf8');
|
|
243
|
+
const data = yaml.parse(content);
|
|
244
|
+
return normalizeVersion(data?.version || data?.module_version || data?.moduleVersion);
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async function readJsonFile(filePath) {
|
|
251
|
+
try {
|
|
252
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
253
|
+
return JSON.parse(content);
|
|
254
|
+
} catch {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function extractMarketplaceVersion(data, moduleName, marketplacePluginNames = []) {
|
|
260
|
+
const plugins = Array.isArray(data?.plugins) ? data.plugins : [];
|
|
261
|
+
if (plugins.length === 0) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const preferredNames = new Set(
|
|
266
|
+
[moduleName, ...marketplacePluginNames]
|
|
267
|
+
.filter((value) => typeof value === 'string')
|
|
268
|
+
.map((value) => value.trim())
|
|
269
|
+
.filter(Boolean),
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const exactMatches = [];
|
|
273
|
+
const fallbackVersions = [];
|
|
274
|
+
|
|
275
|
+
for (const plugin of plugins) {
|
|
276
|
+
const version = normalizeVersion(plugin?.version);
|
|
277
|
+
if (!version) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
fallbackVersions.push(version);
|
|
282
|
+
|
|
283
|
+
const pluginNames = [plugin?.name, plugin?.code].filter((value) => typeof value === 'string').map((value) => value.trim());
|
|
284
|
+
if (pluginNames.some((name) => preferredNames.has(name))) {
|
|
285
|
+
exactMatches.push(version);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return pickBestVersion(exactMatches.length > 0 ? exactMatches : fallbackVersions);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function pickBestVersion(versions) {
|
|
293
|
+
const candidates = versions.map(normalizeVersion).filter(Boolean);
|
|
294
|
+
if (candidates.length === 0) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
candidates.sort(compareVersionsDescending);
|
|
299
|
+
return candidates[0];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function compareVersionsDescending(left, right) {
|
|
303
|
+
const leftSemver = normalizeSemver(left);
|
|
304
|
+
const rightSemver = normalizeSemver(right);
|
|
305
|
+
|
|
306
|
+
if (leftSemver && rightSemver) {
|
|
307
|
+
return semver.rcompare(leftSemver, rightSemver);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (leftSemver) {
|
|
311
|
+
return -1;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (rightSemver) {
|
|
315
|
+
return 1;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return right.localeCompare(left, undefined, { numeric: true, sensitivity: 'base' });
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function normalizeSemver(version) {
|
|
322
|
+
return semver.valid(version) || semver.valid(semver.coerce(version));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function normalizeVersion(version) {
|
|
326
|
+
if (typeof version !== 'string') {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const trimmed = version.trim();
|
|
331
|
+
return trimmed || null;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
module.exports = {
|
|
335
|
+
resolveModuleVersion,
|
|
336
|
+
};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const os = require('node:os');
|
|
3
|
+
const yaml = require('yaml');
|
|
4
|
+
const fs = require('./fs-native');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Find the DRT project root directory by looking for package.json
|
|
8
|
+
* or specific DRT markers
|
|
9
|
+
*/
|
|
10
|
+
function findProjectRoot(startPath = __dirname) {
|
|
11
|
+
let currentPath = path.resolve(startPath);
|
|
12
|
+
|
|
13
|
+
// Keep going up until we find package.json with drt-method
|
|
14
|
+
while (currentPath !== path.dirname(currentPath)) {
|
|
15
|
+
const packagePath = path.join(currentPath, 'package.json');
|
|
16
|
+
|
|
17
|
+
if (fs.existsSync(packagePath)) {
|
|
18
|
+
try {
|
|
19
|
+
const pkg = fs.readJsonSync(packagePath);
|
|
20
|
+
// Check if this is the DRT project
|
|
21
|
+
if (pkg.name === 'drt-method' || fs.existsSync(path.join(currentPath, 'src', 'core-skills'))) {
|
|
22
|
+
return currentPath;
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
// Continue searching
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Also check for src/core-skills as a marker
|
|
30
|
+
if (fs.existsSync(path.join(currentPath, 'src', 'core-skills', 'agents'))) {
|
|
31
|
+
return currentPath;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
currentPath = path.dirname(currentPath);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// If we can't find it, use process.cwd() as fallback
|
|
38
|
+
return process.cwd();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Cache the project root after first calculation
|
|
42
|
+
let cachedRoot = null;
|
|
43
|
+
|
|
44
|
+
function getProjectRoot() {
|
|
45
|
+
if (!cachedRoot) {
|
|
46
|
+
cachedRoot = findProjectRoot();
|
|
47
|
+
}
|
|
48
|
+
return cachedRoot;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get path to source directory
|
|
53
|
+
*/
|
|
54
|
+
function getSourcePath(...segments) {
|
|
55
|
+
return path.join(getProjectRoot(), 'src', ...segments);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get path to a module's directory
|
|
60
|
+
* bmm is a built-in module directly under src/
|
|
61
|
+
* core is also directly under src/
|
|
62
|
+
* All other modules are stored remote
|
|
63
|
+
*/
|
|
64
|
+
function getModulePath(moduleName, ...segments) {
|
|
65
|
+
if (moduleName === 'core') {
|
|
66
|
+
return getSourcePath('core-skills', ...segments);
|
|
67
|
+
}
|
|
68
|
+
if (moduleName === 'drt') {
|
|
69
|
+
return getSourcePath('drt-skills', ...segments);
|
|
70
|
+
}
|
|
71
|
+
return getSourcePath('modules', moduleName, ...segments);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Path to the local external-module clone cache.
|
|
76
|
+
* External official modules (bmb, cis, gds, tea, wds, etc.) are cloned here
|
|
77
|
+
* by ExternalModuleManager during install and are not copied into <src>/modules/.
|
|
78
|
+
*/
|
|
79
|
+
function getExternalModuleCachePath(moduleName, ...segments) {
|
|
80
|
+
const base = process.env.DRT_EXTERNAL_MODULES_CACHE || path.join(os.homedir(), '.drt', 'cache', 'external-modules');
|
|
81
|
+
return path.join(base, moduleName, ...segments);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Locate an installed module's `module.yaml` by filesystem lookup only.
|
|
86
|
+
*
|
|
87
|
+
* Built-in modules (core, bmm) live under <src>. External official modules are
|
|
88
|
+
* cloned into ~/.drt/cache/external-modules/<name>/ with varying internal
|
|
89
|
+
* layouts (some at src/module.yaml, some at skills/module.yaml, some nested).
|
|
90
|
+
* Url-source custom modules are cloned into ~/.drt/cache/custom-modules/<host>/<owner>/<repo>/
|
|
91
|
+
* and are resolved by walking the cache and matching `code` or `name` from the
|
|
92
|
+
* discovered module.yaml. Local custom-source modules are not cached; their
|
|
93
|
+
* path is read from the CustomModuleManager resolution cache set during the
|
|
94
|
+
* same install run.
|
|
95
|
+
* This mirrors the candidate-path search in
|
|
96
|
+
* ExternalModuleManager.findExternalModuleSource but performs no git/network
|
|
97
|
+
* work, which keeps it safe to call during manifest writing.
|
|
98
|
+
*
|
|
99
|
+
* @param {string} moduleName
|
|
100
|
+
* @returns {Promise<string|null>} Absolute path to module.yaml, or null if not found.
|
|
101
|
+
*/
|
|
102
|
+
async function resolveInstalledModuleYaml(moduleName) {
|
|
103
|
+
const builtIn = path.join(getModulePath(moduleName), 'module.yaml');
|
|
104
|
+
if (await fs.pathExists(builtIn)) return builtIn;
|
|
105
|
+
|
|
106
|
+
// Collect every module.yaml under a root using the standard candidate paths.
|
|
107
|
+
// Url-source repos can host multiple plugins (discovery mode), so we need all
|
|
108
|
+
// matches, not just the first. Returned in priority order.
|
|
109
|
+
async function searchRootAll(root) {
|
|
110
|
+
const results = [];
|
|
111
|
+
for (const dir of ['skills', 'src']) {
|
|
112
|
+
const direct = path.join(root, dir, 'module.yaml');
|
|
113
|
+
if (await fs.pathExists(direct)) results.push(direct);
|
|
114
|
+
|
|
115
|
+
const dirPath = path.join(root, dir);
|
|
116
|
+
if (await fs.pathExists(dirPath)) {
|
|
117
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
if (!entry.isDirectory()) continue;
|
|
120
|
+
const nested = path.join(dirPath, entry.name, 'module.yaml');
|
|
121
|
+
if (await fs.pathExists(nested)) results.push(nested);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// BMB standard: {setup-skill}/assets/module.yaml (setup skill is any *-setup directory).
|
|
127
|
+
// Check at the repo root, and also under src/skills/ and skills/ since
|
|
128
|
+
// marketplace plugins commonly nest skills under src/skills/<name>/.
|
|
129
|
+
const setupSearchRoots = [root, path.join(root, 'src', 'skills'), path.join(root, 'skills')];
|
|
130
|
+
for (const setupRoot of setupSearchRoots) {
|
|
131
|
+
if (!(await fs.pathExists(setupRoot))) continue;
|
|
132
|
+
const entries = await fs.readdir(setupRoot, { withFileTypes: true });
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
if (!entry.isDirectory() || !entry.name.endsWith('-setup')) continue;
|
|
135
|
+
const setupAssets = path.join(setupRoot, entry.name, 'assets', 'module.yaml');
|
|
136
|
+
if (await fs.pathExists(setupAssets)) results.push(setupAssets);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const atRoot = path.join(root, 'module.yaml');
|
|
141
|
+
if (await fs.pathExists(atRoot)) results.push(atRoot);
|
|
142
|
+
return results;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Backwards-compatible single-result variant for the existing external-cache
|
|
146
|
+
// and resolution-cache fallbacks (one module per root by construction).
|
|
147
|
+
async function searchRoot(root) {
|
|
148
|
+
const all = await searchRootAll(root);
|
|
149
|
+
return all.length > 0 ? all[0] : null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const cacheRoot = getExternalModuleCachePath(moduleName);
|
|
153
|
+
if (await fs.pathExists(cacheRoot)) {
|
|
154
|
+
const found = await searchRoot(cacheRoot);
|
|
155
|
+
if (found) return found;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Community modules are cloned to ~/.drt/cache/community-modules/<name>/
|
|
159
|
+
// (parallel to the external-modules cache used above). Search there too so
|
|
160
|
+
// collectAgentsFromModuleYaml and writeCentralConfig can locate community
|
|
161
|
+
// module.yaml files regardless of how nested the layout is.
|
|
162
|
+
const communityCacheRoot = path.join(os.homedir(), '.drt', 'cache', 'community-modules', moduleName);
|
|
163
|
+
if (await fs.pathExists(communityCacheRoot)) {
|
|
164
|
+
const found = await searchRoot(communityCacheRoot);
|
|
165
|
+
if (found) return found;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Fallback: local custom-source modules store their source path in the
|
|
169
|
+
// CustomModuleManager resolution cache populated during the same install run.
|
|
170
|
+
// Match by code OR name since callers may use either form.
|
|
171
|
+
try {
|
|
172
|
+
const { CustomModuleManager } = require('./modules/custom-module-manager');
|
|
173
|
+
for (const [, mod] of CustomModuleManager._resolutionCache) {
|
|
174
|
+
if ((mod.code === moduleName || mod.name === moduleName) && mod.localPath) {
|
|
175
|
+
const found = await searchRoot(mod.localPath);
|
|
176
|
+
if (found) return found;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} catch {
|
|
180
|
+
// Resolution cache unavailable — continue
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Fallback: url-source custom modules cloned to ~/.drt/cache/custom-modules/.
|
|
184
|
+
// Walk every cached repo, enumerate ALL module.yaml files via searchRootAll
|
|
185
|
+
// (a single repo can host multiple plugins in discovery mode), and match by
|
|
186
|
+
// the yaml's `code` or `name` field. This works on re-install runs where
|
|
187
|
+
// _resolutionCache is empty and covers both discovery-mode (with marketplace.json)
|
|
188
|
+
// and direct-mode modules, since we identify repo roots by .drt-source.json
|
|
189
|
+
// (written by cloneRepo) or .claude-plugin/ rather than by marketplace.json.
|
|
190
|
+
try {
|
|
191
|
+
const customCacheDir = path.join(os.homedir(), '.drt', 'cache', 'custom-modules');
|
|
192
|
+
if (await fs.pathExists(customCacheDir)) {
|
|
193
|
+
const { CustomModuleManager } = require('./modules/custom-module-manager');
|
|
194
|
+
const customMgr = new CustomModuleManager();
|
|
195
|
+
const repoRoots = await customMgr._findCacheRepoRoots(customCacheDir);
|
|
196
|
+
for (const { repoPath } of repoRoots) {
|
|
197
|
+
const candidates = await searchRootAll(repoPath);
|
|
198
|
+
for (const candidate of candidates) {
|
|
199
|
+
try {
|
|
200
|
+
const parsed = yaml.parse(await fs.readFile(candidate, 'utf8'));
|
|
201
|
+
if (parsed && (parsed.code === moduleName || parsed.name === moduleName)) {
|
|
202
|
+
return candidate;
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// Malformed yaml — skip
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
// Custom-modules cache walk failed — continue
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
module.exports = {
|
|
218
|
+
getProjectRoot,
|
|
219
|
+
getSourcePath,
|
|
220
|
+
getModulePath,
|
|
221
|
+
getExternalModuleCachePath,
|
|
222
|
+
resolveInstalledModuleYaml,
|
|
223
|
+
findProjectRoot,
|
|
224
|
+
};
|