fix(bmad-prd): utf-8 encoding on render script, correct workflow-map outputs

- render-validation-html.py reads findings/template and writes HTML/MD with
  explicit utf-8 encoding so non-ASCII content (smart quotes, em-dashes,
  non-English text under {document_output_language}) does not break on
  platforms whose default encoding is not utf-8.
- workflow-map.md 'Produces' column for bmad-prd now distinguishes
  Create/Update outputs from the Validate intent's validation-report
  artifacts.
This commit is contained in:
Brian Madison 2026-05-13 16:33:47 -05:00
parent e7f80909fa
commit 6a56d2eb11
2 changed files with 5 additions and 5 deletions

View File

@ -46,7 +46,7 @@ Define what to build and for whom.
| Workflow | Purpose | Produces | | Workflow | Purpose | Produces |
|-------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------| |-------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------|
| `bmad-prd` | Create, update, or validate a PRD — facilitated discovery, three intents in one skill | `prd.md`, `addendum.md`, `decision-log.md` | | `bmad-prd` | Create, update, or validate a PRD — facilitated discovery, three intents in one skill | Create/Update: `prd.md`, `addendum.md`, `decision-log.md`; Validate: `validation-report.html` + `.md` |
| `bmad-create-ux-design` | Design user experience (when UX matters) | `ux-spec.md` | | `bmad-create-ux-design` | Design user experience (when UX matters) | `ux-spec.md` |
:::tip[Three intents in one skill] :::tip[Three intents in one skill]

View File

@ -220,7 +220,7 @@ def main(argv: list[str]) -> int:
output_path = Path(args.output) output_path = Path(args.output)
try: try:
data = json.loads(findings_path.read_text()) data = json.loads(findings_path.read_text(encoding="utf-8"))
except FileNotFoundError: except FileNotFoundError:
print(f"error: findings file not found: {findings_path}", file=sys.stderr) print(f"error: findings file not found: {findings_path}", file=sys.stderr)
return 1 return 1
@ -228,7 +228,7 @@ def main(argv: list[str]) -> int:
print(f"error: findings file is not valid JSON ({findings_path}): {e}", file=sys.stderr) print(f"error: findings file is not valid JSON ({findings_path}): {e}", file=sys.stderr)
return 1 return 1
try: try:
template = template_path.read_text() template = template_path.read_text(encoding="utf-8")
except FileNotFoundError: except FileNotFoundError:
print(f"error: template file not found: {template_path}", file=sys.stderr) print(f"error: template file not found: {template_path}", file=sys.stderr)
return 1 return 1
@ -268,10 +268,10 @@ def main(argv: list[str]) -> int:
} }
rendered = string.Template(template).safe_substitute(substitutions) rendered = string.Template(template).safe_substitute(substitutions)
output_path.write_text(rendered) output_path.write_text(rendered, encoding="utf-8")
md_path = output_path.with_suffix(".md") md_path = output_path.with_suffix(".md")
md_path.write_text(render_markdown_report(data, findings, stats, grade)) md_path.write_text(render_markdown_report(data, findings, stats, grade), encoding="utf-8")
print(json.dumps({ print(json.dumps({
"output": str(output_path), "output": str(output_path),