Skip to content

bmad-brainstorming: selectable ideas + Export, in the artifact's own style#2559

Open
paulpreibisch wants to merge 1 commit into
bmad-code-org:brainstorming-improvedfrom
paulpreibisch:feat/brainstorm-idea-export-native
Open

bmad-brainstorming: selectable ideas + Export, in the artifact's own style#2559
paulpreibisch wants to merge 1 commit into
bmad-code-org:brainstorming-improvedfrom
paulpreibisch:feat/brainstorm-idea-export-native

Conversation

@paulpreibisch

Copy link
Copy Markdown
Contributor

Why

While reviewing a brainstorm, there was no way to act on it — just scroll and read. This lets the user mark the ideas (and insights, and chosen-direction cards) they like as they read, then export that shortlist for later — into bmad-forge-idea, bmad-product-brief, or another round of bmad-brainstorming.

What's in this PR

  • Updates references/finalize.md: every generated brainstorm.html must let the user mark favorites — every idea, every synthesis insight, every chosen-direction/convergence card — using a selection control built in that session's own visual language (checkbox, toggle, tap-to-star, whatever fits), never a generic bolted-on toolbar. An in-theme Export button appears once something's selected.
  • On Export, the page collects {text, section} for every selected item and downloads it as selection.json — a static local HTML page can't write files or invoke a script directly, so a browser download is the only thing its JS can do. The page then shows an in-page note pointing the user at the next step.
  • New src/core-skills/bmad-brainstorming/scripts/export-ideas.py: reads that selection.json and writes a clean selected-ideas.md next to the artifact, grouped by section, with pointers to what to feed it into next.
  • 10 pytest cases covering grouping, missing/blank text, malformed input, custom output names, etc. — all passing.

Test plan

  • uv run --with pytest pytest scripts/tests/test_export_ideas.py — 10/10 passing
  • Built two full test artifacts in distinct visual styles against a real 83-idea/7-insight/3-direction session, confirmed every idea/insight/direction card gets a selection control, confirmed a click-to-flip card's own interaction isn't triggered by the selection control
  • Full round trip: hand-built a selection.json matching what a real click would produce, ran export-ideas.py against it, confirmed selected-ideas.md landed correctly grouped next to the artifact
  • Maintainer review of the in-theme selection UX on a fresh session

…t's own visual style

Every generated brainstorm.html now lets the user mark favorites — every
idea, every synthesis insight, every chosen-direction card — using a
selection control built in that session's own visual language, never a
generic bolted-on toolbar. An in-theme Export button (visible once
something's selected) downloads the picks as selection.json, since a
static local HTML page can't write files or invoke a script directly.

scripts/export-ideas.py is the other half of that handoff: it reads the
downloaded selection.json and writes a clean selected-ideas.md next to
the artifact, ready to feed into bmad-forge-idea, bmad-product-brief, or
another round of bmad-brainstorming scoped to just the picks.
@augmentcode

augmentcode Bot commented Jul 5, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR makes brainstorm HTML keepsakes actionable by letting users mark favorite ideas/insights/directions and export them for downstream skills.

Changes:

  • Updates references/finalize.md to require in-theme selection controls on every meaningful unit (ideas, synthesis insights, convergence cards) and to show an in-theme Export CTA only after selections are made.
  • Defines Export behavior for static local HTML: collect {text, section} entries for selected items and trigger a browser download of selection.json, then show an in-page “next step” note.
  • Adds scripts/export-ideas.py CLI to read the downloaded selection.json, group entries by section, and write selected-ideas.md into the session workspace.
  • Implements whitespace-collapsing and a default “Selected” section for missing/blank section values.
  • Adds 10 pytest cases covering grouping, blank text skipping, malformed/non-array JSON handling, workspace creation, and custom output filenames.

Technical Notes: The export script is designed as a “bridge” between static HTML constraints and markdown artifacts that can be fed into bmad-forge-idea, bmad-product-brief, or another scoped brainstorm run.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

for item in items:
if not isinstance(item, dict):
continue
text = " ".join(str(item.get("text", "")).split()) # collapse whitespace, no prose bloat

@augmentcode augmentcode Bot Jul 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/core-skills/bmad-brainstorming/scripts/export-ideas.py:45 — If an item has "text": null, str(None) becomes the literal string "None", so the output markdown would include a bogus bullet instead of skipping it like other blank texts.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

try:
data = json.loads(path.read_text(encoding="utf-8"))
except OSError as e:
raise SystemExit(f"error: could not read {path}: {e}")

@augmentcode augmentcode Bot Jul 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/core-skills/bmad-brainstorming/scripts/export-ideas.py:32 — load_selection() raises SystemExit, but main() returns status code 2 for other input problems; this means malformed JSON/non-array JSON will typically exit with code 1 instead of 2, which may be surprising if callers/scripts interpret exit codes.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


workspace = Path(args.workspace)
workspace.mkdir(parents=True, exist_ok=True)
out_path = workspace / args.out_name

@augmentcode augmentcode Bot Jul 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/core-skills/bmad-brainstorming/scripts/export-ideas.py:90 — out_path = workspace / args.out_name will ignore workspace if --out-name is absolute (and can also traverse with ../), so the script can write outside the intended session directory even though the flag help says it’s “within --workspace”.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant