Compare commits

...

8 Commits

Author SHA1 Message Date
Markus Ende 4f7ee75e01
Merge 147144a1ec into 8cf22a4182 2026-02-22 18:00:19 +00:00
Brian Madison 8cf22a4182 open source tool skills updated, will move to separate plugin at a later time 2026-02-22 11:26:19 -06:00
Wendy Smoak d48d40d397
feat: migrate Codex installer from .codex/prompts to .agents/skills format (#1729)
* feat: migrate Codex installer from .codex/prompts to .agents/skills format

Switch CodexSetup to write BMAD artifacts as Agent Skills (agentskills.io
format) in .agents/skills/<name>/SKILL.md instead of flat files in
.codex/prompts. Remove global/project location prompt. Add legacy cleanup
of old .codex/prompts directories during install and uninstall.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ignore .agents for codex

* fix: normalize line endings and use platform-native EOL in SKILL.md output

Normalize all content to LF in transformToSkillFormat, then convert to
os.EOL (CRLF on Windows, LF on Linux/macOS) before writing SKILL.md
files in both writeSkillArtifacts and installCustomAgentLauncher.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ignore .agents directory

* use description from metadata in custom agent launcher

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:47:05 -06:00
Alex Verkhovsky 675e753e9b
refactor(skills): convert review-pr and audit-file-refs to bmad-os skills (#1732)
Move Raven PR review and file-ref audit from tools/ into
.claude/skills/ as proper bmad-os skills with SKILL.md + prompts/
instructions.md split pattern. Strip XML tags from Raven content,
promote sections to H2 headings. Delete originals from tools/.

Co-authored-by: Brian <bmadcode@gmail.com>
2026-02-22 10:46:32 -06:00
Alex Verkhovsky 276fcb1042
fix(workflows): correct broken step refs in create-architecture (#1734)
Update 9 files that referenced the old path
bmm/workflows/3-solutioning/architecture/steps/ to the correct
bmm/workflows/3-solutioning/create-architecture/steps/ after the
directory was renamed.

Fixes #1625

Co-authored-by: Junie <junie@jetbrains.com>
2026-02-22 10:45:38 -06:00
Alex Verkhovsky 99c1fa940a
feat: add LLM audit prompt for file reference conventions (#1720)
tools/audit-file-refs.md — a repeatable prompt that spawns parallel
Haiku subagents to semantically audit new-format source files for
non-conforming file references. Includes a self-check that verifies
all files are accounted for before producing the final report.

Replaces the planned regex extension (Item 1 of the master plan) with
an approach that can handle the full surface area of reference patterns
without exhaustive pattern enumeration.

Also excludes .junie/ from Prettier checks (IDE integration folder,
user-specific, not in repo).

Refs #1718

Co-authored-by: Brian <bmadcode@gmail.com>
2026-02-20 20:42:33 -06:00
wison bea89893fd
feat: add CodeBuddy platform support (#1483)
Add CodeBuddy (Tencent Cloud Code Assistant) as a supported IDE platform:

- Add platform config to tools/platform-codes.yaml

- Add installer config to tools/cli/installers/lib/ide/platform-codes.yaml

- Add .codebuddy to .gitignore

CodeBuddy uses the default template type with target directory .codebuddy/commands

Co-authored-by: wison <wisonlin@tencent.com>
Co-authored-by: Brian <bmadcode@gmail.com>
2026-02-20 20:39:52 -06:00
Daniel Bates eb6cf96912
fix: correct step file path in check-implementation-readiness workflow (#1709)
Fixes #1615

Co-authored-by: Your Name <your-email@example.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:38:12 -06:00
25 changed files with 314 additions and 326 deletions

View File

@ -0,0 +1,6 @@
---
name: bmad-os-audit-file-refs
description: Audit BMAD source files for file-reference convention violations using parallel Haiku subagents. Use when users requests an "audit file references" for a skill, workflow or task.
---
Read `prompts/instructions.md` and execute.

View File

@ -0,0 +1,59 @@
# audit-file-refs
Audit new-format BMAD source files for file-reference convention violations using parallel Haiku subagents.
## Convention
In new-format BMAD workflow and task files (`src/bmm/`, `src/core/`, `src/utility/`), every file path reference must use one of these **valid** forms:
- `{project-root}/_bmad/path/to/file.ext` — canonical form, always correct
- `{installed_path}/relative/path` — valid in new-format step files (always defined by workflow.md before any step is reached)
- Template/runtime variables: `{nextStepFile}`, `{workflowFile}`, `{{mustache}}`, `{output_folder}`, `{communication_language}`, etc. — skip these, they are substituted at runtime
**Flag any reference that uses:**
- `./step-NN.md` or `../something.md` — relative paths
- `step-NN.md` — bare filename with no path prefix
- `steps/step-NN.md` — bare steps-relative path (missing `{project-root}/_bmad/...` prefix)
- `` `_bmad/core/tasks/help.md` `` — bare `_bmad/` path (missing `{project-root}/`)
- `/Users/...`, `/home/...`, `C:\...` — absolute system paths
References inside fenced code blocks (``` ``` ```) are examples — skip them.
Old-format files in `src/bmm/workflows/4-implementation/` use `{installed_path}` by design within the XML calling chain — exclude that directory entirely.
## Steps
1. Run this command to get the file list:
```
find src/bmm src/core src/utility -type f \( -name "*.md" -o -name "*.yaml" \) | grep -v "4-implementation" | sort
```
2. Divide the resulting file paths into batches of roughly 20 files each.
3. For each batch, spawn a subagent (`subagent_type: "Explore"`, `model: "haiku"`) with this prompt (fill in the actual file paths):
> Read each of these files (use the Read tool on each):
> [list the file paths from this batch]
>
> For each file, identify every line that contains a file path reference that violates the convention described below. Skip references inside fenced code blocks. Skip template variables (anything containing `{` that isn't `{project-root}` or `{installed_path}`).
>
> **Valid references:** `{project-root}/_bmad/...`, `{installed_path}/...`, template variables.
> **Flag:** bare filenames (`step-NN.md`), `./` or `../` relative paths, bare `steps/` paths, bare `_bmad/` paths (without `{project-root}/`), absolute system paths.
>
> Return findings as a list:
> `path/to/file.md:LINE_NUMBER | VIOLATION_TYPE | offending text`
>
> If a file has no violations, include it as: `path/to/file.md | clean`
>
> End your response with a single line: `FILES CHECKED: N` where N is the exact number of files you read.
4. Collect all findings from all subagents.
5. **Self-check before reporting:** Count the total number of files returned by the `find` command. Sum the `FILES CHECKED: N` values across all subagent responses. If the totals do not match, identify which files are missing and re-run subagents for those files before proceeding. Do not produce the final report until all files are accounted for.
6. Output a final report:
- Group findings by violation type
- List each finding as `file:line — offending text`
- Show total count of violations and number of affected files
- If nothing found, say "All files conform to the convention."

View File

@ -1,7 +1,6 @@
---
name: bmad-os-changelog-social
description: Generate social media announcements for Discord, Twitter, and LinkedIn from the latest changelog entry. Use when user asks to create release announcements, social posts, or share changelog updates. Reads CHANGELOG.md in current working directory. Reference examples/ for tone and format.
disable-model-invocation: true
description: Generate social media announcements for Discord, Twitter, and LinkedIn from the latest changelog entry. Use when user asks to 'create release announcement' or 'create social posts' or share changelog updates.
---
# Changelog Social

View File

@ -1,7 +1,6 @@
---
name: bmad-os-diataxis-style-fix
description: Fixes documentation to comply with Diataxis framework and BMad Method style guide rules
disable-model-invocation: true
description: Fixes documentation to comply with Diataxis framework and BMad Method style guide rules. Use when user asks to check or fix style of files under the docs folder.
---
Read `prompts/instructions.md` and execute.

View File

@ -1,7 +1,6 @@
---
name: bmad-os-draft-changelog
description: Analyzes changes since last release and updates CHANGELOG.md ONLY. Does NOT trigger releases.
disable-model-invocation: true
description: "Analyzes changes since last release and updates CHANGELOG.md ONLY. Use when users requests 'update the changelog' or 'prepare changelog release notes'"
---
Read `prompts/instructions.md` and execute.

View File

@ -1,14 +0,0 @@
# gh-triage
Fetches all GitHub issues via gh CLI and uses AI agents to deeply analyze, cluster, and prioritize issues.
## Usage
Run from within any BMad Method repository to triage issues.
## What It Does
1. Fetches all open issues via `gh issue list`
2. Splits issues into batches
3. Launches parallel agents to analyze each batch
4. Generates comprehensive triage report to `_bmad-output/triage-reports/`

View File

@ -1,12 +1,6 @@
---
name: bmad-os-gh-triage
description: Fetch all GitHub issues via gh CLI and use AI agents to deeply analyze, cluster, and prioritize issues
license: MIT
disable-model-invocation: true
metadata:
author: bmad-code-org
version: "3.0.0"
compatibility: Requires gh CLI, git repository, and BMad Method with Task tool support
description: Analyze all github issues. Use when the user says 'triage the github issues' or 'analyze open github issues'.
---
Read `prompts/instructions.md` and execute.

View File

@ -1,24 +0,0 @@
# release-module
Automates the complete release process for npm modules.
## Usage
Run from project root or pass project path:
```
bmad-utility-skills:release-module
```
## Prerequisite
First run `draft-changelog` to analyze changes and create a draft changelog.
## What It Does
1. Gets and confirms changelog entry
2. Confirms version bump type (patch/minor/major)
3. Updates CHANGELOG.md
4. Bumps version with `npm version`
5. Pushes git tag
6. Publishes to npm
7. Creates GitHub release

View File

@ -1,7 +1,6 @@
---
name: bmad-os-release-module
description: Automates the complete release process for npm modules - version bump, changelog, git tag, npm publish, GitHub release
disable-model-invocation: true
description: Perform requested version bump, git tag, npm publish, GitHub release. Use when user requests 'perform a release' only.
---
Read `prompts/instructions.md` and execute.

View File

@ -0,0 +1,6 @@
---
name: bmad-os-review-pr
description: Adversarial PR review tool (Raven's Verdict). Cynical deep review transformed into professional engineering findings. Use when user asks to 'review a PR' and provides a PR url or id.
---
Read `prompts/instructions.md` and execute.

View File

@ -2,8 +2,7 @@
A cynical adversarial review, transformed into cold engineering professionalism.
<orientation>
CRITICAL: Sandboxed Execution Rules
## CRITICAL: Sandboxed Execution Rules
Before proceeding, you MUST verify:
@ -14,9 +13,6 @@ Before proceeding, you MUST verify:
**If no explicit PR number/URL was provided, STOP immediately and ask:**
"What PR number or URL should I review?"
</orientation>
<preflight-checks>
## Preflight Checks
@ -97,9 +93,7 @@ gh pr diff {PR_NUMBER} [--repo {REPO}] --name-only | grep -E '\.(png|jpg|jpeg|gi
Store list of binary files to skip. Note them in final output.
</preflight-checks>
<adversarial-review>
## Adversarial Review
### 1.1 Run Cynical Review
@ -130,9 +124,7 @@ Likely tag:
- Add `[likely]` to findings with high confidence, e.g. with direct evidence
- Sort findings by severity (Critical → Moderate → Minor), not by confidence
</adversarial-review>
<tone-transformation>
## Tone Transformation
**Transform the cynical output into cold engineering professionalism.**
@ -177,9 +169,8 @@ Output format after transformation:
_Review generated by Raven's Verdict. LLM-produced analysis - findings may be incorrect or lack context. Verify before acting._
```
</tone-transformation>
## Post Review
<post-review>
### 3.1 Preview
Display the complete transformed review to the user.
@ -231,12 +222,10 @@ Do NOT use heredocs or `echo` - Markdown code blocks will break shell parsing. U
Keep the temp file and inform user of location.
</post-review>
## Notes
<notes>
- The "cynical asshole" phase is internal only - never posted
- Tone transform MUST happen before any external output
- When in doubt, ask the user - never assume
- If you're unsure about severity, err toward higher severity
- If you're unsure about confidence, be honest and use Medium or Low
</notes>

2
.gitignore vendored
View File

@ -37,6 +37,7 @@ CLAUDE.local.md
.serena/
.claude/settings.local.json
.junie/
.agents/
z*/
@ -46,6 +47,7 @@ _bmad-output
# .augment/ is gitignored except tracked config files — add exceptions explicitly
.augment/*
!.augment/code_review_guidelines.yaml
.codebuddy
.crush
.cursor
.iflow

View File

@ -44,7 +44,7 @@ First, check if the output document already exists:
If the document exists and has frontmatter with `stepsCompleted`:
- **STOP here** and load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-01b-continue.md` immediately
- **STOP here** and load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md` immediately
- Do not proceed with any initialization tasks
- Let step-01b handle the continuation logic
@ -148,6 +148,6 @@ Ready to begin architectural decision making. Do you have any other documents yo
## NEXT STEP:
After user selects [C] to continue, only after ensuring all the template output has been created, then load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-02-context.md` to analyze the project context and begin architectural decision making.
After user selects [C] to continue, only after ensuring all the template output has been created, then load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md` to analyze the project context and begin architectural decision making.
Remember: Do NOT proceed to step-02 until user explicitly selects [C] from the menu and setup is confirmed!

View File

@ -85,7 +85,7 @@ Show the user their current progress:
- Identify the next step based on `stepsCompleted`
- Load the appropriate step file to continue
- Example: If `stepsCompleted: [1, 2, 3]`, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-04-decisions.md`
- Example: If `stepsCompleted: [1, 2, 3]`, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md`
#### If 'C' (Continue to next logical step):
@ -103,7 +103,7 @@ Show the user their current progress:
#### If 'X' (Start over):
- Confirm: "This will delete all existing architectural decisions. Are you sure? (y/n)"
- If confirmed: Delete existing document and read fully and follow: `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-01-init.md`
- If confirmed: Delete existing document and read fully and follow: `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md`
- If not confirmed: Return to continuation menu
### 4. Navigate to Selected Step
@ -162,12 +162,12 @@ After user makes choice:
After user selects their continuation option, load the appropriate step file based on their choice. The step file will handle the detailed work from that point forward.
Valid step files to load:
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-02-context.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-03-starter.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-04-decisions.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-05-patterns.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-06-structure.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-07-validation.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-08-complete.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md`
- `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md`
Remember: The goal is smooth, transparent resumption that respects the work already done while giving the user control over how to proceed.

View File

@ -188,7 +188,7 @@ Show the generated content and present choices:
- Append the final content to `{planning_artifacts}/architecture.md`
- Update frontmatter: `stepsCompleted: [1, 2]`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-03-starter.md`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md`
## APPEND TO DOCUMENT:
@ -219,6 +219,6 @@ When user selects 'C', append the content directly to the document using the str
## NEXT STEP:
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-03-starter.md` to evaluate starter template options.
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md` to evaluate starter template options.
Remember: Do NOT proceed to step-03 until user explicitly selects 'C' from the A/P/C menu and content is saved!

View File

@ -294,7 +294,7 @@ Show the generated content and present choices:
- Append the final content to `{planning_artifacts}/architecture.md`
- Update frontmatter: `stepsCompleted: [1, 2, 3]`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-04-decisions.md`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md`
## APPEND TO DOCUMENT:
@ -324,6 +324,6 @@ When user selects 'C', append the content directly to the document using the str
## NEXT STEP:
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-04-decisions.md` to begin making specific architectural decisions.
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md` to begin making specific architectural decisions.
Remember: Do NOT proceed to step-04 until user explicitly selects 'C' from the A/P/C menu and content is saved!

View File

@ -282,7 +282,7 @@ Show the generated decisions content and present choices:
- Append the final content to `{planning_artifacts}/architecture.md`
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4]`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-05-patterns.md`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md`
## APPEND TO DOCUMENT:
@ -313,6 +313,6 @@ When user selects 'C', append the content directly to the document using the str
## NEXT STEP:
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-05-patterns.md` to define implementation patterns that ensure consistency across AI agents.
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md` to define implementation patterns that ensure consistency across AI agents.
Remember: Do NOT proceed to step-05 until user explicitly selects 'C' from the A/P/C menu and content is saved!

View File

@ -323,7 +323,7 @@ Show the generated patterns content and present choices:
- Append the final content to `{planning_artifacts}/architecture.md`
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5]`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-06-structure.md`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md`
## APPEND TO DOCUMENT:
@ -354,6 +354,6 @@ When user selects 'C', append the content directly to the document using the str
## NEXT STEP:
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-06-structure.md` to define the complete project structure.
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md` to define the complete project structure.
Remember: Do NOT proceed to step-06 until user explicitly selects 'C' from the A/P/C menu and content is saved!

View File

@ -343,7 +343,7 @@ Show the generated project structure content and present choices:
- Append the final content to `{planning_artifacts}/architecture.md`
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5, 6]`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-07-validation.md`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md`
## APPEND TO DOCUMENT:
@ -374,6 +374,6 @@ When user selects 'C', append the content directly to the document using the str
## NEXT STEP:
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-07-validation.md` to validate architectural coherence and completeness.
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md` to validate architectural coherence and completeness.
Remember: Do NOT proceed to step-07 until user explicitly selects 'C' from the A/P/C menu and content is saved!

View File

@ -323,7 +323,7 @@ Show the validation results and present choices:
- Append the final content to `{planning_artifacts}/architecture.md`
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5, 6, 7]`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-08-complete.md`
- Load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md`
## APPEND TO DOCUMENT:
@ -354,6 +354,6 @@ When user selects 'C', append the content directly to the document using the str
## NEXT STEP:
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-08-complete.md` to complete the workflow and provide implementation guidance.
After user selects 'C' and content is saved to document, load `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md` to complete the workflow and provide implementation guidance.
Remember: Do NOT proceed to step-08 until user explicitly selects 'C' from the A/P/C menu and content is saved!

View File

@ -44,6 +44,6 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
## EXECUTION
Read fully and follow: `{project-root}/_bmad/bmm/workflows/3-solutioning/architecture/steps/step-01-init.md` to begin the workflow.
Read fully and follow: `{project-root}/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md` to begin the workflow.
**Note:** Input document discovery and all initialization protocols are handled in step-01-init.md.

View File

@ -1,6 +1,7 @@
const path = require('node:path');
const fs = require('fs-extra');
const os = require('node:os');
const fs = require('fs-extra');
const yaml = require('yaml');
const { BaseIdeSetup } = require('./_base-ide');
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
@ -17,57 +18,6 @@ class CodexSetup extends BaseIdeSetup {
super('codex', 'Codex', false);
}
/**
* Collect configuration choices before installation
* @param {Object} options - Configuration options
* @returns {Object} Collected configuration
*/
async collectConfiguration(options = {}) {
// Non-interactive mode: use default (project) - recommended for real work
if (options.skipPrompts) {
return { installLocation: options.codexLocation || 'project' };
}
let confirmed = false;
let installLocation = 'global';
while (!confirmed) {
installLocation = await prompts.select({
message: 'Where would you like to install Codex CLI prompts?',
choices: [
{
name: 'Global - Simple for single project ' + '(~/.codex/prompts, but references THIS project only)',
value: 'global',
},
{
name: `Project-specific - Recommended for real work (requires CODEX_HOME=<project-dir>${path.sep}.codex)`,
value: 'project',
},
],
default: 'global',
});
// Show brief confirmation hint (detailed instructions available via verbose)
if (installLocation === 'project') {
await prompts.log.info('Prompts installed to: <project>/.codex/prompts (requires CODEX_HOME)');
} else {
await prompts.log.info('Prompts installed to: ~/.codex/prompts');
}
// Confirm the choice
confirmed = await prompts.confirm({
message: 'Proceed with this installation option?',
default: true,
});
if (!confirmed) {
await prompts.log.warn("Let's choose a different installation option.");
}
}
return { installLocation };
}
/**
* Setup Codex configuration
* @param {string} projectDir - Project directory
@ -80,20 +30,25 @@ class CodexSetup extends BaseIdeSetup {
// Always use CLI mode
const mode = 'cli';
// Get installation location from pre-collected config or default to global
const installLocation = options.preCollectedConfig?.installLocation || 'global';
const { artifacts, counts } = await this.collectClaudeArtifacts(projectDir, bmadDir, options);
const destDir = this.getCodexPromptDir(projectDir, installLocation);
await fs.ensureDir(destDir);
await this.clearOldBmadFiles(destDir, options);
// Clean up old .codex/prompts locations (both global and project)
const oldGlobalDir = this.getOldCodexPromptDir(null, 'global');
await this.clearOldBmadFiles(oldGlobalDir, options);
const oldProjectDir = this.getOldCodexPromptDir(projectDir, 'project');
await this.clearOldBmadFiles(oldProjectDir, options);
// Collect artifacts and write using underscore format
// Install to .agents/skills
const destDir = this.getCodexSkillsDir(projectDir);
await fs.ensureDir(destDir);
await this.clearOldBmadSkills(destDir, options);
// Collect and write agent skills
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
const agentCount = await agentGen.writeDashArtifacts(destDir, agentArtifacts);
const agentCount = await this.writeSkillArtifacts(destDir, agentArtifacts, 'agent-launcher');
// Collect and write task skills
const tasks = await getTasksFromBmad(bmadDir, options.selectedModules || []);
const taskArtifacts = [];
for (const task of tasks) {
@ -117,19 +72,23 @@ class CodexSetup extends BaseIdeSetup {
});
}
const ttGen = new TaskToolCommandGenerator(this.bmadFolderName);
const taskSkillArtifacts = taskArtifacts.map((artifact) => ({
...artifact,
content: ttGen.generateCommandContent(artifact, artifact.type),
}));
const tasksWritten = await this.writeSkillArtifacts(destDir, taskSkillArtifacts, 'task');
// Collect and write workflow skills
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
const { artifacts: workflowArtifacts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
const workflowCount = await workflowGenerator.writeDashArtifacts(destDir, workflowArtifacts);
// Also write tasks using underscore format
const ttGen = new TaskToolCommandGenerator(this.bmadFolderName);
const tasksWritten = await ttGen.writeDashArtifacts(destDir, taskArtifacts);
const workflowCount = await this.writeSkillArtifacts(destDir, workflowArtifacts, 'workflow-command');
const written = agentCount + workflowCount + tasksWritten;
if (!options.silent) {
await prompts.log.success(
`${this.name} configured: ${counts.agents} agents, ${counts.workflows} workflows, ${counts.tasks} tasks, ${written} files → ${destDir}`,
`${this.name} configured: ${counts.agents} agents, ${counts.workflows} workflows, ${counts.tasks} tasks, ${written} skills → ${destDir}`,
);
}
@ -140,35 +99,18 @@ class CodexSetup extends BaseIdeSetup {
counts,
destination: destDir,
written,
installLocation,
};
}
/**
* Detect Codex installation by checking for BMAD prompt exports
* Detect Codex installation by checking for BMAD skills
*/
async detect(projectDir) {
// Check both global and project-specific locations
const globalDir = this.getCodexPromptDir(null, 'global');
const projectDir_local = projectDir || process.cwd();
const projectSpecificDir = this.getCodexPromptDir(projectDir_local, 'project');
const dir = this.getCodexSkillsDir(projectDir || process.cwd());
// Check global location
if (await fs.pathExists(globalDir)) {
if (await fs.pathExists(dir)) {
try {
const entries = await fs.readdir(globalDir);
if (entries && entries.some((entry) => entry && typeof entry === 'string' && entry.startsWith('bmad'))) {
return true;
}
} catch {
// Ignore errors
}
}
// Check project-specific location
if (await fs.pathExists(projectSpecificDir)) {
try {
const entries = await fs.readdir(projectSpecificDir);
const entries = await fs.readdir(dir);
if (entries && entries.some((entry) => entry && typeof entry === 'string' && entry.startsWith('bmad'))) {
return true;
}
@ -240,26 +182,138 @@ class CodexSetup extends BaseIdeSetup {
};
}
getCodexPromptDir(projectDir = null, location = 'global') {
getCodexSkillsDir(projectDir) {
if (!projectDir) {
throw new Error('projectDir is required for project-scoped skill installation');
}
return path.join(projectDir, '.agents', 'skills');
}
/**
* Get the old .codex/prompts directory for cleanup purposes
*/
getOldCodexPromptDir(projectDir = null, location = 'global') {
if (location === 'project' && projectDir) {
return path.join(projectDir, '.codex', 'prompts');
}
return path.join(os.homedir(), '.codex', 'prompts');
}
async flattenAndWriteArtifacts(artifacts, destDir) {
let written = 0;
/**
* Write artifacts as Agent Skills (agentskills.io format).
* Each artifact becomes a directory containing SKILL.md.
* @param {string} destDir - Base skills directory
* @param {Array} artifacts - Artifacts to write
* @param {string} artifactType - Type filter (e.g., 'agent-launcher', 'workflow-command', 'task')
* @returns {number} Number of skills written
*/
async writeSkillArtifacts(destDir, artifacts, artifactType) {
let writtenCount = 0;
for (const artifact of artifacts) {
const flattenedName = this.flattenFilename(artifact.relativePath);
const targetPath = path.join(destDir, flattenedName);
await fs.writeFile(targetPath, artifact.content);
written++;
// Filter by type if the artifact has a type field
if (artifact.type && artifact.type !== artifactType) {
continue;
}
// Get the dash-format name (e.g., bmad-bmm-create-prd.md) and remove .md
const flatName = toDashPath(artifact.relativePath);
const skillName = flatName.replace(/\.md$/, '');
// Create skill directory
const skillDir = path.join(destDir, skillName);
await fs.ensureDir(skillDir);
// Transform content: rewrite frontmatter for skills format
const skillContent = this.transformToSkillFormat(artifact.content, skillName);
// Write SKILL.md with platform-native line endings
const platformContent = skillContent.replaceAll('\n', os.EOL);
await fs.writeFile(path.join(skillDir, 'SKILL.md'), platformContent, 'utf8');
writtenCount++;
}
return written;
return writtenCount;
}
/**
* Transform artifact content from Codex prompt format to Agent Skills format.
* Removes disable-model-invocation, ensures name matches directory.
* @param {string} content - Original content with YAML frontmatter
* @param {string} skillName - Skill name (must match directory name)
* @returns {string} Transformed content
*/
transformToSkillFormat(content, skillName) {
// Normalize line endings so body matches rebuilt frontmatter (both LF)
content = content.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
// Parse frontmatter
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
if (!fmMatch) {
// No frontmatter -- wrap with minimal frontmatter
const fm = yaml.stringify({ name: skillName, description: skillName }).trimEnd();
return `---\n${fm}\n---\n\n${content}`;
}
const frontmatter = fmMatch[1];
const body = fmMatch[2];
// Parse frontmatter with yaml library to handle all quoting variants
let description;
try {
const parsed = yaml.parse(frontmatter);
description = parsed?.description || `${skillName} skill`;
} catch {
description = `${skillName} skill`;
}
// Build new frontmatter with only skills-spec fields, let yaml handle quoting
const newFrontmatter = yaml.stringify({ name: skillName, description }, { lineWidth: 0 }).trimEnd();
return `---\n${newFrontmatter}\n---\n${body}`;
}
/**
* Remove existing BMAD skill directories from the skills directory.
*/
async clearOldBmadSkills(destDir, options = {}) {
if (!(await fs.pathExists(destDir))) {
return;
}
let entries;
try {
entries = await fs.readdir(destDir);
} catch (error) {
if (!options.silent) await prompts.log.warn(`Warning: Could not read directory ${destDir}: ${error.message}`);
return;
}
if (!entries || !Array.isArray(entries)) {
return;
}
for (const entry of entries) {
if (!entry || typeof entry !== 'string') {
continue;
}
if (!entry.startsWith('bmad')) {
continue;
}
const entryPath = path.join(destDir, entry);
try {
await fs.remove(entryPath);
} catch (error) {
if (!options.silent) {
await prompts.log.message(` Skipping ${entry}: ${error.message}`);
}
}
}
}
/**
* Clean old BMAD files from legacy .codex/prompts directories.
*/
async clearOldBmadFiles(destDir, options = {}) {
if (!(await fs.pathExists(destDir))) {
return;
@ -299,30 +353,11 @@ class CodexSetup extends BaseIdeSetup {
}
async readAndProcessWithProject(filePath, metadata, projectDir) {
const content = await fs.readFile(filePath, 'utf8');
const rawContent = await fs.readFile(filePath, 'utf8');
const content = rawContent.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
return super.processContent(content, metadata, projectDir);
}
/**
* Get instructions for global installation
* @returns {string} Instructions text
*/
getGlobalInstructions(destDir) {
const lines = [
'IMPORTANT: Codex Configuration',
'',
'/prompts installed globally to your HOME DIRECTORY.',
'',
'These prompts reference a specific _bmad path.',
"To use with other projects, you'd need to copy the _bmad dir.",
'',
'You can now use /commands in Codex CLI',
' Example: /bmad_bmm_pm',
' Type / to see all available commands',
];
return lines.join('\n');
}
/**
* Get instructions for project-specific installation
* @param {string} projectDir - Optional project directory
@ -330,95 +365,74 @@ class CodexSetup extends BaseIdeSetup {
* @returns {string} Instructions text
*/
getProjectSpecificInstructions(projectDir = null, destDir = null) {
const isWindows = os.platform() === 'win32';
const commonLines = [
const lines = [
'Project-Specific Codex Configuration',
'',
`Prompts will be installed to: ${destDir || '<project>/.codex/prompts'}`,
'',
'REQUIRED: You must set CODEX_HOME to use these prompts',
`Skills installed to: ${destDir || '<project>/.agents/skills'}`,
'',
'Codex automatically discovers skills in .agents/skills/ at and above the current directory and in your home directory.',
'No additional configuration is needed.',
];
const windowsLines = [
'Create a codex.cmd file in your project root:',
'',
' @echo off',
' set CODEX_HOME=%~dp0.codex',
' codex %*',
'',
String.raw`Then run: .\codex instead of codex`,
'(The %~dp0 gets the directory of the .cmd file)',
];
const unixLines = [
'Add this alias to your ~/.bashrc or ~/.zshrc:',
'',
' alias codex=\'CODEX_HOME="$PWD/.codex" codex\'',
'',
'After adding, run: source ~/.bashrc (or source ~/.zshrc)',
'(The $PWD uses your current working directory)',
];
const closingLines = ['', 'This tells Codex CLI to use prompts from this project instead of ~/.codex'];
const lines = [...commonLines, ...(isWindows ? windowsLines : unixLines), ...closingLines];
return lines.join('\n');
}
/**
* Cleanup Codex configuration
* Cleanup Codex configuration - cleans both new .agents/skills and old .codex/prompts
*/
async cleanup(projectDir = null) {
// Clean both global and project-specific locations
const globalDir = this.getCodexPromptDir(null, 'global');
await this.clearOldBmadFiles(globalDir);
// Clean old .codex/prompts locations
const oldGlobalDir = this.getOldCodexPromptDir(null, 'global');
await this.clearOldBmadFiles(oldGlobalDir);
if (projectDir) {
const projectSpecificDir = this.getCodexPromptDir(projectDir, 'project');
await this.clearOldBmadFiles(projectSpecificDir);
const oldProjectDir = this.getOldCodexPromptDir(projectDir, 'project');
await this.clearOldBmadFiles(oldProjectDir);
// Clean new .agents/skills location
const destDir = this.getCodexSkillsDir(projectDir);
await this.clearOldBmadSkills(destDir);
}
}
/**
* Install a custom agent launcher for Codex
* @param {string} projectDir - Project directory (not used, Codex installs to home)
* Install a custom agent launcher for Codex as an Agent Skill
* @param {string} projectDir - Project directory
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
* @param {string} agentPath - Path to compiled agent (relative to project root)
* @param {Object} metadata - Agent metadata
* @returns {Object|null} Info about created command
* @returns {Object|null} Info about created skill
*/
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
const destDir = this.getCodexPromptDir(projectDir, 'project');
await fs.ensureDir(destDir);
const destDir = this.getCodexSkillsDir(projectDir);
const launcherContent = `---
name: '${agentName}'
description: '${agentName} agent'
disable-model-invocation: true
---
// Skill name from the dash name (without .md)
const skillName = customAgentDashName(agentName).replace(/\.md$/, '');
const skillDir = path.join(destDir, skillName);
await fs.ensureDir(skillDir);
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
const description = metadata?.description || `${agentName} agent`;
const fm = yaml.stringify({ name: skillName, description }).trimEnd();
const skillContent =
`---\n${fm}\n---\n` +
"\nYou must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.\n" +
'\n<agent-activation CRITICAL="TRUE">\n' +
`1. LOAD the FULL agent file from @${agentPath}\n` +
'2. READ its entire contents - this contains the complete agent persona, menu, and instructions\n' +
'3. FOLLOW every step in the <activation> section precisely\n' +
'4. DISPLAY the welcome/greeting as instructed\n' +
'5. PRESENT the numbered menu\n' +
'6. WAIT for user input before proceeding\n' +
'</agent-activation>\n';
<agent-activation CRITICAL="TRUE">
1. LOAD the FULL agent file from @${agentPath}
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
3. FOLLOW every step in the <activation> section precisely
4. DISPLAY the welcome/greeting as instructed
5. PRESENT the numbered menu
6. WAIT for user input before proceeding
</agent-activation>
`;
// Use underscore format: bmad_custom_fred-commit-poet.md
const fileName = customAgentDashName(agentName);
const launcherPath = path.join(destDir, fileName);
await fs.writeFile(launcherPath, launcherContent, 'utf8');
// Write with platform-native line endings
const platformContent = skillContent.replaceAll('\n', os.EOL);
const skillPath = path.join(skillDir, 'SKILL.md');
await fs.writeFile(skillPath, platformContent, 'utf8');
return {
path: path.relative(projectDir, launcherPath),
command: `/${fileName.replace('.md', '')}`,
path: path.relative(projectDir, skillPath),
command: `$${skillName}`,
};
}
}

View File

@ -57,6 +57,15 @@ platforms:
description: "OpenAI Codex integration"
# No installer config - uses custom codex.js
codebuddy:
name: "CodeBuddy"
preferred: false
category: ide
description: "Tencent Cloud Code Assistant - AI-powered coding companion"
installer:
target_dir: .codebuddy/commands
template_type: default
crush:
name: "Crush"
preferred: false

View File

@ -1,55 +0,0 @@
# Raven's Verdict - Deep PR Review Tool
Adversarial code review for GitHub PRs. Works with any LLM agent.
> **Status: Experimental.** We're still figuring out how to use this effectively. Expect the workflow to evolve.
## How It Works
Point your agent at `review-pr.md` and ask it to review a specific PR:
> "Read tools/maintainer/review-pr.md and apply it to PR #123"
The tool will:
1. Check out the PR branch locally
2. Run an adversarial review (find at least 5 issues)
3. Transform findings into professional tone
4. Preview the review and ask before posting
See `review-pr.md` for full prompt structure, severity ratings, and sandboxing rules.
## When to Use
**Good candidates:**
- PRs with meaningful logic changes
- Refactors touching multiple files
- New features or architectural changes
**Skip it for:**
- Trivial PRs (typo fixes, version bumps, single-line changes)
- PRs you've already reviewed manually
- PRs where you haven't agreed on the approach yet — fix the direction before the implementation
## Workflow Tips
**Always review before posting.** The preview step exists for a reason:
- **[y] Yes** — Post as-is (only if you're confident)
- **[e] Edit** — Modify findings before posting
- **[s] Save only** — Write to file, don't post
The save option is useful when you want to:
- Hand-edit the review before posting
- Use the findings as input for a second opinion ("Hey Claude, here's what Raven found — what do you think?")
- Cherry-pick specific findings
**Trust but verify.** LLM reviews can miss context or flag non-issues. Skim the findings before they hit the PR.
## Prerequisites
- `gh` CLI installed and authenticated (`gh auth status`)
- Any LLM agent capable of running bash commands

View File

@ -37,6 +37,12 @@ platforms:
category: ide
description: "OpenCode terminal coding assistant"
codebuddy:
name: "CodeBuddy"
preferred: false
category: ide
description: "Tencent Cloud Code Assistant - AI-powered coding companion"
auggie:
name: "Auggie"
preferred: false