From 7f7f5f04586c1bf675498711f483f36ae55a34ba Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Mon, 25 May 2026 11:30:30 -0500 Subject: [PATCH] feat(web-bundles): add release packager + bundle manifest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the infrastructure for shipping web bundles as downloadable ZIPs attached to a GitHub Release, consumed by the upcoming bmadcode.com/web-bundles/ page. - web-bundles/bundles.json — manifest with persona, tagline, description, accent color, motif key, knowledge files, and feature flags (web-browsing, deep-research, stitch integration) for each of the 6 bundles. Top-level releaseTag and downloadUrlPattern so the consuming page can construct download URLs without hardcoding. - tools/bundle-web-bundles.js — packager that zips each bundle dir into dist/web-bundles/{slug}.zip and prints the gh release create command. Zero dependencies; uses system zip. - .gitignore — exclude dist/web-bundles/ build artifacts. The web-bundles-v1.0.0 release on GitHub is currently in draft state with the 6 zips attached; it'll be published in coordination with the Ghost site page going live. --- .gitignore | 3 + tools/bundle-web-bundles.js | 68 ++++++++++++++++++ web-bundles/bundles.json | 140 ++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 tools/bundle-web-bundles.js create mode 100644 web-bundles/bundles.json diff --git a/.gitignore b/.gitignore index 9279c89d1..1483c0538 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,6 @@ _bmad/custom/*.user.toml website/.astro/ website/dist/ build/ + +# Web bundle release artifacts +dist/web-bundles/ diff --git a/tools/bundle-web-bundles.js b/tools/bundle-web-bundles.js new file mode 100644 index 000000000..ba1d7519c --- /dev/null +++ b/tools/bundle-web-bundles.js @@ -0,0 +1,68 @@ +/** + * Web Bundle Release Packager + * + * Zips each bundle under web-bundles/ into dist/web-bundles/{slug}.zip + * for attachment to a GitHub Release. + * + * Usage: + * node tools/bundle-web-bundles.js + * + * Then upload the resulting zips to a GitHub Release: + * gh release create web-bundles-v1 dist/web-bundles/*.zip \ + * --title "Web Bundles v1" \ + * --notes "BMad web bundles for Gemini Gems and ChatGPT Custom GPTs" + */ + +const fs = require('node:fs'); +const path = require('node:path'); +const { execSync } = require('node:child_process'); + +const REPO_ROOT = path.resolve(__dirname, '..'); +const BUNDLES_DIR = path.join(REPO_ROOT, 'web-bundles'); +const DIST_DIR = path.join(REPO_ROOT, 'dist', 'web-bundles'); +const MANIFEST = path.join(BUNDLES_DIR, 'bundles.json'); + +function main() { + if (!fs.existsSync(MANIFEST)) { + console.error(`Error: bundles.json not found at ${MANIFEST}`); + process.exit(1); + } + + const manifest = JSON.parse(fs.readFileSync(MANIFEST, 'utf-8')); + const releaseTag = manifest.releaseTag || 'web-bundles-v1'; + + fs.mkdirSync(DIST_DIR, { recursive: true }); + + console.log(`Packaging ${manifest.bundles.length} bundles for release ${releaseTag}\n`); + + const zipped = []; + for (const bundle of manifest.bundles) { + const src = path.join(BUNDLES_DIR, bundle.slug); + if (!fs.existsSync(src)) { + console.warn(` [SKIP] ${bundle.slug} — directory not found`); + continue; + } + + const out = path.join(DIST_DIR, `${bundle.slug}.zip`); + if (fs.existsSync(out)) fs.unlinkSync(out); + + execSync(`zip -r -X -q "${out}" "${bundle.slug}" -x "*.DS_Store"`, { + cwd: BUNDLES_DIR, + stdio: 'inherit', + }); + + const size = (fs.statSync(out).size / 1024).toFixed(1); + console.log(` [OK] ${bundle.slug}.zip (${size} KB)`); + zipped.push(bundle.slug); + } + + console.log(`\nWrote ${zipped.length} bundles to ${path.relative(REPO_ROOT, DIST_DIR)}/`); + console.log('\nNext step — create or update the GitHub Release:\n'); + console.log(` gh release create ${releaseTag} dist/web-bundles/*.zip \\`); + console.log(` --title "Web Bundles v1" \\`); + console.log(` --notes "BMad web bundles for Gemini Gems and ChatGPT Custom GPTs. See https://bmadcode.com/web-bundles/"\n`); + console.log('Or, to refresh an existing release:\n'); + console.log(` gh release upload ${releaseTag} dist/web-bundles/*.zip --clobber\n`); +} + +main(); diff --git a/web-bundles/bundles.json b/web-bundles/bundles.json new file mode 100644 index 000000000..cf1f99d18 --- /dev/null +++ b/web-bundles/bundles.json @@ -0,0 +1,140 @@ +{ + "schemaVersion": "1.0", + "releaseTag": "web-bundles-v1.0.0", + "releasedAt": "2026-05-25", + "downloadUrlPattern": "https://github.com/bmad-code-org/BMAD-METHOD/releases/download/web-bundles-v1.0.0/{slug}.zip", + "bundles": [ + { + "slug": "brainstorming-coach", + "name": "Brainstorming Coach", + "tagline": "Facilitated ideation across 60+ techniques", + "description": "Unlock creativity through guided exploration. The coach walks you through proven brainstorming methods — divergent, convergent, lateral — and helps you converge to a decision worth acting on.", + "defaultPersona": { + "name": "Carson", + "title": "Elite Brainstorming Specialist", + "lineage": "Osborn lineage" + }, + "swapPersona": { + "name": "Mary", + "title": "Strategic Business Analyst", + "lineage": "BMad analyst — research-first rigor" + }, + "accentColor": "#3b82f6", + "motif": "constellation", + "knowledgeFiles": ["SKILL.md", "brain-methods.csv"], + "needsWebBrowsing": true, + "needsDeepResearch": false, + "stitchIntegration": false + }, + { + "slug": "product-brief-coach", + "name": "Product Brief Coach", + "tagline": "Build a one-page product brief through guided discovery", + "description": "Shape a raw idea, evolve an existing brief, or pressure-test a draft before it goes downstream. The coach mirrors before pushing, names the assumption hiding under your confident sentence, and refuses to write the brief for you.", + "defaultPersona": { + "name": "Mary", + "title": "Strategic Business Analyst", + "lineage": "BMad analyst" + }, + "swapPersona": { + "name": "Iris", + "title": "Senior Product Strategist", + "lineage": "Mirror-then-push, unhurried thinking-partner voice" + }, + "accentColor": "#d4a853", + "motif": "single-page", + "knowledgeFiles": ["SKILL.md"], + "needsWebBrowsing": true, + "needsDeepResearch": false, + "stitchIntegration": false + }, + { + "slug": "prfaq-coach", + "name": "PRFAQ Coach", + "tagline": "Working Backwards challenge to forge product concepts", + "description": "Write the press release first. Stress-test a product concept against the customer who will actually buy it, before any building begins. Customer-first by force of method.", + "defaultPersona": { + "name": "Mary", + "title": "Strategic Business Analyst", + "lineage": "BMad analyst" + }, + "swapPersona": { + "name": "Bezos", + "title": "Working Backwards Coach", + "lineage": "Amazon discipline — direct, dry, customer-first" + }, + "accentColor": "#dc2626", + "motif": "document-ribbon", + "knowledgeFiles": ["SKILL.md"], + "needsWebBrowsing": true, + "needsDeepResearch": false, + "stitchIntegration": false + }, + { + "slug": "prd-coach", + "name": "PRD Coach", + "tagline": "Product Requirements with built-in validation", + "description": "Coach a PRD that engineering can actually build from. Capabilities go in the PRD, mechanism in the Addendum. Validation pass surfaces the gap between what you said and what you meant.", + "defaultPersona": { + "name": "John", + "title": "Product Manager", + "lineage": "BMad PM — Cagan lineage" + }, + "swapPersona": { + "name": "Ezra", + "title": "Principal Product Manager", + "lineage": "Calmer, slower-tempo coaching" + }, + "accentColor": "#6366f1", + "motif": "section-stack", + "knowledgeFiles": ["SKILL.md", "prd-template.md", "prd-validation-checklist.md"], + "needsWebBrowsing": true, + "needsDeepResearch": false, + "stitchIntegration": false + }, + { + "slug": "ux-coach", + "name": "UX Coach", + "tagline": "UX patterns, flows, and design specifications", + "description": "Build spines engineering can take and ship. Pressure-test hierarchy, behavior, and visual logic. Hand-off-ready specs with optional Stitch integration for editable mockups.", + "defaultPersona": { + "name": "Sally", + "title": "UX Designer", + "lineage": "BMad UX designer" + }, + "swapPersona": { + "name": "Kenji", + "title": "Principal Product Designer", + "lineage": "Rams restraint + Zhuo systems discipline" + }, + "accentColor": "#10b981", + "motif": "nested-layers", + "knowledgeFiles": ["SKILL.md", "ux-validation.md"], + "needsWebBrowsing": true, + "needsDeepResearch": false, + "stitchIntegration": true + }, + { + "slug": "market-and-industry-research", + "name": "Market & Industry Research", + "tagline": "Competitive landscape, JTBD, segments — Deep Research integrated", + "description": "Market research that drives a positioning decision, not a deliverable. Segments, competitive alternatives, regulatory and technical lenses. Uses Deep Research for the heavy lift.", + "defaultPersona": { + "name": "Mary", + "title": "Strategic Business Analyst", + "lineage": "BMad analyst" + }, + "swapPersona": { + "name": "Geoff", + "title": "Market Strategist", + "lineage": "Geoffrey Moore + April Dunford lineage" + }, + "accentColor": "#f59e0b", + "motif": "positioning-rings", + "knowledgeFiles": ["SKILL.md"], + "needsWebBrowsing": true, + "needsDeepResearch": true, + "stitchIntegration": false + } + ] +}