Merge branch 'main' into v6-gems
This commit is contained in:
commit
67b2dd6717
|
|
@ -36,7 +36,7 @@ BMad ships six named agents, each anchored to a phase of the BMad Method:
|
||||||
| 📋 **John**, Product Manager | Planning | PRD creation, epic/story breakdown, implementation readiness |
|
| 📋 **John**, Product Manager | Planning | PRD creation, epic/story breakdown, implementation readiness |
|
||||||
| 🎨 **Sally**, UX Designer | Planning | UX design specifications |
|
| 🎨 **Sally**, UX Designer | Planning | UX design specifications |
|
||||||
| 🏗️ **Winston**, System Architect | Solutioning | technical architecture, alignment checks |
|
| 🏗️ **Winston**, System Architect | Solutioning | technical architecture, alignment checks |
|
||||||
| 💻 **Amelia**, Senior Engineer | Implementation | story execution, quick-dev, code review, sprint planning |
|
| 💻 **Amelia**, Senior Engineer | Implementation | story execution, quick-dev, code review, sprint planning, [forensic investigation](./forensic-investigation.md) |
|
||||||
|
|
||||||
They each have a hardcoded identity (name, title, domain) and a customizable layer (role, principles, communication style, icon, menu). You can rewrite Mary's principles or add menu items; you can't rename her — that's deliberate. Brand recognition survives customization so "hey Mary" always activates the analyst, regardless of how a team has shaped her behavior.
|
They each have a hardcoded identity (name, title, domain) and a customizable layer (role, principles, communication style, icon, menu). You can rewrite Mary's principles or add menu items; you can't rename her — that's deliberate. Brand recognition survives customization so "hey Mary" always activates the analyst, regardless of how a team has shaped her behavior.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ This page lists the default BMM (Agile suite) agents that install with BMad Meth
|
||||||
| Analyst (Mary) | `bmad-analyst` | `BP`, `MR`, `DR`, `TR`, `CB`, `WB`, `DP` | Brainstorm, Market Research, Domain Research, Technical Research, Create Brief, PRFAQ Challenge, Document Project |
|
| Analyst (Mary) | `bmad-analyst` | `BP`, `MR`, `DR`, `TR`, `CB`, `WB`, `DP` | Brainstorm, Market Research, Domain Research, Technical Research, Create Brief, PRFAQ Challenge, Document Project |
|
||||||
| Product Manager (John) | `bmad-pm` | `CP`, `VP`, `EP`, `CE`, `IR`, `CC` | Create/Validate/Edit PRD, Create Epics and Stories, Implementation Readiness, Correct Course |
|
| Product Manager (John) | `bmad-pm` | `CP`, `VP`, `EP`, `CE`, `IR`, `CC` | Create/Validate/Edit PRD, Create Epics and Stories, Implementation Readiness, Correct Course |
|
||||||
| Architect (Winston) | `bmad-architect` | `CA`, `IR` | Create Architecture, Implementation Readiness |
|
| Architect (Winston) | `bmad-architect` | `CA`, `IR` | Create Architecture, Implementation Readiness |
|
||||||
| Developer (Amelia) | `bmad-agent-dev` | `DS`, `QD`, `QA`, `CR`, `SP`, `CS`, `ER` | Dev Story, Quick Dev, QA Test Generation, Code Review, Sprint Planning, Create Story, Epic Retrospective |
|
| Developer (Amelia) | `bmad-agent-dev` | `DS`, `QD`, `QA`, `CR`, `SP`, `CS`, `ER`, `IN` | Dev Story, Quick Dev, QA Test Generation, Code Review, Sprint Planning, Create Story, Epic Retrospective, [Forensic Investigation](../explanation/forensic-investigation.md) |
|
||||||
| UX Designer (Sally) | `bmad-ux-designer` | `CU` | Create UX Design |
|
| UX Designer (Sally) | `bmad-ux-designer` | `CU` | Create UX Design |
|
||||||
| Technical Writer (Paige) | `bmad-tech-writer` | `DP`, `WD`, `US`, `MG`, `VD`, `EC` | Document Project, Write Document, Update Standards, Mermaid Generate, Validate Doc, Explain Concept |
|
| Technical Writer (Paige) | `bmad-tech-writer` | `DP`, `WD`, `US`, `MG`, `VD`, `EC` | Document Project, Write Document, Update Standards, Mermaid Generate, Validate Doc, Explain Concept |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,14 @@ def extract_key(data, dotted_key: str):
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
|
||||||
|
def write_json_stdout(output):
|
||||||
|
"""Write JSON as UTF-8 so Windows cp1252 stdout can carry emoji icons."""
|
||||||
|
reconfigure = getattr(sys.stdout, "reconfigure", None)
|
||||||
|
if reconfigure is not None:
|
||||||
|
reconfigure(encoding="utf-8")
|
||||||
|
sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Resolve customization for a BMad skill using three-layer TOML merge.",
|
description="Resolve customization for a BMad skill using three-layer TOML merge.",
|
||||||
|
|
@ -223,7 +231,7 @@ def main():
|
||||||
else:
|
else:
|
||||||
output = merged
|
output = merged
|
||||||
|
|
||||||
sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
|
write_json_stdout(output)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
SCRIPT = Path(__file__).resolve().parents[1] / "resolve_customization.py"
|
||||||
|
|
||||||
|
|
||||||
|
class ResolveCustomizationStdoutTests(unittest.TestCase):
|
||||||
|
def test_writes_emoji_json_when_stdout_encoding_is_cp1252(self):
|
||||||
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
|
skill_dir = Path(temp_dir) / "emoji-agent"
|
||||||
|
skill_dir.mkdir()
|
||||||
|
(skill_dir / "customize.toml").write_text(
|
||||||
|
'[agent]\nname = "Emoji Agent"\nicon = "🧭"\n',
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["PYTHONIOENCODING"] = "cp1252"
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(SCRIPT),
|
||||||
|
"--skill",
|
||||||
|
str(skill_dir),
|
||||||
|
"--key",
|
||||||
|
"agent",
|
||||||
|
],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
env=env,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
stderr = result.stderr.decode("utf-8", errors="replace")
|
||||||
|
self.assertEqual(result.returncode, 0, msg=stderr)
|
||||||
|
|
||||||
|
output = result.stdout.decode("utf-8")
|
||||||
|
self.assertIn("🧭", output)
|
||||||
|
resolved = json.loads(output)
|
||||||
|
self.assertEqual(resolved["agent"]["icon"], "🧭")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Loading…
Reference in New Issue