feat(cli): add /list-envs and enhance /set-project interactivity
This commit is contained in:
parent
89e310a6ce
commit
eb6568c8c1
|
|
@ -49,18 +49,21 @@ Core and BMM workflows automatically check for the existence of `{project-root}/
|
||||||
- **If found**: It reads the content (e.g., "app-alpha") and overrides the `output_folder` to `_bmad-output/app-alpha`.
|
- **If found**: It reads the content (e.g., "app-alpha") and overrides the `output_folder` to `_bmad-output/app-alpha`.
|
||||||
- **If not found**: It behaves like a standard single-project installation, outputting to `_bmad-output` root.
|
- **If not found**: It behaves like a standard single-project installation, outputting to `_bmad-output` root.
|
||||||
|
|
||||||
|
### The /list-envs Command
|
||||||
|
|
||||||
|
You can view all available environments created in your monorepo by running the `/list-envs` command. This will scan your `_bmad-output/` directory and display all existing project environments, as well as indicate which one is currently active.
|
||||||
|
|
||||||
### The /set-project Command
|
### The /set-project Command
|
||||||
|
|
||||||
You can easily manage the active project context using the `/set-project` workflow.
|
You can easily manage the active project context using the `/set-project` workflow.
|
||||||
|
|
||||||
**To set a context:**
|
**To set a context:**
|
||||||
1. Run `/set-project` in your chat.
|
1. Run `/set-project <env_name>` in your chat.
|
||||||
2. Select "Set Project Context".
|
2. If the environment does not exist, you will be prompted to create it interactively.
|
||||||
3. Enter the name of your project (e.g., `frontend`, `backend`, `mobile-app`).
|
3. If you run `/set-project` without an argument, it will automatically list available environments and prompt you to select one or create a new one.
|
||||||
|
|
||||||
**To clear context (return to single-project mode):**
|
**To clear context (return to single-project mode):**
|
||||||
1. Run `/set-project`.
|
1. Run `/set-project CLEAR`.
|
||||||
2. Select "Clear Project Context".
|
|
||||||
|
|
||||||
### Inline Override
|
### Inline Override
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
name: list-envs
|
||||||
|
description: List available project environments for monorepo support
|
||||||
|
main_config: '{project-root}/_bmad/bmm/config.yaml'
|
||||||
|
---
|
||||||
|
|
||||||
|
# List Project Environments
|
||||||
|
|
||||||
|
**Goal:** List the available project context environments for BMAD artifacts.
|
||||||
|
|
||||||
|
**Your Role:** Configuration Assistant.
|
||||||
|
|
||||||
|
## WORKFLOW ARCHITECTURE
|
||||||
|
|
||||||
|
### 1. Identify Environments
|
||||||
|
|
||||||
|
- Use your file listing/system capabilities to examine the `{project-root}/_bmad-output/` directory.
|
||||||
|
- Identify all subdirectories within this path. Each subdirectory represents an available environment (ignore hidden directories starting with `.`).
|
||||||
|
- The root `_bmad-output/` directory itself represents the `default (root)` unset environment.
|
||||||
|
|
||||||
|
### 2. Output Results
|
||||||
|
|
||||||
|
1. Display a formatted bulleted list of the existing environments you found.
|
||||||
|
2. Clearly indicate the `default (root)` environment.
|
||||||
|
3. Check if there is an active environment currently set. Read `{project-root}/{{bmadFolderName}}/.current_project`. If it exists, indicate which environment from the list is currently active (e.g. by adding `(ACTIVE)` next to the bullet point).
|
||||||
|
4. Inform the user that they can switch to another environment or create a new one using the `/set-project <env_name>` command.
|
||||||
|
|
@ -20,24 +20,35 @@ Load and read full config from {main_config} and resolve variables and artifact
|
||||||
|
|
||||||
### 2. Context Management
|
### 2. Context Management
|
||||||
|
|
||||||
1. **Ask User:** "Please enter the **project name** or path relative to `_bmad-output/` (e.g. `project-name` or `auth-lib`). Enter `CLEAR` to reset to root."
|
1. **Analyze Request**: Determine the requested project name from the user's initial invocation (e.g., `/set-project my-app`).
|
||||||
2. **Wait for Input.**
|
2. **Wait for Input (If Missing)**: If the user did NOT provide a project name:
|
||||||
3. **Process Input:**
|
- Use your file listing capabilities to examine the `{project-root}/_bmad-output/` directory.
|
||||||
|
- Output: A formatted list of the existing environments (subdirectories) you found, explicitly noting the `default (root)` environment.
|
||||||
|
- Ask the user: "Please select an existing environment from the list above, or type a new name to create one. Enter `CLEAR` to reset to root."
|
||||||
|
- **Wait for Input.**
|
||||||
|
3. **Process Input**: Once a project name is established:
|
||||||
- **Case: CLEAR**:
|
- **Case: CLEAR**:
|
||||||
- Delete file: `{project-root}/_bmad/.current_project`
|
- Delete file: `{project-root}/{{bmadFolderName}}/.current_project`
|
||||||
- Output: "✅ Project context cleared. Artifacts will go to root `_bmad-output/`."
|
- Output: "✅ Project context cleared. Artifacts will go to root `_bmad-output/`."
|
||||||
|
- **HALT**
|
||||||
- **Case: Path Provided**:
|
- **Case: Path Provided**:
|
||||||
- **1. Cleanup**: Remove leading/trailing slashes and any occurrences of `_bmad-output/`.
|
- **1. Cleanup**: Remove leading/trailing slashes and any occurrences of `_bmad-output/`.
|
||||||
- **2. Validate - No Traversal**: Reject if path contains `..`.
|
- **2. Validate Existence**: Check if `{project-root}/_bmad-output/<sanitized_path>` exists on the file system.
|
||||||
- **3. Validate - No Absolute**: Reject if path starts with `/` or drive letter (e.g., `C:`).
|
- **If it DOES NOT exist**:
|
||||||
- **4. Validate - Empty/Whitespace**: Reject if empty or only whitespace.
|
- Ask: "The environment `<sanitized_path>` is not present. Do you want to create a new one? (Yes/No)"
|
||||||
- **5. Validate - Whitelist**: Match against regex `^[a-zA-Z0-9._-/]+$`.
|
- **Wait for Input.**
|
||||||
|
- **If No**: Inform the user to run `/list-envs` to see available environments or `/set-project` to try again. **HALT**.
|
||||||
|
- **If Yes**: Proceed to validation.
|
||||||
|
- **3. Validate - No Traversal**: Reject if path contains `..`.
|
||||||
|
- **4. Validate - No Absolute**: Reject if path starts with `/` or drive letter (e.g., `C:`).
|
||||||
|
- **5. Validate - Empty/Whitespace**: Reject if empty or only whitespace.
|
||||||
|
- **6. Validate - Whitelist**: Match against regex `^[a-zA-Z0-9._-/]+$`.
|
||||||
- **Check Results**:
|
- **Check Results**:
|
||||||
- **If Invalid**:
|
- **If Invalid**:
|
||||||
- Output: "❌ Error: Invalid project context — must be a relative path and contain only alphanumeric characters, dots, dashes, underscores, or slashes. Traversal (..) is strictly forbidden."
|
- Output: "❌ Error: Invalid project context — must be a relative path and contain only alphanumeric characters, dots, dashes, underscores, or slashes. Traversal (..) is strictly forbidden."
|
||||||
- **HALT**
|
- **HALT**
|
||||||
- **If Valid**:
|
- **If Valid**:
|
||||||
- Write file: `{project-root}/_bmad/.current_project` with content `<sanitized_path>`
|
- Write file: `{project-root}/{{bmadFolderName}}/.current_project` with content `<sanitized_path>`
|
||||||
- Output: "✅ Project context set to: `<sanitized_path>`. Artifacts will go to `_bmad-output/<sanitized_path>/`."
|
- Output: "✅ Project context set to: `<sanitized_path>`. Artifacts will go to `_bmad-output/<sanitized_path>/`."
|
||||||
|
|
||||||
### 3. Verification
|
### 3. Verification
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ async function runTests() {
|
||||||
assert(exists, 'set-project workflow file exists');
|
assert(exists, 'set-project workflow file exists');
|
||||||
if (exists) {
|
if (exists) {
|
||||||
const content = await fs.readFile(setProjectPath, 'utf8');
|
const content = await fs.readFile(setProjectPath, 'utf8');
|
||||||
assert(content.includes('_bmad/.current_project'), 'set-project implementation manages .current_project');
|
assert(content.includes('{{bmadFolderName}}/.current_project'), 'set-project implementation manages .current_project');
|
||||||
const examplePattern = /(?:example|my[-_ ]?app|[a-z0-9]+-[a-z0-9]+)/i;
|
const examplePattern = /(?:example|my[-_ ]?app|[a-z0-9]+-[a-z0-9]+)/i;
|
||||||
assert(examplePattern.test(content), 'set-project examples use generic public-friendly names');
|
assert(examplePattern.test(content), 'set-project examples use generic public-friendly names');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue