feat(prompts): add directory prompt with updated Clack runtime (#2387)
* chore(deps): update @clack/core and @clack/prompts to latest versions and adjust Node.js engine requirement * feat(prompts): add directory prompt with autocomplete and create-directory support * chore(docs): update Node.js version requirement to 20.12+ across multiple documentation files * fix(prompts): code review fixes
This commit is contained in:
parent
5090cfb096
commit
0f852a38ac
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[](https://www.npmjs.com/package/bmad-method)
|
||||
[](LICENSE)
|
||||
[](https://nodejs.org)
|
||||
[](https://nodejs.org)
|
||||
[](https://www.python.org)
|
||||
[](https://docs.astral.sh/uv/)
|
||||
[](https://discord.gg/gk8jAdXWmj)
|
||||
|
|
@ -36,7 +36,7 @@ Traditional AI tools do the thinking for you, producing average results. BMad ag
|
|||
|
||||
## Quick Start
|
||||
|
||||
**Prerequisites**: [Node.js](https://nodejs.org) v20+ · [Python](https://www.python.org) 3.10+ · [uv](https://docs.astral.sh/uv/)
|
||||
**Prerequisites**: [Node.js](https://nodejs.org) v20.12+ · [Python](https://www.python.org) 3.10+ · [uv](https://docs.astral.sh/uv/)
|
||||
|
||||
```bash
|
||||
npx bmad-method install
|
||||
|
|
@ -82,11 +82,11 @@ BMad Method extends with official modules for specialized domains. Available dur
|
|||
[BMad Method Docs Site](https://docs.bmad-method.org) — Tutorials, guides, concepts, and reference
|
||||
|
||||
**Quick links:**
|
||||
|
||||
- [Getting Started Tutorial](https://docs.bmad-method.org/tutorials/getting-started/)
|
||||
- [Upgrading from Previous Versions](https://docs.bmad-method.org/how-to/upgrade-to-v6/)
|
||||
- [Test Architect Documentation](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/)
|
||||
|
||||
|
||||
## Community
|
||||
|
||||
- [Discord](https://discord.gg/gk8jAdXWmj) — Get help, share ideas, collaborate
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Pokud chcete použít neinteraktivní instalátor a zadat všechny možnosti na
|
|||
- Aktualizujete stávající instalaci BMad
|
||||
|
||||
:::note[Předpoklady]
|
||||
- **Node.js** 20+ (vyžadováno pro instalátor)
|
||||
- **Node.js** 20.12+ (vyžadováno pro instalátor)
|
||||
- **Git** (doporučeno)
|
||||
- **AI nástroj** (Claude Code, Cursor nebo podobný)
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Použijte příznaky příkazové řádky k neinteraktivní instalaci BMad. To j
|
|||
- Rychlé instalace se známými konfiguracemi
|
||||
|
||||
:::note[Předpoklady]
|
||||
Vyžaduje [Node.js](https://nodejs.org) v20+ a `npx` (součástí npm).
|
||||
Vyžaduje [Node.js](https://nodejs.org) v20.12+ a `npx` (součástí npm).
|
||||
:::
|
||||
|
||||
## Dostupné příznaky
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Použijte instalátor BMad pro upgrade z v4 na v6, který zahrnuje automatickou
|
|||
- Máte existující plánovací artefakty k zachování
|
||||
|
||||
:::note[Předpoklady]
|
||||
- Node.js 20+
|
||||
- Node.js 20.12+
|
||||
- Existující instalace BMad v4
|
||||
:::
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Vytvářejte software rychleji pomocí pracovních postupů řízených AI se sp
|
|||
- Efektivně používat agenty a pracovní postupy
|
||||
|
||||
:::note[Předpoklady]
|
||||
- **Node.js 20+** — Vyžadováno pro instalátor
|
||||
- **Node.js 20.12+** — Vyžadováno pro instalátor
|
||||
- **Git** — Doporučeno pro správu verzí
|
||||
- **AI-powered IDE** — Claude Code, Cursor nebo podobné
|
||||
- **Nápad na projekt** — I jednoduchý stačí pro učení
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Si vous souhaitez utiliser un installateur non interactif et fournir toutes les
|
|||
- Mettre à jour une installation BMad existante
|
||||
|
||||
:::note[Prérequis]
|
||||
- **Node.js** 20+ (requis pour l'installateur)
|
||||
- **Node.js** 20.12+ (requis pour l'installateur)
|
||||
- **Git** (recommandé)
|
||||
- **Outil d'IA** (Claude Code, Cursor, ou similaire)
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Utilisez les options de ligne de commande pour installer BMad de manière non-in
|
|||
- Installations rapides avec des configurations connues
|
||||
|
||||
:::note[Prérequis]
|
||||
Nécessite [Node.js](https://nodejs.org) v20+ et `npx` (inclus avec npm).
|
||||
Nécessite [Node.js](https://nodejs.org) v20.12+ et `npx` (inclus avec npm).
|
||||
:::
|
||||
|
||||
## Options disponibles
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Utilisez l'installateur BMad pour passer de la v4 à la v6, qui inclut une déte
|
|||
- Vous avez des artefacts de planification existants à préserver
|
||||
|
||||
:::note[Prérequis]
|
||||
- Node.js 20+
|
||||
- Node.js 20.12+
|
||||
- Installation BMad v4 existante
|
||||
:::
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Construisez des logiciels plus rapidement en utilisant des workflows propulsés
|
|||
- Utiliser efficacement les agents et les workflows
|
||||
|
||||
:::note[Prérequis]
|
||||
- **Node.js 20+** — Requis pour l'installateur
|
||||
- **Node.js 20.12+** — Requis pour l'installateur
|
||||
- **Git** — Recommandé pour le contrôle de version
|
||||
- **IDE IA** — Claude Code, Cursor, ou similaire
|
||||
- **Une idée de projet** — Même simple, elle fonctionne pour apprendre
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Use `npx bmad-method install` to set up BMad in your project. One command handle
|
|||
|
||||
:::note[Prerequisites]
|
||||
|
||||
- **Node.js** 20+ (the installer requires it)
|
||||
- **Node.js** 20.12+ (the installer requires it)
|
||||
- **Git** (for cloning external modules)
|
||||
- **An AI tool** such as Claude Code or Cursor (run `npx bmad-method install --list-tools` to see all supported tools)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Use the BMad installer to add modules from the community registry, third-party G
|
|||
- Installing modules from a private or self-hosted Git server
|
||||
|
||||
:::note[Prerequisites]
|
||||
Requires [Node.js](https://nodejs.org) v20+ and `npx` (included with npm). Custom and community modules can be selected during a fresh install or added to an existing installation.
|
||||
Requires [Node.js](https://nodejs.org) v20.12+ and `npx` (included with npm). Custom and community modules can be selected during a fresh install or added to an existing installation.
|
||||
:::
|
||||
|
||||
## Community Modules
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Use the BMad installer to upgrade from v4 to v6, which includes automatic detect
|
|||
|
||||
:::note[Prerequisites]
|
||||
|
||||
- Node.js 20+
|
||||
- Node.js 20.12+
|
||||
- Existing BMad v4 installation
|
||||
:::
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: "Getting Started"
|
||||
title: 'Getting Started'
|
||||
description: Install BMad and build your first project
|
||||
---
|
||||
|
||||
|
|
@ -14,11 +14,12 @@ Build software faster using AI-powered workflows with specialized agents that gu
|
|||
- Use agents and workflows effectively
|
||||
|
||||
:::note[Prerequisites]
|
||||
- **Node.js 20+** — Required for the installer
|
||||
|
||||
- **Node.js 20.12+** — Required for the installer
|
||||
- **Git** — Recommended for version control
|
||||
- **AI-powered IDE** — Claude Code, Cursor, or similar
|
||||
- **A project idea** — Even a simple one works for learning
|
||||
:::
|
||||
:::
|
||||
|
||||
:::tip[The Easiest Path]
|
||||
**Install** → `npx bmad-method install`
|
||||
|
|
@ -50,6 +51,7 @@ bmad-help I have an idea for a SaaS product, I already know all the features I w
|
|||
```
|
||||
|
||||
BMad-Help will respond with:
|
||||
|
||||
- What's recommended for your situation
|
||||
- What the first required task is
|
||||
- What the rest of the process looks like
|
||||
|
|
@ -67,10 +69,10 @@ After installing BMad, invoke the `bmad-help` skill immediately. It will detect
|
|||
BMad helps you build software through guided workflows with specialized AI agents. The process follows four phases:
|
||||
|
||||
| Phase | Name | What Happens |
|
||||
| ----- | -------------- | --------------------------------------------------- |
|
||||
| 1 | Analysis | Brainstorming, research, product brief or PRFAQ *(optional)* |
|
||||
| ----- | -------------- | ------------------------------------------------------------ |
|
||||
| 1 | Analysis | Brainstorming, research, product brief or PRFAQ _(optional)_ |
|
||||
| 2 | Planning | Create requirements (PRD or spec) |
|
||||
| 3 | Solutioning | Design architecture *(BMad Method/Enterprise only)* |
|
||||
| 3 | Solutioning | Design architecture _(BMad Method/Enterprise only)_ |
|
||||
| 4 | Implementation | Build epic by epic, story by story |
|
||||
|
||||
**[Open the Workflow Map](../reference/workflow-map.md)** to explore phases, workflows, and context management.
|
||||
|
|
@ -100,6 +102,7 @@ If you want the newest prerelease build instead of the default release channel,
|
|||
When prompted to select modules, choose **BMad Method**.
|
||||
|
||||
The installer creates two folders:
|
||||
|
||||
- `_bmad/` — agents, workflows, tasks, and configuration
|
||||
- `_bmad-output/` — empty for now, but this is where your artifacts will be saved
|
||||
|
||||
|
|
@ -134,6 +137,7 @@ Create it manually at `_bmad-output/project-context.md` or generate it after arc
|
|||
### Phase 1: Analysis (Optional)
|
||||
|
||||
All workflows in this phase are optional. [**Not sure which to use?**](../explanation/analysis-phase.md)
|
||||
|
||||
- **brainstorming** (`bmad-brainstorming`) — Guided ideation
|
||||
- **research** (`bmad-market-research` / `bmad-domain-research` / `bmad-technical-research`) — Market, domain, and technical research
|
||||
- **product-brief** (`bmad-product-brief`) — Recommended foundation document when your concept is clear
|
||||
|
|
@ -142,16 +146,19 @@ All workflows in this phase are optional. [**Not sure which to use?**](../explan
|
|||
### Phase 2: Planning (Required)
|
||||
|
||||
**For BMad Method and Enterprise tracks:**
|
||||
|
||||
1. Run `bmad-prd` in a new chat — state your intent (Create / Update / Validate) or let the skill ask
|
||||
2. Output: `prd.md`, `addendum.md`, `decision-log.md`
|
||||
|
||||
:::note[`bmad-prd` intents]
|
||||
|
||||
- **Create** — coached discovery from scratch; the skill names the workspace folder and guides you to a PRD you're proud of
|
||||
- **Update** — point it at an existing PRD and a change signal; it surfaces conflicts before applying changes
|
||||
- **Validate** — critique a finished PRD against a checklist and produce an HTML findings report
|
||||
:::
|
||||
:::
|
||||
|
||||
**For Quick Flow track:**
|
||||
|
||||
- Run `bmad-quick-dev` — it handles planning and implementation in a single workflow, skip to implementation
|
||||
|
||||
:::note[UX Design (Optional)]
|
||||
|
|
@ -161,6 +168,7 @@ If your project has a user interface, invoke the **UX-Designer agent** (`bmad-ag
|
|||
### Phase 3: Solutioning (BMad Method/Enterprise)
|
||||
|
||||
**Create Architecture**
|
||||
|
||||
1. Invoke the **Architect agent** (`bmad-agent-architect`) in a new chat
|
||||
2. Run `bmad-create-architecture` (`bmad-create-architecture`)
|
||||
3. Output: Architecture document with technical decisions
|
||||
|
|
@ -168,14 +176,15 @@ If your project has a user interface, invoke the **UX-Designer agent** (`bmad-ag
|
|||
**Create Epics and Stories**
|
||||
|
||||
:::tip[V6 Improvement]
|
||||
Epics and stories are now created *after* architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down.
|
||||
Epics and stories are now created _after_ architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down.
|
||||
:::
|
||||
|
||||
1. Invoke the **PM agent** (`bmad-agent-pm`) in a new chat
|
||||
2. Run `bmad-create-epics-and-stories` (`bmad-create-epics-and-stories`)
|
||||
3. The workflow uses both PRD and Architecture to create technically-informed stories
|
||||
|
||||
**Implementation Readiness Check** *(Highly Recommended)*
|
||||
**Implementation Readiness Check** _(Highly Recommended)_
|
||||
|
||||
1. Invoke the **Architect agent** (`bmad-agent-architect`) in a new chat
|
||||
2. Run `bmad-check-implementation-readiness` (`bmad-check-implementation-readiness`)
|
||||
3. Validates cohesion across all planning documents
|
||||
|
|
@ -193,10 +202,10 @@ Invoke the **Developer agent** (`bmad-agent-dev`) and run `bmad-sprint-planning`
|
|||
For each story, repeat this cycle with fresh chats:
|
||||
|
||||
| Step | Agent | Workflow | Command | Purpose |
|
||||
| ---- | ----- | -------------- | -------------------------- | ---------------------------------- |
|
||||
| ---- | ----- | ------------------- | ------------------- | ---------------------------------- |
|
||||
| 1 | DEV | `bmad-create-story` | `bmad-create-story` | Create story file from epic |
|
||||
| 2 | DEV | `bmad-dev-story` | `bmad-dev-story` | Implement the story |
|
||||
| 3 | DEV | `bmad-code-review` | `bmad-code-review` | Quality validation *(recommended)* |
|
||||
| 3 | DEV | `bmad-code-review` | `bmad-code-review` | Quality validation _(recommended)_ |
|
||||
|
||||
After completing all stories in an epic, invoke the **Developer agent** (`bmad-agent-dev`) and run `bmad-retrospective` (`bmad-retrospective`).
|
||||
|
||||
|
|
@ -228,7 +237,7 @@ your-project/
|
|||
## Quick Reference
|
||||
|
||||
| Workflow | Command | Agent | Purpose |
|
||||
| ------------------------------------- | ------------------------------------------ | --------- | ----------------------------------------------- |
|
||||
| ------------------------------------- | ------------------------------------- | --------- | ------------------------------------------ |
|
||||
| **`bmad-help`** ⭐ | `bmad-help` | Any | **Your intelligent guide — ask anything!** |
|
||||
| `bmad-prd` | `bmad-prd` | Any | Create, update, or validate a PRD |
|
||||
| `bmad-create-architecture` | `bmad-create-architecture` | Architect | Create architecture document |
|
||||
|
|
@ -258,6 +267,7 @@ Not strictly. Once you learn the flow, you can run workflows directly using the
|
|||
|
||||
:::tip[First Stop: BMad-Help]
|
||||
**Invoke `bmad-help` anytime** — it's the fastest way to get unstuck. Ask it anything:
|
||||
|
||||
- "What should I do after installing?"
|
||||
- "I'm stuck on workflow X"
|
||||
- "What are my options for Y?"
|
||||
|
|
@ -272,10 +282,11 @@ BMad-Help inspects your project, detects what you've completed, and tells you ex
|
|||
## Key Takeaways
|
||||
|
||||
:::tip[Remember These]
|
||||
|
||||
- **Start with `bmad-help`** — Your intelligent guide that knows your project and options
|
||||
- **Always use fresh chats** — Start a new chat for each workflow
|
||||
- **Track matters** — Quick Flow uses `bmad-quick-dev`; Method/Enterprise need PRD and architecture
|
||||
- **BMad-Help runs automatically** — Every workflow ends with guidance on what's next
|
||||
:::
|
||||
:::
|
||||
|
||||
Ready to start? Install BMad, invoke `bmad-help`, and let your intelligent guide lead the way.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Nếu bạn muốn dùng trình cài đặt không tương tác và cung cấp t
|
|||
- Cập nhật bản cài đặt BMad hiện tại
|
||||
|
||||
:::note[Điều kiện tiên quyết]
|
||||
- **Node.js** 20+ (bắt buộc cho trình cài đặt)
|
||||
- **Node.js** 20.12+ (bắt buộc cho trình cài đặt)
|
||||
- **Git** (khuyến nghị)
|
||||
- **Công cụ AI** (Claude Code, Cursor, hoặc tương tự)
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Sử dụng trình cài đặt BMad để thêm module từ kho cộng đồng (
|
|||
- Cài module từ máy chủ Git riêng tư hoặc tự host
|
||||
|
||||
:::note[Điều kiện tiên quyết]
|
||||
Yêu cầu [Node.js](https://nodejs.org) v20+ và `npx` đi kèm npm. Bạn có thể chọn module tùy chỉnh và module cộng đồng trong lúc cài mới, hoặc thêm chúng vào một bản cài hiện có.
|
||||
Yêu cầu [Node.js](https://nodejs.org) v20.12+ và `npx` đi kèm npm. Bạn có thể chọn module tùy chỉnh và module cộng đồng trong lúc cài mới, hoặc thêm chúng vào một bản cài hiện có.
|
||||
:::
|
||||
|
||||
## Module cộng đồng
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Sử dụng các cờ dòng lệnh để cài đặt BMad mà không cần tươ
|
|||
- Cài đặt nhanh với cấu hình đã biết trước
|
||||
|
||||
:::note[Điều kiện tiên quyết]
|
||||
Yêu cầu [Node.js](https://nodejs.org) v20+ và `npx` (đi kèm với npm).
|
||||
Yêu cầu [Node.js](https://nodejs.org) v20.12+ và `npx` (đi kèm với npm).
|
||||
:::
|
||||
|
||||
## Các cờ khả dụng
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Sử dụng trình cài đặt BMad để nâng cấp từ v4 lên v6, bao gồm
|
|||
- Bạn có các planning artifact hiện có cần giữ lại
|
||||
|
||||
:::note[Điều kiện tiên quyết]
|
||||
- Node.js 20+
|
||||
- Node.js 20.12+
|
||||
- Bản cài đặt BMad v4 hiện có
|
||||
:::
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Xây dựng phần mềm nhanh hơn bằng các workflow vận hành bởi AI, v
|
|||
- Sử dụng agent và workflow hiệu quả
|
||||
|
||||
:::note[Điều kiện tiên quyết]
|
||||
- **Node.js 20+** — Bắt buộc cho trình cài đặt
|
||||
- **Node.js 20.12+** — Bắt buộc cho trình cài đặt
|
||||
- **Git** — Khuyến nghị để quản lý phiên bản
|
||||
- **IDE có AI** — Claude Code, Cursor hoặc công cụ tương tự
|
||||
- **Một ý tưởng dự án** — Chỉ cần đơn giản cũng đủ để học
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ sidebar:
|
|||
- 更新现有的 BMad 安装
|
||||
|
||||
:::note[前置条件]
|
||||
- **Node.js** 20+(安装程序必需)
|
||||
- **Node.js** 20.12+(安装程序必需)
|
||||
- **Git**(推荐)
|
||||
- **AI 工具**(Claude Code、Cursor 或类似工具)
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ sidebar:
|
|||
- 从私有或自托管 Git 服务器安装模块
|
||||
|
||||
:::note[前置条件]
|
||||
需要 [Node.js](https://nodejs.org) v20+ 和 `npx`(npm 自带)。自定义和社区模块可以在全新安装时选择,也可以添加到现有安装中。
|
||||
需要 [Node.js](https://nodejs.org) v20.12+ 和 `npx`(npm 自带)。自定义和社区模块可以在全新安装时选择,也可以添加到现有安装中。
|
||||
:::
|
||||
|
||||
## 社区模块
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ sidebar:
|
|||
- 使用已知配置的快速安装
|
||||
|
||||
:::note[前置条件]
|
||||
需要 [Node.js](https://nodejs.org) v20+ 和 `npx`(随 npm 附带)。
|
||||
需要 [Node.js](https://nodejs.org) v20.12+ 和 `npx`(随 npm 附带)。
|
||||
:::
|
||||
|
||||
## 可用参数(Flags)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ sidebar:
|
|||
- 你有要保留的规划产物或进行中的开发工作
|
||||
|
||||
:::note[前置条件]
|
||||
- Node.js 20+
|
||||
- Node.js 20.12+
|
||||
- 现有 BMad v4 安装
|
||||
:::
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ description: 安装 BMad 并构建你的第一个项目
|
|||
- 有效使用智能体和工作流
|
||||
|
||||
:::note[前置条件]
|
||||
- **Node.js 20+** — 安装程序必需
|
||||
- **Node.js 20.12+** — 安装程序必需
|
||||
- **Git** — 推荐用于版本控制
|
||||
- **AI 驱动的 IDE** — Claude Code、Cursor 或类似工具
|
||||
- **一个项目想法** — 即使是简单的想法也可以用于学习
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
"version": "6.6.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/core": "^1.0.0",
|
||||
"@clack/prompts": "^1.0.0",
|
||||
"@clack/core": "^1.3.1",
|
||||
"@clack/prompts": "^1.4.0",
|
||||
"@kayvan/markdown-tree-parser": "^1.6.1",
|
||||
"chalk": "^4.1.2",
|
||||
"commander": "^14.0.0",
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
"yaml-lint": "^1.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=20.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@astrojs/compiler": {
|
||||
|
|
@ -752,24 +752,31 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@clack/core": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@clack/core/-/core-1.0.0.tgz",
|
||||
"integrity": "sha512-Orf9Ltr5NeiEuVJS8Rk2XTw3IxNC2Bic3ash7GgYeA8LJ/zmSNpSQ/m5UAhe03lA6KFgklzZ5KTHs4OAMA/SAQ==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@clack/core/-/core-1.3.1.tgz",
|
||||
"integrity": "sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"picocolors": "^1.0.0",
|
||||
"fast-wrap-ansi": "^0.2.0",
|
||||
"sisteransi": "^1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@clack/prompts": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.0.0.tgz",
|
||||
"integrity": "sha512-rWPXg9UaCFqErJVQ+MecOaWsozjaxol4yjnmYcGNipAWzdaWa2x+VJmKfGq7L0APwBohQOYdHC+9RO4qRXej+A==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.4.0.tgz",
|
||||
"integrity": "sha512-S0My7XPGIgpRWMDG8uRqalbgT+a6FmCUdOW+HaIOVVpUPHOb7RrpvjTjiODadKp06fsrVDJZlIzc6yCTp4AnxA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/core": "1.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"@clack/core": "1.3.1",
|
||||
"fast-string-width": "^3.0.2",
|
||||
"fast-wrap-ansi": "^0.2.0",
|
||||
"sisteransi": "^1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
|
|
@ -7332,6 +7339,30 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-string-truncated-width": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
|
||||
"integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-string-width": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz",
|
||||
"integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-string-truncated-width": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-wrap-ansi": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz",
|
||||
"integrity": "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-string-width": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@clack/core": "^1.0.0",
|
||||
"@clack/prompts": "^1.0.0",
|
||||
"@clack/core": "^1.3.1",
|
||||
"@clack/prompts": "^1.4.0",
|
||||
"@kayvan/markdown-tree-parser": "^1.6.1",
|
||||
"chalk": "^4.1.2",
|
||||
"commander": "^14.0.0",
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
"yaml-lint": "^1.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=20.12.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
let _clack = null;
|
||||
let _clackCore = null;
|
||||
let _picocolors = null;
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
|
||||
/**
|
||||
* Lazy-load @clack/prompts (ESM module)
|
||||
|
|
@ -575,6 +578,151 @@ async function autocomplete(options) {
|
|||
return result;
|
||||
}
|
||||
|
||||
function hasPathSeparator(value) {
|
||||
return value.endsWith('/') || value.endsWith('\\');
|
||||
}
|
||||
|
||||
function expandHome(input) {
|
||||
if (!input) return input;
|
||||
if (input === '~') return os.homedir();
|
||||
if (input.startsWith('~/') || input.startsWith('~\\')) {
|
||||
return path.join(os.homedir(), input.slice(2));
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function toDirectoryOption(value, label = value, synthetic = false) {
|
||||
return { value, label, synthetic };
|
||||
}
|
||||
|
||||
function isExistingDirectory(value) {
|
||||
try {
|
||||
return fs.existsSync(value) && fs.statSync(value).isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function listDirectoryOptions(input, options) {
|
||||
const cwd = options.cwd || process.cwd();
|
||||
const rawInput = input.trim();
|
||||
const expandedInput = expandHome(rawInput);
|
||||
const trailingSep = hasPathSeparator(rawInput) || hasPathSeparator(expandedInput);
|
||||
const resolvedInput = expandedInput ? path.resolve(cwd, expandedInput) : cwd;
|
||||
const browseDir = expandedInput && !trailingSep && !isExistingDirectory(resolvedInput) ? path.dirname(resolvedInput) : resolvedInput;
|
||||
const prefix = expandedInput && browseDir !== resolvedInput ? path.basename(resolvedInput).toLowerCase() : '';
|
||||
const results = [];
|
||||
|
||||
if (!trailingSep && isExistingDirectory(resolvedInput)) {
|
||||
results.push(toDirectoryOption(resolvedInput, `. (use this directory)`));
|
||||
}
|
||||
|
||||
if (isExistingDirectory(browseDir)) {
|
||||
try {
|
||||
for (const entry of fs.readdirSync(browseDir, { withFileTypes: true })) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
if (prefix && !entry.name.toLowerCase().startsWith(prefix)) continue;
|
||||
const fullPath = path.join(browseDir, entry.name);
|
||||
if (!results.some((option) => option.value === fullPath)) {
|
||||
results.push(toDirectoryOption(fullPath));
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Skip unreadable directories; validation still reports path issues.
|
||||
}
|
||||
}
|
||||
|
||||
const validation = options.validate?.(rawInput);
|
||||
const hasMatchingOption = results.some((option) => option.value === resolvedInput);
|
||||
if (expandedInput && !validation && !hasMatchingOption) {
|
||||
results.unshift(toDirectoryOption(resolvedInput, `Create/use: ${resolvedInput}`, true));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory prompt with autocomplete candidates and create-directory support.
|
||||
* Uses @clack/core directly so typed paths that do not exist yet can still be
|
||||
* submitted when validation allows creating them.
|
||||
* @param {Object} options - Prompt options
|
||||
* @param {string} options.message - Prompt message
|
||||
* @param {string} [options.default] - Default directory
|
||||
* @param {string} [options.placeholder] - Placeholder text
|
||||
* @param {Function} [options.validate] - Sync validation function
|
||||
* @returns {Promise<string>} Selected or typed directory path
|
||||
*/
|
||||
async function directory(options) {
|
||||
const core = await getClackCore();
|
||||
const color = await getPicocolors();
|
||||
const tabCompletion = {
|
||||
prefix: '',
|
||||
index: -1,
|
||||
options: [],
|
||||
lastValue: '',
|
||||
};
|
||||
|
||||
let prompt;
|
||||
prompt = new core.AutocompletePrompt({
|
||||
initialValue: options.default,
|
||||
options: () => listDirectoryOptions(prompt?.userInput || '', options),
|
||||
filter: () => true,
|
||||
validate: (value) => options.validate?.(value ?? prompt.userInput),
|
||||
render() {
|
||||
const title = `${color.gray('◆')} ${options.message}`;
|
||||
const bar = color.gray('│');
|
||||
const barEnd = color.gray('└');
|
||||
const userInput = this.userInput;
|
||||
const placeholder = options.placeholder || options.default;
|
||||
const inputDisplay = userInput ? this.userInputWithCursor : `${color.inverse(color.hidden('_'))}${color.dim(placeholder || '')}`;
|
||||
const errorLine = this.state === 'error' ? [`${color.yellow('│')} ${color.yellow(this.error)}`] : [];
|
||||
|
||||
switch (this.state) {
|
||||
case 'submit': {
|
||||
return `${color.gray('◇')} ${options.message}\n${bar} ${color.dim(this.value || '')}`;
|
||||
}
|
||||
case 'cancel': {
|
||||
return `${color.gray('◇')} ${options.message}\n${bar} ${color.strikethrough(color.dim(userInput || ''))}`;
|
||||
}
|
||||
default: {
|
||||
return [title, `${bar} ${inputDisplay}`, ...errorLine, barEnd].join('\n');
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const hasSetUserInput = typeof prompt._setUserInput === 'function';
|
||||
const hasClearUserInput = typeof prompt._clearUserInput === 'function';
|
||||
|
||||
prompt.on('key', (_, key) => {
|
||||
if (key?.name !== 'tab') return;
|
||||
if (!hasSetUserInput) return; // @clack/core API surface changed — skip Tab silently.
|
||||
const currentInput = prompt.userInput;
|
||||
const isContinuingCycle = tabCompletion.lastValue && currentInput === tabCompletion.lastValue;
|
||||
const completionOptions = isContinuingCycle ? tabCompletion.options : prompt.filteredOptions.filter((option) => !option.synthetic);
|
||||
if (completionOptions.length === 0) return;
|
||||
|
||||
if (isContinuingCycle) {
|
||||
tabCompletion.index = (tabCompletion.index + 1) % completionOptions.length;
|
||||
} else {
|
||||
tabCompletion.prefix = currentInput;
|
||||
tabCompletion.options = completionOptions;
|
||||
tabCompletion.index = 0;
|
||||
}
|
||||
|
||||
const focusedOption = completionOptions[tabCompletion.index];
|
||||
if (!focusedOption) return;
|
||||
const completedValue = focusedOption.value;
|
||||
tabCompletion.lastValue = completedValue;
|
||||
if (hasClearUserInput) prompt._clearUserInput();
|
||||
prompt._setUserInput(completedValue, true);
|
||||
});
|
||||
|
||||
const result = await prompt.prompt();
|
||||
await handleCancel(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color utility (picocolors instance from @clack/prompts)
|
||||
* @returns {Promise<Object>} The color utility (picocolors)
|
||||
|
|
@ -694,6 +842,7 @@ module.exports = {
|
|||
multiselect,
|
||||
autocompleteMultiselect,
|
||||
autocomplete,
|
||||
directory,
|
||||
confirm,
|
||||
text,
|
||||
password,
|
||||
|
|
|
|||
|
|
@ -1436,7 +1436,7 @@ class UI {
|
|||
*/
|
||||
async promptForDirectory() {
|
||||
// Use sync validation because @clack/prompts doesn't support async validate
|
||||
const directory = await prompts.text({
|
||||
const directory = await prompts.directory({
|
||||
message: 'Installation directory:',
|
||||
default: process.cwd(),
|
||||
placeholder: process.cwd(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue