bmad 6.11
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
||||
BMad Method,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
||||
BMad Method,bmad-prd,Create Edit and Review PRD,PRD,"Facilitated PRD workflow — create a new PRD via coached discovery, update an existing one against a change signal, or validate a finished PRD against a checklist with an HTML findings report.",,,2-planning,bmad-product-brief,,true,planning_artifacts,prd
|
||||
BMad Method,bmad-ux,Create UX,CU,"Guidance through realizing the plan for your UX, strongly recommended if a UI is a primary piece of the proposed project.",,,2-planning,bmad-prd,,false,planning_artifacts,ux design
|
||||
BMad Method,bmad-project-context,Project Context,PC,"Set up or refresh a repo's agent instructions so AI agents work well in it: verified commands, policy, conventions that differ from defaults, and known pitfalls. Setup, refresh, record, and audit — replaces document-project and generate-project-context.",,,anytime,,,false,repo root,AGENTS.md managed block
|
||||
BMad Method,bmad-spec,Spec,SPC,"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
|
||||
BMad Method,bmad-correct-course,Correct Course,CC,Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories.,,,anytime,,,false,planning_artifacts,change proposal
|
||||
BMad Method,bmad-sprint-planning,Sprint Status,SS,Anytime: summarize sprint status with risks open action items and the next recommended action; can also validate or repair the tracking file.,status,,anytime,,,false,,status summary
|
||||
BMad Method,bmad-brainstorming,Brainstorm Project,BP,Expert guided facilitation through a single or multiple techniques.,,,plan,,,false,{output_folder}/brainstorming,brainstorming session
|
||||
BMad Method,bmad-product-brief,Create Brief,CB,An expert guided experience to nail down your product idea in a brief. a gentler approach than PRFAQ when you are already sure of your concept and nothing will sway you.,,-A,plan,,,false,planning_artifacts,product brief
|
||||
BMad Method,bmad-prfaq,PRFAQ Challenge,WB,Working Backwards guided experience to forge and stress-test your product concept to ensure you have a great product that users will love and need through the PRFAQ gauntlet to determine feasibility and alignment with user needs. alternative to product brief.,,-H,plan,,,false,planning_artifacts,prfaq document
|
||||
BMad Method,bmad-architecture,Architecture,CA,Offer once requirements exist (a PRD or spec; plus UX if present) and the user is ready to move from what to how. Also offer any time independently-built parts risk diverging. Produces the architecture spine: the invariants that keep features epics and stories consistent. Comes before epics and stories and scales from a quick spine to a full architecture (brownfield: ratifies the existing codebase).,,,plan,,,true,planning_artifacts,architecture
|
||||
BMad Method,bmad-create-epics-and-stories,Create Epics and Stories,CE,,,,plan,bmad-architecture,,true,planning_artifacts,epics and stories
|
||||
BMad Method,bmad-sprint-planning,Sprint Planning,SP,Readiness gate then tracking: verifies the planning is implementable (PASS/CONCERNS/FAIL) and produces the sprint status the implementation agents follow for every story.,,,plan,,,true,implementation_artifacts,sprint status
|
||||
BMad Method,bmad-build,Build,BD,Official Phase 4 implementation loop: clarify intent plan implement review and present.,,,ship,bmad-sprint-planning,bmad-code-review,true,implementation_artifacts,spec and project implementation
|
||||
BMad Method,bmad-code-review,Code Review,CR,Ad hoc review of any code change. Optional extra layer after Build's built-in review.,,,ship,bmad-build,,false,,
|
||||
BMad Method,bmad-checkpoint-preview,Checkpoint,CK,Guided walkthrough of a change from purpose and context into details. Use for human review of commits branches or PRs.,,,ship,,,false,,
|
||||
BMad Method,bmad-qa-generate-e2e-tests,QA Automation Test,QA,Generate automated API and E2E tests for implemented code. NOT for code review or story validation — use CR for that.,,,ship,bmad-build,,false,implementation_artifacts,test suite
|
||||
BMad Method,bmad-retrospective,Retrospective,ER,Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC.,,,ship,bmad-code-review,,false,implementation_artifacts,retrospective
|
||||
Core,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
||||
Core,bmad-brainstorming,Brainstorming,BSP,Use early in ideation or when stuck generating ideas.,,,anytime,,,false,{output_folder}/brainstorming,brainstorming session
|
||||
Core,bmad-party-mode,Party Mode,PM,Orchestrate multi-agent discussions when you need multiple perspectives or want agents to collaborate.,,,anytime,,,false,,
|
||||
Core,bmad-help,BMad Help,BH,,,,anytime,,,false,,
|
||||
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
|
||||
Core,bmad-advanced-elicitation,Advanced Elicitation,AE,"Use at any checkpoint to push a just-produced draft, section, or plan past its first version — pick from a menu of elicitation methods (pre-mortem, first principles, red team, socratic) and apply the improvements.",,,anytime,,,false,,
|
||||
Core,bmad-review,Review,RV,"Use to review anything before it ships — a diff, branch, or uncommitted changes; a PRD, spec, story, or architecture doc; any prose document. Runs whichever installed lenses fit the content and reports findings in one shape: shipped lenses cover adversarial critique, edge cases, verification gaps, document structure (cuts, merges, moves), and prose copy-edit, and installs may add more. Reach for it to tighten a bloated or LLM-slop draft, pressure-test a plan before building, or check a change is adequately tested. Run every applicable lens or name the ones you want. Code Review in other modules calls it automatically.",,[path],anytime,,,false,,findings JSON array + markdown report
|
||||
Core,bmad-forge-idea,Forge Idea,FI,"Use to pressure-test and harden an idea — software, business, creative, research, or life — until it proves out, hardens into something buildable, or dies cheaply. Persona-driven interrogation; optional handoff to bmad-spec or bmad-build.",,,anytime,,,false,{output_folder}/forge,refined-idea brief (optional)
|
||||
Core,bmad-deep-recon,Deep Recon,RS,Decision-grade research three ways: draft a deep-research prompt for your own AI tool then process the returned report into a downstream-ready cited summary — or run the research directly via web fan-out. Types: market domain technical competitive user-voice academic-lit plus a select shape for choose-between decisions; claim verification and refresh lifecycle. Custom types via overrides.,,[type],anytime,,,false,{planning_artifacts}/research,research report/summary + optional html briefing
|
||||
|
@@ -0,0 +1,265 @@
|
||||
type,name,module,path,hash
|
||||
"yaml","manifest","_config","_config/manifest.yaml","539f190c0099d21cffad41c6d5d3840155acea619c4acbe5eb4b4bf22d1c41bd"
|
||||
"csv","module-help","bmm","bmm/module-help.csv","fe1f3c778d5d909d5858e0d13f2a7d4d18f40180de05a3c4fa7a5470dabeb945"
|
||||
"html","validation-report-template","bmm","bmm/plan/bmad-prd/assets/validation-report-template.html","a80becdd8205d2d7c18738855830b096172a496b96b5ca8a0820ec55c9bb8bf9"
|
||||
"html","validation-report-template","bmm","bmm/plan/bmad-ux/assets/validation-report-template.html","8656945636fabe96624f8ef8fce931b073b5aecbe42d490584c1d5c7f31e1353"
|
||||
"json","bmad-manifest","bmm","bmm/plan/bmad-prfaq/bmad-manifest.json","9d91d2ae277b87bdfb8785df6a660788743c5cdf98cbd9fcf88c29f957324709"
|
||||
"md","acceptance-verdict","bmm","bmm/ship/bmad-retrospective/references/acceptance-verdict.md","09a65007c39af83e01e039331c252e6e670b134cd5e2a4b5e05ac9d9fb7e37f1"
|
||||
"md","aggregate-views","bmm","bmm/ship/bmad-retrospective/references/aggregate-views.md","5b278afce4a53692d8715b4af178e4233da0876921dc3154b5763d056cb5ff0b"
|
||||
"md","artifact-analyzer","bmm","bmm/plan/bmad-prfaq/agents/artifact-analyzer.md","7bdc44830f8d593346ec0ee15e36e1e431432fcc6c38b70bb861999315c9cfa4"
|
||||
"md","best-practices","bmm","bmm/plan/bmad-project-context/references/best-practices.md","ded4ad303ea7a62c2c55a8673085cb4deeaf8306a68ebcc09fa2c308589fbf9b"
|
||||
"md","brief-template","bmm","bmm/plan/bmad-product-brief/assets/brief-template.md","bb28edf75d023067551c8d417b19b8803324e7acfb2ad0c80f882e9134f4c1f1"
|
||||
"md","checklist","bmm","bmm/ship/bmad-correct-course/checklist.md","3e082b95def90ccb876e3101ce0bbaf797a0f03a9471e1347361897f27977327"
|
||||
"md","checklist","bmm","bmm/ship/bmad-qa-generate-e2e-tests/checklist.md","b58f810aeb1040c2f6758c88aa133afce72f8cc178d3d97ff0fbaa3d943057dc"
|
||||
"md","checklist","bmm","bmm/v6-shims/bmad-create-story/checklist.md","b94e28e774c3be0288f04ea163424bece4ddead5cd3f3680d1603ed07383323a"
|
||||
"md","checklist","bmm","bmm/v6-shims/bmad-dev-story/checklist.md","630b68c6824a8785003a65553c1f335222b17be93b1bd80524c23b38bde1d8af"
|
||||
"md","color-themes","bmm","bmm/plan/bmad-ux/assets/color-themes.md","ccb6e4ef47a196476cf9392d788938ad3ca8d07b9ce095b7c092dcb4e06735f0"
|
||||
"md","compile-epic-context","bmm","bmm/ship/bmad-build/compile-epic-context.md","6793b15ae85766cee529e6b349e45f2c6ec9e3212019611c29e8c77b4dc4b924"
|
||||
"md","compile-epic-context","bmm","bmm/ship/bmad-build-auto/compile-epic-context.md","64d13b41974cfa0dfc1de64b6fbd8365e9b99f91c7c98f0ee1a9fbd018f324ca"
|
||||
"md","creative-tools","bmm","bmm/plan/bmad-ux/references/creative-tools.md","e281292d7c0fdecdbb67ca9b7d95d4bed803626ba5edfd8dcc99146fcaa118e6"
|
||||
"md","customer-faq","bmm","bmm/plan/bmad-prfaq/references/customer-faq.md","96f8565197649c58908a1d61b6cd805fd01f57da7945ba889c18d087ad597aeb"
|
||||
"md","deletion-check","bmm","bmm/ship/bmad-build/references/deletion-check.md","0f1f124e4e957147e89164a272b10bedc694ad0d9ad2618c8610ac74ee9cb0da"
|
||||
"md","deletion-check","bmm","bmm/ship/bmad-build-auto/references/deletion-check.md","0f1f124e4e957147e89164a272b10bedc694ad0d9ad2618c8610ac74ee9cb0da"
|
||||
"md","deletion-check","bmm","bmm/ship/bmad-code-review/references/deletion-check.md","0f1f124e4e957147e89164a272b10bedc694ad0d9ad2618c8610ac74ee9cb0da"
|
||||
"md","design-directions","bmm","bmm/plan/bmad-ux/assets/design-directions.md","eab73b948da76a27abc908e1e7d6b124e8ff0362e6dd1990f7e60b9541cbcb98"
|
||||
"md","design-example-editorial","bmm","bmm/plan/bmad-ux/assets/design-example-editorial.md","a659166845b1a4ed3f9aef942c5935537a97382b10303684fbb78ed86265870e"
|
||||
"md","design-example-mobile","bmm","bmm/plan/bmad-ux/assets/design-example-mobile.md","a93fb9f114f2e83af0c961c0d7909b3859fc80bcd713715517cd639a53a0372a"
|
||||
"md","design-example-shadcn","bmm","bmm/plan/bmad-ux/assets/design-example-shadcn.md","25e0dfb2bb21483973a8f0a6ed650288b3dc2ae5ed02aa0f091bb9b6b0b39fc0"
|
||||
"md","design-md-spec","bmm","bmm/plan/bmad-ux/references/design-md-spec.md","d04d5f663607aba3f3181e818ae33856e6caf5e560dcb16fa64ed80b7cf3d590"
|
||||
"md","discover-inputs","bmm","bmm/v6-shims/bmad-create-story/discover-inputs.md","dfedba6a8ea05c9a91c6d202c4b29ee3ea793d8ef77575034787ae0fef280507"
|
||||
"md","edge-case-hunter","bmm","bmm/ship/bmad-build/review-prompts/edge-case-hunter.md","4ccb3599ed1b8cc54876b304dc567d1b4e3e0ec5c1add34df9a2445224ac77af"
|
||||
"md","edge-case-hunter","bmm","bmm/ship/bmad-build-auto/review-prompts/edge-case-hunter.md","4ccb3599ed1b8cc54876b304dc567d1b4e3e0ec5c1add34df9a2445224ac77af"
|
||||
"md","edge-case-hunter","bmm","bmm/ship/bmad-code-review/review-prompts/edge-case-hunter.md","4ccb3599ed1b8cc54876b304dc567d1b4e3e0ec5c1add34df9a2445224ac77af"
|
||||
"md","epics-template","bmm","bmm/plan/bmad-create-epics-and-stories/templates/epics-template.md","a804f740155156d89661fa04e7a4264a8f712c4dc227c44fd8ae804a9b0f6b72"
|
||||
"md","evidence-gathering","bmm","bmm/ship/bmad-retrospective/references/evidence-gathering.md","575bace78d7c03c48d86a209dd664f7dd22295a222b75e6d6298894cb7b7ce00"
|
||||
"md","excalidraw-wireframe","bmm","bmm/plan/bmad-ux/assets/excalidraw-wireframe.md","660bbcdebff50cd044a3752eda43f3cb303aca4b0f521b55a270da93b89ddb18"
|
||||
"md","experience-example-mobile","bmm","bmm/plan/bmad-ux/assets/experience-example-mobile.md","f8cd54c92193cd8c34a472df9c212ac7330976f6a115b729721dcb60034dc4f0"
|
||||
"md","experience-example-shadcn","bmm","bmm/plan/bmad-ux/assets/experience-example-shadcn.md","d6ca16e87b768e8b41f352c02ee08af21d7cdac04ca21e6ae1556864b4d27590"
|
||||
"md","fix-sprint-status","bmm","bmm/plan/bmad-sprint-planning/references/fix-sprint-status.md","0406c31b70da33e2a354d9785f43d8f9918f4b923d0aac2ebd1e3707ebad5806"
|
||||
"md","generate-tracking","bmm","bmm/plan/bmad-sprint-planning/references/generate-tracking.md","4dbf7aca26d0e6e893f288fc5e6158dbbcd65f77bbaf95e941ca705abceb1741"
|
||||
"md","generate-trail","bmm","bmm/ship/bmad-checkpoint-preview/generate-trail.md","4a5936d86fbe5a85285b4535097b1e2edda8849da35586f4b588a982d7224459"
|
||||
"md","headless","bmm","bmm/plan/bmad-architecture/references/headless.md","4db2708f335c94cb024b5eba022b1e3d88b1ec61c94c4716626d9b89684f5833"
|
||||
"md","headless","bmm","bmm/plan/bmad-prd/references/headless.md","4dad58ebee63933a53179016513ff94d143ce9f68e226489d390e2c36bf1d848"
|
||||
"md","headless","bmm","bmm/plan/bmad-ux/references/headless.md","8da7e23d269b1644f45b5104a243a6a27fd8d075aebb95d9b7752f0d143f0f5d"
|
||||
"md","headless-schemas","bmm","bmm/plan/bmad-prd/assets/headless-schemas.md","8d3621333a72400512bd62511bc4c73fc745711505e1f852c697ff8c5fa2de93"
|
||||
"md","headless-schemas","bmm","bmm/plan/bmad-spec/assets/headless-schemas.md","83afb3614716db2347d83586a67b9c524492dd50db5282436ccb35c99fb5f08a"
|
||||
"md","headless-schemas","bmm","bmm/plan/bmad-ux/assets/headless-schemas.md","e3a773dde85286f1a6f6dd8b26fc17e09ccea96f6257dfe7fb436353cd79242d"
|
||||
"md","internal-faq","bmm","bmm/plan/bmad-prfaq/references/internal-faq.md","26eb83f844cda1ed8efb50f4703d61713ada8a64bd27eb387f759f858b5748de"
|
||||
"md","key-screens","bmm","bmm/plan/bmad-ux/assets/key-screens.md","ff1c5060673dd595edd61e76806bae876264ec6895c2eaadf8a6190785bf5f7b"
|
||||
"md","prd-template","bmm","bmm/plan/bmad-prd/assets/prd-template.md","b6fe8fc1390b8e46961d5eb5e6f2fe6c65dca2f30623d492677672e02868f7ab"
|
||||
"md","prd-validation-checklist","bmm","bmm/plan/bmad-prd/assets/prd-validation-checklist.md","41d9f09064772a92ec908d970618e47ba63dc86b5c5a1a21d5a2c676d3ba8e3f"
|
||||
"md","press-release","bmm","bmm/plan/bmad-prfaq/references/press-release.md","c406adb0e2d2cc326cbc45d0174f89d014523448ad82bc272293999d22aec596"
|
||||
"md","prfaq-template","bmm","bmm/plan/bmad-prfaq/assets/prfaq-template.md","b27e6964f0437ab4e78c8c0ffbe5052c28e3b3ef2fc811726cbb394d5a5c7559"
|
||||
"md","readiness-gate","bmm","bmm/plan/bmad-sprint-planning/references/readiness-gate.md","7d58ea61fafe3c1d8218203abc7512e322ca384c78d9e71829df55dfabe1245b"
|
||||
"md","README","bmm","bmm/v6-shims/README.md","05315a8e369f5ebb9e615c1a33fd2b3f85eb92a9455c974cdc7ec7d3ea0d10bf"
|
||||
"md","retro-document","bmm","bmm/ship/bmad-retrospective/references/retro-document.md","de8164664cd2be7f73b8ba5552e9e0f58816d2a7c4be8efc7715461846bb7001"
|
||||
"md","reviewer-gate","bmm","bmm/plan/bmad-architecture/references/reviewer-gate.md","d32e32a3c1d59b5612b947004f3f6fef1117a13ce9f1ffa428d616e0b5d4db69"
|
||||
"md","SKILL","bmm","bmm/agents/bmad-agent-analyst/SKILL.md","99c72ea74b833743a71a8e3c54369348530525edcfae43da2d267ec27cefc8ff"
|
||||
"md","SKILL","bmm","bmm/agents/bmad-agent-architect/SKILL.md","72a542f7cd34ebf844c26431be564040824f0c16cf060b8795eff2c9e019f003"
|
||||
"md","SKILL","bmm","bmm/agents/bmad-agent-dev/SKILL.md","b980cf2c99976b5e1bd53128dc7b56bdd181ac39a57098d9b5a6bf0692db2675"
|
||||
"md","SKILL","bmm","bmm/agents/bmad-agent-pm/SKILL.md","7b84234262e749f22fe31032124024c8c4283ba55294916b2ec67917a3bb9fb5"
|
||||
"md","SKILL","bmm","bmm/agents/bmad-agent-ux-designer/SKILL.md","2ba39678706fd536a98f7afcbb3d85c3b74e24bdb86a191b330fcd7fd7e64c03"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-architecture/SKILL.md","b3d8c6e5024cb9747ef1659cec8109f5bb797fd1760338e65237bb084b60fcdc"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-create-epics-and-stories/SKILL.md","6b27b0730c61309190eb7c9c84ae98b11cbfe7187941ef88f45ddc8ded850c04"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-generate-project-context/SKILL.md","8cc66337d465bb088831d8973a25cfb4374f1a3427638cc2fb553fad29d08f12"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-prd/SKILL.md","5c220a51dc6f25499b7f18c7104a0a981dc3d721aa63d0fba88ec3de32c3fbde"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-prfaq/SKILL.md","042611ccabfdab1254e6591f6b86f81f332acb874fc2d148af5ac6dcd5a1c726"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-product-brief/SKILL.md","4c15a8ec688c998eeb71957f208b5953b1ac7a5641b008b3509f1f4fcdc8e6cd"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-project-context/SKILL.md","1a276f306ed76f98ad2b04864cfe365426420d33438879ea4f0705c2a013324c"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-spec/SKILL.md","5b5680dbf01dbfc5b4a5485e70f20ea48ac21a1d6137c4ea2ff704262dcc45d2"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-sprint-planning/SKILL.md","6ed5dd51be5d6a807c7e6af0542bff609fe69e84b67025ed7aa3fd9ae1ccb36d"
|
||||
"md","SKILL","bmm","bmm/plan/bmad-ux/SKILL.md","6475c8171bf7346964234bd35994b9d5518102dc245768c660e4dacd1e6b50fd"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-build/SKILL.md","bce4778d8d275095ca1836733337163c1bf11a5a62e6585b951de458a5ac2c8e"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-build-auto/SKILL.md","ea6931f8210e92f7d9cfb845040d557d4d8c02eced3acc3d77bd2fcc4fffc235"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-checkpoint-preview/SKILL.md","fbc932defc41c7d9ffd107dbbccc296854b2ece76d95e9712e19d24f0a4c3606"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-code-review/SKILL.md","1ba6481b28c7e4b2ea0b1447e9011a9cac3ef51fdf957d09050606d2d16b196b"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-correct-course/SKILL.md","507394a758e297152a806fe5529ecc54c6c2725c951bdcbbdb250622a83fa820"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-qa-generate-e2e-tests/SKILL.md","4aad390d3f063efb8783637a0f72b993135ec2acb810693d3146a161172057c8"
|
||||
"md","SKILL","bmm","bmm/ship/bmad-retrospective/SKILL.md","8da5b53055afa76cf88135f186d35a6cb95bab1096ed96022354846dc788d26a"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-create-architecture/SKILL.md","2d199970238a7f415aa4b9224ec01f296b4b3ee7b399f75092ed8bdd3e414be1"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-create-prd/SKILL.md","fa8cc47fff80a19446057b0469e79ea65973ceccb71e96079bf734b34699eb69"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-create-story/SKILL.md","bea46d2823aded992d90a8d6d684f7c67c0865478b01c1443ba4c3eac04bbd28"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-dev-auto/SKILL.md","1c056c69a17043bfb4b80f9e42a8ec8338fc6fa47c6ae8d5cf53f8a326966b4a"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-dev-story/SKILL.md","8f9baf6a4643a3e9b307864eceed5aa9ddfe4e325226d70b78e0c85908ab7d5d"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-document-project/SKILL.md","c4a09a6dc3aaaf90e12e1467b48a37416820ff351316a4eda7cda826dbb7fbd7"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-domain-research/SKILL.md","6c873cdb44ed6444c2abfb335ad7af474fda56f4ba62c1c9c7cff42d9a243cd4"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-edit-prd/SKILL.md","26448c4017c09ad8defa8525d9517ce681bb50222320517eaa635fa0f31989f9"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-market-research/SKILL.md","b52667b85bee97ff23dd02532a2f286c72e63fd14b1afaedd6592de4d6112df6"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-quick-dev/SKILL.md","23bb1434e03693152311b8e79570bb8a042eb39f57615cc4d0df15b72f29b113"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-sprint-status/SKILL.md","95e695ce9665c6b3d617d41b0581bc30de6288263609a910559a97b26eb49e78"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-technical-research/SKILL.md","d8e6177fc03c3d815642bdf6b54b83ef37874e73118d89112f155dbda14afbfa"
|
||||
"md","SKILL","bmm","bmm/v6-shims/bmad-validate-prd/SKILL.md","16bff9ed7ec003add9c56818575f613380925782bd4ef0cc0804ed34a074eeaf"
|
||||
"md","spec-template","bmm","bmm/plan/bmad-spec/assets/spec-template.md","4b3a032c045fdd0903933446fc07f93e879997f28a0294ed4344da71192b20ee"
|
||||
"md","spec-template","bmm","bmm/ship/bmad-build/spec-template.md","68d0e3b9acaa0c22ab3b0dd1dbce9d8ef9b4d16637ed5e6fbd5244528732943e"
|
||||
"md","spec-template","bmm","bmm/ship/bmad-build-auto/spec-template.md","5fccfa92dd632d4be646ab40f2882452189aba49db57fe3fa00fcc1806666d74"
|
||||
"md","spine-template","bmm","bmm/plan/bmad-architecture/assets/spine-template.md","ef4ff795624eb5439fae54a06edb389feb5a0cf79cb01ae007af51109335d198"
|
||||
"md","status-view","bmm","bmm/plan/bmad-sprint-planning/references/status-view.md","c3547e221ebf6e55c874e2ada3e8c18198835213c76f0bb2e0e64150aac355ab"
|
||||
"md","step-01-clarify-and-route","bmm","bmm/ship/bmad-build/step-01-clarify-and-route.md","0a3afcde2b1d4475250896f132fd8839cf442b3364ebfbeeace5a489042c7c7f"
|
||||
"md","step-01-clarify-and-route","bmm","bmm/ship/bmad-build-auto/step-01-clarify-and-route.md","7480db7720720212bd045793fddcb91f06091fe512e53b38127f6440c3fd96e2"
|
||||
"md","step-01-gather-context","bmm","bmm/ship/bmad-code-review/steps/step-01-gather-context.md","3f5a74d63a91fb385d33786b78d09bb9bca483b1ac45933b9715c9fb79b79e9d"
|
||||
"md","step-01-orientation","bmm","bmm/ship/bmad-checkpoint-preview/step-01-orientation.md","d9e3b949c36d49a025f3535773af2b51888fe4ce616b6d6d69683a122716b1d2"
|
||||
"md","step-01-validate-prerequisites","bmm","bmm/plan/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md","7181608c1ee4e55c084c6627d68fc55a8a0b6917e489f8ac77531a0530428a30"
|
||||
"md","step-02-design-epics","bmm","bmm/plan/bmad-create-epics-and-stories/steps/step-02-design-epics.md","7c66987808c1f84e853fe54b7aff26d209196d450b5644704110f124a15179bc"
|
||||
"md","step-02-plan","bmm","bmm/ship/bmad-build/step-02-plan.md","d90db50ca7a679dd42f7d1587a909d0579f24480b116d6ed82b4c7d4fe9bea66"
|
||||
"md","step-02-plan","bmm","bmm/ship/bmad-build-auto/step-02-plan.md","a08e303c10f88dbfce88c55044757ec5059afe338793eb414e1ddb0b7c324625"
|
||||
"md","step-02-review","bmm","bmm/ship/bmad-code-review/steps/step-02-review.md","3d146c060e838413f1262211cc58b06eeee1a9a86b8997efd83d0dc8c03cfa60"
|
||||
"md","step-02-walkthrough","bmm","bmm/ship/bmad-checkpoint-preview/step-02-walkthrough.md","66cf893f8f968ee81034e9ccd8c20415692c3a8c23a9a143c2245fe6c800acdc"
|
||||
"md","step-03-create-stories","bmm","bmm/plan/bmad-create-epics-and-stories/steps/step-03-create-stories.md","c5b787a82e4e49ed9cd9c028321ee1689f32b8cd69d89eea609b37cd3d481afc"
|
||||
"md","step-03-detail-pass","bmm","bmm/ship/bmad-checkpoint-preview/step-03-detail-pass.md","d48163b9f305f15af57729a8443142e47beb6c3e977554afe12b39ee49cb9fc0"
|
||||
"md","step-03-implement","bmm","bmm/ship/bmad-build/step-03-implement.md","3b77ca64380b2989016191f488311ff392df0ebf4f641b9898d02b01767a646f"
|
||||
"md","step-03-implement","bmm","bmm/ship/bmad-build-auto/step-03-implement.md","f3e427c6033a26adcc327e4367db38c619527858a1175b148ec5a6f53d1bb408"
|
||||
"md","step-03-triage","bmm","bmm/ship/bmad-code-review/steps/step-03-triage.md","46a9e661e8aed6a7347cd7bc0b3f7edd8e4bffcfc96b2e15895f7a8ce2517d70"
|
||||
"md","step-04-final-validation","bmm","bmm/plan/bmad-create-epics-and-stories/steps/step-04-final-validation.md","5f6033e26ed06e070dcfcefb47d648b5a266012aaed7d53f028ab3f2c0542d20"
|
||||
"md","step-04-present","bmm","bmm/ship/bmad-code-review/steps/step-04-present.md","08baa98dae5e3bd70f211d1d3ce42f14e25030f4d6b17fc18e8635644847850c"
|
||||
"md","step-04-review","bmm","bmm/ship/bmad-build/step-04-review.md","bcf300e2faaf413afe1a25498284baabba09681bca089e615530d0b9dc5cee72"
|
||||
"md","step-04-review","bmm","bmm/ship/bmad-build-auto/step-04-review.md","8e9ff909192e1d5d50f9fc071c4b5eb8830cc921200d423904a30dadca58c3e9"
|
||||
"md","step-04-testing","bmm","bmm/ship/bmad-checkpoint-preview/step-04-testing.md","28a56e868968ea2d18add0df8c4bccced0f94b698e218df3d45ddac072ce369c"
|
||||
"md","step-05-present","bmm","bmm/ship/bmad-build/step-05-present.md","81e80f3fd38f8e3049afe9daf41783b86b00ac22544f7f36bd430496a12d8e46"
|
||||
"md","step-05-wrapup","bmm","bmm/ship/bmad-checkpoint-preview/step-05-wrapup.md","b1f04d64f0c9c9e4c051ebdd81eee1083d60c6aaca96bb5d3d85e0cbeca0143e"
|
||||
"md","step-oneshot","bmm","bmm/ship/bmad-build/step-oneshot.md","e75505130a2fcc49cd71dfb36c92e76255d39fdfe8d4f735c7c9276e2917cb8a"
|
||||
"md","stories-schema","bmm","bmm/plan/bmad-spec/assets/stories-schema.md","4f8137c00e2710288354a4466d1cfb90704f4b2a04bd3b63924218fd589cc6a9"
|
||||
"md","sync-sprint-status","bmm","bmm/ship/bmad-build/sync-sprint-status.md","6c9e2ec17245d2dcb796bd9a36997371a20db8e579a2f803d16064e3bc36c40b"
|
||||
"md","team-discussion","bmm","bmm/ship/bmad-retrospective/references/team-discussion.md","a9c504c436038c7e47d08322413aa3c213d2859b36ae30e873cb8c60fd9e008e"
|
||||
"md","template","bmm","bmm/plan/bmad-project-context/references/template.md","c8b9a1fc165996614504bb9c90c5b1c6c808a8d483e36a4d250d79f62fda6fa1"
|
||||
"md","template","bmm","bmm/v6-shims/bmad-create-story/template.md","29ba697368d77e88e88d0e7ac78caf7a78785a7dcfc291082aa96a62948afb67"
|
||||
"md","validate","bmm","bmm/plan/bmad-prd/references/validate.md","19b2fa66d58cb4fef3d920cd09c81f8add4ee44dd4191bec87eaba84c2093338"
|
||||
"md","validate","bmm","bmm/plan/bmad-sprint-planning/references/validate.md","ac680fa0a0f945a9bc0fc89ca709b2a8e6bc3b2617cd0d3d730378c4b5edd86d"
|
||||
"md","validate","bmm","bmm/plan/bmad-ux/references/validate.md","7c2189d9ac1585d9408b6ed0346ba564869e7db89dba8f81044db3431cfcee65"
|
||||
"md","verdict","bmm","bmm/plan/bmad-prfaq/references/verdict.md","81c06748ae2cb8e191cd282ecff83bea79532512c994fd4fffbf12c56be58a13"
|
||||
"md","verification-gap","bmm","bmm/ship/bmad-build/review-prompts/verification-gap.md","11b6bbbd4e3426a25cca81229c98971e5f20ce99638940c47c9c1484011b457a"
|
||||
"md","verification-gap","bmm","bmm/ship/bmad-build-auto/review-prompts/verification-gap.md","11b6bbbd4e3426a25cca81229c98971e5f20ce99638940c47c9c1484011b457a"
|
||||
"md","verification-gap","bmm","bmm/ship/bmad-code-review/review-prompts/verification-gap.md","11b6bbbd4e3426a25cca81229c98971e5f20ce99638940c47c9c1484011b457a"
|
||||
"md","web-researcher","bmm","bmm/plan/bmad-prfaq/agents/web-researcher.md","6e9127bb9bd3e4b15c701e4ced9eef328769262cd34eadc221bebe954c1f3aef"
|
||||
"md","workflow","bmm","bmm/ship/bmad-build/workflow.md","481ff00ef349a9c7845feca02bbfd5722b1e318ccabac858355da6c90c2d8a39"
|
||||
"md","workflow","bmm","bmm/ship/bmad-build-auto/workflow.md","f5f538a647b2a09406b11337244d1bd74fe97e7fa85b58a990184fcb480bfd90"
|
||||
"py","git_evidence","bmm","bmm/ship/bmad-retrospective/scripts/git_evidence.py","6e08688d2943217b61e784c7df3508aa1502d7cecf53ea7cd530944c431c91b6"
|
||||
"py","lint_spine","bmm","bmm/plan/bmad-architecture/scripts/lint_spine.py","040e0f1c13d31e6a21c518df943d1d7de7b75d8d98a07603b0983f3f3fb500db"
|
||||
"py","sprint_plan","bmm","bmm/plan/bmad-sprint-planning/scripts/sprint_plan.py","4c30f62c261599fc1da3fd319ea6ce5092aa0332221cedee1763a1040627e6bc"
|
||||
"py","sprint_status","bmm","bmm/ship/bmad-retrospective/scripts/sprint_status.py","a697eecd53cd9177657aee4cfdb2eab06d7d81f3e855b096cfe0482a74c50ebe"
|
||||
"py","test_git_evidence","bmm","bmm/ship/bmad-retrospective/scripts/tests/test_git_evidence.py","0abfc8fad338830fc2db656d3ccc500631b0ea7a2ab87d853c13a6bbd46ff13c"
|
||||
"py","test_lint_spine","bmm","bmm/plan/bmad-architecture/scripts/tests/test_lint_spine.py","e86bb9a62c5cca74ddc89c843386f2b992610fcc1792d40e03bc9cd445b77681"
|
||||
"py","test_sprint_plan","bmm","bmm/plan/bmad-sprint-planning/scripts/tests/test_sprint_plan.py","f1c3b640e156946b0a234e233807b2a3983cb0d3f2d13dbb9830fbe0c67e5238"
|
||||
"py","test_sprint_status","bmm","bmm/ship/bmad-retrospective/scripts/tests/test_sprint_status.py","23da16cca54904a256fcf88fd8f912c3f6091ea343768c241bbd2aeebbca2af3"
|
||||
"pyc","sprint_plan.cpython-311","bmm","bmm/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc","c92c8bd560b76b970c88ec2e3b18c6611f423ca91ffe6f741348ea94e04da61d"
|
||||
"pyc","sprint_status.cpython-311","bmm","bmm/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc","a1f809abad01386d1342d3a70df401ced7c1de42c94133b65422ad3f2b2f382b"
|
||||
"pyc","test_git_evidence.cpython-311-pytest-9.1.1","bmm","bmm/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc","bd1ab9d967e7e77c9a734640a64e5c0282e6ce4a53a6b0956cc54f4cefd25770"
|
||||
"pyc","test_sprint_plan.cpython-311-pytest-9.1.1","bmm","bmm/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc","640ded70adc12c995a3b92680a44ad9b679ca80bce6b0ae03f70e17a19aa5ae8"
|
||||
"pyc","test_sprint_status.cpython-311-pytest-9.1.1","bmm","bmm/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc","9f3cb3413808cd73dbdd619051b624482d7b5ce1359d2d549310e7b5434c0c55"
|
||||
"toml","customize","bmm","bmm/agents/bmad-agent-analyst/customize.toml","9b3e94d90784bbb24ab2c8f0563aaece48aa317554622750538e6c0e14478b37"
|
||||
"toml","customize","bmm","bmm/agents/bmad-agent-architect/customize.toml","82f0f082935f56e6fde41b007440edaa04984eb23abf26a3be7b1442baf0047a"
|
||||
"toml","customize","bmm","bmm/agents/bmad-agent-dev/customize.toml","f3f107f11f150f62091a792fcdf224dbf8d6c351d24e2b1d08aabb077e655feb"
|
||||
"toml","customize","bmm","bmm/agents/bmad-agent-pm/customize.toml","086d498b0e3d0c5dd193f8347ba30fdc93efcb57bbdfaff21fb0b418dba81ba8"
|
||||
"toml","customize","bmm","bmm/agents/bmad-agent-ux-designer/customize.toml","3df7da44945f9df34dbb3a64de086c756e6c298e73078e388e8f9a4f57cbf7ab"
|
||||
"toml","customize","bmm","bmm/plan/bmad-architecture/customize.toml","a6bb60a3adf976031f2870203285b1fc7a56e71e21232cd23bba544b178b5f15"
|
||||
"toml","customize","bmm","bmm/plan/bmad-create-epics-and-stories/customize.toml","da9e43605bc6aec83173050b5d37ede6aebfa9a17c5959a5029681d73e744ba3"
|
||||
"toml","customize","bmm","bmm/plan/bmad-prd/customize.toml","7f9a3a3503a3f758003ce2f1de59c31cc53658223e355fc76055f3140ef34e90"
|
||||
"toml","customize","bmm","bmm/plan/bmad-prfaq/customize.toml","8994f925bab65bd310e5ab38781286b6137f3e0c9e89f3ab8a2f480eb05e0de5"
|
||||
"toml","customize","bmm","bmm/plan/bmad-product-brief/customize.toml","50abc46f7c2e7cc7b02e2edc4aa6a237a46ea49dcc6781da5b42bd8968de39ab"
|
||||
"toml","customize","bmm","bmm/plan/bmad-project-context/customize.toml","9bf8a3aa919832cd8932853da550fcaebd06a9e13c0cde453f4379d8327f9c0f"
|
||||
"toml","customize","bmm","bmm/plan/bmad-spec/customize.toml","a89e0f53f9b6386c281dd0158a21801a6b16f122085fd68b0220cd403c18f830"
|
||||
"toml","customize","bmm","bmm/plan/bmad-sprint-planning/customize.toml","f7bde2f792e8604f26122ee792c5493e270710296044b07680db7d90e886caf3"
|
||||
"toml","customize","bmm","bmm/plan/bmad-ux/customize.toml","61f8bfbb020beb159b8da570ed416b02ec4a9ba3709aa0d08b417648d85328d8"
|
||||
"toml","customize","bmm","bmm/ship/bmad-build/customize.toml","68a0134f3f9e7f4a7b077aa2dcca1c68f208701d3487482e84afbee8717efec6"
|
||||
"toml","customize","bmm","bmm/ship/bmad-build-auto/customize.toml","eb0b39a3e24e86e9dbca98506c8384ec452c539acb690063cabab4385c82f09a"
|
||||
"toml","customize","bmm","bmm/ship/bmad-checkpoint-preview/customize.toml","1a1e0c3a8914adda3cec925eed51287e067c7f84120de64a8df53348e7b77de5"
|
||||
"toml","customize","bmm","bmm/ship/bmad-code-review/customize.toml","4f50371c61dea41c100b137e3d2ac750b4e55bb3be55e5a62c77f527dae22f94"
|
||||
"toml","customize","bmm","bmm/ship/bmad-correct-course/customize.toml","78095d25afb5b2d4844956f61e9ac640a62d0245174fab9406e9c289f33fd84b"
|
||||
"toml","customize","bmm","bmm/ship/bmad-qa-generate-e2e-tests/customize.toml","04a99926b2d79318b927434c7344dc666f143026ed99c7fcc0d6e3d68263ae66"
|
||||
"toml","customize","bmm","bmm/ship/bmad-retrospective/customize.toml","ff6fdda35fa4b7d9c2dcb4ffc3e06e56de9a588d4e4e6908379bc16a904d4225"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-create-architecture/customize.toml","618be49b0286f18dfb4b6bac3d96bf1cf062994fa5278cd327be9898e651b43c"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-create-prd/customize.toml","0c990af4c0a755402abbef893850bd542744a8b6f36c0587c9f3fb6dab6bf5e7"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-create-story/customize.toml","1204f6de064436922f2813069778eb4eaa5f1f945aa8ea5a5ffb87897a2ba8fe"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-dev-story/customize.toml","baba9f07f653063aa94981f1413d5dd4f604931077fbfb04d9c2e397f8d33237"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-edit-prd/customize.toml","35cc2dfb3eda73a0ae4dc987cac58867b25c43ce5c5a1bf552e215826ede6c22"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-sprint-status/customize.toml","96261fd227befaa4685b0a5091d3e85299d4ae8e4404176b42f5ef2e2fb501bd"
|
||||
"toml","customize","bmm","bmm/v6-shims/bmad-validate-prd/customize.toml","bfb3c8af5b81b2cdb9bb84f844f1b0dafc40d8c283effa6ad48db966b9446cef"
|
||||
"yaml","config","bmm","bmm/config.yaml","2f538aabeb6d78ea7dc0cc0d43f1aad5ece108b70e15465220a7c7de4007cf1a"
|
||||
"yaml","sprint-status-template","bmm","bmm/plan/bmad-sprint-planning/sprint-status-template.yaml","64b1a937e1fe03b8b8d158e3b1caeb89e7d51692a56c16038e2af091decc553a"
|
||||
"yaml","sprint-status-template","bmm","bmm/ship/bmad-retrospective/scripts/tests/fixtures/sprint-status-template.yaml","64b1a937e1fe03b8b8d158e3b1caeb89e7d51692a56c16038e2af091decc553a"
|
||||
"toml","config","config.toml","config.toml","75675094e803188d1a297580eb75a529cc3402f0b878d9b0260d398357e3c21f"
|
||||
"toml","config.user","config.user.toml","config.user.toml","e710ec2275165cd80616ff41899789eb6677223508d9acfadd89f305cdfda3e2"
|
||||
"csv","brain-methods","core","core/bmad-brainstorming/assets/brain-methods.csv","fff112eabca1a9cb8b190f8314bc47678becc5782a2372e11c83daa0e33b6dfd"
|
||||
"csv","methods","core","core/bmad-advanced-elicitation/assets/methods.csv","d110ff5f076fb9421552b83692fde2c2d367734049169c7a55f7267a3dc7ef89"
|
||||
"csv","module-help","core","core/module-help.csv","3d5feb19c1750d35676530c746a5c71e8959616f3c32fb161847971611d81b6b"
|
||||
"html","brain-selector","core","core/bmad-brainstorming/assets/brain-selector.html","c110919a3366bd96061f050f98503e3586185e3d1df5ff8b62a5a046c571a436"
|
||||
"json","brain-icons","core","core/bmad-brainstorming/assets/brain-icons.json","a101c56e89f1d0f9e4131dfdfc19e10c746e3a61c3f92537d04a6f4897b7d331"
|
||||
"md","academic-lit","core","core/bmad-deep-recon/types/academic-lit.md","514b0b7b1184cb95363dedeb0c2298a9bf5c430c74146fe2114f31780fadb325"
|
||||
"md","competitive","core","core/bmad-deep-recon/types/competitive.md","39b53df87d295fdc4388719fcdf31ad2221e64afc136e669207f46d2727a3aec"
|
||||
"md","converge","core","core/bmad-brainstorming/references/converge.md","1528c32ddc64f8061fec663306f7208d2fd4d4a90e660552b8138bda7e452dc0"
|
||||
"md","create-party","core","core/bmad-party-mode/references/create-party.md","2f810332c36c17d14eb55717aed48f3020acf0713bb9f932479be9fbc3856e9e"
|
||||
"md","domain","core","core/bmad-deep-recon/types/domain.md","3a34b2e62c3589f8c8d01158357ee9fba32648c9fdfe70035bb3ca971862896b"
|
||||
"md","draft","core","core/bmad-deep-recon/references/draft.md","ac19b33a00ca529c3281df6076f87a833a3b11fc30915ca2c6e7590f7986b90e"
|
||||
"md","editorial-common","core","core/bmad-review/references/editorial-common.md","f0cdc72ea345b2c5dc3001477b3dfcc909ca11b78f7db8865b6763d18ffc66c8"
|
||||
"md","finalize","core","core/bmad-brainstorming/references/finalize.md","b6074e7fb4d86ffcf899abc50b9049b4a1f6fe550917f4be7a1c7a888477e07e"
|
||||
"md","finalize","core","core/bmad-deep-recon/references/finalize.md","d2ba4bee615dfbca6e7725179fb5ebd856dd34a54ba3f306e25255dfd7b1d126"
|
||||
"md","headless","core","core/bmad-brainstorming/references/headless.md","b8ea5951199cff7e4813e06aef35683ca0658230fa015e358cacc466b1138a42"
|
||||
"md","html-briefing","core","core/bmad-deep-recon/references/html-briefing.md","cd3a88c1a5505fa7f1b715afc3adb34f3d64ade66f4c6b49a59f7e8cfcbe38d4"
|
||||
"md","in-chat-techniques","core","core/bmad-brainstorming/references/in-chat-techniques.md","18239464e3e4f00ea9063d015d26d6b0a696b72e7e3c5be92352da6db9a3f244"
|
||||
"md","lens-adversarial","core","core/bmad-review/references/lens-adversarial.md","7c5ce97ab2f3ecb96ceb6aa76417f68c1b7df535edd3cc51666d8e1216e6e557"
|
||||
"md","lens-edge-case-hunter","core","core/bmad-review/references/lens-edge-case-hunter.md","f2709e3adb40943ea0f19d0797be379caf0875eaef9a55081dc1e170e8288b68"
|
||||
"md","lens-prose","core","core/bmad-review/references/lens-prose.md","4cbcb1eaea8567d272f5db7c6cdfd74ed5a8aae6831053cb2f01cbfc2cb98b98"
|
||||
"md","lens-structure","core","core/bmad-review/references/lens-structure.md","98c08221f517133e57ef6325013935360c3365ebd7dcb8411b2050d7df507ee3"
|
||||
"md","lens-verification-gap","core","core/bmad-review/references/lens-verification-gap.md","e7123d81171eeeee1b3782d13d94c2988969fe357dd71949131a5eb97803e2c6"
|
||||
"md","lifecycle","core","core/bmad-deep-recon/references/lifecycle.md","2315fd9cb9223504639616b861ad593bfecb53d605efbd598ae2cf94fb6c4cdf"
|
||||
"md","market","core","core/bmad-deep-recon/types/market.md","81ac04499da441857672e29fcd7169436a7e239e67194288ac0d526ec514cb5e"
|
||||
"md","mode-agent-team","core","core/bmad-party-mode/references/mode-agent-team.md","def759a17f4bb45463b68fb74c2b828b0a4241720b2b6cc1c9c611a1016ae9d7"
|
||||
"md","mode-auto","core","core/bmad-party-mode/references/mode-auto.md","a37fd24f76dfcde385890d5c5947bb6f40ca44bea86c805d267b6ae3aab39f70"
|
||||
"md","mode-autonomous","core","core/bmad-brainstorming/references/mode-autonomous.md","d815d2c7f0f8cc0cdfa7c619eaf61f59fd78142f13c69365eda257da38b97bdf"
|
||||
"md","mode-facilitator","core","core/bmad-brainstorming/references/mode-facilitator.md","1b908498d285d190859aed00c3ba5b399d7f6aa8e94d54e95456d15cd6fe6073"
|
||||
"md","mode-partner","core","core/bmad-brainstorming/references/mode-partner.md","caa0ed378c116def4de382f4e5a95173c6ae6cc5464f1792e7d8196360f79c8a"
|
||||
"md","mode-subagent","core","core/bmad-party-mode/references/mode-subagent.md","86161b24a0b13b8f9cb9309042e4249d8caefff8cc33728b084cd2ec22f9d2e1"
|
||||
"md","party-memory","core","core/bmad-party-mode/references/party-memory.md","800b4b4b920bb881a7b32aaabca8559a98273799b2476d83a23e290e301fb315"
|
||||
"md","process","core","core/bmad-deep-recon/references/process.md","9017d04774807a29103ea97331e555e2793f90098af65752b72f3ee09df85906"
|
||||
"md","README","core","core/v6-shims/README.md","017900bb03baeddc0262041a6aa85bce744e8c45991dcde32ef042f9bc2a32b2"
|
||||
"md","research.template","core","core/bmad-deep-recon/assets/research.template.md","87d7cfa85fa5036b5a309b7bfb88f7934f50bb81f3cff02d2b49b4c7345cfc38"
|
||||
"md","resume","core","core/bmad-brainstorming/references/resume.md","0f79535d72eefe6c55bd5ae47fe4753de8d27235cf129f10b2c596a124c26526"
|
||||
"md","run","core","core/bmad-deep-recon/references/run.md","8e259dc88820ac989c79620af5c37e24f00df21ac4af308ce3563c0e66c9406c"
|
||||
"md","selection","core","core/bmad-deep-recon/references/selection.md","2b488c08f9550afe7fda32c2dc5d4591927afd7b9ad507fcce0ae8593c4b9d31"
|
||||
"md","SKILL","core","core/bmad-advanced-elicitation/SKILL.md","23a1f2903f6a19255e3ceae798afe48f6394694769b3b034502d174d683612b2"
|
||||
"md","SKILL","core","core/bmad-brainstorming/SKILL.md","e9cb07fe86aa254f9fb7217720d77fd693bf66a0c01af8114ecdf7148159fdd1"
|
||||
"md","SKILL","core","core/bmad-customize/SKILL.md","a42086f90024013e2611503eb0224ac0e90b2aecac44a886ae0e38cfdda69511"
|
||||
"md","SKILL","core","core/bmad-deep-recon/SKILL.md","dce5f7db03094a617cc3fcae1711b1dc7ccebe379376e67216544956d375f0d2"
|
||||
"md","SKILL","core","core/bmad-forge-idea/SKILL.md","a838096deb871b3482dffe6163be16104f7911698b25af5617751655fd3295c9"
|
||||
"md","SKILL","core","core/bmad-help/SKILL.md","68a19089a0073b299c705e9afaa8d18183e78f88a185a68e9efba2e14062effc"
|
||||
"md","SKILL","core","core/bmad-party-mode/SKILL.md","de035b4e081fdd626a20114178f706ac222f519171d82b02139a7cec561a3487"
|
||||
"md","SKILL","core","core/bmad-review/SKILL.md","144e6c46d9157f7a88722c56139cd78c12903b1283ed84dd9c2b1f5dfa7673c1"
|
||||
"md","SKILL","core","core/v6-shims/bmad-editorial-review/SKILL.md","3b939876b4977bec7f2d3ee33a8871b266f25efc72768d72868ac26ff9158cd2"
|
||||
"md","SKILL","core","core/v6-shims/bmad-editorial-review-prose/SKILL.md","153e7b0a240c3f5e49d6128ff1797aabc368618611d895f7f152e73fbcb12fab"
|
||||
"md","SKILL","core","core/v6-shims/bmad-editorial-review-structure/SKILL.md","5e45da216b00aad3955a7196df6cb8e52167f441d2dcd7c064983881691bf1e8"
|
||||
"md","SKILL","core","core/v6-shims/bmad-review-adversarial-general/SKILL.md","ca1d05a05eb41ec446abd862e9afe4a88b9188a3bb93bc3e70ca68ecb8740619"
|
||||
"md","SKILL","core","core/v6-shims/bmad-review-edge-case-hunter/SKILL.md","f9db1d7f58c5e3f7586c10c920d4dd9d6c6d6e2dff5cd49110ec1edb387937a1"
|
||||
"md","SKILL","core","core/v6-shims/bmad-review-verification-gap/SKILL.md","4ee67cc3d7355ba05d195797cb2d57d45f9046ee31781f2d133ff3484cfb53ae"
|
||||
"md","structure-models","core","core/bmad-review/references/structure-models.md","f84f85070e1af75f2482757aba9d37d69d805a20826d185527e598f2ba6b9292"
|
||||
"md","synthesis","core","core/bmad-deep-recon/references/synthesis.md","4d9ef1247ab45241f919010e94c99699abc0a6e18b5bd68fa93ae54afe59d172"
|
||||
"md","technical","core","core/bmad-deep-recon/types/technical.md","55f71428c70547b89d67ef0c6cdad59caeb0ee21082cd1230c05618ba8d04707"
|
||||
"md","user-voice","core","core/bmad-deep-recon/types/user-voice.md","1831ce46e53e8c68244d28e336c5ef9e53e64f21a00b74a817b9b2924c1e8e72"
|
||||
"md","verification","core","core/bmad-deep-recon/references/verification.md","0393ded4828fec69a4819d7236827910d641d09c3b61144c0211a9a78776fdd2"
|
||||
"py","brain","core","core/bmad-brainstorming/scripts/brain.py","1c75c667fc70a85055dd19d77fb21478e190874e4a61d070c3b0971dd1bd25cc"
|
||||
"py","list_customizable_skills","core","core/bmad-customize/scripts/list_customizable_skills.py","8787f542930b927789e7fdf12bc5a67ff08e19865903a5ad05ff2cc8fc426b66"
|
||||
"py","pick_methods","core","core/bmad-advanced-elicitation/scripts/pick_methods.py","60020ec4767894ea3d8707c4b61e78b679d434315be1dd29154bf64d88126fff"
|
||||
"py","recon_kit","core","core/bmad-deep-recon/scripts/recon_kit.py","8cb5187b5114b779532907383a013d40fdea1022bb9bed9a23bd8d0fdfa79e8c"
|
||||
"py","resolve_party","core","core/bmad-party-mode/scripts/resolve_party.py","0bed5ad2139f4412699c07d571c218470901b901ca4a72b441ec9308dbc8ce74"
|
||||
"py","resolve_personas","core","core/bmad-forge-idea/scripts/resolve_personas.py","b3e5f2f38de013ad878d8ac9c1d4e77d555c2d665dd6c0bc16f9f567d2bbd30c"
|
||||
"py","test_brain","core","core/bmad-brainstorming/scripts/tests/test_brain.py","021c0b9fae8db859725312d50d8b304fff00ee7acc310699c35523e86bffbdd8"
|
||||
"py","test_list_customizable_skills","core","core/bmad-customize/scripts/tests/test_list_customizable_skills.py","24c3d384b3b5d490b7335c17866bfe0425af253ce669c32382fa88feb705934d"
|
||||
"py","test_pick_methods","core","core/bmad-advanced-elicitation/scripts/tests/test_pick_methods.py","610099d8494529f9203d7262567810b500552bcef006b3b6388d58da3da71978"
|
||||
"py","test_recon_kit","core","core/bmad-deep-recon/scripts/tests/test_recon_kit.py","1b4ddf482dd2d11a214ee2f821c35d7a8c41905b5d8d9cc69a293304bb8a1665"
|
||||
"py","test_resolve_party","core","core/bmad-party-mode/scripts/tests/test_resolve_party.py","bb53fe03ec3013ed96c0fb399c1948f28bcf55cb2d7727fe0189343fcaa667d5"
|
||||
"py","test_resolve_personas","core","core/bmad-forge-idea/scripts/tests/test_resolve_personas.py","1c4fa4b1d68bfbd10e4b38cad3c8286dad62345cebd08fe94a6862351b02855e"
|
||||
"py","test_word_metrics","core","core/bmad-review/scripts/tests/test_word_metrics.py","3b5a285d3c9f611b3cda8c9c1d52d6b214c1f72e6e64a94ea5b0e220db5a8765"
|
||||
"py","word_metrics","core","core/bmad-review/scripts/word_metrics.py","fb45007a7f3cfc18d13ee8bd4787facdaae297570193bc769456297dd33da78b"
|
||||
"toml","customize","core","core/bmad-advanced-elicitation/customize.toml","735a276edd51786ccfd2c3417d9a2b9dee4244a6102698981b3888f68d979ed9"
|
||||
"toml","customize","core","core/bmad-brainstorming/customize.toml","21fcbc60c78db99ca0424da192ba0942dce2189f350f77838e4d3ecd501edd1c"
|
||||
"toml","customize","core","core/bmad-deep-recon/customize.toml","24d1383066034fd4fcf282279aaf0d29d21910fd1247dfe3dbad74a70e78814d"
|
||||
"toml","customize","core","core/bmad-forge-idea/customize.toml","ef5fadd1df3550cae00b1b442606bf84d187bfd55397563f143e1057430df45c"
|
||||
"toml","customize","core","core/bmad-party-mode/customize.toml","9c6ee33cd7fdd80e4adf514c3d54636d933d5250c2ddd78041c6cfe73b745bb0"
|
||||
"toml","customize","core","core/bmad-review/customize.toml","38470c888a809ee030dc11d38868bb1ac5c1d547f06d218b711be5df53385c00"
|
||||
"toml","customize","core","core/v6-shims/bmad-editorial-review/customize.toml","a5c5fed539e6543121e57cc29bb65559bb6391efc806bf8759c8e29697a94a34"
|
||||
"yaml","config","core","core/config.yaml","ebcfa97b8bf21a76d29993cc52c2f4f5508753b6119b873ce7a4bad1e9df2af5"
|
||||
"file",".gitignore","custom","custom/.gitignore","973b03a33f142c22cf9b65be285bebadd85790b6b55be04637d2f8c716f58fab"
|
||||
"file",".gitignore","render","render/.gitignore","240a3e0d37d2e86b614063f5347eb02d4f99ca6c254de6b82871ff8d95532a7d"
|
||||
"py","config_utils","scripts","scripts/config_utils.py","48afe2bc18a29201e343cce3703be1e70df9c83ee74eeb68e57ef8ef42e8c651"
|
||||
"py","memlog","scripts","scripts/memlog.py","3b00f82ca33dc4227f715123b939514ee35c4f9c71150c894c3d8185df1b48df"
|
||||
"py","render_skill","scripts","scripts/render_skill.py","8496d0d8b449d64c21b42a9aab3b13fc8a813a430c0695ffd84ad75bb1da7942"
|
||||
"py","resolve_config","scripts","scripts/resolve_config.py","fc78866fd42862d486d4346d2b35705f916a19e6c07bb474f8add25c71734a8e"
|
||||
"py","resolve_customization","scripts","scripts/resolve_customization.py","9b5124e0b781823a015a19d6cf5db52bbc34b6bab41c036fd1b3d464c2a137cd"
|
||||
|
@@ -0,0 +1,21 @@
|
||||
installation:
|
||||
version: 6.11.0
|
||||
installDate: 2026-08-14T15:07:31.092Z
|
||||
lastUpdated: 2026-08-14T15:07:31.092Z
|
||||
modules:
|
||||
- name: core
|
||||
version: 6.11.0
|
||||
installDate: 2026-08-14T15:07:31.003Z
|
||||
lastUpdated: 2026-08-14T15:07:31.092Z
|
||||
source: built-in
|
||||
npmPackage: null
|
||||
repoUrl: null
|
||||
- name: bmm
|
||||
version: 6.11.0
|
||||
installDate: 2026-08-14T15:07:31.069Z
|
||||
lastUpdated: 2026-08-14T15:07:31.092Z
|
||||
source: built-in
|
||||
npmPackage: null
|
||||
repoUrl: null
|
||||
ides:
|
||||
- claude-code
|
||||
@@ -0,0 +1,50 @@
|
||||
canonicalId,name,description,module,path
|
||||
"bmad-advanced-elicitation","bmad-advanced-elicitation","Push the LLM to reconsider, refine, and improve its recent output. Use when user asks for deeper critique or mentions a known deeper critique method, e.g. socratic, first principles, pre-mortem, red team.","core","_bmad/core/bmad-advanced-elicitation/SKILL.md"
|
||||
"bmad-brainstorming","bmad-brainstorming","Facilitate a brainstorming session using diverse creative techniques. Use when the user says 'help me brainstorm' or 'help me ideate'.","core","_bmad/core/bmad-brainstorming/SKILL.md"
|
||||
"bmad-customize","bmad-customize","Authors and updates customization overrides for installed BMad skills. Use when the user says 'customize bmad', 'override a skill', 'change agent behavior', or 'customize a workflow'.","core","_bmad/core/bmad-customize/SKILL.md"
|
||||
"bmad-deep-recon","bmad-deep-recon","Decision-grade research, three ways: draft a deep-research prompt for the user to run in their own tool (ChatGPT, Gemini, Grok, Perplexity, …), process a finished research report — file it, distill a succinct cited summary with metadata that downstream skills consume without reprocessing — or run the research here through web fan-out. Shipped type packs: market, domain, technical, competitive, user-voice, academic-lit — plus a select shape for choose-between decisions and custom types via overrides. Use when the user says ""deep recon"", ""research this"", ""draft a research prompt"", ""process this research report"", ""market research"", ""domain research"", ""technical research"", ""competitor research"", ""literature review"", or ""help me choose between"".","core","_bmad/core/bmad-deep-recon/SKILL.md"
|
||||
"bmad-forge-idea","bmad-forge-idea","Pressure-test an idea through persona-driven interrogation until it hardens, proves out, or dies cheaply. Use when the user says 'forge an idea', 'pressure-test this idea', 'stress-test my thinking', or 'harden this idea'.","core","_bmad/core/bmad-forge-idea/SKILL.md"
|
||||
"bmad-help","bmad-help","Analyzes current state and user query to answer BMad questions or recommend the next skill(s) to use. Use when user asks for help, bmad help, what to do next, or what to start with in BMad.","core","_bmad/core/bmad-help/SKILL.md"
|
||||
"bmad-party-mode","bmad-party-mode","Orchestrates lively group discussions between installed BMAD agents or custom personas, and helps author custom parties. Use when the user requests party mode, a roundtable, or multiple agent perspectives — or wants to create/configure a party, define personas, or build an AI focus-group panel.","core","_bmad/core/bmad-party-mode/SKILL.md"
|
||||
"bmad-review","bmad-review","Multi-lens review over any diff, doc, spec, or artifact — whichever installed lenses fit the content, run singly or together. Shipped lenses include adversarial, edge-case, verification-gap, structure, and prose. Use when the user says ""review this"", ""critical review"", ""editorial review"", ""hunt edge cases"", ""review the structure"", or ""review the prose"".","core","_bmad/core/bmad-review/SKILL.md"
|
||||
"bmad-editorial-review","bmad-editorial-review","Deprecated — forwards to bmad-review.","core","_bmad/core/v6-shims/bmad-editorial-review/SKILL.md"
|
||||
"bmad-editorial-review-prose","bmad-editorial-review-prose","Deprecated — forwards to bmad-review.","core","_bmad/core/v6-shims/bmad-editorial-review-prose/SKILL.md"
|
||||
"bmad-editorial-review-structure","bmad-editorial-review-structure","Deprecated — forwards to bmad-review.","core","_bmad/core/v6-shims/bmad-editorial-review-structure/SKILL.md"
|
||||
"bmad-review-adversarial-general","bmad-review-adversarial-general","Deprecated — forwards to bmad-review.","core","_bmad/core/v6-shims/bmad-review-adversarial-general/SKILL.md"
|
||||
"bmad-review-edge-case-hunter","bmad-review-edge-case-hunter","Deprecated — forwards to bmad-review.","core","_bmad/core/v6-shims/bmad-review-edge-case-hunter/SKILL.md"
|
||||
"bmad-review-verification-gap","bmad-review-verification-gap","Deprecated — forwards to bmad-review.","core","_bmad/core/v6-shims/bmad-review-verification-gap/SKILL.md"
|
||||
"bmad-agent-analyst","bmad-agent-analyst","Strategic business analyst and requirements expert. Use when the user asks to talk to Mary or requests the business analyst.","bmm","_bmad/bmm/agents/bmad-agent-analyst/SKILL.md"
|
||||
"bmad-agent-architect","bmad-agent-architect","System architect and technical design leader. Use when the user asks to talk to Winston or requests the architect.","bmm","_bmad/bmm/agents/bmad-agent-architect/SKILL.md"
|
||||
"bmad-agent-dev","bmad-agent-dev","Senior software engineer for story execution and code implementation. Use when the user asks to talk to Amelia or requests the developer agent.","bmm","_bmad/bmm/agents/bmad-agent-dev/SKILL.md"
|
||||
"bmad-agent-pm","bmad-agent-pm","Product manager for PRD creation and requirements discovery. Use when the user asks to talk to John or requests the product manager.","bmm","_bmad/bmm/agents/bmad-agent-pm/SKILL.md"
|
||||
"bmad-agent-ux-designer","bmad-agent-ux-designer","UX designer and UI specialist. Use when the user asks to talk to Sally or requests the UX designer.","bmm","_bmad/bmm/agents/bmad-agent-ux-designer/SKILL.md"
|
||||
"bmad-architecture","bmad-architecture","Produce the architecture: a lean spine of invariants that keeps everything built from it consistent, projected into whatever format the work needs. Use when the user says ""create the architecture"", ""create technical architecture"", ""architecture spine"", or ""create a solution design"".","bmm","_bmad/bmm/plan/bmad-architecture/SKILL.md"
|
||||
"bmad-create-epics-and-stories","bmad-create-epics-and-stories","Break requirements into epics and user stories. Use when the user says ""create the epics and stories list""","bmm","_bmad/bmm/plan/bmad-create-epics-and-stories/SKILL.md"
|
||||
"bmad-generate-project-context","bmad-generate-project-context","Deprecated — forwards to bmad-project-context. Use when the user says ""generate project context"" or ""create project context""","bmm","_bmad/bmm/plan/bmad-generate-project-context/SKILL.md"
|
||||
"bmad-prd","bmad-prd","Create, update, or validate a PRD. Use when the user wants help producing, editing, or validating a PRD.","bmm","_bmad/bmm/plan/bmad-prd/SKILL.md"
|
||||
"bmad-prfaq","bmad-prfaq","Working Backwards PRFAQ challenge that stress-tests a product concept customer-first. Use when the user requests to 'create a PRFAQ', 'work backwards', or 'run the PRFAQ challenge'.","bmm","_bmad/bmm/plan/bmad-prfaq/SKILL.md"
|
||||
"bmad-product-brief","bmad-product-brief","Create, update, or validate a product brief. Use when the user wants help producing, editing, or validating a brief.","bmm","_bmad/bmm/plan/bmad-product-brief/SKILL.md"
|
||||
"bmad-project-context","bmad-project-context","Set up, refresh, or audit a repository's agent instructions (the AGENTS.md block) so AI agents work well in that repo. Also records observed agent mistakes as pitfall lines. Must be invoked by name.","bmm","_bmad/bmm/plan/bmad-project-context/SKILL.md"
|
||||
"bmad-spec","bmad-spec","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"", ""update the spec"", or ""break this into stories"".","bmm","_bmad/bmm/plan/bmad-spec/SKILL.md"
|
||||
"bmad-sprint-planning","bmad-sprint-planning","Gate planning readiness, generate sprint status tracking from epics, summarize sprint progress, and validate or repair the tracking file. Use when the user says ""run sprint planning"", ""generate sprint plan"", ""check implementation readiness"", ""show sprint status"", ""validate sprint status"", or ""fix sprint status""","bmm","_bmad/bmm/plan/bmad-sprint-planning/SKILL.md"
|
||||
"bmad-ux","bmad-ux","Plan UX patterns and design specifications. Use when the user says ""lets create UX design"" or ""create UX specifications"" or ""help me plan the UX""","bmm","_bmad/bmm/plan/bmad-ux/SKILL.md"
|
||||
"bmad-build","bmad-build","Implements any user intent, requirement, story, bug fix or change request by producing clean working code artifacts that follow the project's existing architecture, patterns and conventions. Use when the user wants to build, fix, tweak, refactor, add or modify any code, component or feature.","bmm","_bmad/bmm/ship/bmad-build/SKILL.md"
|
||||
"bmad-build-auto","bmad-build-auto","One iteration of an unattended development loop. Use when invoked by name.","bmm","_bmad/bmm/ship/bmad-build-auto/SKILL.md"
|
||||
"bmad-checkpoint-preview","bmad-checkpoint-preview","LLM-assisted human-in-the-loop review. Make sense of a change, focus attention where it matters, test. Use when the user says ""checkpoint"", ""human review"", or ""walk me through this change"".","bmm","_bmad/bmm/ship/bmad-checkpoint-preview/SKILL.md"
|
||||
"bmad-code-review","bmad-code-review","Adversarial code review using parallel review layers and structured triage. Use when the user says ""run code review"" or ""review this code""","bmm","_bmad/bmm/ship/bmad-code-review/SKILL.md"
|
||||
"bmad-correct-course","bmad-correct-course","Manage significant changes during sprint execution. Use when the user says ""correct course"" or ""propose sprint change""","bmm","_bmad/bmm/ship/bmad-correct-course/SKILL.md"
|
||||
"bmad-qa-generate-e2e-tests","bmad-qa-generate-e2e-tests","Generate end to end automated tests for existing features. Use when the user says ""create qa automated tests for [feature]""","bmm","_bmad/bmm/ship/bmad-qa-generate-e2e-tests/SKILL.md"
|
||||
"bmad-retrospective","bmad-retrospective","Evidence-based epic retrospective — collect what the epic produced, verify findings against sources, render an acceptance verdict. Use when the user says ""run a retrospective"" or ""lets retro the epic [epic]"". Supports -H/--headless.","bmm","_bmad/bmm/ship/bmad-retrospective/SKILL.md"
|
||||
"bmad-create-architecture","bmad-create-architecture","Deprecated — forwards to bmad-architecture (create intent).","bmm","_bmad/bmm/v6-shims/bmad-create-architecture/SKILL.md"
|
||||
"bmad-create-prd","bmad-create-prd","Deprecated — forwards to bmad-prd (create intent).","bmm","_bmad/bmm/v6-shims/bmad-create-prd/SKILL.md"
|
||||
"bmad-create-story","bmad-create-story","Deprecated: `bmad-build` is now the official implementation method. Only use this when explicitly invoked by name.","bmm","_bmad/bmm/v6-shims/bmad-create-story/SKILL.md"
|
||||
"bmad-dev-auto","bmad-dev-auto","Deprecated: forwards to bmad-build-auto. Do not use unless invoked by name.","bmm","_bmad/bmm/v6-shims/bmad-dev-auto/SKILL.md"
|
||||
"bmad-dev-story","bmad-dev-story","Deprecated: `bmad-build` is now the official implementation method. Only use this when explicitly invoked by name.","bmm","_bmad/bmm/v6-shims/bmad-dev-story/SKILL.md"
|
||||
"bmad-document-project","bmad-document-project","Deprecated — forwards to bmad-project-context. Use when the user says ""document this project"" or ""generate project docs""","bmm","_bmad/bmm/v6-shims/bmad-document-project/SKILL.md"
|
||||
"bmad-domain-research","bmad-domain-research","Deprecated — forwards to bmad-deep-recon (domain type).","bmm","_bmad/bmm/v6-shims/bmad-domain-research/SKILL.md"
|
||||
"bmad-edit-prd","bmad-edit-prd","Deprecated — forwards to bmad-prd (update intent).","bmm","_bmad/bmm/v6-shims/bmad-edit-prd/SKILL.md"
|
||||
"bmad-market-research","bmad-market-research","Deprecated — forwards to bmad-deep-recon (market type).","bmm","_bmad/bmm/v6-shims/bmad-market-research/SKILL.md"
|
||||
"bmad-quick-dev","bmad-quick-dev","Deprecated: forwards to bmad-build. Do not use unless invoked by name.","bmm","_bmad/bmm/v6-shims/bmad-quick-dev/SKILL.md"
|
||||
"bmad-sprint-status","bmad-sprint-status","Deprecated — forwards to bmad-sprint-planning (status view).","bmm","_bmad/bmm/v6-shims/bmad-sprint-status/SKILL.md"
|
||||
"bmad-technical-research","bmad-technical-research","Deprecated — forwards to bmad-deep-recon (technical type).","bmm","_bmad/bmm/v6-shims/bmad-technical-research/SKILL.md"
|
||||
"bmad-validate-prd","bmad-validate-prd","Deprecated — forwards to bmad-prd (validate intent).","bmm","_bmad/bmm/v6-shims/bmad-validate-prd/SKILL.md"
|
||||
|
@@ -0,0 +1,16 @@
|
||||
# BMM Module Configuration
|
||||
# Generated by BMAD installer
|
||||
# Version: 6.11.0
|
||||
# Date: 2026-08-14T15:07:31.074Z
|
||||
|
||||
user_skill_level: intermediate
|
||||
planning_artifacts: "{project-root}/_bmad-output/planning-artifacts"
|
||||
implementation_artifacts: "{project-root}/_bmad-output/implementation-artifacts"
|
||||
project_knowledge: "{project-root}/docs"
|
||||
|
||||
# Core Configuration Values
|
||||
user_name: ProMods
|
||||
project_name: wow20
|
||||
communication_language: Deutsch
|
||||
document_output_language: Deutsch
|
||||
output_folder: "{project-root}/_bmad-output"
|
||||
@@ -0,0 +1,19 @@
|
||||
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
||||
BMad Method,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
||||
BMad Method,bmad-project-context,Project Context,PC,"Set up or refresh a repo's agent instructions so AI agents work well in it: verified commands, policy, conventions that differ from defaults, and known pitfalls. Setup, refresh, record, and audit — replaces document-project and generate-project-context.",,,anytime,,,false,repo root,AGENTS.md managed block
|
||||
BMad Method,bmad-build,Build,BD,Official Phase 4 implementation loop: clarify intent plan implement review and present.,,,ship,bmad-sprint-planning,bmad-code-review,true,implementation_artifacts,spec and project implementation
|
||||
BMad Method,bmad-spec,Spec,SPC,"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
|
||||
BMad Method,bmad-correct-course,Correct Course,CC,Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories.,,,anytime,,,false,planning_artifacts,change proposal
|
||||
BMad Method,bmad-brainstorming,Brainstorm Project,BP,Expert guided facilitation through a single or multiple techniques.,,,plan,,,false,{output_folder}/brainstorming,brainstorming session
|
||||
BMad Method,bmad-product-brief,Create Brief,CB,An expert guided experience to nail down your product idea in a brief. a gentler approach than PRFAQ when you are already sure of your concept and nothing will sway you.,,-A,plan,,,false,planning_artifacts,product brief
|
||||
BMad Method,bmad-prfaq,PRFAQ Challenge,WB,Working Backwards guided experience to forge and stress-test your product concept to ensure you have a great product that users will love and need through the PRFAQ gauntlet to determine feasibility and alignment with user needs. alternative to product brief.,,-H,plan,,,false,planning_artifacts,prfaq document
|
||||
BMad Method,bmad-prd,Create Edit and Review PRD,PRD,"Facilitated PRD workflow — create a new PRD via coached discovery, update an existing one against a change signal, or validate a finished PRD against a checklist with an HTML findings report.",,,2-planning,bmad-product-brief,,true,planning_artifacts,prd
|
||||
BMad Method,bmad-ux,Create UX,CU,"Guidance through realizing the plan for your UX, strongly recommended if a UI is a primary piece of the proposed project.",,,2-planning,bmad-prd,,false,planning_artifacts,ux design
|
||||
BMad Method,bmad-architecture,Architecture,CA,Offer once requirements exist (a PRD or spec; plus UX if present) and the user is ready to move from what to how. Also offer any time independently-built parts risk diverging. Produces the architecture spine: the invariants that keep features epics and stories consistent. Comes before epics and stories and scales from a quick spine to a full architecture (brownfield: ratifies the existing codebase).,,,plan,,,true,planning_artifacts,architecture
|
||||
BMad Method,bmad-create-epics-and-stories,Create Epics and Stories,CE,,,,plan,bmad-architecture,,true,planning_artifacts,epics and stories
|
||||
BMad Method,bmad-sprint-planning,Sprint Planning,SP,Readiness gate then tracking: verifies the planning is implementable (PASS/CONCERNS/FAIL) and produces the sprint status the implementation agents follow for every story.,,,plan,,,true,implementation_artifacts,sprint status
|
||||
BMad Method,bmad-sprint-planning,Sprint Status,SS,Anytime: summarize sprint status with risks open action items and the next recommended action; can also validate or repair the tracking file.,status,,anytime,,,false,,status summary
|
||||
BMad Method,bmad-code-review,Code Review,CR,Ad hoc review of any code change. Optional extra layer after Build's built-in review.,,,ship,bmad-build,,false,,
|
||||
BMad Method,bmad-checkpoint-preview,Checkpoint,CK,Guided walkthrough of a change from purpose and context into details. Use for human review of commits branches or PRs.,,,ship,,,false,,
|
||||
BMad Method,bmad-qa-generate-e2e-tests,QA Automation Test,QA,Generate automated API and E2E tests for implemented code. NOT for code review or story validation — use CR for that.,,,ship,bmad-build,,false,implementation_artifacts,test suite
|
||||
BMad Method,bmad-retrospective,Retrospective,ER,Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC.,,,ship,bmad-code-review,,false,implementation_artifacts,retrospective
|
||||
|
@@ -0,0 +1,28 @@
|
||||
# v6 Deprecation Shims
|
||||
|
||||
Skills in this folder are deprecated skills kept for backward compatibility with v6 skill IDs.
|
||||
Some retain their full workflow, while others forward to the skill that replaced them, passing a
|
||||
stated intent and pre-resolved customization fields so the target skips its own intent inference.
|
||||
|
||||
| Shim | Forwards to |
|
||||
| -------------------------- | ------------------------------------ |
|
||||
| `bmad-quick-dev` | `bmad-build` |
|
||||
| `bmad-dev-auto` | `bmad-build-auto` |
|
||||
| `bmad-create-story` | Retained in full |
|
||||
| `bmad-dev-story` | Retained in full |
|
||||
| `bmad-create-prd` | `bmad-prd` (create intent) |
|
||||
| `bmad-edit-prd` | `bmad-prd` (update intent) |
|
||||
| `bmad-validate-prd` | `bmad-prd` (validate intent) |
|
||||
| `bmad-create-architecture` | `bmad-architecture` (create intent) |
|
||||
| `bmad-market-research` | `bmad-deep-recon` (market type) |
|
||||
| `bmad-domain-research` | `bmad-deep-recon` (domain type) |
|
||||
| `bmad-technical-research` | `bmad-deep-recon` (technical type) |
|
||||
| `bmad-sprint-status` | `bmad-sprint-planning` (status view) |
|
||||
|
||||
Enterprise users may still depend on these IDs, so they ship by default. Removal rides the
|
||||
v7 cut — never a 6.x minor.
|
||||
|
||||
The folder is grouping only: the installer discovers skills recursively and installs each
|
||||
one under its own `name`, so nesting here does not change any installed path or skill ID.
|
||||
A future install option will let users include or exclude this folder before it is removed
|
||||
outright.
|
||||
@@ -0,0 +1,61 @@
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
# Installer-managed. Regenerated on every install — treat as read-only.
|
||||
#
|
||||
# Direct edits to this file will be overwritten on the next install.
|
||||
# To change an install answer durably, re-run the installer (your prior
|
||||
# answers are remembered as defaults). To pin a value regardless of
|
||||
# install answers, or to add custom agents / override descriptors, use:
|
||||
# _bmad/custom/config.toml (team, committed)
|
||||
# _bmad/custom/config.user.toml (personal, gitignored)
|
||||
# Those files are never touched by the installer.
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
|
||||
[core]
|
||||
project_name = "wow20"
|
||||
document_output_language = "Deutsch"
|
||||
output_folder = "{project-root}/_bmad-output"
|
||||
|
||||
[modules.bmm]
|
||||
planning_artifacts = "{project-root}/_bmad-output/planning-artifacts"
|
||||
implementation_artifacts = "{project-root}/_bmad-output/implementation-artifacts"
|
||||
project_knowledge = "{project-root}/docs"
|
||||
|
||||
[agents.bmad-agent-analyst]
|
||||
module = "bmm"
|
||||
team = "software-development"
|
||||
name = "Mary"
|
||||
title = "Business Analyst"
|
||||
icon = "📊"
|
||||
description = "Channels Porter's strategic rigor and Minto's Pyramid Principle, grounds every finding in verifiable evidence, represents every stakeholder voice. Speaks like a treasure hunter narrating the find: thrilled by every clue, precise once the pattern emerges."
|
||||
|
||||
[agents.bmad-agent-pm]
|
||||
module = "bmm"
|
||||
team = "software-development"
|
||||
name = "John"
|
||||
title = "Product Manager"
|
||||
icon = "📋"
|
||||
description = "Drives Jobs-to-be-Done over template filling, user value first, technical feasibility is a constraint not the driver. Speaks like a detective interrogating a cold case: short questions, sharper follow-ups, every 'why?' tightening the net."
|
||||
|
||||
[agents.bmad-agent-ux-designer]
|
||||
module = "bmm"
|
||||
team = "software-development"
|
||||
name = "Sally"
|
||||
title = "UX Designer"
|
||||
icon = "🎨"
|
||||
description = "Balances empathy with edge-case rigor, starts simple and evolves through feedback, every decision serves a genuine user need. Speaks like a filmmaker pitching the scene before the code exists, painting user stories that make you feel the problem."
|
||||
|
||||
[agents.bmad-agent-architect]
|
||||
module = "bmm"
|
||||
team = "software-development"
|
||||
name = "Winston"
|
||||
title = "System Architect"
|
||||
icon = "🏗️"
|
||||
description = "Favors boring technology for stability, developer productivity as architecture, ties every decision to business value. Speaks like a seasoned engineer at the whiteboard: measured, always laying out trade-offs rather than verdicts."
|
||||
|
||||
[agents.bmad-agent-dev]
|
||||
module = "bmm"
|
||||
team = "software-development"
|
||||
name = "Amelia"
|
||||
title = "Senior Software Engineer"
|
||||
icon = "💻"
|
||||
description = "Test-first discipline (red, green, refactor), 100% pass before review, no fluff all precision. Speaks like a terminal prompt: exact file paths, AC IDs, and commit-message brevity — every statement citable."
|
||||
@@ -0,0 +1,17 @@
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
# Installer-managed. Regenerated on every install — treat as read-only.
|
||||
# Holds install answers scoped to YOU personally.
|
||||
#
|
||||
# Direct edits to this file will be overwritten on the next install.
|
||||
# To change an answer durably, re-run the installer (your prior answers
|
||||
# are remembered as defaults). For pinned overrides or custom sections
|
||||
# the installer does not know about, use _bmad/custom/config.user.toml
|
||||
# — it is never touched by the installer.
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
|
||||
[core]
|
||||
user_name = "ProMods"
|
||||
communication_language = "Deutsch"
|
||||
|
||||
[modules.bmm]
|
||||
user_skill_level = "intermediate"
|
||||
@@ -0,0 +1,10 @@
|
||||
# CORE Module Configuration
|
||||
# Generated by BMAD installer
|
||||
# Version: 6.11.0
|
||||
# Date: 2026-08-14T15:07:31.074Z
|
||||
|
||||
user_name: ProMods
|
||||
project_name: wow20
|
||||
communication_language: Deutsch
|
||||
document_output_language: Deutsch
|
||||
output_folder: "{project-root}/_bmad-output"
|
||||
@@ -0,0 +1,10 @@
|
||||
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
||||
Core,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
||||
Core,bmad-brainstorming,Brainstorming,BSP,Use early in ideation or when stuck generating ideas.,,,anytime,,,false,{output_folder}/brainstorming,brainstorming session
|
||||
Core,bmad-party-mode,Party Mode,PM,Orchestrate multi-agent discussions when you need multiple perspectives or want agents to collaborate.,,,anytime,,,false,,
|
||||
Core,bmad-help,BMad Help,BH,,,,anytime,,,false,,
|
||||
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
|
||||
Core,bmad-advanced-elicitation,Advanced Elicitation,AE,"Use at any checkpoint to push a just-produced draft, section, or plan past its first version — pick from a menu of elicitation methods (pre-mortem, first principles, red team, socratic) and apply the improvements.",,,anytime,,,false,,
|
||||
Core,bmad-review,Review,RV,"Use to review anything before it ships — a diff, branch, or uncommitted changes; a PRD, spec, story, or architecture doc; any prose document. Runs whichever installed lenses fit the content and reports findings in one shape: shipped lenses cover adversarial critique, edge cases, verification gaps, document structure (cuts, merges, moves), and prose copy-edit, and installs may add more. Reach for it to tighten a bloated or LLM-slop draft, pressure-test a plan before building, or check a change is adequately tested. Run every applicable lens or name the ones you want. Code Review in other modules calls it automatically.",,[path],anytime,,,false,,findings JSON array + markdown report
|
||||
Core,bmad-forge-idea,Forge Idea,FI,"Use to pressure-test and harden an idea — software, business, creative, research, or life — until it proves out, hardens into something buildable, or dies cheaply. Persona-driven interrogation; optional handoff to bmad-spec or bmad-build.",,,anytime,,,false,{output_folder}/forge,refined-idea brief (optional)
|
||||
Core,bmad-deep-recon,Deep Recon,RS,Decision-grade research three ways: draft a deep-research prompt for your own AI tool then process the returned report into a downstream-ready cited summary — or run the research directly via web fan-out. Types: market domain technical competitive user-voice academic-lit plus a select shape for choose-between decisions; claim verification and refresh lifecycle. Custom types via overrides.,,[type],anytime,,,false,{planning_artifacts}/research,research report/summary + optional html briefing
|
||||
|
@@ -0,0 +1,25 @@
|
||||
# v6 Deprecation Shims
|
||||
|
||||
Skills in this folder are forwarders kept for backward compatibility with v6 skill IDs.
|
||||
Each one holds no logic of its own — it forwards to the skill that replaced it, pinning
|
||||
the legacy output contract so existing callers keep working.
|
||||
|
||||
| Shim | Forwards to |
|
||||
| --------------------------------- | ---------------------------------------- |
|
||||
| `bmad-editorial-review` | `bmad-review` (structure + prose lenses) |
|
||||
| `bmad-editorial-review-prose` | `bmad-review` (prose lens) |
|
||||
| `bmad-editorial-review-structure` | `bmad-review` (structure lens) |
|
||||
| `bmad-review-adversarial-general` | `bmad-review` (adversarial lens) |
|
||||
| `bmad-review-edge-case-hunter` | `bmad-review` (edge-case lens) |
|
||||
| `bmad-review-verification-gap` | `bmad-review` (verification-gap lens) |
|
||||
|
||||
`bmad-editorial-review` keeps its `customize.toml` so existing team and user
|
||||
overrides still resolve; the shim forwards those resolved values to `bmad-review`.
|
||||
|
||||
External module repos (gds, loop, tea, bmb, os-utils) still invoke these IDs, so they
|
||||
ship by default. Removal rides the v7 cut — never a 6.x minor.
|
||||
|
||||
The folder is grouping only: the installer discovers skills recursively and installs each
|
||||
one under its own `name`, so nesting here does not change any installed path or skill ID.
|
||||
A future install option will let users include or exclude this folder before it is removed
|
||||
outright.
|
||||
@@ -0,0 +1 @@
|
||||
*.user.toml
|
||||
@@ -0,0 +1,7 @@
|
||||
# Team / enterprise overrides for _bmad/config.toml.
|
||||
# Committed to the repo — applies to every developer on the project.
|
||||
# Tables deep-merge over base config; keyed entries merge by key.
|
||||
# Example: override an agent descriptor, or add a new agent.
|
||||
#
|
||||
# [agents.bmad-agent-pm]
|
||||
# description = "Prefers short, bulleted PRDs over narrative drafts."
|
||||
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,119 @@
|
||||
"""Shared strict TOML loading and structural merge support."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
from typing import Any, Iterable
|
||||
|
||||
|
||||
class ConfigError(ValueError):
|
||||
"""Raised when a present configuration layer cannot be used safely."""
|
||||
|
||||
|
||||
_KEYED_MERGE_FIELDS = ("code", "id")
|
||||
|
||||
|
||||
def load_toml(path: Path, *, required: bool = False) -> dict[str, Any]:
|
||||
"""Load a TOML table, allowing absence only for optional layers."""
|
||||
if not path.exists():
|
||||
if required:
|
||||
raise ConfigError(f"required TOML file not found: {path}")
|
||||
return {}
|
||||
if not path.is_file():
|
||||
raise ConfigError(f"TOML layer is not a file: {path}")
|
||||
try:
|
||||
with path.open("rb") as stream:
|
||||
parsed = tomllib.load(stream)
|
||||
except tomllib.TOMLDecodeError as error:
|
||||
raise ConfigError(f"failed to parse {path}: {error}") from error
|
||||
except OSError as error:
|
||||
raise ConfigError(f"failed to read {path}: {error}") from error
|
||||
if not isinstance(parsed, dict):
|
||||
raise ConfigError(f"TOML layer did not parse to a table: {path}")
|
||||
return parsed
|
||||
|
||||
|
||||
def _detect_keyed_merge_field(items: list[Any]) -> str | None:
|
||||
if not items or not all(isinstance(item, dict) for item in items):
|
||||
return None
|
||||
for candidate in _KEYED_MERGE_FIELDS:
|
||||
if all(candidate in item for item in items):
|
||||
for item in items:
|
||||
value = item[candidate]
|
||||
if not isinstance(value, str):
|
||||
raise ConfigError(
|
||||
f"keyed array identifier `{candidate}` must be a string, "
|
||||
f"got {type(value).__name__}"
|
||||
)
|
||||
if not value:
|
||||
raise ConfigError(
|
||||
f"keyed array identifier `{candidate}` must not be empty"
|
||||
)
|
||||
return candidate
|
||||
return None
|
||||
|
||||
|
||||
def _merge_arrays(base: list[Any], override: list[Any]) -> list[Any]:
|
||||
keyed_field = _detect_keyed_merge_field(base + override)
|
||||
if keyed_field is None:
|
||||
return list(base) + list(override)
|
||||
|
||||
result: list[Any] = []
|
||||
index_by_key: dict[str, int] = {}
|
||||
for item in base:
|
||||
copied = dict(item)
|
||||
index_by_key[copied[keyed_field]] = len(result)
|
||||
result.append(copied)
|
||||
for item in override:
|
||||
copied = dict(item)
|
||||
key = copied[keyed_field]
|
||||
if key in index_by_key:
|
||||
result[index_by_key[key]] = copied
|
||||
else:
|
||||
index_by_key[key] = len(result)
|
||||
result.append(copied)
|
||||
return result
|
||||
|
||||
|
||||
def structural_merge(base: Any, override: Any) -> Any:
|
||||
"""Merge tables recursively, keyed table arrays by identity, and append other arrays."""
|
||||
if isinstance(base, dict) and isinstance(override, dict):
|
||||
result = dict(base)
|
||||
for key, value in override.items():
|
||||
result[key] = structural_merge(result[key], value) if key in result else value
|
||||
return result
|
||||
if isinstance(base, list) and isinstance(override, list):
|
||||
return _merge_arrays(base, override)
|
||||
return override
|
||||
|
||||
|
||||
def merge_layers(layers: Iterable[dict[str, Any]]) -> dict[str, Any]:
|
||||
merged: dict[str, Any] = {}
|
||||
for layer in layers:
|
||||
merged = structural_merge(merged, layer)
|
||||
return merged
|
||||
|
||||
|
||||
def load_central_config(project_root: Path) -> dict[str, Any]:
|
||||
bmad_dir = project_root / "_bmad"
|
||||
return merge_layers(
|
||||
(
|
||||
load_toml(bmad_dir / "config.toml", required=True),
|
||||
load_toml(bmad_dir / "config.user.toml"),
|
||||
load_toml(bmad_dir / "custom" / "config.toml"),
|
||||
load_toml(bmad_dir / "custom" / "config.user.toml"),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def load_customization(project_root: Path | None, skill_dir: Path) -> dict[str, Any]:
|
||||
skill_name = skill_dir.name
|
||||
custom_dir = project_root / "_bmad" / "custom" if project_root else None
|
||||
return merge_layers(
|
||||
(
|
||||
load_toml(skill_dir / "customize.toml", required=True),
|
||||
load_toml(custom_dir / f"{skill_name}.toml") if custom_dir else {},
|
||||
load_toml(custom_dir / f"{skill_name}.user.toml") if custom_dir else {},
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.8"
|
||||
# ///
|
||||
"""memlog — an append-only memory log: LLM-optimal working memory for a skill.
|
||||
|
||||
A memlog is the dense, chronological record of everything that mattered in a piece of
|
||||
work — every item the user generated or accepted — kept minimal like human memory: only
|
||||
what's important, never bloated. It persists ACROSS sessions, so a fresh session can
|
||||
load it and continue. It is NOT a deliverable; downstream artifacts (a brief, a PRD, a
|
||||
deck, a report) are *derived* from it on demand. The host skill supplies the vocabulary
|
||||
by how it calls `append` — the tool stays neutral.
|
||||
|
||||
It is a FLAT log: there are no sections or grouping. Every entry is one line, recorded
|
||||
at the END in the order it happened. The chronology itself is the structure — an event
|
||||
like "started technique X" is just another entry, same as an idea or an insight.
|
||||
|
||||
Three invariants make it trustworthy:
|
||||
|
||||
1. Append-only, chronological. Entries land at the end, in the order they happen.
|
||||
Nothing is ever inserted backward, reordered, edited, or removed. There is no
|
||||
edit or delete subcommand by design; history is never rewritten.
|
||||
2. Write-only / blind. Every command is an atomic, context-free write and echoes the
|
||||
new state as one line of JSON, so the caller never re-reads the file mid-session.
|
||||
The one time the file is read is on resume — and the caller reads it itself, not
|
||||
via this script.
|
||||
3. No lifecycle status. A memory log has no "complete" flag. Whether the work is done,
|
||||
blocked, or paused is itself a fact that happened, so it is recorded as an entry
|
||||
(e.g. `append --type event --text "session complete"`), never as frontmatter the
|
||||
log would have to mutate. The chronology stays the single source of truth, and a
|
||||
resume learns the state by reading the last entries — the same way it learns
|
||||
everything else.
|
||||
|
||||
Atomicity: every write goes to a temp file, is flushed and fsync'd, then atomically
|
||||
renamed over the target, so a crash never leaves a half-written entry.
|
||||
|
||||
The file shape (.memlog.md):
|
||||
|
||||
---
|
||||
topic: Onboarding flow for a budgeting app
|
||||
goal: lift week-1 retention
|
||||
updated: 2026-06-07T14:22
|
||||
---
|
||||
|
||||
- (note) user picked techniques: SCAMPER, then Six Thinking Hats
|
||||
- (technique) started SCAMPER
|
||||
- (idea) skip the signup wall: let people try with sample data first
|
||||
- (idea) auto-import one bank account so the first screen shows real numbers
|
||||
- (question) is open-banking consent too heavy for step one?
|
||||
- (insight) the "scary numbers" risk and the "real numbers" idea are one lever: show real data, pre-categorized
|
||||
- (direction) optimize for the anxious first-timer, not the power user
|
||||
- (decision) lead with one pre-categorized account; defer multi-account import
|
||||
- (event) session complete
|
||||
|
||||
Each entry may carry an optional `--type` — what KIND it is (idea, insight, question,
|
||||
decision, direction, assumption, gap, note, event, …) — and an optional `--by` naming
|
||||
who it came from (e.g. `user`, `coach`), for sessions where authorship matters. Both
|
||||
render into one short inline tag: `(idea)`, `(idea by user)`, `(by coach)`. Omit them
|
||||
for a plain note. The host skill names the vocabulary; the script does not enforce one.
|
||||
|
||||
Commands:
|
||||
init (--workspace DIR | --path FILE) [--field k=v ...] create the memlog (errors if it exists)
|
||||
append (--workspace DIR | --path FILE) --text STR [--type T] [--by W] append one entry at the end
|
||||
set (--workspace DIR | --path FILE) --key K --value V set/replace a descriptive frontmatter field
|
||||
|
||||
Addressing: `--workspace` is the run folder, and the memlog is always {workspace}/.memlog.md.
|
||||
`--path` points straight at the memlog file instead, for callers that already hold the path.
|
||||
"""
|
||||
from __future__ import annotations # keep type-hint syntax lazy so the script runs on 3.8+
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
MEMLOG = ".memlog.md"
|
||||
|
||||
|
||||
def now() -> str:
|
||||
return datetime.now().strftime("%Y-%m-%dT%H:%M")
|
||||
|
||||
|
||||
def resolve(args) -> Path:
|
||||
"""The memlog file, from either addressing mode: {workspace}/.memlog.md or an explicit --path."""
|
||||
return Path(args.path) if args.path else Path(args.workspace) / MEMLOG
|
||||
|
||||
|
||||
def split(text: str) -> tuple[dict, str]:
|
||||
"""Return (frontmatter dict in source order, body str). Frontmatter is plain key: value.
|
||||
|
||||
The closing fence is the first line that is *exactly* `---`, so a `---` inside a
|
||||
field value (topic/goal are free user text) never truncates the frontmatter.
|
||||
"""
|
||||
lines = text.splitlines()
|
||||
if not lines or lines[0] != "---":
|
||||
raise ValueError(".memlog.md has no frontmatter")
|
||||
end = next((i for i in range(1, len(lines)) if lines[i] == "---"), None)
|
||||
if end is None:
|
||||
raise ValueError(".memlog.md frontmatter is not terminated")
|
||||
meta: dict[str, str] = {}
|
||||
for line in lines[1:end]:
|
||||
if ":" in line:
|
||||
k, v = line.split(":", 1)
|
||||
meta[k.strip()] = v.strip()
|
||||
return meta, "\n".join(lines[end + 1:]).lstrip("\n")
|
||||
|
||||
|
||||
def render(meta: dict, body: str) -> str:
|
||||
# Neutralize newlines in values so a multi-line field can't break the fence on re-read.
|
||||
fm = "\n".join(f"{k}: {' '.join(str(v).splitlines())}" for k, v in meta.items())
|
||||
return "---\n" + fm + "\n---\n\n" + body.rstrip("\n") + "\n"
|
||||
|
||||
|
||||
def touch(meta: dict) -> None:
|
||||
"""Stamp `updated` and keep it last so the field order stays predictable."""
|
||||
meta.pop("updated", None)
|
||||
meta["updated"] = now()
|
||||
|
||||
|
||||
def write_atomic(path: Path, text: str) -> None:
|
||||
"""Temp + flush + fsync + atomic rename, so a crash never half-writes an entry."""
|
||||
tmp = path.with_suffix(path.suffix + ".tmp")
|
||||
with open(tmp, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
os.replace(tmp, path)
|
||||
|
||||
|
||||
def entry_count(body: str) -> int:
|
||||
return sum(1 for ln in body.splitlines() if ln.startswith("- "))
|
||||
|
||||
|
||||
def ack(path: Path, body: str) -> None:
|
||||
"""Echo new state so the caller never re-reads the file to know where it stands."""
|
||||
print(json.dumps({
|
||||
"ok": True,
|
||||
"memlog": str(path),
|
||||
"entries": entry_count(body),
|
||||
}))
|
||||
|
||||
|
||||
def cmd_init(args) -> int:
|
||||
path = resolve(args)
|
||||
if path.exists():
|
||||
print(f"error: {path} already exists; use append/set to update it", file=sys.stderr)
|
||||
return 2
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
meta: dict[str, str] = {}
|
||||
for pair in args.field or []:
|
||||
if "=" not in pair:
|
||||
print(f"error: --field expects key=value, got {pair!r}", file=sys.stderr)
|
||||
return 2
|
||||
k, v = pair.split("=", 1)
|
||||
meta[k.strip()] = v.strip()
|
||||
touch(meta)
|
||||
write_atomic(path, render(meta, ""))
|
||||
ack(path, "")
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_append(args) -> int:
|
||||
path = resolve(args)
|
||||
meta, body = split(path.read_text(encoding="utf-8"))
|
||||
text = " ".join(args.text.split()) # collapse newlines/runs → one-line entry, no prose bloat
|
||||
label = args.type or ""
|
||||
if args.by:
|
||||
label = f"{label} by {args.by}".strip() # attribution: "(idea by user)" / "(by coach)"
|
||||
tag = f"({label}) " if label else ""
|
||||
entry = f"- {tag}{text}"
|
||||
body = (body.rstrip("\n") + "\n" + entry) if body.strip() else entry # always at the end
|
||||
touch(meta)
|
||||
write_atomic(path, render(meta, body))
|
||||
ack(path, body)
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_set(args) -> int:
|
||||
path = resolve(args)
|
||||
meta, body = split(path.read_text(encoding="utf-8"))
|
||||
meta[args.key] = args.value
|
||||
touch(meta)
|
||||
write_atomic(path, render(meta, body))
|
||||
ack(path, body)
|
||||
return 0
|
||||
|
||||
|
||||
def add_target(sp) -> None:
|
||||
"""Every command addresses the memlog the same way: a run folder or an explicit path."""
|
||||
g = sp.add_mutually_exclusive_group(required=True)
|
||||
g.add_argument("--workspace", help="run folder; the memlog is {workspace}/.memlog.md")
|
||||
g.add_argument("--path", help="explicit memlog file path (alternative to --workspace)")
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
sub = p.add_subparsers(dest="cmd", required=True)
|
||||
|
||||
pi = sub.add_parser("init", help="create the memlog")
|
||||
add_target(pi)
|
||||
pi.add_argument("--field", action="append", metavar="KEY=VALUE", help="frontmatter field (repeatable)")
|
||||
pi.set_defaults(func=cmd_init)
|
||||
|
||||
pa = sub.add_parser("append", help="append one entry at the end")
|
||||
add_target(pa)
|
||||
pa.add_argument("--text", required=True)
|
||||
pa.add_argument("--type", help="entry kind, rendered as an inline tag")
|
||||
pa.add_argument("--by", help="who the entry came from (e.g. user, coach); rendered into the tag")
|
||||
pa.set_defaults(func=cmd_append)
|
||||
|
||||
pset = sub.add_parser("set", help="set a descriptive frontmatter field")
|
||||
add_target(pset)
|
||||
pset.add_argument("--key", required=True)
|
||||
pset.add_argument("--value", required=True)
|
||||
pset.set_defaults(func=cmd_set)
|
||||
|
||||
args = p.parse_args(argv)
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,401 @@
|
||||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# ///
|
||||
"""Render a skill's Markdown sources into an immutable project snapshot."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
# Installed scripts are consumer files, not a location for interpreter caches.
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
from config_utils import ConfigError, load_central_config, load_customization, load_toml
|
||||
|
||||
|
||||
class RenderError(ValueError):
|
||||
"""Raised when rendering cannot safely publish a snapshot."""
|
||||
|
||||
|
||||
_CONFIG_TOKEN = re.compile(r"\{\{config\.([A-Za-z0-9_.-]+)\}\}")
|
||||
_SHORT_CONFIG_TOKEN = re.compile(r"\{\{\.([A-Za-z0-9_]+)\}\}")
|
||||
_CUSTOM_TOKEN = re.compile(r"\{workflow\.([A-Za-z0-9_.-]+)\}")
|
||||
_SNAPSHOT_TOKEN = re.compile(r"\[\[bmad-snapshot:([A-Za-z0-9_./-]+\.md)\]\]")
|
||||
|
||||
|
||||
def _hash_bytes(content: bytes) -> str:
|
||||
return hashlib.sha256(content).hexdigest()
|
||||
|
||||
|
||||
def _canonical_json(value: Any) -> bytes:
|
||||
return json.dumps(
|
||||
value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
|
||||
).encode("utf-8")
|
||||
|
||||
|
||||
def _lookup(data: dict[str, Any], dotted_path: str, label: str) -> Any:
|
||||
current: Any = data
|
||||
for part in dotted_path.split("."):
|
||||
if not isinstance(current, dict) or part not in current:
|
||||
raise RenderError(f"missing {label} `{dotted_path}`")
|
||||
current = current[part]
|
||||
return current
|
||||
|
||||
|
||||
def _require_string(value: Any, label: str, *, allow_empty: bool = False) -> str:
|
||||
if not isinstance(value, str):
|
||||
raise RenderError(f"{label} must be a string, got {type(value).__name__}")
|
||||
if not allow_empty and not value.strip():
|
||||
raise RenderError(f"{label} must not be empty")
|
||||
return value
|
||||
|
||||
|
||||
def _require_string_list(value: Any, label: str) -> list[str]:
|
||||
if not isinstance(value, list):
|
||||
raise RenderError(f"{label} must be a list, got {type(value).__name__}")
|
||||
result = []
|
||||
for index, item in enumerate(value):
|
||||
result.append(_require_string(item, f"{label}[{index}]"))
|
||||
return result
|
||||
|
||||
|
||||
def _require_review_layers(value: Any, label: str) -> list[dict[str, str]]:
|
||||
if not isinstance(value, list):
|
||||
raise RenderError(f"{label} must be a list of tables")
|
||||
result: list[dict[str, str]] = []
|
||||
seen: set[str] = set()
|
||||
for index, item in enumerate(value):
|
||||
item_label = f"{label}[{index}]"
|
||||
if not isinstance(item, dict):
|
||||
raise RenderError(f"{item_label} must be a table")
|
||||
identifier = _require_string(item.get("id"), f"{item_label}.id")
|
||||
if identifier in seen:
|
||||
raise RenderError(f"duplicate review layer id `{identifier}`")
|
||||
seen.add(identifier)
|
||||
layer = {
|
||||
"id": identifier,
|
||||
"name": _require_string(item.get("name", identifier), f"{item_label}.name"),
|
||||
"instruction": _require_string(
|
||||
item.get("instruction"), f"{item_label}.instruction", allow_empty=True
|
||||
),
|
||||
}
|
||||
if "when" in item:
|
||||
layer["when"] = _require_string(item["when"], f"{item_label}.when")
|
||||
result.append(layer)
|
||||
return result
|
||||
|
||||
|
||||
def _load_sources(skill_dir: Path) -> dict[str, str]:
|
||||
sources: dict[str, str] = {}
|
||||
for candidate in sorted(skill_dir.rglob("*.md")):
|
||||
if candidate.name == "SKILL.md":
|
||||
continue
|
||||
name = candidate.relative_to(skill_dir).as_posix()
|
||||
path = candidate.resolve(strict=True)
|
||||
if not path.is_relative_to(skill_dir):
|
||||
raise RenderError(f"render source escapes skill directory: {name}")
|
||||
if not path.is_file():
|
||||
raise RenderError(f"render source is missing or not a file: {path}")
|
||||
try:
|
||||
sources[name] = path.read_text(encoding="utf-8")
|
||||
except (OSError, UnicodeError) as error:
|
||||
raise RenderError(f"failed to read render source {path}: {error}") from error
|
||||
if "workflow.md" not in sources:
|
||||
raise RenderError(f"render entry is missing: {skill_dir / 'workflow.md'}")
|
||||
return sources
|
||||
|
||||
|
||||
def _resolve_config_value(value: Any, label: str, project_root: Path) -> str:
|
||||
text = _require_string(value, label)
|
||||
if "{project-root}" not in text:
|
||||
return text
|
||||
resolved = text.replace("{project-root}", str(project_root))
|
||||
if not Path(resolved).is_absolute():
|
||||
raise RenderError(f"{label} must resolve to an absolute path: {resolved}")
|
||||
return resolved
|
||||
|
||||
|
||||
def _find_config_values(data: Any, key: str, prefix: str = "") -> list[tuple[str, Any]]:
|
||||
matches: list[tuple[str, Any]] = []
|
||||
if not isinstance(data, dict):
|
||||
return matches
|
||||
for name, value in data.items():
|
||||
path = f"{prefix}.{name}" if prefix else name
|
||||
if name == key and not isinstance(value, (dict, list)):
|
||||
matches.append((path, value))
|
||||
matches.extend(_find_config_values(value, key, path))
|
||||
return matches
|
||||
|
||||
|
||||
def _resolve_short_config(
|
||||
central: dict[str, Any], key: str, project_root: Path
|
||||
) -> tuple[str, str]:
|
||||
matches = _find_config_values(central, key)
|
||||
if not matches:
|
||||
raise RenderError(f"missing config value `{key}`")
|
||||
if len(matches) > 1:
|
||||
paths = ", ".join(path for path, _ in matches)
|
||||
raise RenderError(f"ambiguous config value `{key}` found at: {paths}")
|
||||
path, value = matches[0]
|
||||
return path, _resolve_config_value(value, f"config.{path}", project_root)
|
||||
|
||||
|
||||
def _format_markdown_list(items: list[str]) -> str:
|
||||
if not items:
|
||||
return "_None._"
|
||||
rendered = []
|
||||
for item in items:
|
||||
lines = item.splitlines() or [""]
|
||||
rendered.append("- " + lines[0])
|
||||
rendered.extend(" " + line for line in lines[1:])
|
||||
return "\n".join(rendered)
|
||||
|
||||
|
||||
def _format_review_layers(layers: list[dict[str, str]]) -> str:
|
||||
active = [layer for layer in layers if layer["instruction"].strip()]
|
||||
if not active:
|
||||
return "No active review layers. HALT with blocking condition `no active review layers`."
|
||||
sections = []
|
||||
for layer in active:
|
||||
section = [f"#### {layer['name']} (`{layer['id']}`)"]
|
||||
if layer.get("when"):
|
||||
section.extend(["", f"Run only when: {layer['when']}"])
|
||||
section.extend(["", layer["instruction"].strip()])
|
||||
sections.append("\n".join(section))
|
||||
return "\n\n".join(sections)
|
||||
|
||||
|
||||
def _resolve_customization_value(value: Any, default: Any, label: str) -> tuple[Any, str]:
|
||||
if isinstance(default, str):
|
||||
allow_empty = not default.strip() or label == "customization.workflow.open_spec"
|
||||
resolved = _require_string(value, label, allow_empty=allow_empty)
|
||||
return resolved, resolved
|
||||
if isinstance(default, list):
|
||||
if default and all(isinstance(item, dict) for item in default):
|
||||
resolved = _require_review_layers(value, label)
|
||||
return resolved, _format_review_layers(resolved)
|
||||
resolved = _require_string_list(value, label)
|
||||
return resolved, _format_markdown_list(resolved)
|
||||
raise RenderError(f"{label} has unsupported default type {type(default).__name__}")
|
||||
|
||||
|
||||
def _resolve_replacements(
|
||||
sources: dict[str, str],
|
||||
central: dict[str, Any],
|
||||
customization: dict[str, Any],
|
||||
defaults: dict[str, Any] | None,
|
||||
project_root: Path,
|
||||
) -> tuple[dict[str, str], dict[str, Any]]:
|
||||
replacements: dict[str, str] = {}
|
||||
input_values: dict[str, Any] = {}
|
||||
for content in sources.values():
|
||||
for match in _SHORT_CONFIG_TOKEN.finditer(content):
|
||||
token, key = match.group(0), match.group(1)
|
||||
path, resolved = _resolve_short_config(central, key, project_root)
|
||||
source = f"config.{path}"
|
||||
replacements[token] = resolved
|
||||
input_values[source] = resolved
|
||||
for match in _CONFIG_TOKEN.finditer(content):
|
||||
token, path = match.group(0), match.group(1)
|
||||
source = f"config.{path}"
|
||||
resolved = _resolve_config_value(
|
||||
_lookup(central, path, "config value"), source, project_root
|
||||
)
|
||||
replacements[token] = resolved
|
||||
input_values[source] = resolved
|
||||
for match in _CUSTOM_TOKEN.finditer(content):
|
||||
if defaults is None:
|
||||
raise RenderError("customization tokens require customize.toml")
|
||||
token, relative_path = match.group(0), match.group(1)
|
||||
path = f"workflow.{relative_path}"
|
||||
source = f"customization.{path}"
|
||||
resolved, rendered = _resolve_customization_value(
|
||||
_lookup(customization, path, "customization value"),
|
||||
_lookup(defaults, path, "customization default"),
|
||||
source,
|
||||
)
|
||||
replacements[token] = rendered
|
||||
input_values[source] = resolved
|
||||
return replacements, input_values
|
||||
|
||||
|
||||
def _render_sources(
|
||||
sources: dict[str, str], replacements: dict[str, str], destination: Path
|
||||
) -> dict[str, str]:
|
||||
"""Resolve only tokens authored in installed sources in one opaque pass."""
|
||||
# Workflow customization may reference installed skill files; bind those
|
||||
# references to the immutable generation before inserting the prose.
|
||||
replacements = {
|
||||
token: value.replace("{skill-root}", str(destination))
|
||||
if token.startswith("{workflow.")
|
||||
else value
|
||||
for token, value in replacements.items()
|
||||
}
|
||||
source_names = set(sources)
|
||||
patterns = [
|
||||
*(re.escape(token) for token in sorted(replacements, key=len, reverse=True)),
|
||||
_SNAPSHOT_TOKEN.pattern,
|
||||
]
|
||||
token_pattern = re.compile("|".join(patterns))
|
||||
|
||||
def replace(match: re.Match[str]) -> str:
|
||||
token = match.group(0)
|
||||
if token in replacements:
|
||||
return replacements[token]
|
||||
snapshot = _SNAPSHOT_TOKEN.fullmatch(token)
|
||||
if snapshot is None:
|
||||
raise RenderError(f"unsupported render token: {token}")
|
||||
target = snapshot.group(1)
|
||||
if target not in source_names:
|
||||
raise RenderError(f"snapshot reference targets undeclared source: {target}")
|
||||
return str(destination / target)
|
||||
|
||||
rendered: dict[str, str] = {}
|
||||
for name, content in sources.items():
|
||||
# Inserted paths and customization prose are never scanned as source tokens.
|
||||
rendered[name] = token_pattern.sub(replace, content)
|
||||
return rendered
|
||||
|
||||
|
||||
def _verify_existing(destination: Path, manifest: dict[str, Any]) -> None:
|
||||
manifest_path = destination / "manifest.json"
|
||||
try:
|
||||
existing = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||||
except (OSError, UnicodeError, json.JSONDecodeError) as error:
|
||||
raise RenderError(f"corrupt existing generation {destination}: {error}") from error
|
||||
if existing != manifest:
|
||||
raise RenderError(f"generation collision or corruption at {destination}")
|
||||
expected_files = set(manifest["outputs"]) | {"manifest.json"}
|
||||
actual_files = {
|
||||
path.relative_to(destination).as_posix()
|
||||
for path in destination.rglob("*")
|
||||
if path.is_file()
|
||||
}
|
||||
if actual_files != expected_files:
|
||||
raise RenderError(f"generation contains unexpected or missing files: {destination}")
|
||||
for name, expected_hash in manifest["outputs"].items():
|
||||
try:
|
||||
actual_hash = _hash_bytes((destination / name).read_bytes())
|
||||
except OSError as error:
|
||||
raise RenderError(f"failed to verify {destination / name}: {error}") from error
|
||||
if actual_hash != expected_hash:
|
||||
raise RenderError(f"generation output hash mismatch: {destination / name}")
|
||||
|
||||
|
||||
def _publish(destination: Path, outputs: dict[str, bytes], manifest: dict[str, Any]) -> None:
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
if destination.exists():
|
||||
_verify_existing(destination, manifest)
|
||||
return
|
||||
staging = Path(tempfile.mkdtemp(prefix=".staging-", dir=destination.parent))
|
||||
try:
|
||||
for name, content in outputs.items():
|
||||
path = staging / name
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_bytes(content)
|
||||
(staging / "manifest.json").write_bytes(
|
||||
json.dumps(manifest, ensure_ascii=False, indent=2, sort_keys=True).encode("utf-8")
|
||||
+ b"\n"
|
||||
)
|
||||
try:
|
||||
os.rename(staging, destination)
|
||||
except OSError:
|
||||
if destination.exists():
|
||||
_verify_existing(destination, manifest)
|
||||
else:
|
||||
raise
|
||||
finally:
|
||||
if staging.exists():
|
||||
shutil.rmtree(staging, ignore_errors=True)
|
||||
|
||||
|
||||
def render(project_root: Path, skill_dir: Path) -> Path:
|
||||
project_root = project_root.resolve(strict=True)
|
||||
skill_dir = skill_dir.resolve(strict=True)
|
||||
if not (project_root / "_bmad").is_dir():
|
||||
raise RenderError(f"project root does not contain _bmad/: {project_root}")
|
||||
|
||||
sources = _load_sources(skill_dir)
|
||||
central = load_central_config(project_root)
|
||||
has_customization = any(
|
||||
_CUSTOM_TOKEN.search(content) for content in sources.values()
|
||||
)
|
||||
defaults = (
|
||||
load_toml(skill_dir / "customize.toml", required=True)
|
||||
if has_customization
|
||||
else None
|
||||
)
|
||||
customization = (
|
||||
load_customization(project_root, skill_dir) if has_customization else {}
|
||||
)
|
||||
replacements, input_values = _resolve_replacements(
|
||||
sources, central, customization, defaults, project_root
|
||||
)
|
||||
source_hashes = {
|
||||
name: _hash_bytes(content.encode("utf-8")) for name, content in sources.items()
|
||||
}
|
||||
root_hash = _hash_bytes(str(project_root).encode("utf-8"))[:12]
|
||||
slug = re.sub(r"[^a-z0-9]+", "-", project_root.name.lower()).strip("-") or "project"
|
||||
slug = slug[:80].rstrip("-") or "project"
|
||||
renderer_hash = _hash_bytes(Path(__file__).read_bytes())
|
||||
identity = {
|
||||
"project_root": str(project_root),
|
||||
"renderer_sha256": renderer_hash,
|
||||
"resolved_values": input_values,
|
||||
"source_sha256": source_hashes,
|
||||
}
|
||||
generation_hash = _hash_bytes(_canonical_json(identity))[:20]
|
||||
destination = (
|
||||
project_root
|
||||
/ "_bmad"
|
||||
/ "render"
|
||||
/ skill_dir.name
|
||||
/ f"{slug}-{root_hash}"
|
||||
/ generation_hash
|
||||
)
|
||||
rendered = _render_sources(sources, replacements, destination)
|
||||
outputs = {name: content.encode("utf-8") for name, content in rendered.items()}
|
||||
output_hashes = {name: _hash_bytes(content) for name, content in outputs.items()}
|
||||
manifest = {
|
||||
"schema_version": 1,
|
||||
"skill": skill_dir.name,
|
||||
"project_root": str(project_root),
|
||||
"project_slug": slug,
|
||||
"root_hash": root_hash,
|
||||
"generation_hash": generation_hash,
|
||||
"inputs": identity,
|
||||
"outputs": output_hashes,
|
||||
}
|
||||
_publish(destination, outputs, manifest)
|
||||
return destination / "workflow.md"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--project-root", required=True)
|
||||
parser.add_argument("--skill", required=True)
|
||||
args = parser.parse_args()
|
||||
reconfigure = getattr(sys.stdout, "reconfigure", None)
|
||||
if reconfigure is not None:
|
||||
reconfigure(encoding="utf-8")
|
||||
try:
|
||||
entry = render(Path(args.project_root), Path(args.skill))
|
||||
except (ConfigError, RenderError, OSError, UnicodeError, ValueError) as error:
|
||||
sys.stdout.write(f"HALT: {error}\n")
|
||||
return 1
|
||||
sys.stdout.write(f"read and follow {entry}\n")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# ///
|
||||
"""Resolve BMad's four central TOML layers to JSON."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Installed scripts are consumer files, not a location for interpreter caches.
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
try:
|
||||
from config_utils import ConfigError, load_central_config
|
||||
except ModuleNotFoundError as error:
|
||||
if error.name != "tomllib":
|
||||
raise
|
||||
sys.stderr.write("error: Python 3.11+ is required (stdlib `tomllib` not found).\n")
|
||||
raise SystemExit(3) from None
|
||||
|
||||
|
||||
_MISSING = object()
|
||||
|
||||
|
||||
def extract_key(data, dotted_key: str):
|
||||
current = data
|
||||
for part in dotted_key.split("."):
|
||||
if isinstance(current, dict) and part in current:
|
||||
current = current[part]
|
||||
else:
|
||||
return _MISSING
|
||||
return current
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Resolve BMad central config using four-layer TOML merge."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--project-root",
|
||||
"-p",
|
||||
required=True,
|
||||
help="Absolute project root containing _bmad/",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--key",
|
||||
"-k",
|
||||
action="append",
|
||||
default=[],
|
||||
help="Dotted field path to resolve (repeatable). Omit for full dump.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
merged = load_central_config(Path(args.project_root).resolve())
|
||||
except ConfigError as error:
|
||||
sys.stderr.write(f"error: {error}\n")
|
||||
return 1
|
||||
|
||||
output = merged
|
||||
if args.key:
|
||||
output = {}
|
||||
for key in args.key:
|
||||
value = extract_key(merged, key)
|
||||
if value is not _MISSING:
|
||||
output[key] = value
|
||||
sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# ///
|
||||
"""Resolve a skill's default, team, and user TOML customization layers."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Installed scripts are consumer files, not a location for interpreter caches.
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
try:
|
||||
from config_utils import ConfigError, load_customization
|
||||
except ModuleNotFoundError as error:
|
||||
if error.name != "tomllib":
|
||||
raise
|
||||
sys.stderr.write("error: Python 3.11+ is required (stdlib `tomllib` not found).\n")
|
||||
raise SystemExit(3) from None
|
||||
|
||||
|
||||
_MISSING = object()
|
||||
|
||||
|
||||
def find_project_root(start: Path) -> Path | None:
|
||||
current = start.resolve()
|
||||
while True:
|
||||
if (current / "_bmad").exists() or (current / ".git").exists():
|
||||
return current
|
||||
if current.parent == current:
|
||||
return None
|
||||
current = current.parent
|
||||
|
||||
|
||||
def extract_key(data, dotted_key: str):
|
||||
current = data
|
||||
for part in dotted_key.split("."):
|
||||
if isinstance(current, dict) and part in current:
|
||||
current = current[part]
|
||||
else:
|
||||
return _MISSING
|
||||
return current
|
||||
|
||||
|
||||
def write_json_stdout(output) -> None:
|
||||
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() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Resolve skill customization using three-layer TOML merge."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skill", "-s", required=True, help="Absolute path to the skill directory"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--project-root",
|
||||
"-p",
|
||||
help="Explicit project root containing _bmad/ (recommended)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--key",
|
||||
"-k",
|
||||
action="append",
|
||||
default=[],
|
||||
help="Dotted field path to resolve (repeatable). Omit for full dump.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
skill_dir = Path(args.skill).resolve()
|
||||
project_root = (
|
||||
Path(args.project_root).resolve()
|
||||
if args.project_root
|
||||
else find_project_root(skill_dir) or find_project_root(Path.cwd())
|
||||
)
|
||||
try:
|
||||
merged = load_customization(project_root, skill_dir)
|
||||
except ConfigError as error:
|
||||
sys.stderr.write(f"error: {error}\n")
|
||||
return 1
|
||||
|
||||
output = merged
|
||||
if args.key:
|
||||
output = {}
|
||||
for key in args.key:
|
||||
value = extract_key(merged, key)
|
||||
if value is not _MISSING:
|
||||
output[key] = value
|
||||
write_json_stdout(output)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user