bmad-method 6.7.1 → 6.8.1-next.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +10 -0
- package/package.json +3 -2
- package/removals.txt +8 -0
- package/src/bmm-skills/1-analysis/bmad-agent-analyst/SKILL.md +2 -0
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/SKILL.md +2 -0
- package/src/bmm-skills/1-analysis/bmad-document-project/SKILL.md +1 -1
- package/src/bmm-skills/1-analysis/bmad-prfaq/SKILL.md +1 -1
- package/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md +5 -2
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/SKILL.md +1 -1
- package/src/bmm-skills/1-analysis/research/bmad-market-research/SKILL.md +1 -1
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/SKILL.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-agent-pm/SKILL.md +2 -0
- package/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/SKILL.md +2 -0
- package/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/customize.toml +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-prd/SKILL.md +9 -4
- package/src/bmm-skills/2-plan-workflows/bmad-prd/assets/prd-template.md +4 -7
- package/src/bmm-skills/2-plan-workflows/bmad-prd/assets/prd-validation-checklist.md +4 -4
- package/src/bmm-skills/2-plan-workflows/bmad-prd/references/headless.md +2 -2
- package/src/bmm-skills/2-plan-workflows/bmad-ux/SKILL.md +90 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/color-themes.md +9 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/design-directions.md +9 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/design-example-editorial.md +158 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/design-example-mobile.md +93 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/design-example-shadcn.md +109 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/excalidraw-wireframe.md +19 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/experience-example-mobile.md +112 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/experience-example-shadcn.md +133 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/headless-schemas.md +84 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/key-screens.md +29 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/assets/validation-report-template.html +319 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/customize.toml +100 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/references/creative-tools.md +19 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/references/design-md-spec.md +50 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/references/headless.md +37 -0
- package/src/bmm-skills/2-plan-workflows/bmad-ux/references/validate.md +115 -0
- package/src/bmm-skills/3-solutioning/bmad-agent-architect/SKILL.md +2 -0
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/SKILL.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-create-architecture/SKILL.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/SKILL.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-agent-dev/SKILL.md +2 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-code-review/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-correct-course/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-create-story/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-dev-story/SKILL.md +23 -8
- package/src/bmm-skills/4-implementation/bmad-investigate/SKILL.md +2 -0
- package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-quick-dev/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-retrospective/SKILL.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-sprint-planning/SKILL.md +2 -1
- package/src/bmm-skills/4-implementation/bmad-sprint-status/SKILL.md +2 -1
- package/src/bmm-skills/module-help.csv +1 -1
- package/src/core-skills/bmad-advanced-elicitation/methods.csv +69 -50
- package/src/core-skills/bmad-brainstorming/steps/step-03-technique-execution.md +6 -4
- package/src/core-skills/bmad-brainstorming/workflow.md +1 -1
- package/src/core-skills/bmad-party-mode/SKILL.md +44 -97
- package/src/core-skills/bmad-spec/SKILL.md +129 -0
- package/src/core-skills/bmad-spec/assets/headless-schemas.md +33 -0
- package/src/core-skills/bmad-spec/assets/spec-template.md +49 -0
- package/src/core-skills/bmad-spec/customize.toml +53 -0
- package/src/core-skills/module-help.csv +1 -1
- package/src/scripts/resolve_customization.py +9 -1
- package/src/scripts/tests/test_resolve_customization.py +50 -0
- package/tools/bundle-web-bundles.js +117 -0
- package/tools/installer/modules/custom-module-manager.js +113 -4
- package/tools/installer/modules/official-modules.js +83 -3
- package/tools/skill-validator.md +1 -19
- package/tools/validate-sidebar-order.js +388 -0
- package/tools/validate-skills.js +1 -40
- package/web-bundles/README.md +46 -0
- package/web-bundles/brainstorming-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/brainstorming-coach/SKILL.md +83 -0
- package/web-bundles/brainstorming-coach/brain-methods.csv +62 -0
- package/web-bundles/bundles.json +139 -0
- package/web-bundles/market-and-industry-research/INSTRUCTIONS.md +88 -0
- package/web-bundles/market-and-industry-research/SKILL.md +59 -0
- package/web-bundles/prd-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/prd-coach/SKILL.md +101 -0
- package/web-bundles/prd-coach/prd-template.md +165 -0
- package/web-bundles/prd-coach/prd-validation-checklist.md +135 -0
- package/web-bundles/prfaq-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/prfaq-coach/SKILL.md +139 -0
- package/web-bundles/product-brief-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/product-brief-coach/SKILL.md +113 -0
- package/web-bundles/ux-coach/INSTRUCTIONS.md +92 -0
- package/web-bundles/ux-coach/SKILL.md +187 -0
- package/web-bundles/ux-coach/ux-validation.md +100 -0
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/SKILL.md +0 -75
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/customize.toml +0 -41
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-01-init.md +0 -135
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-01b-continue.md +0 -127
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-02-discovery.md +0 -190
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-03-core-experience.md +0 -217
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-04-emotional-response.md +0 -220
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-05-inspiration.md +0 -235
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-06-design-system.md +0 -253
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-07-defining-experience.md +0 -255
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-08-visual-foundation.md +0 -225
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-09-design-directions.md +0 -225
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-10-user-journeys.md +0 -242
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-11-component-strategy.md +0 -249
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-12-ux-patterns.md +0 -238
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-13-responsive-accessibility.md +0 -265
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-14-complete.md +0 -177
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/ux-design-template.md +0 -13
- package/src/core-skills/bmad-distillator/SKILL.md +0 -177
- package/src/core-skills/bmad-distillator/agents/distillate-compressor.md +0 -116
- package/src/core-skills/bmad-distillator/agents/round-trip-reconstructor.md +0 -68
- package/src/core-skills/bmad-distillator/resources/compression-rules.md +0 -51
- package/src/core-skills/bmad-distillator/resources/distillate-format-reference.md +0 -227
- package/src/core-skills/bmad-distillator/resources/splitting-strategy.md +0 -78
- package/src/core-skills/bmad-distillator/scripts/analyze_sources.py +0 -300
- package/src/core-skills/bmad-distillator/scripts/tests/test_analyze_sources.py +0 -204
|
@@ -1,128 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bmad-party-mode
|
|
3
|
-
description: 'Orchestrates group discussions between installed BMAD agents
|
|
3
|
+
description: 'Orchestrates lively group discussions between installed BMAD agents or other personas. Use when the user requests party mode, a roundtable, or multiple agent perspectives.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Party Mode
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Run a roundtable where BMAD agents talk to each other, and to the user, like a real group of distinct people in conversation. Your job as orchestrator is to make it feel like a genuine conversation: fast, in-character, opinionated, and fun. Everything below is an objective, not a script. Use whatever mechanism your model and harness make available to hit it.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## What "Good" Feels Like
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- **It reads like people talking, not reports being filed.** Short turns. Reactions to what was just said. Banter. The energy of a group chat, not a stack of memos.
|
|
13
|
+
- **Every persona is unmistakably themselves:** their voice, humor, pet peeves, and ethos. If you hid the name labels, you'd still know who's speaking.
|
|
14
|
+
- **They clash.** Real drama beats consensus. Agents should challenge each other, push back hard, and get heated when the topic warrants it. Nobody is here to clap each other (or the user) on the back. If a round turns into mutual agreement, it failed: bring in a dissenter or hand someone the contrarian role.
|
|
15
|
+
- **Brevity by default.** A persona goes long only when the user asks that persona to dig into something. Nobody delivers a wall of text unprompted. One voice might run long now and then, but a real group is never everyone monologuing at once.
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
If a round comes back feeling like four essays stapled together, you missed the objective. Tighten it the next round.
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
## Setup
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
1. Load `{project-root}/_bmad/core/config.yaml`: greet with `{user_name}`, speak in `{communication_language}`.
|
|
22
|
+
2. Resolve the roster:
|
|
23
|
+
```bash
|
|
24
|
+
python3 {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root} --key agents
|
|
25
|
+
```
|
|
26
|
+
Each entry is keyed by `code` and carries `name`, `title`, `icon`, `description`, `module`, and `team`.
|
|
27
|
+
3. Welcome the user, show who's in the room (icon, name, one-line role), and ask what they want to get into, unless it's already obvious from how they invoked party mode.
|
|
28
|
+
4. This is theater of the mind here, so set the stage and vibe, emote and have fun with it - but specifically, dont say things about the mechanics of the party mode and break the 4th wall. Don't say "you have 4 agents in the room" or "agent X says". Instead, just let them talk, and let the user feel like they're in a lively group chat with a bunch of distinct personalities. Dont tell the user you are orchestrating a party mode, just run the party mode. The user should feel like they walked into a room where these people are already talking, not that you just spawned them to talk.
|
|
20
29
|
|
|
21
|
-
##
|
|
30
|
+
## How It Runs
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
**Default: you voice the room.** Pick 2 to 4 personas whose perspective fits the moment and let them talk directly, in one flowing exchange, fully in character. This is what keeps it fast and conversational. Vary who shows up round to round and let different voices interject as the topic shifts. Don't fall back on the same three agents every time.
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
- Use `{user_name}` for greeting
|
|
27
|
-
- Use `{communication_language}` for all communications
|
|
34
|
+
Each turn opens with `{icon} **{name}:**` and then that persona speaks. Present turns back to back so it reads as one conversation. Don't summarize, blend, or narrate what they "would" say. Let them say it.
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
**When independence matters, spawn them for real.** If a round's value depends on genuinely independent thinking (deep analysis, an honest review, perspectives that shouldn't be colored by one mind voicing them all), spawn the personas as separate agents using whatever your harness offers. Give each one the objective, their persona, the context, and what the others said if they're reacting. Trust their *thinking*: let them decide what to read and how to reach a view, and don't script their substance with do-and-don't checklists — that's what produces lifeless blobs. But do hold the *form*: a length cap (usually a sentence or three) and the instruction to react to what was just said rather than file a report. Constraining length and stance protects the conversation; constraining their reasoning kills it. Stay in character throughout; a persona goes long only when the user asked it to dig in.
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
python3 {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root} --key agents
|
|
33
|
-
```
|
|
38
|
+
Spawn in parallel for independent first-takes — everyone reacts to the topic fresh, fast. Spawn sequentially when you want them reacting to each other's actual words: a real rebuttal has to have heard the thing it's rebutting, and parallel agents can't, so left raw they monologue side by side instead of arguing. Sequential is slower but it's the only way subagents genuinely engage. Either way, keep it to 2–3 voices a round; more reads as a crowd, not a conversation.
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
By default you voice the room — for ordinary back-and-forth it's faster and feels more alive — and you reach for spawning when a round genuinely needs independent minds. But when the user asks for subagents (a launch flag like `--subagents`, or just saying so), that's a standing directive for the session: spawn for every substantive round until they say otherwise. Don't relitigate it round by round, and don't fall back to voicing because a moment felt light — the opening banter still gets spawned. A user who pinned the mode already made that call for you.
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
**Model choice:** match the model to the round. Something quick for banter, something stronger for deep work. If the user pins a model (for example, `--model <name>`), use it for everyone.
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
## Make It Feel Like One Conversation
|
|
40
45
|
|
|
41
|
-
|
|
46
|
+
Whether you voiced the room or spawned subagents, your job before presenting is the same: make it read like people responding to each other, not a row of separate answers all aimed at the user.
|
|
42
47
|
|
|
43
|
-
|
|
48
|
+
This matters most with subagents. Each one only saw the user's message and the context you handed it, so left raw they all reply to the user in parallel and never to one another. Stitch them together. Reorder turns so a rebuttal lands right after the thing it rebuts. Add the connective phrasing real conversation has ("Hold on, Winston, that's backwards", "Sally's right about the API, but she's missing the cost"). Let one persona pick up a thread another dropped, or cut in mid-thought.
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
Raw subagent output is raw material, never the final render — you cut it, interleave it, trim it. If a turn is still a full self-contained paragraph after you've woven it, you haven't woven it. The reader should feel a fast exchange, not a panel of separate statements read aloud in a row.
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
The hard rule: never change what an agent actually argued. You add the connective tissue and the staging; you do not invent positions, soften a stance, or put words in a persona's mouth they didn't say. Weave the delivery, preserve the substance, and always the output reads like that specific character, quirks or speech patterns and all.
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
- **Complex or cross-cutting topic**: 3-4 agents from different domains
|
|
51
|
-
- **User names specific agents**: Always include those, plus 1-2 complementary voices
|
|
52
|
-
- **User asks an agent to respond to another**: Spawn just that agent with the other's response as context
|
|
53
|
-
- **Rotate over time** — avoid the same 2 agents dominating every round
|
|
54
|
+
## Following the User's Lead
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
The user steers. Whatever they raise, serve the conversation:
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
- A new topic: fresh voices, keep it moving.
|
|
59
|
+
- "Winston, what do you make of Sally's take?": just Winston, reacting to Sally.
|
|
60
|
+
- "Bring in Amelia": Amelia joins, caught up on what's been said.
|
|
61
|
+
- "Go deeper on that, John": this is the cue to let John stretch out. Depth is earned by a direct ask.
|
|
62
|
+
- A question to the whole room: everyone relevant chimes in.
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
You are {name} ({title}), a BMAD agent in a collaborative roundtable discussion.
|
|
64
|
+
Any combination, any time, from one voice to the whole table.
|
|
62
65
|
|
|
63
|
-
##
|
|
64
|
-
{icon} {name} — {description}
|
|
66
|
+
## Keeping It Healthy
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
- **Everyone agreeing?** Drop in a contrarian, or hand someone the devil's-advocate hat.
|
|
69
|
+
- **Going in circles?** Name the impasse and ask the user where to point next.
|
|
70
|
+
- **User's gone quiet?** Ask straight: keep going, switch topics, or wrap up?
|
|
71
|
+
- **A flat turn?** Don't retry it. Move on; the user will ask for more if they want it.
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
## Wrapping Up
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
{if this is a cross-talk or reaction request, include the responses being reacted to — otherwise omit this section}
|
|
73
|
-
|
|
74
|
-
## The User's Message
|
|
75
|
-
{the user's actual message}
|
|
76
|
-
|
|
77
|
-
## Guidelines
|
|
78
|
-
- Respond authentically as {name}. Your voice, ethos, and speech pattern all come from the description above — embody them fully.
|
|
79
|
-
- Start your response with: {icon} **{name}:**
|
|
80
|
-
- Speak in {communication_language}.
|
|
81
|
-
- Scale your response to the substance — don't pad. If you have a brief point, make it briefly.
|
|
82
|
-
- Disagree with other agents when your perspective tells you to. Don't hedge or be polite about it.
|
|
83
|
-
- If you have nothing substantive to add, say so in one sentence rather than manufacturing an opinion.
|
|
84
|
-
- You may ask the user direct questions if something needs clarification.
|
|
85
|
-
- Do NOT use tools. Just respond with your perspective.
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**Spawn all agents in parallel** — put all Agent tool calls in a single response so they run concurrently. If `--model` was specified, use that model for all subagents. Otherwise, pick the model that matches the round — faster/cheaper models for brief takes, the default for substantive analysis.
|
|
89
|
-
|
|
90
|
-
**Solo mode** — if `--solo` is active, skip spawning. Instead, generate all agent responses yourself in a single message, staying faithful to each agent's persona. Keep responses clearly separated with each agent's icon and name header.
|
|
91
|
-
|
|
92
|
-
### 3. Present Responses
|
|
93
|
-
|
|
94
|
-
Present each agent's full response to the user — distinct, complete, and in their own voice. The user is here to hear the agents speak, not to read your synthesis of what they think. Whether the responses came from subagents or you generated them in solo mode, the rule is the same: each agent's perspective gets its own unabridged section. Never blend, paraphrase, or condense agent responses into a summary.
|
|
95
|
-
|
|
96
|
-
The format is simple: each agent's response one after another, separated by a blank line. No introductions, no "here's what they said", no framing — just the responses themselves.
|
|
97
|
-
|
|
98
|
-
After all agent responses are presented in full, you may optionally add a brief **Orchestrator Note** — flagging a disagreement worth exploring, or suggesting an agent to bring in next round. Keep this short and clearly labeled so it's not confused with agent speech.
|
|
99
|
-
|
|
100
|
-
### 4. Handle Follow-ups
|
|
101
|
-
|
|
102
|
-
The user drives what happens next. Common patterns:
|
|
103
|
-
|
|
104
|
-
| User says... | You do... |
|
|
105
|
-
|---|---|
|
|
106
|
-
| Continues the general discussion | Pick fresh agents, repeat the loop |
|
|
107
|
-
| "Winston, what do you think about what Sally said?" | Spawn just Winston with Sally's response as context |
|
|
108
|
-
| "Bring in Amelia on this" | Spawn Amelia with a summary of the discussion so far |
|
|
109
|
-
| "I agree with John, let's go deeper on that" | Spawn John + 1-2 others to expand on John's point |
|
|
110
|
-
| "What would Mary and Amelia think about Winston's approach?" | Spawn Mary and Amelia with Winston's response as context |
|
|
111
|
-
| Asks a question directed at everyone | Back to step 1 with all agents |
|
|
112
|
-
|
|
113
|
-
The key insight: you can spawn any combination at any time. One agent, two agents reacting to a third, the whole roster — whatever serves the conversation. Each spawn is cheap and independent.
|
|
114
|
-
|
|
115
|
-
## Keeping Context Manageable
|
|
116
|
-
|
|
117
|
-
As the conversation grows, you'll need to summarize prior rounds rather than passing the full transcript to each subagent. Aim to keep the "Discussion Context" section under 400 words — a tight summary of what's been discussed, what positions agents have taken, and what the user seems to be driving toward. Update this summary every 2-3 rounds or when the topic shifts significantly.
|
|
118
|
-
|
|
119
|
-
## When Things Go Sideways
|
|
120
|
-
|
|
121
|
-
- **Agents are all saying the same thing**: Bring in a contrarian voice, or ask a specific agent to play devil's advocate by framing the prompt that way.
|
|
122
|
-
- **Discussion is going in circles**: Summarize the impasse and ask the user what angle they want to explore next.
|
|
123
|
-
- **User seems disengaged**: Ask directly — continue, change topic, or wrap up?
|
|
124
|
-
- **Agent gives a weak response**: Don't retry. Present it and let the user decide if they want more from that agent.
|
|
125
|
-
|
|
126
|
-
## Exit
|
|
127
|
-
|
|
128
|
-
When the user says they're done (any natural phrasing — "thanks", "that's all", "end party mode", etc.), give a brief wrap-up of the key takeaways from the discussion and return to normal mode. Don't force exit triggers — just read the room.
|
|
75
|
+
When the user signals they're done (any phrasing: "thanks", "that's all", "end party"), give a quick read-back of the best takeaways and drop back to normal mode. Read the room; don't wait for a magic word.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmad-spec
|
|
3
|
+
description: Distill any intent input into the SPEC kernel + companions — the canonical, preservation-validated machine contract for downstream work. Use when the user says "create a spec", "distill this into a spec", "validate this spec", or "update the spec".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# BMad Spec
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Canonical transformer for the BMad spec-kernel ecosystem. Takes any intent input — vague idea, brain dump, PRD, GDD, RFC, brief, Slack thread, customer email, meeting transcript, mockups, mixed multi-source — and produces **SPEC.md** carrying the five-field kernel (Why, Capabilities, Constraints, Non-goals, Success signal) plus companion files for load-bearing content that does not fit or would bloat the kernel with expansive line-item detail. Together they are the machine contract every downstream BMad skill consumes.
|
|
10
|
+
|
|
11
|
+
Multiple skills may call to update the same spec over time.
|
|
12
|
+
|
|
13
|
+
## Conventions
|
|
14
|
+
|
|
15
|
+
- Bare paths (e.g. `assets/spec-template.md`) resolve from the skill root.
|
|
16
|
+
- `{skill-root}` is this skill's install dir; `{project-root}` is the working dir.
|
|
17
|
+
- `{workflow.<name>}` resolves to fields in `customize.toml`.
|
|
18
|
+
|
|
19
|
+
## On Activation
|
|
20
|
+
|
|
21
|
+
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly.
|
|
22
|
+
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (`file:` entries are loaded).
|
|
23
|
+
3. Load `{project-root}/_bmad/core/config.yaml` (and `config.user.yaml` if present), root level and `bmm` section. Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`.
|
|
24
|
+
4. Detect mode. **Headless** when any of: no TTY, programmatic caller (another skill or non-interactive runner), or the first message pre-supplies all inputs and asks for an artifact path back. **Interactive** otherwise. In interactive mode, greet by `{user_name}` in `{communication_language}`, stay in that language, and mention that `bmad-party-mode` and `bmad-advanced-elicitation` are available for deeper exploration on any field.
|
|
25
|
+
|
|
26
|
+
Run `{workflow.activation_steps_append}`.
|
|
27
|
+
|
|
28
|
+
Activation is complete. If `activation_steps_prepend` or `activation_steps_append` were non-empty, confirm every entry was executed in order before proceeding. Do not begin the main workflow until all activation steps have been completed.
|
|
29
|
+
|
|
30
|
+
## Workspace
|
|
31
|
+
|
|
32
|
+
The spec is **always a folder** named `{workflow.spec_output_path}/{workflow.run_folder_pattern}`, resolving by default to `{output_folder}/specs/spec-{slug}/`.
|
|
33
|
+
|
|
34
|
+
`{slug}` describes the thing being specced, not the input shape:
|
|
35
|
+
|
|
36
|
+
- Source artifact already carries a slug (e.g., `prd-foo-bar-2026-05-23/`): inherit (`foo-bar`).
|
|
37
|
+
- Sparse, in-chat, or multi-source input: interactive asks; headless caller provides it as part of the input. If absent and underivable, headless blocks with `error_code: "missing_slug"`.
|
|
38
|
+
- Same slug = same folder. A second invocation with the same `{slug}` lands at the existing spec folder and updates in place, preserving capability IDs.
|
|
39
|
+
|
|
40
|
+
**No input.** Interactive: ask the user to share a file path, paste content, explain the idea in detail, or point to a source. Headless: respond with JSON containing `error_code: "insufficient_intent"`.
|
|
41
|
+
|
|
42
|
+
Inside the spec folder:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
<spec-folder>/
|
|
46
|
+
SPEC.md ← uppercase, the kernel
|
|
47
|
+
<companion-1>.md ← optional, content-typed (e.g. glossary.md)
|
|
48
|
+
<companion-2>.md
|
|
49
|
+
.decision-log.md ← canonical memory for this spec
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## The Operation
|
|
53
|
+
|
|
54
|
+
Read the input and its ancillary linked materials. If there is no input, follow the no-input branch in **Workspace** (ask or block). If a prior `SPEC.md` exists at the target folder, read it too — the operation becomes an update. Preserve capability IDs; new capabilities get the next unused `CAP-N`; never reuse retired IDs. Otherwise this is a create.
|
|
55
|
+
|
|
56
|
+
When the input is structured and pre-sorted (a PRD with an addendum, a GDD, a brief produced by an upstream BMad skill), trust the authored separation: lift kernel-fitting content into SPEC.md, lift overflow into appropriately-named companions. When the input is mixed (a brain dump, a transcript, an RFC, a customer email), do the sorting yourself: walk each claim, apply the three-lens load-bearing test (Spec Law rule 7), and route to the kernel field or a companion.
|
|
57
|
+
|
|
58
|
+
Distill the input into the five-field kernel using `{workflow.spec_template}` as the skeleton. When input is rich, extract directly — no elicitation. When input is sparse, choose: **express** (best-effort distill, every gap becomes an `open_questions[]` entry) or **guided** (walk the five fields with the user one at a time). Headless defaults to express and logs the choice. Interactive asks.
|
|
59
|
+
|
|
60
|
+
Write lean from the first pass: every sentence must earn its place. Decoration costs tokens and dilutes downstream readers.
|
|
61
|
+
|
|
62
|
+
If the input is genuinely too thin to distill (e.g. "an app for hikers" with no surrounding context), stop and suggest `bmad-prd` (or sibling ceremony skill). This skill distills; it does not coach.
|
|
63
|
+
|
|
64
|
+
## Load-bearing
|
|
65
|
+
|
|
66
|
+
A claim is **load-bearing** if any consumer (downstream skill, implementing agent, verification pass) would change a decision without it.
|
|
67
|
+
|
|
68
|
+
## Companions
|
|
69
|
+
|
|
70
|
+
When load-bearing content does not fit the five-field kernel, it lives in a companion. The kernel cites it; the companion holds it. Companions are part of the contract; every consumer reads `companions:` in SPEC.md frontmatter to discover them. Companions follow the same lean discipline as SPEC.md (Spec Law rule 8).
|
|
71
|
+
|
|
72
|
+
**Spawn a companion when the content needs more than one kernel-shape line:** multi-item catalogs (per-entity matrices like archetypes, drinks, modes, routes), tables, diagrams (always), editorial voice rules, long-form reference material the kernel cites by name (glossary, brownfield notes, project conventions). Single-line decision-benders stay in Constraints; intent+success pairs stay in Capabilities. If a kernel field is starting to bullet into sub-bullets, the content has outgrown the kernel and wants a companion.
|
|
73
|
+
|
|
74
|
+
Companions are either:
|
|
75
|
+
|
|
76
|
+
- **Spec-authored** companions are written by bmad-spec and live as **siblings of SPEC.md** (e.g., `glossary.md`, `patron-archetypes.md`). bmad-spec owns them and may edit them on update operations.
|
|
77
|
+
- **Adopted** companions are load-bearing artifacts written by an upstream skill that downstream still needs to read. bmad-spec references them into `companions:` by relative path but does NOT edit them (e.g., a `DESIGN.md` or `EXPERIENCE.md` from a UX run, an integration partner's API spec). The originating skill owns them.
|
|
78
|
+
|
|
79
|
+
Two rules govern companions:
|
|
80
|
+
|
|
81
|
+
1. **Name spec-authored companions for the content type they hold.** `glossary.md`, `<entity-class>.md` (e.g. `patron-archetypes.md`, `medication-routes.md`, `flight-modes.md`), `stack.md`, `conventions.md`, `brownfield.md`, `architecture-diagrams.md`, `state-machines.md`, `failure-modes.md`, `compliance-references.md`. The principle: "a reader should know what is inside before opening it." Adopted companions keep whatever name their originating skill gave them.
|
|
82
|
+
2. **Diagrams always land in a companion**, regardless of size. SPEC.md kernel holds prose only. Mermaid blocks, ASCII diagrams, and image references all live in a companion (e.g. `architecture-diagrams.md`), with sibling image files referenced from there.
|
|
83
|
+
|
|
84
|
+
Pre-existing project-wide docs (e.g. `project-context.md`) that downstream needs are listed as **adopted companions**, never duplicated into SPEC.md or a spec-authored companion.
|
|
85
|
+
|
|
86
|
+
## Spec Law
|
|
87
|
+
|
|
88
|
+
Every spec must satisfy these eight rules. The operation aims for them; the self-validate sweep enforces them.
|
|
89
|
+
|
|
90
|
+
1. **Each capability has both `intent` and `success`.** Missing either = not a capability.
|
|
91
|
+
2. **Intents describe WHAT, not HOW.** Implementation prescription belongs in a companion (stack, conventions).
|
|
92
|
+
3. **Constraints actually bend design decisions.** A "constraint" that rules nothing out is decoration.
|
|
93
|
+
4. **Non-goals are explicit.** At least one. Absence means downstream skills fill the vacuum.
|
|
94
|
+
5. **Success signal is concrete enough to test or demonstrate against.** "Users love it" doesn't qualify.
|
|
95
|
+
6. **Capability IDs are stable and unique.** Never reused, never renumbered.
|
|
96
|
+
7. **Preservation.** Every load-bearing source claim lands in SPEC.md or a companion. Wrapper ceremony does not.
|
|
97
|
+
8. **Lean prose.** Every sentence carries load-bearing content. Cut decoration, hedges, backstory, throat-clearing. Applies to SPEC.md, companions, and `.decision-log.md`.
|
|
98
|
+
|
|
99
|
+
## Self-Validate
|
|
100
|
+
|
|
101
|
+
After every create or update, sweep the resulting artifact in **two passes** before presenting.
|
|
102
|
+
|
|
103
|
+
**Pass 1 — Coherence.** Judge the spec against Spec Law rules 1–6 and 8. For anything that fails or feels weak, attempt to fix it without inventing content the input did not support. Calls made without direct confirmation become `assumptions[]`; gaps that could not be filled become `open_questions[]`.
|
|
104
|
+
|
|
105
|
+
**Pass 2 — Preservation.** Walk the source claim by claim. Confirm each load-bearing claim landed in SPEC.md or a companion. Wrapper-ceremony drops are logged under "Wrapper-only content" so the drop is on the record, not silent.
|
|
106
|
+
|
|
107
|
+
Append a one-paragraph verdict to `.decision-log.md` covering both passes. In interactive mode, review the verdict with the user. In headless mode, `.decision-log.md` is one of the files returned, so the caller (or its downstream LLM) reads the verdict there.
|
|
108
|
+
|
|
109
|
+
## Spec with no change signal
|
|
110
|
+
|
|
111
|
+
When the user points the skill at an existing spec folder (or its SPEC.md) with no change signal, offer to review assumptions or open questions, or determine what they want to do.
|
|
112
|
+
|
|
113
|
+
## Output
|
|
114
|
+
|
|
115
|
+
**Interactive** — share the spec folder path conversationally. Name the capability count, the companions produced, and the verdict in one or two sentences. If `assumptions[]` or `open_questions[]` are non-empty, list them (short — one line each) and invite the user to walk through them. Make clear that addressing them can update the source input (if it was a file), the spec, or both — whichever combination the user prefers. Do not dump JSON or present a wall of output.
|
|
116
|
+
|
|
117
|
+
**Headless** — return JSON per `assets/headless-schemas.md`.
|
|
118
|
+
|
|
119
|
+
Run `{workflow.on_complete}` if set.
|
|
120
|
+
|
|
121
|
+
## After Spec is Output
|
|
122
|
+
|
|
123
|
+
Any update to spec regarding assumptions, open questions, or other changes should be appended to that source's decision log also and offer to update the source.
|
|
124
|
+
|
|
125
|
+
## Frontmatter conventions
|
|
126
|
+
|
|
127
|
+
- `companions:` array of `.md` files downstream MUST read alongside SPEC.md to have the full contract. Paths may point inside the spec folder (spec-authored companions like `glossary.md`) or outside it (adopted companions like `../planning-artifacts/ux-designs/ux-foo-bar-2026-05-23/DESIGN.md`). The split between spec-authored and adopted is implicit by path; downstream treats both the same.
|
|
128
|
+
- `sources:` array of paths to files that were **fully absorbed** into the SPEC, with no remaining downstream value (e.g., a PRD whose every load-bearing claim is now in the kernel). Listed for audit and for bmad-spec to re-read on update. Downstream does NOT read these. Files that downstream still needs to read belong in `companions:`, not here.
|
|
129
|
+
- **Do not list** decision logs, README files, organizational artifacts, or any operational record of how upstream skills produced their artifacts. Those are not source content; they are process metadata that downstream consumers don't need.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Headless JSON Response
|
|
2
|
+
|
|
3
|
+
The default invocation is headless: input goes in, JSON comes out. The contract is intentionally tiny — return the outcome and the files touched. Anything else a caller needs is inside those files (SPEC.md, companions, `.decision-log.md`).
|
|
4
|
+
|
|
5
|
+
## Success
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"status": "complete",
|
|
10
|
+
"files": [
|
|
11
|
+
"_bmad-output/specs/spec-quarter-drop/SPEC.md",
|
|
12
|
+
"_bmad-output/specs/spec-quarter-drop/glossary.md",
|
|
13
|
+
"_bmad-output/specs/spec-quarter-drop/.decision-log.md"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`files` lists every file written or modified in this run, in any order. The spec folder, kernel filename, decision log location, capabilities, companions, and verdict are all readable from those files; no need to re-encode them in the response.
|
|
19
|
+
|
|
20
|
+
## Blocked
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"status": "blocked",
|
|
25
|
+
"error_code": "insufficient_intent",
|
|
26
|
+
"reason": "Input was a one-line idea with no surrounding context; too thin to distill. Suggest bmad-prd to draw the vision out first."
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Defined `error_code` values:
|
|
31
|
+
|
|
32
|
+
- `insufficient_intent` — input too thin to distill into a kernel.
|
|
33
|
+
- `missing_slug` — input is sparse or multi-source and no slug was provided by the caller or derivable from a source path.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SPEC-{slug}
|
|
3
|
+
companions: [] # files downstream MUST read alongside SPEC.md. Paths may point inside the spec folder (spec-authored) or outside it (adopted from an upstream skill).
|
|
4
|
+
sources: [] # files fully absorbed into the SPEC (audit only; downstream does NOT read these). Never decision logs.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
> **Canonical contract.** This SPEC and the files in `companions:` are the complete, preservation-validated contract for what to build, test, and validate. Source documents listed in frontmatter are for traceability only — consult them only if you need narrative rationale or prose color this contract intentionally omits.
|
|
8
|
+
|
|
9
|
+
# {Spec Title}
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
{One paragraph naming the force behind this work. A spec can exist for any of:
|
|
14
|
+
- **a pain to solve** — a user or operator is stuck on a specific gap;
|
|
15
|
+
- **an opportunity to capture** — something newly possible we want to claim;
|
|
16
|
+
- **a vision to realize** — a thing we want to make exist because we want it to exist;
|
|
17
|
+
- **a mandate to meet** — a regulation, deprecation, deadline, or contractual obligation.
|
|
18
|
+
|
|
19
|
+
Name which (or which combination) applies, who is affected, and the backdrop that makes it matter now. This is the anchor every downstream trade-off resolves against.}
|
|
20
|
+
|
|
21
|
+
## Capabilities
|
|
22
|
+
|
|
23
|
+
- id: CAP-1
|
|
24
|
+
intent: {One sentence. "User or system can do X to achieve Y." WHAT, not HOW.}
|
|
25
|
+
success: {Testable or demonstrable criterion. Something a test or a real demonstration can decide.}
|
|
26
|
+
|
|
27
|
+
## Constraints
|
|
28
|
+
|
|
29
|
+
- {A non-negotiable that bends design. If it doesn't rule anything out, it doesn't belong.}
|
|
30
|
+
|
|
31
|
+
## Non-goals
|
|
32
|
+
|
|
33
|
+
- {Explicit out-of-scope item. At least one. Stops downstream from filling the vacuum.}
|
|
34
|
+
|
|
35
|
+
## Success signal
|
|
36
|
+
|
|
37
|
+
- {One or two sentences. World-change moment, not dashboard. Concrete enough to write a test or run a demonstration against.}
|
|
38
|
+
|
|
39
|
+
## Assumptions
|
|
40
|
+
|
|
41
|
+
<!-- Optional. Omit this section entirely if empty. Inferred calls made without direct confirmation from the input. -->
|
|
42
|
+
|
|
43
|
+
- {Statement of fact the Spec proceeded under, e.g. "Assumed mobile-first since input mentioned GPS but no platform."}
|
|
44
|
+
|
|
45
|
+
## Open Questions
|
|
46
|
+
|
|
47
|
+
<!-- Optional. Omit this section entirely if empty. Gaps the input did not resolve that need a human decision before downstream skills consume the Spec. -->
|
|
48
|
+
|
|
49
|
+
- {Question phrased so a human can answer it, e.g. "Is offline playback in scope for CAP-2?"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# DO NOT EDIT -- overwritten on every update.
|
|
2
|
+
#
|
|
3
|
+
# Workflow customization surface for bmad-spec.
|
|
4
|
+
#
|
|
5
|
+
# Override files (not edited here):
|
|
6
|
+
# {project-root}/_bmad/custom/bmad-spec.toml (team)
|
|
7
|
+
# {project-root}/_bmad/custom/bmad-spec.user.toml (personal)
|
|
8
|
+
|
|
9
|
+
[workflow]
|
|
10
|
+
|
|
11
|
+
# --- Configurable below. Overrides merge per BMad structural rules: ---
|
|
12
|
+
# scalars: override wins • arrays: append
|
|
13
|
+
|
|
14
|
+
# Steps to run before the standard activation (config load, greet).
|
|
15
|
+
activation_steps_prepend = []
|
|
16
|
+
|
|
17
|
+
# Steps to run after greet but before the operation begins.
|
|
18
|
+
activation_steps_append = []
|
|
19
|
+
|
|
20
|
+
# Persistent facts the workflow keeps in mind for the whole run.
|
|
21
|
+
# Each entry is either a literal sentence, a skill prefixed with `skill:`,
|
|
22
|
+
# or a `file:`-prefixed path/glob whose contents are loaded as facts.
|
|
23
|
+
# Default points to a single top-level file; override in team/user TOML
|
|
24
|
+
# to widen the scope (e.g. `_bmad/**/project-context.md`) if needed.
|
|
25
|
+
persistent_facts = [
|
|
26
|
+
"file:{project-root}/project-context.md",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
# Executed when the workflow completes. Scalar or array of instructions.
|
|
30
|
+
on_complete = ""
|
|
31
|
+
|
|
32
|
+
# Spec template. The five-field kernel skeleton. Override the path in
|
|
33
|
+
# team/user TOML to enforce a different shape (e.g. a hypothesis field
|
|
34
|
+
# for research initiatives, or a mechanics field for games).
|
|
35
|
+
spec_template = "assets/spec-template.md"
|
|
36
|
+
|
|
37
|
+
# Canonical filename for the kernel artifact inside the spec folder.
|
|
38
|
+
# Uppercase by convention to signal "the central source of truth."
|
|
39
|
+
spec_filename = "SPEC.md"
|
|
40
|
+
|
|
41
|
+
# Output path for spec folders. Lands directly under {output_folder}
|
|
42
|
+
# so bmad-spec works in core-only installs and matches the
|
|
43
|
+
# long-term BMad direction of grouping artifacts as siblings under
|
|
44
|
+
# {output_folder}/<type>/ rather than nested inside planning vs
|
|
45
|
+
# implementation folders.
|
|
46
|
+
spec_output_path = "{output_folder}/specs"
|
|
47
|
+
|
|
48
|
+
# Run-folder pattern inside spec_output_path. Resolved against the
|
|
49
|
+
# input-derived slug at activation. Same slug = same folder, so a
|
|
50
|
+
# second invocation updates the existing spec in place (capability
|
|
51
|
+
# IDs preserved). Override to add {date} or other components if a
|
|
52
|
+
# fresh dated history is preferred.
|
|
53
|
+
run_folder_pattern = "spec-{slug}"
|
|
@@ -9,5 +9,5 @@ Core,bmad-editorial-review-prose,Editorial Review - Prose,EP,Use after drafting
|
|
|
9
9
|
Core,bmad-editorial-review-structure,Editorial Review - Structure,ES,Use when doc produced from multiple subprocesses or needs structural improvement.,,[path],anytime,,,false,report located with target document,
|
|
10
10
|
Core,bmad-review-adversarial-general,Adversarial Review,AR,"Use for quality assurance or before finalizing deliverables. Code Review in other modules runs this automatically, but also useful for document reviews.",,[path],anytime,,,false,,
|
|
11
11
|
Core,bmad-review-edge-case-hunter,Edge Case Hunter Review,ECH,Use alongside adversarial review for orthogonal coverage — method-driven not attitude-driven.,,[path],anytime,,,false,,
|
|
12
|
-
Core,bmad-
|
|
12
|
+
Core,bmad-spec,Spec,SP,"Use to distill any intent input (brief, PRD, transcript, brain dump, design folder, mixed multi-source) into a succinct, no-fluff SPEC.md contract + companions that downstream work derives from. Locks the WHAT before the HOW. Works for software, game design, research, editorial, policy, business, anything intent-bearing. Validation mode also available.",,[path],anytime,,,false,{output_folder}/specs/spec-{slug},SPEC.md + companion files
|
|
13
13
|
Core,bmad-customize,BMad Customize,BC,"Use when you want to change how an agent or workflow behaves — add persistent facts, swap templates, insert activation hooks, or customize menus. Scans what's customizable, picks the right scope (agent vs workflow), writes the override to _bmad/custom/, and verifies the merge. No TOML hand-authoring required.",,,anytime,,,false,{project-root}/_bmad/custom,TOML override files
|
|
@@ -177,6 +177,14 @@ def extract_key(data, dotted_key: str):
|
|
|
177
177
|
return current
|
|
178
178
|
|
|
179
179
|
|
|
180
|
+
def write_json_stdout(output):
|
|
181
|
+
"""Write JSON as UTF-8 so Windows cp1252 stdout can carry emoji icons."""
|
|
182
|
+
reconfigure = getattr(sys.stdout, "reconfigure", None)
|
|
183
|
+
if reconfigure is not None:
|
|
184
|
+
reconfigure(encoding="utf-8")
|
|
185
|
+
sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
|
|
186
|
+
|
|
187
|
+
|
|
180
188
|
def main():
|
|
181
189
|
parser = argparse.ArgumentParser(
|
|
182
190
|
description="Resolve customization for a BMad skill using three-layer TOML merge.",
|
|
@@ -223,7 +231,7 @@ def main():
|
|
|
223
231
|
else:
|
|
224
232
|
output = merged
|
|
225
233
|
|
|
226
|
-
|
|
234
|
+
write_json_stdout(output)
|
|
227
235
|
|
|
228
236
|
|
|
229
237
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import tempfile
|
|
6
|
+
import unittest
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
SCRIPT = Path(__file__).resolve().parents[1] / "resolve_customization.py"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ResolveCustomizationStdoutTests(unittest.TestCase):
|
|
14
|
+
def test_writes_emoji_json_when_stdout_encoding_is_cp1252(self):
|
|
15
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
16
|
+
skill_dir = Path(temp_dir) / "emoji-agent"
|
|
17
|
+
skill_dir.mkdir()
|
|
18
|
+
(skill_dir / "customize.toml").write_text(
|
|
19
|
+
'[agent]\nname = "Emoji Agent"\nicon = "🧭"\n',
|
|
20
|
+
encoding="utf-8",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
env = os.environ.copy()
|
|
24
|
+
env["PYTHONIOENCODING"] = "cp1252"
|
|
25
|
+
result = subprocess.run(
|
|
26
|
+
[
|
|
27
|
+
sys.executable,
|
|
28
|
+
str(SCRIPT),
|
|
29
|
+
"--skill",
|
|
30
|
+
str(skill_dir),
|
|
31
|
+
"--key",
|
|
32
|
+
"agent",
|
|
33
|
+
],
|
|
34
|
+
stdout=subprocess.PIPE,
|
|
35
|
+
stderr=subprocess.PIPE,
|
|
36
|
+
env=env,
|
|
37
|
+
check=False,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
stderr = result.stderr.decode("utf-8", errors="replace")
|
|
41
|
+
self.assertEqual(result.returncode, 0, msg=stderr)
|
|
42
|
+
|
|
43
|
+
output = result.stdout.decode("utf-8")
|
|
44
|
+
self.assertIn("🧭", output)
|
|
45
|
+
resolved = json.loads(output)
|
|
46
|
+
self.assertEqual(resolved["agent"]["icon"], "🧭")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
unittest.main()
|