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.
Files changed (299) hide show
  1. package/AGENTS.md +45 -0
  2. package/GETTING-STARTED.md +269 -0
  3. package/README.md +233 -0
  4. package/drt-method-1.0.0.tgz +0 -0
  5. package/drt-modules.yaml +1 -0
  6. package/package.json +51 -0
  7. package/scripts/install-from-github.ps1 +22 -0
  8. package/scripts/install-from-github.sh +17 -0
  9. package/src/core-skills/drt-advanced-elicitation/SKILL.md +142 -0
  10. package/src/core-skills/drt-advanced-elicitation/methods.csv +72 -0
  11. package/src/core-skills/drt-brainstorming/SKILL.md +80 -0
  12. package/src/core-skills/drt-brainstorming/assets/brain-icons.json +166 -0
  13. package/src/core-skills/drt-brainstorming/assets/brain-methods.csv +109 -0
  14. package/src/core-skills/drt-brainstorming/assets/brain-selector.html +326 -0
  15. package/src/core-skills/drt-brainstorming/customize.toml +84 -0
  16. package/src/core-skills/drt-brainstorming/references/converge.md +24 -0
  17. package/src/core-skills/drt-brainstorming/references/finalize.md +26 -0
  18. package/src/core-skills/drt-brainstorming/references/headless.md +54 -0
  19. package/src/core-skills/drt-brainstorming/references/in-chat-techniques.md +18 -0
  20. package/src/core-skills/drt-brainstorming/references/mode-autonomous.md +10 -0
  21. package/src/core-skills/drt-brainstorming/references/mode-facilitator.md +11 -0
  22. package/src/core-skills/drt-brainstorming/references/mode-partner.md +16 -0
  23. package/src/core-skills/drt-brainstorming/references/resume.md +5 -0
  24. package/src/core-skills/drt-brainstorming/scripts/brain.py +740 -0
  25. package/src/core-skills/drt-customize/SKILL.md +111 -0
  26. package/src/core-skills/drt-customize/scripts/list_customizable_skills.py +231 -0
  27. package/src/core-skills/drt-editorial-review-prose/SKILL.md +86 -0
  28. package/src/core-skills/drt-editorial-review-structure/SKILL.md +179 -0
  29. package/src/core-skills/drt-forge-idea/SKILL.md +107 -0
  30. package/src/core-skills/drt-forge-idea/customize.toml +42 -0
  31. package/src/core-skills/drt-forge-idea/scripts/resolve_personas.py +270 -0
  32. package/src/core-skills/drt-help/SKILL.md +75 -0
  33. package/src/core-skills/drt-index-docs/SKILL.md +66 -0
  34. package/src/core-skills/drt-party-mode/SKILL.md +60 -0
  35. package/src/core-skills/drt-party-mode/customize.toml +211 -0
  36. package/src/core-skills/drt-party-mode/references/create-party.md +70 -0
  37. package/src/core-skills/drt-party-mode/references/mode-agent-team.md +13 -0
  38. package/src/core-skills/drt-party-mode/references/mode-auto.md +13 -0
  39. package/src/core-skills/drt-party-mode/references/mode-subagent.md +31 -0
  40. package/src/core-skills/drt-party-mode/references/party-memory.md +51 -0
  41. package/src/core-skills/drt-party-mode/scripts/resolve_party.py +272 -0
  42. package/src/core-skills/drt-review-adversarial-general/SKILL.md +37 -0
  43. package/src/core-skills/drt-review-edge-case-hunter/SKILL.md +73 -0
  44. package/src/core-skills/drt-review-edge-case-hunter/references/deletion-check.md +14 -0
  45. package/src/core-skills/drt-review-verification-gap/SKILL.md +106 -0
  46. package/src/core-skills/drt-shard-doc/SKILL.md +105 -0
  47. package/src/core-skills/drt-spec/SKILL.md +160 -0
  48. package/src/core-skills/drt-spec/assets/headless-schemas.md +33 -0
  49. package/src/core-skills/drt-spec/assets/spec-template.md +49 -0
  50. package/src/core-skills/drt-spec/assets/stories-schema.md +44 -0
  51. package/src/core-skills/drt-spec/customize.toml +53 -0
  52. package/src/core-skills/module-help.csv +14 -0
  53. package/src/core-skills/module.yaml +33 -0
  54. package/src/drt-skills/1-analysis/drt-agent-analyst/SKILL.md +76 -0
  55. package/src/drt-skills/1-analysis/drt-agent-analyst/customize.toml +90 -0
  56. package/src/drt-skills/1-analysis/drt-agent-tech-writer/SKILL.md +76 -0
  57. package/src/drt-skills/1-analysis/drt-agent-tech-writer/customize.toml +81 -0
  58. package/src/drt-skills/1-analysis/drt-agent-tech-writer/explain-concept.md +20 -0
  59. package/src/drt-skills/1-analysis/drt-agent-tech-writer/mermaid-gen.md +20 -0
  60. package/src/drt-skills/1-analysis/drt-agent-tech-writer/validate-doc.md +19 -0
  61. package/src/drt-skills/1-analysis/drt-agent-tech-writer/write-document.md +20 -0
  62. package/src/drt-skills/1-analysis/drt-document-project/SKILL.md +62 -0
  63. package/src/drt-skills/1-analysis/drt-document-project/checklist.md +245 -0
  64. package/src/drt-skills/1-analysis/drt-document-project/customize.toml +41 -0
  65. package/src/drt-skills/1-analysis/drt-document-project/documentation-requirements.csv +12 -0
  66. package/src/drt-skills/1-analysis/drt-document-project/instructions.md +128 -0
  67. package/src/drt-skills/1-analysis/drt-document-project/templates/deep-dive-template.md +345 -0
  68. package/src/drt-skills/1-analysis/drt-document-project/templates/index-template.md +169 -0
  69. package/src/drt-skills/1-analysis/drt-document-project/templates/project-overview-template.md +103 -0
  70. package/src/drt-skills/1-analysis/drt-document-project/templates/project-scan-report-schema.json +160 -0
  71. package/src/drt-skills/1-analysis/drt-document-project/templates/source-tree-template.md +135 -0
  72. package/src/drt-skills/1-analysis/drt-document-project/workflows/deep-dive-instructions.md +300 -0
  73. package/src/drt-skills/1-analysis/drt-document-project/workflows/deep-dive-workflow.md +34 -0
  74. package/src/drt-skills/1-analysis/drt-document-project/workflows/full-scan-instructions.md +1111 -0
  75. package/src/drt-skills/1-analysis/drt-document-project/workflows/full-scan-workflow.md +34 -0
  76. package/src/drt-skills/1-analysis/drt-prfaq/SKILL.md +135 -0
  77. package/src/drt-skills/1-analysis/drt-prfaq/agents/artifact-analyzer.md +60 -0
  78. package/src/drt-skills/1-analysis/drt-prfaq/agents/web-researcher.md +49 -0
  79. package/src/drt-skills/1-analysis/drt-prfaq/assets/prfaq-template.md +62 -0
  80. package/src/drt-skills/1-analysis/drt-prfaq/bmad-manifest.json +16 -0
  81. package/src/drt-skills/1-analysis/drt-prfaq/customize.toml +41 -0
  82. package/src/drt-skills/1-analysis/drt-prfaq/references/customer-faq.md +55 -0
  83. package/src/drt-skills/1-analysis/drt-prfaq/references/internal-faq.md +51 -0
  84. package/src/drt-skills/1-analysis/drt-prfaq/references/press-release.md +60 -0
  85. package/src/drt-skills/1-analysis/drt-prfaq/references/verdict.md +83 -0
  86. package/src/drt-skills/1-analysis/drt-product-brief/SKILL.md +91 -0
  87. package/src/drt-skills/1-analysis/drt-product-brief/assets/brief-template.md +41 -0
  88. package/src/drt-skills/1-analysis/drt-product-brief/customize.toml +99 -0
  89. package/src/drt-skills/1-analysis/research/drt-domain-research/SKILL.md +96 -0
  90. package/src/drt-skills/1-analysis/research/drt-domain-research/customize.toml +41 -0
  91. package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-01-init.md +137 -0
  92. package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-02-domain-analysis.md +229 -0
  93. package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-03-competitive-landscape.md +238 -0
  94. package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-04-regulatory-focus.md +206 -0
  95. package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-05-technical-trends.md +234 -0
  96. package/src/drt-skills/1-analysis/research/drt-domain-research/domain-steps/step-06-research-synthesis.md +450 -0
  97. package/src/drt-skills/1-analysis/research/drt-domain-research/research.template.md +29 -0
  98. package/src/drt-skills/1-analysis/research/drt-market-research/SKILL.md +96 -0
  99. package/src/drt-skills/1-analysis/research/drt-market-research/customize.toml +41 -0
  100. package/src/drt-skills/1-analysis/research/drt-market-research/research.template.md +29 -0
  101. package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-01-init.md +184 -0
  102. package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-02-customer-behavior.md +239 -0
  103. package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-03-customer-pain-points.md +251 -0
  104. package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-04-customer-decisions.md +261 -0
  105. package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-05-competitive-analysis.md +173 -0
  106. package/src/drt-skills/1-analysis/research/drt-market-research/steps/step-06-research-completion.md +484 -0
  107. package/src/drt-skills/1-analysis/research/drt-technical-research/SKILL.md +96 -0
  108. package/src/drt-skills/1-analysis/research/drt-technical-research/customize.toml +41 -0
  109. package/src/drt-skills/1-analysis/research/drt-technical-research/research.template.md +29 -0
  110. package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-01-init.md +137 -0
  111. package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-02-technical-overview.md +239 -0
  112. package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-03-integration-patterns.md +248 -0
  113. package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-04-architectural-patterns.md +202 -0
  114. package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-05-implementation-research.md +233 -0
  115. package/src/drt-skills/1-analysis/research/drt-technical-research/technical-steps/step-06-research-synthesis.md +493 -0
  116. package/src/drt-skills/2-plan-workflows/drt-agent-pm/SKILL.md +76 -0
  117. package/src/drt-skills/2-plan-workflows/drt-agent-pm/customize.toml +75 -0
  118. package/src/drt-skills/2-plan-workflows/drt-agent-ux-designer/SKILL.md +76 -0
  119. package/src/drt-skills/2-plan-workflows/drt-agent-ux-designer/customize.toml +60 -0
  120. package/src/drt-skills/2-plan-workflows/drt-create-prd/SKILL.md +30 -0
  121. package/src/drt-skills/2-plan-workflows/drt-create-prd/customize.toml +41 -0
  122. package/src/drt-skills/2-plan-workflows/drt-edit-prd/SKILL.md +30 -0
  123. package/src/drt-skills/2-plan-workflows/drt-edit-prd/customize.toml +42 -0
  124. package/src/drt-skills/2-plan-workflows/drt-prd/SKILL.md +92 -0
  125. package/src/drt-skills/2-plan-workflows/drt-prd/assets/headless-schemas.md +76 -0
  126. package/src/drt-skills/2-plan-workflows/drt-prd/assets/prd-template.md +165 -0
  127. package/src/drt-skills/2-plan-workflows/drt-prd/assets/prd-validation-checklist.md +135 -0
  128. package/src/drt-skills/2-plan-workflows/drt-prd/assets/validation-report-template.html +325 -0
  129. package/src/drt-skills/2-plan-workflows/drt-prd/customize.toml +147 -0
  130. package/src/drt-skills/2-plan-workflows/drt-prd/references/headless.md +39 -0
  131. package/src/drt-skills/2-plan-workflows/drt-prd/references/validate.md +97 -0
  132. package/src/drt-skills/2-plan-workflows/drt-ux/SKILL.md +90 -0
  133. package/src/drt-skills/2-plan-workflows/drt-ux/assets/color-themes.md +9 -0
  134. package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-directions.md +9 -0
  135. package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-example-editorial.md +158 -0
  136. package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-example-mobile.md +93 -0
  137. package/src/drt-skills/2-plan-workflows/drt-ux/assets/design-example-shadcn.md +109 -0
  138. package/src/drt-skills/2-plan-workflows/drt-ux/assets/excalidraw-wireframe.md +19 -0
  139. package/src/drt-skills/2-plan-workflows/drt-ux/assets/experience-example-mobile.md +112 -0
  140. package/src/drt-skills/2-plan-workflows/drt-ux/assets/experience-example-shadcn.md +133 -0
  141. package/src/drt-skills/2-plan-workflows/drt-ux/assets/headless-schemas.md +84 -0
  142. package/src/drt-skills/2-plan-workflows/drt-ux/assets/key-screens.md +29 -0
  143. package/src/drt-skills/2-plan-workflows/drt-ux/assets/validation-report-template.html +319 -0
  144. package/src/drt-skills/2-plan-workflows/drt-ux/customize.toml +100 -0
  145. package/src/drt-skills/2-plan-workflows/drt-ux/references/creative-tools.md +19 -0
  146. package/src/drt-skills/2-plan-workflows/drt-ux/references/design-md-spec.md +50 -0
  147. package/src/drt-skills/2-plan-workflows/drt-ux/references/headless.md +37 -0
  148. package/src/drt-skills/2-plan-workflows/drt-ux/references/validate.md +115 -0
  149. package/src/drt-skills/2-plan-workflows/drt-validate-prd/SKILL.md +30 -0
  150. package/src/drt-skills/2-plan-workflows/drt-validate-prd/customize.toml +42 -0
  151. package/src/drt-skills/3-solutioning/drt-agent-architect/SKILL.md +76 -0
  152. package/src/drt-skills/3-solutioning/drt-agent-architect/customize.toml +65 -0
  153. package/src/drt-skills/3-solutioning/drt-architecture/SKILL.md +85 -0
  154. package/src/drt-skills/3-solutioning/drt-architecture/assets/spine-template.md +79 -0
  155. package/src/drt-skills/3-solutioning/drt-architecture/customize.toml +100 -0
  156. package/src/drt-skills/3-solutioning/drt-architecture/references/headless.md +26 -0
  157. package/src/drt-skills/3-solutioning/drt-architecture/references/reviewer-gate.md +13 -0
  158. package/src/drt-skills/3-solutioning/drt-architecture/scripts/lint_spine.py +257 -0
  159. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/SKILL.md +91 -0
  160. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/customize.toml +41 -0
  161. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-01-document-discovery.md +179 -0
  162. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-02-prd-analysis.md +168 -0
  163. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +169 -0
  164. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-04-ux-alignment.md +129 -0
  165. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-05-epic-quality-review.md +241 -0
  166. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/steps/step-06-final-assessment.md +132 -0
  167. package/src/drt-skills/3-solutioning/drt-check-implementation-readiness/templates/readiness-report-template.md +4 -0
  168. package/src/drt-skills/3-solutioning/drt-create-architecture/SKILL.md +30 -0
  169. package/src/drt-skills/3-solutioning/drt-create-architecture/customize.toml +41 -0
  170. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/SKILL.md +93 -0
  171. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/customize.toml +41 -0
  172. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-01-validate-prerequisites.md +263 -0
  173. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-02-design-epics.md +242 -0
  174. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
  175. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/steps/step-04-final-validation.md +143 -0
  176. package/src/drt-skills/3-solutioning/drt-create-epics-and-stories/templates/epics-template.md +61 -0
  177. package/src/drt-skills/3-solutioning/drt-generate-project-context/SKILL.md +81 -0
  178. package/src/drt-skills/3-solutioning/drt-generate-project-context/customize.toml +41 -0
  179. package/src/drt-skills/3-solutioning/drt-generate-project-context/project-context-template.md +21 -0
  180. package/src/drt-skills/3-solutioning/drt-generate-project-context/steps/step-01-discover.md +186 -0
  181. package/src/drt-skills/3-solutioning/drt-generate-project-context/steps/step-02-generate.md +321 -0
  182. package/src/drt-skills/3-solutioning/drt-generate-project-context/steps/step-03-complete.md +284 -0
  183. package/src/drt-skills/4-implementation/drt-agent-dev/SKILL.md +76 -0
  184. package/src/drt-skills/4-implementation/drt-agent-dev/customize.toml +95 -0
  185. package/src/drt-skills/4-implementation/drt-checkpoint-preview/SKILL.md +68 -0
  186. package/src/drt-skills/4-implementation/drt-checkpoint-preview/customize.toml +41 -0
  187. package/src/drt-skills/4-implementation/drt-checkpoint-preview/generate-trail.md +38 -0
  188. package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-01-orientation.md +105 -0
  189. package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-02-walkthrough.md +89 -0
  190. package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-03-detail-pass.md +106 -0
  191. package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-04-testing.md +74 -0
  192. package/src/drt-skills/4-implementation/drt-checkpoint-preview/step-05-wrapup.md +30 -0
  193. package/src/drt-skills/4-implementation/drt-code-review/SKILL.md +90 -0
  194. package/src/drt-skills/4-implementation/drt-code-review/customize.toml +93 -0
  195. package/src/drt-skills/4-implementation/drt-code-review/steps/step-01-gather-context.md +84 -0
  196. package/src/drt-skills/4-implementation/drt-code-review/steps/step-02-review.md +32 -0
  197. package/src/drt-skills/4-implementation/drt-code-review/steps/step-03-triage.md +50 -0
  198. package/src/drt-skills/4-implementation/drt-code-review/steps/step-04-present.md +132 -0
  199. package/src/drt-skills/4-implementation/drt-correct-course/SKILL.md +301 -0
  200. package/src/drt-skills/4-implementation/drt-correct-course/checklist.md +288 -0
  201. package/src/drt-skills/4-implementation/drt-correct-course/customize.toml +41 -0
  202. package/src/drt-skills/4-implementation/drt-create-story/SKILL.md +432 -0
  203. package/src/drt-skills/4-implementation/drt-create-story/checklist.md +357 -0
  204. package/src/drt-skills/4-implementation/drt-create-story/customize.toml +41 -0
  205. package/src/drt-skills/4-implementation/drt-create-story/discover-inputs.md +88 -0
  206. package/src/drt-skills/4-implementation/drt-create-story/template.md +49 -0
  207. package/src/drt-skills/4-implementation/drt-dev-auto/SKILL.md +123 -0
  208. package/src/drt-skills/4-implementation/drt-dev-auto/compile-epic-context.md +62 -0
  209. package/src/drt-skills/4-implementation/drt-dev-auto/customize.toml +108 -0
  210. package/src/drt-skills/4-implementation/drt-dev-auto/spec-template.md +98 -0
  211. package/src/drt-skills/4-implementation/drt-dev-auto/step-01-clarify-and-route.md +84 -0
  212. package/src/drt-skills/4-implementation/drt-dev-auto/step-02-plan.md +31 -0
  213. package/src/drt-skills/4-implementation/drt-dev-auto/step-03-implement.md +42 -0
  214. package/src/drt-skills/4-implementation/drt-dev-auto/step-04-review.md +95 -0
  215. package/src/drt-skills/4-implementation/drt-dev-story/SKILL.md +500 -0
  216. package/src/drt-skills/4-implementation/drt-dev-story/checklist.md +80 -0
  217. package/src/drt-skills/4-implementation/drt-dev-story/customize.toml +41 -0
  218. package/src/drt-skills/4-implementation/drt-implement-task/SKILL.md +101 -0
  219. package/src/drt-skills/4-implementation/drt-implement-task/assets/task-spec-template.md +60 -0
  220. package/src/drt-skills/4-implementation/drt-implement-task/customize.toml +17 -0
  221. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-01-gather-intent.md +42 -0
  222. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-02-plan-and-approve.md +43 -0
  223. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-03-confirm-dependencies.md +38 -0
  224. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-04-implement.md +42 -0
  225. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-05-qc-test.md +31 -0
  226. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-06-quality-review.md +30 -0
  227. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-07-fix-findings.md +33 -0
  228. package/src/drt-skills/4-implementation/drt-implement-task/steps/step-08-complete.md +35 -0
  229. package/src/drt-skills/4-implementation/drt-qa-generate-e2e-tests/SKILL.md +176 -0
  230. package/src/drt-skills/4-implementation/drt-qa-generate-e2e-tests/checklist.md +33 -0
  231. package/src/drt-skills/4-implementation/drt-qa-generate-e2e-tests/customize.toml +41 -0
  232. package/src/drt-skills/4-implementation/drt-quick-dev/SKILL.md +13 -0
  233. package/src/drt-skills/4-implementation/drt-quick-dev/compile-epic-context.md +62 -0
  234. package/src/drt-skills/4-implementation/drt-quick-dev/customize.toml +83 -0
  235. package/src/drt-skills/4-implementation/drt-quick-dev/render.js +206 -0
  236. package/src/drt-skills/4-implementation/drt-quick-dev/spec-template.md +89 -0
  237. package/src/drt-skills/4-implementation/drt-quick-dev/step-01-clarify-and-route.md +103 -0
  238. package/src/drt-skills/4-implementation/drt-quick-dev/step-02-plan.md +47 -0
  239. package/src/drt-skills/4-implementation/drt-quick-dev/step-03-implement.md +45 -0
  240. package/src/drt-skills/4-implementation/drt-quick-dev/step-04-review.md +55 -0
  241. package/src/drt-skills/4-implementation/drt-quick-dev/step-05-present.md +78 -0
  242. package/src/drt-skills/4-implementation/drt-quick-dev/step-oneshot.md +78 -0
  243. package/src/drt-skills/4-implementation/drt-quick-dev/sync-sprint-status.md +19 -0
  244. package/src/drt-skills/4-implementation/drt-quick-dev/workflow.md +85 -0
  245. package/src/drt-skills/4-implementation/drt-retrospective/SKILL.md +1527 -0
  246. package/src/drt-skills/4-implementation/drt-retrospective/customize.toml +41 -0
  247. package/src/drt-skills/4-implementation/drt-sprint-planning/SKILL.md +319 -0
  248. package/src/drt-skills/4-implementation/drt-sprint-planning/checklist.md +34 -0
  249. package/src/drt-skills/4-implementation/drt-sprint-planning/customize.toml +41 -0
  250. package/src/drt-skills/4-implementation/drt-sprint-planning/sprint-status-template.yaml +69 -0
  251. package/src/drt-skills/4-implementation/drt-sprint-status/SKILL.md +311 -0
  252. package/src/drt-skills/4-implementation/drt-sprint-status/customize.toml +41 -0
  253. package/src/drt-skills/module-help.csv +32 -0
  254. package/src/drt-skills/module.yaml +95 -0
  255. package/src/scripts/lib/load-toml.js +43 -0
  256. package/src/scripts/lib/merge-utils.js +89 -0
  257. package/src/scripts/memlog.js +184 -0
  258. package/src/scripts/package.json +7 -0
  259. package/src/scripts/resolve-config.js +56 -0
  260. package/src/scripts/resolve-customization.js +77 -0
  261. package/tools/installer/cli-utils.js +53 -0
  262. package/tools/installer/commands/install.js +149 -0
  263. package/tools/installer/commands/status.js +65 -0
  264. package/tools/installer/commands/uninstall.js +167 -0
  265. package/tools/installer/core/config.js +73 -0
  266. package/tools/installer/core/existing-install.js +121 -0
  267. package/tools/installer/core/install-paths.js +132 -0
  268. package/tools/installer/core/installer.js +1762 -0
  269. package/tools/installer/core/legacy-warnings.js +151 -0
  270. package/tools/installer/core/manifest-generator.js +859 -0
  271. package/tools/installer/core/manifest.js +433 -0
  272. package/tools/installer/core/uv-check.js +97 -0
  273. package/tools/installer/core/wsl-node-check.js +109 -0
  274. package/tools/installer/drt-cli.js +104 -0
  275. package/tools/installer/file-ops.js +204 -0
  276. package/tools/installer/fs-native.js +116 -0
  277. package/tools/installer/ide/_config-driven.js +972 -0
  278. package/tools/installer/ide/manager.js +324 -0
  279. package/tools/installer/ide/platform-codes.js +80 -0
  280. package/tools/installer/ide/platform-codes.yaml +343 -0
  281. package/tools/installer/ide/shared/installed-skills.js +50 -0
  282. package/tools/installer/ide/shared/path-utils.js +217 -0
  283. package/tools/installer/ide/shared/skill-manifest.js +57 -0
  284. package/tools/installer/install-messages.yaml +29 -0
  285. package/tools/installer/list-options.js +210 -0
  286. package/tools/installer/message-loader.js +83 -0
  287. package/tools/installer/modules/channel-plan.js +203 -0
  288. package/tools/installer/modules/channel-resolver.js +241 -0
  289. package/tools/installer/modules/custom-module-manager.js +918 -0
  290. package/tools/installer/modules/external-manager.js +667 -0
  291. package/tools/installer/modules/module-help-schema.js +13 -0
  292. package/tools/installer/modules/official-modules.js +2257 -0
  293. package/tools/installer/modules/plugin-resolver.js +398 -0
  294. package/tools/installer/modules/version-resolver.js +336 -0
  295. package/tools/installer/project-root.js +224 -0
  296. package/tools/installer/prompts.js +852 -0
  297. package/tools/installer/set-overrides.js +330 -0
  298. package/tools/installer/ui.js +2090 -0
  299. package/tools/installer/yaml-format.js +245 -0
@@ -0,0 +1,433 @@
1
+ const path = require('node:path');
2
+ const https = require('node:https');
3
+ const { execFile } = require('node:child_process');
4
+ const { promisify } = require('node:util');
5
+ const fs = require('../fs-native');
6
+ const crypto = require('node:crypto');
7
+ const { resolveModuleVersion } = require('../modules/version-resolver');
8
+ const prompts = require('../prompts');
9
+
10
+ const execFileAsync = promisify(execFile);
11
+ const NPM_LOOKUP_TIMEOUT_MS = 10_000;
12
+ const NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
13
+
14
+ function isValidNpmPackageName(packageName) {
15
+ return typeof packageName === 'string' && NPM_PACKAGE_NAME_PATTERN.test(packageName);
16
+ }
17
+
18
+ class Manifest {
19
+ /**
20
+ * Create a new manifest
21
+ * @param {string} drtDir - Path to drt directory
22
+ * @param {Object} data - Manifest data
23
+ * @param {Array} installedFiles - List of installed files (no longer used, files tracked in files-manifest.csv)
24
+ */
25
+ async create(drtDir, data, installedFiles = []) {
26
+ const manifestPath = path.join(drtDir, '_config', 'manifest.yaml');
27
+ const yaml = require('yaml');
28
+
29
+ // Ensure _config directory exists
30
+ await fs.ensureDir(path.dirname(manifestPath));
31
+
32
+ // Get the DRT version from package.json
33
+ const drtVersion = data.version || require(path.join(process.cwd(), 'package.json')).version;
34
+
35
+ // Convert module list to new detailed format
36
+ const moduleDetails = [];
37
+ if (data.modules && Array.isArray(data.modules)) {
38
+ for (const moduleName of data.modules) {
39
+ // Core and BMM modules use the DRT version
40
+ const moduleVersion = moduleName === 'core' || moduleName === 'drt' ? drtVersion : null;
41
+ const now = data.installDate || new Date().toISOString();
42
+
43
+ moduleDetails.push({
44
+ name: moduleName,
45
+ version: moduleVersion,
46
+ installDate: now,
47
+ lastUpdated: now,
48
+ source: moduleName === 'core' || moduleName === 'drt' ? 'built-in' : 'unknown',
49
+ });
50
+ }
51
+ }
52
+
53
+ // Structure the manifest data
54
+ const manifestData = {
55
+ installation: {
56
+ version: drtVersion,
57
+ installDate: data.installDate || new Date().toISOString(),
58
+ lastUpdated: data.lastUpdated || new Date().toISOString(),
59
+ },
60
+ modules: moduleDetails,
61
+ ides: data.ides || [],
62
+ };
63
+
64
+ // Write YAML manifest
65
+ // Clean the manifest data to remove any non-serializable values
66
+ const cleanManifestData = structuredClone(manifestData);
67
+
68
+ const yamlContent = yaml.stringify(cleanManifestData, {
69
+ indent: 2,
70
+ lineWidth: 0,
71
+ sortKeys: false,
72
+ });
73
+
74
+ // Ensure POSIX-compliant final newline
75
+ const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
76
+ await fs.writeFile(manifestPath, content, 'utf8');
77
+ return { success: true, path: manifestPath, filesTracked: 0 };
78
+ }
79
+
80
+ /**
81
+ * Read existing manifest
82
+ * @param {string} drtDir - Path to drt directory
83
+ * @returns {Object|null} Manifest data or null if not found
84
+ */
85
+ async read(drtDir) {
86
+ const yamlPath = path.join(drtDir, '_config', 'manifest.yaml');
87
+ const yaml = require('yaml');
88
+
89
+ if (await fs.pathExists(yamlPath)) {
90
+ try {
91
+ const content = await fs.readFile(yamlPath, 'utf8');
92
+ const manifestData = yaml.parse(content);
93
+
94
+ // Handle new detailed module format
95
+ const modules = manifestData.modules || [];
96
+
97
+ // For backward compatibility: if modules is an array of strings (old format),
98
+ // the calling code may need the array of names
99
+ const moduleNames = modules.map((m) => (typeof m === 'string' ? m : m.name));
100
+
101
+ // Check if we have the new detailed format
102
+ const hasDetailedModules = modules.length > 0 && typeof modules[0] === 'object';
103
+
104
+ // Flatten the structure for compatibility with existing code
105
+ return {
106
+ version: manifestData.installation?.version,
107
+ installDate: manifestData.installation?.installDate,
108
+ lastUpdated: manifestData.installation?.lastUpdated,
109
+ modules: moduleNames, // Simple array of module names for backward compatibility
110
+ modulesDetailed: hasDetailedModules ? modules : null, // New detailed format
111
+ ides: manifestData.ides || [],
112
+ };
113
+ } catch (error) {
114
+ await prompts.log.error(`Failed to read YAML manifest: ${error.message}`);
115
+ }
116
+ }
117
+
118
+ return null;
119
+ }
120
+
121
+ /**
122
+ * Read raw manifest data without flattening
123
+ * @param {string} drtDir - Path to drt directory
124
+ * @returns {Object|null} Raw manifest data or null if not found
125
+ */
126
+ async _readRaw(drtDir) {
127
+ const yamlPath = path.join(drtDir, '_config', 'manifest.yaml');
128
+ const yaml = require('yaml');
129
+
130
+ if (await fs.pathExists(yamlPath)) {
131
+ try {
132
+ const content = await fs.readFile(yamlPath, 'utf8');
133
+ return yaml.parse(content);
134
+ } catch (error) {
135
+ await prompts.log.error(`Failed to read YAML manifest: ${error.message}`);
136
+ }
137
+ }
138
+
139
+ return null;
140
+ }
141
+
142
+ /**
143
+ * Flatten manifest for backward compatibility
144
+ * @param {Object} manifest - Raw manifest data
145
+ * @returns {Object} Flattened manifest
146
+ */
147
+ _flattenManifest(manifest) {
148
+ const modules = manifest.modules || [];
149
+ const moduleNames = modules.map((m) => (typeof m === 'string' ? m : m.name));
150
+ const hasDetailedModules = modules.length > 0 && typeof modules[0] === 'object';
151
+
152
+ return {
153
+ version: manifest.installation?.version,
154
+ installDate: manifest.installation?.installDate,
155
+ lastUpdated: manifest.installation?.lastUpdated,
156
+ modules: moduleNames,
157
+ modulesDetailed: hasDetailedModules ? modules : null,
158
+ ides: manifest.ides || [],
159
+ };
160
+ }
161
+
162
+ /**
163
+ * Add a module to the manifest with optional version info
164
+ * If module already exists, update its version info
165
+ * @param {string} drtDir - Path to drt directory
166
+ * @param {string} moduleName - Module name to add
167
+ * @param {Object} options - Optional version info
168
+ */
169
+ async addModule(drtDir, moduleName, options = {}) {
170
+ let manifest = await this._readRaw(drtDir);
171
+ if (!manifest) {
172
+ // Bootstrap a minimal manifest if it doesn't exist yet
173
+ // (e.g., skill-only modules with no agents to compile)
174
+ manifest = { modules: [] };
175
+ }
176
+
177
+ if (!manifest.modules) {
178
+ manifest.modules = [];
179
+ }
180
+
181
+ const existingIndex = manifest.modules.findIndex((m) => m.name === moduleName);
182
+
183
+ if (existingIndex === -1) {
184
+ // Module doesn't exist, add it
185
+ const entry = {
186
+ name: moduleName,
187
+ version: options.version || null,
188
+ installDate: new Date().toISOString(),
189
+ lastUpdated: new Date().toISOString(),
190
+ source: options.source || 'unknown',
191
+ npmPackage: options.npmPackage || null,
192
+ repoUrl: options.repoUrl || null,
193
+ };
194
+ if (options.channel) entry.channel = options.channel;
195
+ if (options.sha) entry.sha = options.sha;
196
+ if (options.localPath) entry.localPath = options.localPath;
197
+ if (options.rawSource) entry.rawSource = options.rawSource;
198
+ if (options.registryApprovedTag) entry.registryApprovedTag = options.registryApprovedTag;
199
+ if (options.registryApprovedSha) entry.registryApprovedSha = options.registryApprovedSha;
200
+ manifest.modules.push(entry);
201
+ } else {
202
+ // Module exists, update its version info
203
+ const existing = manifest.modules[existingIndex];
204
+ manifest.modules[existingIndex] = {
205
+ ...existing,
206
+ version: options.version === undefined ? existing.version : options.version,
207
+ source: options.source || existing.source,
208
+ npmPackage: options.npmPackage === undefined ? existing.npmPackage : options.npmPackage,
209
+ repoUrl: options.repoUrl === undefined ? existing.repoUrl : options.repoUrl,
210
+ localPath: options.localPath === undefined ? existing.localPath : options.localPath,
211
+ channel: options.channel === undefined ? existing.channel : options.channel,
212
+ sha: options.sha === undefined ? existing.sha : options.sha,
213
+ rawSource: options.rawSource === undefined ? existing.rawSource : options.rawSource,
214
+ registryApprovedTag: options.registryApprovedTag === undefined ? existing.registryApprovedTag : options.registryApprovedTag,
215
+ registryApprovedSha: options.registryApprovedSha === undefined ? existing.registryApprovedSha : options.registryApprovedSha,
216
+ lastUpdated: new Date().toISOString(),
217
+ };
218
+ }
219
+
220
+ await this._writeRaw(drtDir, manifest);
221
+ }
222
+
223
+ /**
224
+ * Get all modules with their version info
225
+ * @param {string} drtDir - Path to drt directory
226
+ * @returns {Array} Array of module info objects
227
+ */
228
+ async getAllModuleVersions(drtDir) {
229
+ const manifest = await this._readRaw(drtDir);
230
+ if (!manifest || !manifest.modules) {
231
+ return [];
232
+ }
233
+
234
+ return manifest.modules;
235
+ }
236
+
237
+ /**
238
+ * Write raw manifest data to file
239
+ * @param {string} drtDir - Path to drt directory
240
+ * @param {Object} manifestData - Raw manifest data to write
241
+ */
242
+ async _writeRaw(drtDir, manifestData) {
243
+ const yaml = require('yaml');
244
+ const manifestPath = path.join(drtDir, '_config', 'manifest.yaml');
245
+
246
+ await fs.ensureDir(path.dirname(manifestPath));
247
+
248
+ const cleanManifestData = structuredClone(manifestData);
249
+
250
+ const yamlContent = yaml.stringify(cleanManifestData, {
251
+ indent: 2,
252
+ lineWidth: 0,
253
+ sortKeys: false,
254
+ });
255
+
256
+ const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
257
+ await fs.writeFile(manifestPath, content, 'utf8');
258
+ }
259
+
260
+ /**
261
+ * Calculate SHA256 hash of a file
262
+ * @param {string} filePath - Path to file
263
+ * @returns {string} SHA256 hash
264
+ */
265
+ async calculateFileHash(filePath) {
266
+ try {
267
+ const content = await fs.readFile(filePath);
268
+ return crypto.createHash('sha256').update(content).digest('hex');
269
+ } catch {
270
+ return null;
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Get module version info from source
276
+ * @param {string} moduleName - Module name/code
277
+ * @param {string} drtDir - Path to drt directory
278
+ * @param {string} moduleSourcePath - Optional source path for custom modules
279
+ * @returns {Object} Version info object with version, source, npmPackage, repoUrl
280
+ */
281
+ async getModuleVersionInfo(moduleName, drtDir, moduleSourcePath = null) {
282
+ // Resolve source type first, then read version with the correct path context
283
+ if (['core', 'drt'].includes(moduleName)) {
284
+ const versionInfo = await resolveModuleVersion(moduleName, { moduleSourcePath });
285
+ return {
286
+ version: versionInfo.version,
287
+ source: 'built-in',
288
+ npmPackage: null,
289
+ repoUrl: null,
290
+ };
291
+ }
292
+
293
+ // Check if this is an external official module
294
+ const { ExternalModuleManager } = require('../modules/external-manager');
295
+ const extMgr = new ExternalModuleManager();
296
+ const moduleInfo = await extMgr.getModuleByCode(moduleName);
297
+
298
+ if (moduleInfo) {
299
+ const externalResolution = extMgr.getResolution(moduleName);
300
+ const versionInfo = await resolveModuleVersion(moduleName, { moduleSourcePath });
301
+ return {
302
+ // Git tag recorded during install trumps the on-disk package.json
303
+ // version, so the manifest carries "v1.7.0" instead of "1.7.0".
304
+ version: externalResolution?.version || versionInfo.version,
305
+ source: 'external',
306
+ npmPackage: moduleInfo.npmPackage || null,
307
+ repoUrl: moduleInfo.url || null,
308
+ channel: externalResolution?.channel || null,
309
+ sha: externalResolution?.sha || null,
310
+ };
311
+ }
312
+
313
+ // Check if this is a custom module (from user-provided URL or local path)
314
+ const { CustomModuleManager } = require('../modules/custom-module-manager');
315
+ const customMgr = new CustomModuleManager();
316
+ const resolved = customMgr.getResolution(moduleName);
317
+ const customSource = await customMgr.findModuleSourceByCode(moduleName, { drtDir });
318
+ if (customSource || resolved) {
319
+ const versionInfo = await resolveModuleVersion(moduleName, {
320
+ moduleSourcePath: moduleSourcePath || customSource,
321
+ fallbackVersion: resolved?.version,
322
+ marketplacePluginNames: resolved?.pluginName ? [resolved.pluginName] : [],
323
+ });
324
+ const hasGitClone = !!resolved?.repoUrl;
325
+ return {
326
+ // Prefer the git ref we actually cloned over the package.json version.
327
+ version: resolved?.cloneRef || (hasGitClone ? 'main' : versionInfo.version),
328
+ source: 'custom',
329
+ npmPackage: null,
330
+ repoUrl: resolved?.repoUrl || null,
331
+ localPath: resolved?.localPath || null,
332
+ channel: hasGitClone ? (resolved?.cloneRef ? 'pinned' : 'next') : null,
333
+ sha: resolved?.cloneSha || null,
334
+ rawSource: resolved?.rawInput || null,
335
+ };
336
+ }
337
+
338
+ // Unknown module
339
+ const versionInfo = await resolveModuleVersion(moduleName, { moduleSourcePath });
340
+ return {
341
+ version: versionInfo.version,
342
+ source: 'unknown',
343
+ npmPackage: null,
344
+ repoUrl: null,
345
+ };
346
+ }
347
+
348
+ /**
349
+ * Fetch latest version from npm for a package
350
+ * @param {string} packageName - npm package name
351
+ * @returns {string|null} Latest version or null
352
+ */
353
+ async fetchNpmVersion(packageName) {
354
+ if (!isValidNpmPackageName(packageName)) {
355
+ return null;
356
+ }
357
+
358
+ try {
359
+ // Try using npm view first (more reliable)
360
+ try {
361
+ const { stdout } = await execFileAsync('npm', ['view', packageName, 'version'], {
362
+ encoding: 'utf8',
363
+ timeout: NPM_LOOKUP_TIMEOUT_MS,
364
+ });
365
+ return stdout.trim();
366
+ } catch {
367
+ // Fallback to npm registry API
368
+ return new Promise((resolve) => {
369
+ const request = https.get(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, (res) => {
370
+ let data = '';
371
+ res.on('data', (chunk) => (data += chunk));
372
+ res.on('end', () => {
373
+ try {
374
+ const pkg = JSON.parse(data);
375
+ resolve(pkg['dist-tags']?.latest || pkg.version || null);
376
+ } catch {
377
+ resolve(null);
378
+ }
379
+ });
380
+ });
381
+
382
+ request.setTimeout(NPM_LOOKUP_TIMEOUT_MS, () => {
383
+ request.destroy();
384
+ resolve(null);
385
+ });
386
+
387
+ request.on('error', () => resolve(null));
388
+ });
389
+ }
390
+ } catch {
391
+ return null;
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Check for available updates for installed modules
397
+ * @param {string} drtDir - Path to drt directory
398
+ * @returns {Array} Array of update info objects
399
+ */
400
+ async checkForUpdates(drtDir) {
401
+ const semver = require('semver');
402
+ const modules = await this.getAllModuleVersions(drtDir);
403
+ const updates = [];
404
+
405
+ for (const module of modules) {
406
+ if (!module.npmPackage) {
407
+ continue; // Skip modules without npm package (built-in)
408
+ }
409
+
410
+ const latestVersion = await this.fetchNpmVersion(module.npmPackage);
411
+ if (!latestVersion) {
412
+ continue;
413
+ }
414
+
415
+ const installedVersion = semver.valid(module.version) || semver.valid(semver.coerce(module.version || ''));
416
+ const availableVersion = semver.valid(latestVersion) || semver.valid(semver.coerce(latestVersion));
417
+
418
+ if (installedVersion && availableVersion && semver.gt(availableVersion, installedVersion)) {
419
+ updates.push({
420
+ name: module.name,
421
+ installedVersion: module.version,
422
+ latestVersion: latestVersion,
423
+ npmPackage: module.npmPackage,
424
+ updateAvailable: true,
425
+ });
426
+ }
427
+ }
428
+
429
+ return updates;
430
+ }
431
+ }
432
+
433
+ module.exports = { Manifest };
@@ -0,0 +1,97 @@
1
+ const { spawnSync } = require('node:child_process');
2
+ const prompts = require('../prompts');
3
+
4
+ // `uv` (https://docs.astral.sh/uv/) is becoming the de facto standard for
5
+ // running the Python scripts DRT workflows shell out to: `uv run <script>`
6
+ // resolves the interpreter and any dependencies on demand, so skills don't
7
+ // have to assume a particular `python3` is on PATH. The ecosystem is mid-
8
+ // migration — some skills still call `python3` directly — so a missing `uv`
9
+ // is a warning, not a blocker: DRT installs and runs either way.
10
+ const RUNTIME_COMMAND = 'uv';
11
+
12
+ /**
13
+ * Parse `uv --version` output into version parts.
14
+ * Example outputs: "uv 0.5.31", "uv 0.5.31 (Homebrew 2025-02-12)".
15
+ * @param {string} output - stdout/stderr from `uv --version`
16
+ * @returns {{major: number, minor: number, patch: number, raw: string}|null}
17
+ */
18
+ function parseUvVersion(output) {
19
+ if (!output) return null;
20
+ const match = output.match(/uv\s+(\d+)\.(\d+)(?:\.(\d+))?/i);
21
+ if (!match) return null;
22
+ return {
23
+ major: Number(match[1]),
24
+ minor: Number(match[2]),
25
+ patch: Number(match[3] || 0),
26
+ raw: `${match[1]}.${match[2]}.${match[3] || 0}`,
27
+ };
28
+ }
29
+
30
+ /**
31
+ * Probe the local environment for `uv`.
32
+ * @returns {{version: {major: number, minor: number, patch: number, raw: string}}|null}
33
+ */
34
+ function detectUv() {
35
+ let result;
36
+ try {
37
+ result = spawnSync(RUNTIME_COMMAND, ['--version'], {
38
+ encoding: 'utf8',
39
+ timeout: 5000,
40
+ windowsHide: true,
41
+ });
42
+ } catch {
43
+ return null;
44
+ }
45
+ if (!result || result.error) return null;
46
+ const version = parseUvVersion(`${result.stdout || ''}\n${result.stderr || ''}`);
47
+ return version ? { version } : null;
48
+ }
49
+
50
+ function setupHints() {
51
+ return [
52
+ 'DRT workflows increasingly run Python scripts via `uv run`, which manages',
53
+ 'the interpreter and dependencies for you — no manual venv or pip needed.',
54
+ '',
55
+ 'Easiest path: ask your AI agent to "install and set up uv for me".',
56
+ '',
57
+ 'Or install it yourself:',
58
+ ' macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh',
59
+ ' Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"',
60
+ ' Homebrew: brew install uv',
61
+ ' Docs: https://docs.astral.sh/uv/getting-started/installation/',
62
+ ].join('\n');
63
+ }
64
+
65
+ /**
66
+ * Check whether `uv` is available and inform the user.
67
+ *
68
+ * Warn-don't-block, and no acknowledgement prompt: `uv` is on its way to being
69
+ * the standard runner for DRT's Python scripts, but the migration is still in
70
+ * progress, so the install never stops on its account. The note tells the user
71
+ * how to set it up (preferably by asking their agent).
72
+ *
73
+ * @returns {Promise<{status: 'found'|'missing', detected: Object|null}>}
74
+ */
75
+ async function checkUvEnvironment() {
76
+ // Called via module.exports so tests can stub detection.
77
+ const detected = module.exports.detectUv();
78
+
79
+ if (detected) {
80
+ await prompts.log.success(`✅ Python UV check pass (uv ${detected.version.raw} detected).`);
81
+ return { status: 'found', detected };
82
+ }
83
+
84
+ await prompts.log.warn(
85
+ "uv not found on PATH. uv is becoming the de facto standard for running DRT's Python\n" +
86
+ 'scripts (`uv run <script>`), and it provisions the interpreter for you. DRT installs\n' +
87
+ 'fine without it, but setting up uv now keeps you ahead as workflows adopt it.',
88
+ );
89
+ await prompts.note(setupHints(), 'uv recommended');
90
+ return { status: 'missing', detected: null };
91
+ }
92
+
93
+ module.exports = {
94
+ checkUvEnvironment,
95
+ detectUv,
96
+ parseUvVersion,
97
+ };
@@ -0,0 +1,109 @@
1
+ const prompts = require('../prompts');
2
+
3
+ const WSL_UNC_PATTERN = /^\\\\wsl(?:\.localhost|\$)?\\/i;
4
+
5
+ function normalizePath(value) {
6
+ return typeof value === 'string' ? value.replaceAll('/', '\\').toLowerCase() : '';
7
+ }
8
+
9
+ function isLinuxStylePath(value) {
10
+ return (
11
+ typeof value === 'string' &&
12
+ value.startsWith('/') &&
13
+ !value.startsWith('//') &&
14
+ !/^\/[a-z](?:\/|$)/i.test(value) &&
15
+ !/^\/cygdrive\/[a-z](?:\/|$)/i.test(value)
16
+ );
17
+ }
18
+
19
+ function isWslUncPath(value) {
20
+ return WSL_UNC_PATTERN.test(value || '');
21
+ }
22
+
23
+ /**
24
+ * Detect the broken interop case where WSL resolved node/npx to Windows.
25
+ * @param {Object} [runtime]
26
+ * @param {string} [runtime.platform]
27
+ * @param {Object} [runtime.env]
28
+ * @param {string} [runtime.cwd]
29
+ * @param {string} [runtime.execPath]
30
+ * @returns {{isMismatch: boolean, reason: string|null, execPath: string}}
31
+ */
32
+ function detectWindowsNodeFromWsl(runtime = {}) {
33
+ const platform = runtime.platform || process.platform;
34
+ const env = runtime.env || process.env;
35
+ const cwd = runtime.cwd || safeCwd();
36
+ const execPath = runtime.execPath || process.execPath || '';
37
+
38
+ if (platform !== 'win32') {
39
+ return { isMismatch: false, reason: null, execPath };
40
+ }
41
+
42
+ if (env.WSL_DISTRO_NAME) {
43
+ return { isMismatch: true, reason: 'WSL_DISTRO_NAME is set', execPath };
44
+ }
45
+
46
+ if (env.WSL_INTEROP) {
47
+ return { isMismatch: true, reason: 'WSL_INTEROP is set', execPath };
48
+ }
49
+
50
+ if (isLinuxStylePath(env.PWD)) {
51
+ return { isMismatch: true, reason: 'PWD is a Linux path', execPath };
52
+ }
53
+
54
+ if (isWslUncPath(cwd)) {
55
+ return { isMismatch: true, reason: 'current directory is a WSL UNC path', execPath };
56
+ }
57
+
58
+ const normalizedExecPath = normalizePath(execPath);
59
+ if (normalizedExecPath.includes('\\wsl$\\') || normalizedExecPath.includes('\\wsl.localhost\\')) {
60
+ return { isMismatch: true, reason: 'Node executable path is under a WSL UNC path', execPath };
61
+ }
62
+
63
+ return { isMismatch: false, reason: null, execPath };
64
+ }
65
+
66
+ function safeCwd() {
67
+ try {
68
+ return process.cwd();
69
+ } catch {
70
+ return '';
71
+ }
72
+ }
73
+
74
+ function formatWindowsNodeFromWslMessage(detection) {
75
+ const lines = [
76
+ 'Windows Node.js was launched from a WSL shell.',
77
+ '',
78
+ 'This usually means Node.js is not installed inside the WSL distro, so WSL resolved `node`/`npx` to Windows.',
79
+ 'The installer cannot safely continue because Linux paths may be interpreted as Windows paths.',
80
+ '',
81
+ 'Install Node.js inside WSL, then rerun the same command from the WSL terminal.',
82
+ ];
83
+
84
+ if (detection.execPath) {
85
+ lines.push('', `Detected Node executable: ${detection.execPath}`);
86
+ }
87
+
88
+ if (detection.reason) {
89
+ lines.push(`Detection signal: ${detection.reason}`);
90
+ }
91
+
92
+ return lines.join('\n');
93
+ }
94
+
95
+ async function checkWindowsNodeFromWsl() {
96
+ const detection = module.exports.detectWindowsNodeFromWsl();
97
+ if (!detection.isMismatch) {
98
+ return detection;
99
+ }
100
+
101
+ await prompts.log.error(formatWindowsNodeFromWslMessage(detection));
102
+ process.exit(1);
103
+ }
104
+
105
+ module.exports = {
106
+ checkWindowsNodeFromWsl,
107
+ detectWindowsNodeFromWsl,
108
+ formatWindowsNodeFromWslMessage,
109
+ };