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,167 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const fs = require('../fs-native');
|
|
3
|
+
const prompts = require('../prompts');
|
|
4
|
+
const { Installer } = require('../core/installer');
|
|
5
|
+
|
|
6
|
+
const installer = new Installer();
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
command: 'uninstall',
|
|
10
|
+
description: 'Remove DRT installation from the current project',
|
|
11
|
+
options: [
|
|
12
|
+
['-y, --yes', 'Remove all DRT components without prompting (preserves user artifacts)'],
|
|
13
|
+
['--directory <path>', 'Project directory (default: current directory)'],
|
|
14
|
+
],
|
|
15
|
+
action: async (options) => {
|
|
16
|
+
try {
|
|
17
|
+
let projectDir;
|
|
18
|
+
|
|
19
|
+
if (options.directory) {
|
|
20
|
+
// Explicit --directory flag takes precedence
|
|
21
|
+
projectDir = path.resolve(options.directory);
|
|
22
|
+
} else if (options.yes) {
|
|
23
|
+
// Non-interactive mode: use current directory
|
|
24
|
+
projectDir = process.cwd();
|
|
25
|
+
} else {
|
|
26
|
+
// Interactive: ask user which directory to uninstall from
|
|
27
|
+
// select() handles cancellation internally (exits process)
|
|
28
|
+
const dirChoice = await prompts.select({
|
|
29
|
+
message: 'Where do you want to uninstall DRT from?',
|
|
30
|
+
choices: [
|
|
31
|
+
{ value: 'cwd', name: `Current directory (${process.cwd()})` },
|
|
32
|
+
{ value: 'other', name: 'Another directory...' },
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (dirChoice === 'other') {
|
|
37
|
+
// text() handles cancellation internally (exits process)
|
|
38
|
+
const customDir = await prompts.text({
|
|
39
|
+
message: 'Enter the project directory path:',
|
|
40
|
+
placeholder: process.cwd(),
|
|
41
|
+
validate: (value) => {
|
|
42
|
+
if (!value || value.trim().length === 0) return 'Directory path is required';
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
projectDir = path.resolve(customDir.trim());
|
|
47
|
+
} else {
|
|
48
|
+
projectDir = process.cwd();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!(await fs.pathExists(projectDir))) {
|
|
53
|
+
await prompts.log.error(`Directory does not exist: ${projectDir}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { drtDir } = await installer.findDrtDir(projectDir);
|
|
58
|
+
|
|
59
|
+
if (!(await fs.pathExists(drtDir))) {
|
|
60
|
+
await prompts.log.warn('No DRT installation found.');
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const existingInstall = await installer.getStatus(projectDir);
|
|
65
|
+
const version = existingInstall.installed ? existingInstall.version : 'unknown';
|
|
66
|
+
const modules = existingInstall.moduleIds.join(', ');
|
|
67
|
+
const ides = existingInstall.ides.join(', ');
|
|
68
|
+
|
|
69
|
+
const outputFolder = await installer.getOutputFolder(projectDir);
|
|
70
|
+
|
|
71
|
+
await prompts.intro('DRT Uninstall');
|
|
72
|
+
await prompts.note(`Version: ${version}\nModules: ${modules}\nIDE integrations: ${ides}`, 'Current Installation');
|
|
73
|
+
|
|
74
|
+
let removeModules = true;
|
|
75
|
+
let removeIdeConfigs = true;
|
|
76
|
+
let removeOutputFolder = false;
|
|
77
|
+
|
|
78
|
+
if (!options.yes) {
|
|
79
|
+
// multiselect() handles cancellation internally (exits process)
|
|
80
|
+
const selected = await prompts.multiselect({
|
|
81
|
+
message: 'Select components to remove:',
|
|
82
|
+
options: [
|
|
83
|
+
{
|
|
84
|
+
value: 'modules',
|
|
85
|
+
label: `DRT Modules & data (${installer.drtFolderName}/)`,
|
|
86
|
+
hint: 'Core installation, agents, workflows, config',
|
|
87
|
+
},
|
|
88
|
+
{ value: 'ide', label: 'IDE integrations', hint: ides || 'No IDEs configured' },
|
|
89
|
+
{ value: 'output', label: `User artifacts (${outputFolder}/)`, hint: 'WARNING: Contains your work products' },
|
|
90
|
+
],
|
|
91
|
+
initialValues: ['modules', 'ide'],
|
|
92
|
+
required: true,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
removeModules = selected.includes('modules');
|
|
96
|
+
removeIdeConfigs = selected.includes('ide');
|
|
97
|
+
removeOutputFolder = selected.includes('output');
|
|
98
|
+
|
|
99
|
+
const red = (s) => `\u001B[31m${s}\u001B[0m`;
|
|
100
|
+
await prompts.note(
|
|
101
|
+
red('💀 This action is IRREVERSIBLE! Removed files cannot be recovered!') +
|
|
102
|
+
'\n' +
|
|
103
|
+
red('💀 IDE configurations and modules will need to be reinstalled.') +
|
|
104
|
+
'\n' +
|
|
105
|
+
red('💀 User artifacts are preserved unless explicitly selected.'),
|
|
106
|
+
'!! DESTRUCTIVE ACTION !!',
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const confirmed = await prompts.confirm({
|
|
110
|
+
message: 'Proceed with uninstall?',
|
|
111
|
+
default: false,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!confirmed) {
|
|
115
|
+
await prompts.outro('Uninstall cancelled.');
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Phase 1: IDE integrations
|
|
121
|
+
if (removeIdeConfigs) {
|
|
122
|
+
const s = await prompts.spinner();
|
|
123
|
+
s.start('Removing IDE integrations...');
|
|
124
|
+
await installer.uninstallIdeConfigs(projectDir, existingInstall, { silent: true });
|
|
125
|
+
s.stop(`Removed IDE integrations (${ides || 'none'})`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Phase 2: User artifacts
|
|
129
|
+
if (removeOutputFolder) {
|
|
130
|
+
const s = await prompts.spinner();
|
|
131
|
+
s.start(`Removing user artifacts (${outputFolder}/)...`);
|
|
132
|
+
await installer.uninstallOutputFolder(projectDir, outputFolder);
|
|
133
|
+
s.stop('User artifacts removed');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Phase 3: DRT modules & data (last — other phases may need _drt/)
|
|
137
|
+
if (removeModules) {
|
|
138
|
+
const s = await prompts.spinner();
|
|
139
|
+
s.start(`Removing DRT modules & data (${installer.drtFolderName}/)...`);
|
|
140
|
+
await installer.uninstallModules(projectDir);
|
|
141
|
+
s.stop('Modules & data removed');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const summary = [];
|
|
145
|
+
if (removeIdeConfigs) summary.push('IDE integrations cleaned');
|
|
146
|
+
if (removeModules) summary.push('Modules & data removed');
|
|
147
|
+
if (removeOutputFolder) summary.push('User artifacts removed');
|
|
148
|
+
if (!removeOutputFolder) summary.push(`User artifacts preserved in ${outputFolder}/`);
|
|
149
|
+
|
|
150
|
+
await prompts.note(summary.join('\n'), 'Summary');
|
|
151
|
+
await prompts.outro('To reinstall, run: npx drt-method install');
|
|
152
|
+
|
|
153
|
+
process.exit(0);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
try {
|
|
156
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
157
|
+
await prompts.log.error(`Uninstall failed: ${errorMessage}`);
|
|
158
|
+
if (error instanceof Error && error.stack) {
|
|
159
|
+
await prompts.log.message(error.stack);
|
|
160
|
+
}
|
|
161
|
+
} catch {
|
|
162
|
+
console.error(error instanceof Error ? error.message : error);
|
|
163
|
+
}
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean install configuration built from user input.
|
|
3
|
+
* User input comes from either UI answers or headless CLI flags.
|
|
4
|
+
*/
|
|
5
|
+
class Config {
|
|
6
|
+
constructor({
|
|
7
|
+
directory,
|
|
8
|
+
modules,
|
|
9
|
+
ides,
|
|
10
|
+
skipPrompts,
|
|
11
|
+
verbose,
|
|
12
|
+
actionType,
|
|
13
|
+
coreConfig,
|
|
14
|
+
moduleConfigs,
|
|
15
|
+
quickUpdate,
|
|
16
|
+
channelOptions,
|
|
17
|
+
setOverrides,
|
|
18
|
+
}) {
|
|
19
|
+
this.directory = directory;
|
|
20
|
+
this.modules = Object.freeze([...modules]);
|
|
21
|
+
this.ides = Object.freeze([...ides]);
|
|
22
|
+
this.skipPrompts = skipPrompts;
|
|
23
|
+
this.verbose = verbose;
|
|
24
|
+
this.actionType = actionType;
|
|
25
|
+
this.coreConfig = coreConfig;
|
|
26
|
+
this.moduleConfigs = moduleConfigs;
|
|
27
|
+
this._quickUpdate = quickUpdate;
|
|
28
|
+
// channelOptions carry a Map + Set; don't deep-freeze.
|
|
29
|
+
this.channelOptions = channelOptions || null;
|
|
30
|
+
// Parsed `--set <module>.<key>=<value>` overrides, applied as a TOML
|
|
31
|
+
// patch AFTER the install finishes. Shape: { moduleCode: { key: value } }.
|
|
32
|
+
// Intentionally NOT integrated with the prompt/template/schema flow; see
|
|
33
|
+
// `tools/installer/set-overrides.js` for the rationale and tradeoffs.
|
|
34
|
+
this.setOverrides = setOverrides || {};
|
|
35
|
+
Object.freeze(this);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Build a clean install config from raw user input.
|
|
40
|
+
* @param {Object} userInput - UI answers or CLI flags
|
|
41
|
+
* @returns {Config}
|
|
42
|
+
*/
|
|
43
|
+
static build(userInput) {
|
|
44
|
+
const modules = [...(userInput.modules || [])];
|
|
45
|
+
if (userInput.installCore && !modules.includes('core')) {
|
|
46
|
+
modules.unshift('core');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return new Config({
|
|
50
|
+
directory: userInput.directory,
|
|
51
|
+
modules,
|
|
52
|
+
ides: userInput.skipIde ? [] : [...(userInput.ides || [])],
|
|
53
|
+
skipPrompts: userInput.skipPrompts || false,
|
|
54
|
+
verbose: userInput.verbose || false,
|
|
55
|
+
actionType: userInput.actionType,
|
|
56
|
+
coreConfig: userInput.coreConfig || {},
|
|
57
|
+
moduleConfigs: userInput.moduleConfigs || null,
|
|
58
|
+
quickUpdate: userInput._quickUpdate || false,
|
|
59
|
+
channelOptions: userInput.channelOptions || null,
|
|
60
|
+
setOverrides: userInput.setOverrides || {},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
hasCoreConfig() {
|
|
65
|
+
return this.coreConfig && Object.keys(this.coreConfig).length > 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
isQuickUpdate() {
|
|
69
|
+
return this._quickUpdate;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = { Config };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const fs = require('../fs-native');
|
|
3
|
+
const yaml = require('yaml');
|
|
4
|
+
const { Manifest } = require('./manifest');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Immutable snapshot of an existing DRT installation.
|
|
8
|
+
* Pure query object — no filesystem operations after construction.
|
|
9
|
+
*/
|
|
10
|
+
class ExistingInstall {
|
|
11
|
+
#version;
|
|
12
|
+
|
|
13
|
+
constructor({ installed, version, hasCore, modules, ides }) {
|
|
14
|
+
this.installed = installed;
|
|
15
|
+
this.#version = version;
|
|
16
|
+
this.hasCore = hasCore;
|
|
17
|
+
this.modules = Object.freeze(modules.map((m) => Object.freeze({ ...m })));
|
|
18
|
+
this.moduleIds = Object.freeze(this.modules.map((m) => m.id));
|
|
19
|
+
this.ides = Object.freeze([...ides]);
|
|
20
|
+
Object.freeze(this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get version() {
|
|
24
|
+
if (!this.installed) {
|
|
25
|
+
throw new Error('version is not available when nothing is installed');
|
|
26
|
+
}
|
|
27
|
+
return this.#version;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static empty() {
|
|
31
|
+
return new ExistingInstall({
|
|
32
|
+
installed: false,
|
|
33
|
+
version: null,
|
|
34
|
+
hasCore: false,
|
|
35
|
+
modules: [],
|
|
36
|
+
ides: [],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Scan a drt directory and return an immutable snapshot of what's installed.
|
|
42
|
+
* @param {string} drtDir - Path to drt directory
|
|
43
|
+
* @returns {Promise<ExistingInstall>}
|
|
44
|
+
*/
|
|
45
|
+
static async detect(drtDir) {
|
|
46
|
+
if (!(await fs.pathExists(drtDir))) {
|
|
47
|
+
return ExistingInstall.empty();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let version = null;
|
|
51
|
+
let hasCore = false;
|
|
52
|
+
const modules = [];
|
|
53
|
+
let ides = [];
|
|
54
|
+
|
|
55
|
+
const manifest = new Manifest();
|
|
56
|
+
const manifestData = await manifest.read(drtDir);
|
|
57
|
+
if (manifestData) {
|
|
58
|
+
version = manifestData.version;
|
|
59
|
+
if (manifestData.ides) {
|
|
60
|
+
ides = manifestData.ides.filter((ide) => ide && typeof ide === 'string');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const corePath = path.join(drtDir, 'core');
|
|
65
|
+
if (await fs.pathExists(corePath)) {
|
|
66
|
+
hasCore = true;
|
|
67
|
+
|
|
68
|
+
if (!version) {
|
|
69
|
+
const coreConfigPath = path.join(corePath, 'config.yaml');
|
|
70
|
+
if (await fs.pathExists(coreConfigPath)) {
|
|
71
|
+
try {
|
|
72
|
+
const configContent = await fs.readFile(coreConfigPath, 'utf8');
|
|
73
|
+
const config = yaml.parse(configContent);
|
|
74
|
+
if (config.version) {
|
|
75
|
+
version = config.version;
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
// Ignore config read errors
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (manifestData && manifestData.modules && manifestData.modules.length > 0) {
|
|
85
|
+
for (const moduleId of manifestData.modules) {
|
|
86
|
+
const modulePath = path.join(drtDir, moduleId);
|
|
87
|
+
const moduleConfigPath = path.join(modulePath, 'config.yaml');
|
|
88
|
+
|
|
89
|
+
const moduleInfo = {
|
|
90
|
+
id: moduleId,
|
|
91
|
+
path: modulePath,
|
|
92
|
+
version: 'unknown',
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if (await fs.pathExists(moduleConfigPath)) {
|
|
96
|
+
try {
|
|
97
|
+
const configContent = await fs.readFile(moduleConfigPath, 'utf8');
|
|
98
|
+
const config = yaml.parse(configContent);
|
|
99
|
+
moduleInfo.version = config.version || 'unknown';
|
|
100
|
+
moduleInfo.name = config.name || moduleId;
|
|
101
|
+
moduleInfo.description = config.description;
|
|
102
|
+
} catch {
|
|
103
|
+
// Ignore config read errors
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
modules.push(moduleInfo);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const installed = hasCore || modules.length > 0 || !!manifestData;
|
|
112
|
+
|
|
113
|
+
if (!installed) {
|
|
114
|
+
return ExistingInstall.empty();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return new ExistingInstall({ installed, version, hasCore, modules, ides });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = { ExistingInstall };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const fs = require('../fs-native');
|
|
3
|
+
const { getProjectRoot } = require('../project-root');
|
|
4
|
+
const { DRT_FOLDER_NAME } = require('../ide/shared/path-utils');
|
|
5
|
+
|
|
6
|
+
class InstallPaths {
|
|
7
|
+
static async create(config) {
|
|
8
|
+
const srcDir = getProjectRoot();
|
|
9
|
+
await assertReadableDir(srcDir, 'DRT source root');
|
|
10
|
+
|
|
11
|
+
const pkgPath = path.join(srcDir, 'package.json');
|
|
12
|
+
await assertReadableFile(pkgPath, 'package.json');
|
|
13
|
+
const version = require(pkgPath).version;
|
|
14
|
+
|
|
15
|
+
const projectRoot = path.resolve(config.directory);
|
|
16
|
+
await ensureWritableDir(projectRoot, 'project root');
|
|
17
|
+
|
|
18
|
+
const drtDir = path.join(projectRoot, DRT_FOLDER_NAME);
|
|
19
|
+
const isUpdate = await fs.pathExists(drtDir);
|
|
20
|
+
|
|
21
|
+
const configDir = path.join(drtDir, '_config');
|
|
22
|
+
const coreDir = path.join(drtDir, 'core');
|
|
23
|
+
const scriptsDir = path.join(drtDir, 'scripts');
|
|
24
|
+
const customDir = path.join(drtDir, 'custom');
|
|
25
|
+
|
|
26
|
+
for (const [dir, label] of [
|
|
27
|
+
[drtDir, 'drt directory'],
|
|
28
|
+
[configDir, 'config directory'],
|
|
29
|
+
[coreDir, 'core module directory'],
|
|
30
|
+
[scriptsDir, 'shared scripts directory'],
|
|
31
|
+
[customDir, 'customizations directory'],
|
|
32
|
+
]) {
|
|
33
|
+
await ensureWritableDir(dir, label);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return new InstallPaths({
|
|
37
|
+
srcDir,
|
|
38
|
+
version,
|
|
39
|
+
projectRoot,
|
|
40
|
+
drtDir,
|
|
41
|
+
configDir,
|
|
42
|
+
coreDir,
|
|
43
|
+
scriptsDir,
|
|
44
|
+
customDir,
|
|
45
|
+
isUpdate,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
constructor(props) {
|
|
50
|
+
Object.assign(this, props);
|
|
51
|
+
Object.freeze(this);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
manifestFile() {
|
|
55
|
+
return path.join(this.configDir, 'manifest.yaml');
|
|
56
|
+
}
|
|
57
|
+
centralConfig() {
|
|
58
|
+
return path.join(this.drtDir, 'config.toml');
|
|
59
|
+
}
|
|
60
|
+
centralUserConfig() {
|
|
61
|
+
return path.join(this.drtDir, 'config.user.toml');
|
|
62
|
+
}
|
|
63
|
+
filesManifest() {
|
|
64
|
+
return path.join(this.configDir, 'files-manifest.csv');
|
|
65
|
+
}
|
|
66
|
+
helpCatalog() {
|
|
67
|
+
return path.join(this.configDir, 'drt-help.csv');
|
|
68
|
+
}
|
|
69
|
+
moduleDir(name) {
|
|
70
|
+
return path.join(this.drtDir, name);
|
|
71
|
+
}
|
|
72
|
+
moduleConfig(name) {
|
|
73
|
+
return path.join(this.drtDir, name, 'config.yaml');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function assertReadableDir(dirPath, label) {
|
|
78
|
+
const stat = await fs.stat(dirPath).catch(() => null);
|
|
79
|
+
if (!stat) {
|
|
80
|
+
throw new Error(`${label} does not exist: ${dirPath}`);
|
|
81
|
+
}
|
|
82
|
+
if (!stat.isDirectory()) {
|
|
83
|
+
throw new Error(`${label} is not a directory: ${dirPath}`);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
await fs.access(dirPath, fs.constants.R_OK);
|
|
87
|
+
} catch {
|
|
88
|
+
throw new Error(`${label} is not readable: ${dirPath}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function assertReadableFile(filePath, label) {
|
|
93
|
+
const stat = await fs.stat(filePath).catch(() => null);
|
|
94
|
+
if (!stat) {
|
|
95
|
+
throw new Error(`${label} does not exist: ${filePath}`);
|
|
96
|
+
}
|
|
97
|
+
if (!stat.isFile()) {
|
|
98
|
+
throw new Error(`${label} is not a file: ${filePath}`);
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
await fs.access(filePath, fs.constants.R_OK);
|
|
102
|
+
} catch {
|
|
103
|
+
throw new Error(`${label} is not readable: ${filePath}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function ensureWritableDir(dirPath, label) {
|
|
108
|
+
const stat = await fs.stat(dirPath).catch(() => null);
|
|
109
|
+
if (stat && !stat.isDirectory()) {
|
|
110
|
+
throw new Error(`${label} exists but is not a directory: ${dirPath}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
await fs.ensureDir(dirPath);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error.code === 'EACCES') {
|
|
117
|
+
throw new Error(`${label}: permission denied creating directory: ${dirPath}`);
|
|
118
|
+
}
|
|
119
|
+
if (error.code === 'ENOSPC') {
|
|
120
|
+
throw new Error(`${label}: no space left on device: ${dirPath}`);
|
|
121
|
+
}
|
|
122
|
+
throw new Error(`${label}: cannot create directory: ${dirPath} (${error.message})`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
await fs.access(dirPath, fs.constants.R_OK | fs.constants.W_OK);
|
|
127
|
+
} catch {
|
|
128
|
+
throw new Error(`${label} is not writable: ${dirPath}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = { InstallPaths };
|