diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/.claude-plugin/plugin.json b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/.claude-plugin/plugin.json new file mode 100644 index 000000000..3d88dd425 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/.claude-plugin/plugin.json @@ -0,0 +1,48 @@ +{ + "name": "acme-devlog", + "version": "0.4.0", + "displayName": "Devlog", + "description": "Daily engineering devlog: write entries, summarize history, and consult Clio the Historian.", + "author": { + "name": "Acme Corp", + "email": "team@acme.example", + "url": "https://acme.example" + }, + "repository": "https://github.com/acme/acme-devlog", + "license": "MIT", + "homepage": "https://acme.example/devlog", + "keywords": ["devlog", "history", "summarization", "engineering-log"], + + "skills": ["./skills/bmad-devlog-setup", "./skills/bmad-devlog-write", "./skills/bmad-devlog-summarize", "./skills/bmad-agent-historian"], + "agents": ["./agents/changelog-archivist.md"], + "hooks": "./hooks/hooks.json", + "mcpServers": "./.mcp.json", + + "bmad": { + "specVersion": "1.0.0", + "code": "devlog", + "category": "knowledge-management", + "subcategory": "history", + "compatibility": { + "bmadMethod": ">=6.6.0 <7.0.0" + }, + "setupSkill": "bmad-devlog-setup", + "moduleDefinition": "skills/bmad-devlog-setup/assets/module.yaml", + "moduleHelpCsv": "skills/bmad-devlog-setup/assets/module-help.csv", + "customize": { + "schemas": ["./skills/bmad-agent-historian/customize.toml"] + }, + "dependencies": { + "modules": [{ "code": "bmm", "version": ">=6.6.0" }] + }, + "install": { + "ignore": ["docs/**", "tests/**", "*.test.*", "README.md", "CHANGELOG.md"], + "postInstallSkill": "bmad-devlog-setup" + }, + "docs": { + "readme": "./README.md", + "changelog": "./CHANGELOG.md", + "homepage": "./docs/index.md" + } + } +} diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/CHANGELOG.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/CHANGELOG.md new file mode 100644 index 000000000..f821f7a0e --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this module will be documented here. Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.4.0] — 2026-05-21 + +### Added + +- Clio the Historian persona-agent (`bmad-agent-historian`) with three menu actions: summarize range, recall topic context, identify patterns. +- `changelog-archivist` Claude subagent for fan-out summarization across long date ranges. +- MCP server stub (`devlog-history`) for programmatic queries against past entries. +- `SessionStart` hook surfaces today's entry (or yesterday's if today is empty). + +### Changed + +- Devlog entry template now includes "Open questions" and "Blockers" sections. +- Setup skill records `devlog_path` separately from `output_folder` so entries are addressable independently of other BMAD output. + +## [0.3.0] — 2026-04-30 + +### Added + +- Initial implementation: `bmad-devlog-write` and `bmad-devlog-summarize` skills. +- Setup skill scaffolding. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/LICENSE b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/LICENSE new file mode 100644 index 000000000..5c1942827 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Acme Corp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/README.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/README.md new file mode 100644 index 000000000..d170ab2d2 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/README.md @@ -0,0 +1,43 @@ +# acme-devlog + +A daily engineering devlog for BMAD-driven projects. + +This module demonstrates **every supported surface** of the BMAD Module Manifest Specification — skills, a persona-agent with a `customize.toml`, a Claude subagent, a SessionStart hook, an MCP server stub, install-time configuration via `module.yaml`, and a setup skill. Use it as a reference when authoring a real module. + +## What it does + +- **Write** a structured daily entry (template-driven) with `/bmad-devlog-write`. +- **Summarize** a date range with `/bmad-devlog-summarize`. +- **Consult Clio**, a persona-agent historian, with `/bmad-agent-historian`. Clio narrates patterns across entries, surfaces forgotten context, and routes you to the right write/summarize skill. +- **Show today's entry** at session start (via the `SessionStart` hook). +- **Query history programmatically** via the bundled MCP server stub (`devlog-history`). + +## Install + +``` +bmad-module install acme/acme-devlog +``` + +Installs to `_bmad/devlog/`. The setup skill (`bmad-devlog-setup`) runs automatically and prompts for the devlog output path (default: `_bmad-output/devlog`). + +## Configuration + +After install, `_bmad/devlog/config.yaml` records your devlog path. Override defaults per skill via `_bmad/custom/`: + +- Team: `_bmad/custom/bmad-agent-historian.toml` +- Personal: `_bmad/custom/bmad-agent-historian.user.toml` + +See `docs/index.md` (in this repo) for the customization recipe. + +## Uninstall + +``` +bmad-module remove devlog # leaves _bmad/custom/devlog/ intact +bmad-module remove devlog --purge # removes user customizations too +``` + +Devlog entries written to `_bmad-output/devlog/` are **never** deleted by uninstall. + +## License + +MIT. See `LICENSE`. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/agents/changelog-archivist.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/agents/changelog-archivist.md new file mode 100644 index 000000000..e923360de --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/agents/changelog-archivist.md @@ -0,0 +1,47 @@ +--- +name: changelog-archivist +description: Summarizes a single week of devlog entries into a tight changelog-style brief. Used as a fan-out subagent by /bmad-devlog-summarize for long date ranges. +model: sonnet +--- + +# Changelog Archivist + +You are a focused subagent invoked by the `bmad-devlog-summarize` skill to compress a single week's devlog entries into a brief paragraph. + +## Inputs + +You receive: + +- A list of devlog entry file paths covering one ISO week. +- The week label (e.g. `2026-W21`). + +## Task + +For each entry, extract: + +- What shipped (verbatim where possible). +- Recurring blockers. +- Decisions visible in the entry. + +Produce a single section in this exact shape: + +``` +### + +**Shipped.** + +**Blockers.** + +**Decisions.** +``` + +## Rules + +- Do not invent content. If the week has no entries, output the week label and `_no entries this week_` and stop. +- Do not editorialize beyond what's in the entries. +- Cite dates inline (e.g. `On 2026-05-14, …`) only when a single day's content dominates. +- Keep the section under 120 words. + +## Why a subagent + +For ranges longer than two weeks, the parent skill fans out one subagent per week so each archivist operates with a small, focused context. The parent then concatenates the sections and adds a top-level intro. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/docs/index.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/docs/index.md new file mode 100644 index 000000000..f61946f8d --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/docs/index.md @@ -0,0 +1,56 @@ +# acme-devlog — Authoring & Customization + +This doc lives in the module source. It is **excluded** from install via `bmad.install.ignore` (see `.claude-plugin/plugin.json`). Read it on GitHub or in a clone of the module repo, not under `_bmad/devlog/`. + +## Customizing Clio + +Clio's defaults live in `_bmad/devlog/skills/bmad-agent-historian/customize.toml`. You should not edit that file directly — the installer overwrites it on `bmad-module update`. + +Instead, drop overrides into one of: + +| File | Scope | Git status | +| --------------------------------------------- | ---------------- | ----------- | +| `_bmad/custom/bmad-agent-historian.toml` | Team (committed) | tracked | +| `_bmad/custom/bmad-agent-historian.user.toml` | Personal | git-ignored | + +Both files use the same TOML shape as the base `customize.toml`. The `bmad-customize` core skill merges them in this order: base → team → personal. + +**Merge rules:** + +- Scalars: override wins. +- Tables: deep merge. +- Arrays of tables keyed by `code` (e.g. `[[agent.menu]]`): matching codes replace, new codes append. +- Other arrays (`persistent_facts`, `principles`, `activation_steps_*`): append. + +### Example — add a menu item + +`_bmad/custom/bmad-agent-historian.user.toml`: + +```toml +[[agent.menu]] +code = "TODAY" +description = "Read today's entry aloud" +prompt = """ +Read the file at `{devlog_path}/$(date +%F).md` if it exists. If not, +say "No entry yet for today — try the WRT menu item." +""" +``` + +### Example — change communication style + +`_bmad/custom/bmad-agent-historian.toml`: + +```toml +[agent] +communication_style = "Crisp, dry, footnoted. Cites entries like a historian writing for The Economist." +``` + +## Why a SessionStart hook? + +The hook is convenience, not requirement. Disable it by removing the `hooks` field from `_bmad/devlog/.claude-plugin/plugin.json` (or by uninstalling). It surfaces the current entry so you have context the moment a session starts; for some teams that's noise — opt out freely. + +## Why `module.yaml` lives under `skills/bmad-devlog-setup/assets/`? + +This module uses PluginResolver Strategy 2 (the `-setup` skill carries the module definition in `assets/`). The advantage is that `bmad-devlog-setup` can be re-run any time to reconfigure without touching the rest of the install. The `bmad.moduleDefinition` field in `plugin.json` points the installer at the right file. + +A simpler module can put `module.yaml` at `skills/module.yaml` (the default) and skip `bmad.setupSkill`. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/hooks/hooks.json b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/hooks/hooks.json new file mode 100644 index 000000000..f09995637 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/hooks/hooks.json @@ -0,0 +1,15 @@ +{ + "description": "Surface today's (or most recent) devlog entry at session start.", + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/fetch-git-history.sh\"" + } + ] + } + ] + } +} diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/scripts/fetch-git-history.sh b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/scripts/fetch-git-history.sh new file mode 100755 index 000000000..2240105a4 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/scripts/fetch-git-history.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# SessionStart hook: print today's devlog entry if it exists, else the most +# recent entry. Reads devlog_path from _bmad/devlog/config.yaml. +# +# Bound by Claude Code's SessionStart event via hooks/hooks.json. Exits 0 +# silently when there's nothing useful to surface. + +set -eu + +config="${PWD}/_bmad/devlog/config.yaml" +[ -f "$config" ] || exit 0 + +devlog_path=$(awk -F': *' '/^devlog_path:/ {print $2; exit}' "$config" | tr -d '"') +[ -n "$devlog_path" ] && [ -d "$devlog_path" ] || exit 0 + +today="$(date +%F)" +today_file="${devlog_path}/${today}.md" + +if [ -f "$today_file" ]; then + echo "=== Devlog — ${today} ===" + cat "$today_file" + exit 0 +fi + +# Fall back to the most recent .md by mtime. +latest=$(ls -t "${devlog_path}"/*.md 2>/dev/null | head -n 1 || true) +if [ -n "$latest" ]; then + echo "=== Most recent devlog ($(basename "$latest" .md)) ===" + cat "$latest" +fi + +exit 0 diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-agent-historian/SKILL.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-agent-historian/SKILL.md new file mode 100644 index 000000000..d3f1a74e5 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-agent-historian/SKILL.md @@ -0,0 +1,60 @@ +--- +name: bmad-agent-historian +description: Clio, the Devlog Historian. A persona-agent for narrative recall, pattern detection across entries, and routing to the right devlog action. Use when the user asks to talk to Clio or requests the historian. +--- + +# Clio — Devlog Historian + +## Overview + +You are Clio, named for the muse of history. You read the project's devlog with an archivist's care and a journalist's nose for the story underneath the entries. You don't invent context — every observation you make is grounded in a specific entry, cited by date. + +## Conventions + +- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives). +- `{project-root}` resolves to the project working directory. +- `{skill-name}` resolves to this skill's directory basename. + +## On Activation + +### Step 1: Resolve the Agent Block + +Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` + +If the script fails, resolve the `agent` block yourself by reading these three files in base → team → user order and applying BMad's structural merge rules: + +1. `{skill-root}/customize.toml` — defaults +2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides +3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides + +Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append. + +### Step 2: Adopt Persona + +Adopt the Clio identity from the Overview. Layer on `{agent.role}`, `{agent.identity}`, `{agent.communication_style}`, and `{agent.principles}` from the resolved block. + +Do not break character until the user dismisses the persona. + +### Step 3: Load Persistent Facts + +Treat every entry in `{agent.persistent_facts}` as foundational context. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. + +### Step 4: Load Devlog Config + +Load `{project-root}/_bmad/devlog/config.yaml`. Note `devlog_path` and `entry_format`. If the config is missing, tell the user kindly: + +> "I can't find the devlog config yet — run `/bmad-devlog-setup` first and call me back." + +…then stand down. + +### Step 5: Greet and Present Menu + +Greet using `{user_name}` from `{project-root}/_bmad/bmm/config.yaml` (fallback: "friend"). Then present the menu (`{agent.menu}`) as a numbered list. Each item has a `code`, `description`, and either a `skill` or a `prompt`. + +### Step 6: Handle Selection + +When the user picks a menu code, invoke its `skill` or execute its `prompt`. The persona carries through; stay in character. + +## Notes for Authors + +This is a reference persona-agent. The `customize.toml` next door defines Clio's defaults — copy and adapt the structure for your own persona-agent skills. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-agent-historian/customize.toml b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-agent-historian/customize.toml new file mode 100644 index 000000000..3e1d4ddaa --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-agent-historian/customize.toml @@ -0,0 +1,77 @@ +# DO NOT EDIT -- overwritten on every update. +# +# Clio, the Devlog Historian, is the hardcoded identity of this agent. +# Customize the persona and menu below to shape behavior without changing +# who the agent is. Override in _bmad/custom/bmad-agent-historian.toml +# (team) or _bmad/custom/bmad-agent-historian.user.toml (personal). + +[agent] +# Non-configurable skill frontmatter. Create a custom persona-agent skill +# if you need a new name/title. +name = "Clio" +title = "Devlog Historian" + +# --- Configurable below. Overrides merge per BMad structural rules: --- +# scalars: override wins • arrays (persistent_facts, principles, activation_steps_*): append +# arrays-of-tables with `code`/`id`: replace matching items, append new ones. + +icon = "🕰️" + +activation_steps_prepend = [] +activation_steps_append = [] + +# Persistent facts the agent keeps in mind for the whole session. +# `file:` entries are loaded as content; literal entries are facts verbatim. +persistent_facts = [ + "file:{project-root}/_bmad/devlog/config.yaml", + "The devlog is a primary source. Never invent context that isn't written down.", +] + +role = "Help the user recall, analyze, and narrate the project's history through the devlog." +identity = "Channels the patient eye of an archivist and the narrative nose of a journalist. Treats every entry as primary source material." +communication_style = "Calm and measured, with date markers (`On 2026-05-14, …`). Tells the story underneath the entries; never editorializes beyond what's written." + +principles = [ + "Every observation cites at least one entry by date.", + "Patterns over events: surface what recurs, not what's loudest.", + "When the record is silent, say so — do not extrapolate.", + "Route the user to write/summarize skills when they need to act, not reminisce.", +] + +# Capabilities menu. Overrides merge by `code`: matching codes replace the +# item in place; new codes append. Each item has exactly one of `skill` +# (invokes a registered skill) or `prompt` (executes the prompt text directly). + +[[agent.menu]] +code = "SUM" +description = "Summarize a date range" +skill = "bmad-devlog-summarize" + +[[agent.menu]] +code = "REC" +description = "Recall context for a topic" +prompt = """ +Ask the user for a topic or keyword. Search every devlog entry under +`{devlog_path}` for matches. For each match, cite the entry date and quote +the relevant lines. End with a one-paragraph narrative tying the matches +together. If no matches, say so plainly. +""" + +[[agent.menu]] +code = "PAT" +description = "Identify recurring patterns" +prompt = """ +Read every entry in the last 30 days. Identify themes that appear in ≥3 +entries (recurring blockers, repeated decisions, drifting open questions). +Present each pattern as: name, evidence (3+ cited entries), implication. +""" + +[[agent.menu]] +code = "WRT" +description = "Write today's entry" +skill = "bmad-devlog-write" + +[[agent.menu]] +code = "EXIT" +description = "Dismiss Clio" +prompt = "Acknowledge the dismissal in character ('Until the next entry, then.'), break persona, and return control." diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/SKILL.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/SKILL.md new file mode 100644 index 000000000..824c00fae --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/SKILL.md @@ -0,0 +1,45 @@ +--- +name: bmad-devlog-setup +description: One-time setup for the acme-devlog module. Use after `bmad-module install acme/acme-devlog`, or when the user says "configure devlog" or "re-run devlog setup". +--- + +# Devlog Setup + +Installs and configures the devlog module by reading `assets/module.yaml`, collecting answers to its prompts, and writing `_bmad/devlog/config.yaml`. + +This skill is invoked automatically by `bmad-module install` (via `bmad.install.postInstallSkill`). It is also safe to re-run any time — it merges over the existing config without losing prior answers. + +## EXECUTION + +### Step 1: Load the module definition + +Read `./assets/module.yaml` from the skill root. Parse its prompt entries (e.g. `devlog_path`, `entry_format`). + +### Step 2: Collect answers + +For each prompt, ask the user. Show the default in parens. Accept the default when the user replies with empty input or "use default". + +If `_bmad/devlog/config.yaml` already exists, load existing answers and pre-fill them as the prompt default. + +### Step 3: Apply variable substitution + +Resolve `{value}`, `{project-root}`, and `{output_folder}` placeholders using each prompt's `result:` template. + +### Step 4: Write config + +Write the resolved key/value map to `_bmad/devlog/config.yaml` (YAML, 2-space indent, keys sorted). + +### Step 5: Create directories + +Ensure `{devlog_path}` exists on disk. Create it if absent. + +### Step 6: Confirm + +Print: + +``` +Devlog configured. + devlog_path: + entry_format: +Try `/bmad-devlog-write` to create today's entry. +``` diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/assets/module-help.csv b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/assets/module-help.csv new file mode 100644 index 000000000..fa8fef8e8 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/assets/module-help.csv @@ -0,0 +1,4 @@ +canonical_id,name,description,module,path,kind,team,agent,visible,deprecated,version,tags,help_text +bmad-devlog-write,bmad-devlog-write,Write today's devlog entry from a template.,devlog,skills/bmad-devlog-write,skill,knowledge-management,,true,false,0.4.0,"devlog,write,daily",Use `/bmad-devlog-write` to create today's entry. +bmad-devlog-summarize,bmad-devlog-summarize,Summarize devlog entries across a date range.,devlog,skills/bmad-devlog-summarize,skill,knowledge-management,,true,false,0.4.0,"devlog,summarize,history",Use `/bmad-devlog-summarize ` (e.g. `last-week`, `2026-05`). +bmad-agent-historian,bmad-agent-historian,Clio the Historian — persona-agent for narrative recall and pattern detection.,devlog,skills/bmad-agent-historian,persona-agent,knowledge-management,Clio,true,false,0.4.0,"devlog,history,persona",Use `/bmad-agent-historian` or ask to "talk to Clio". diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/assets/module.yaml b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/assets/module.yaml new file mode 100644 index 000000000..76385a3f7 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-setup/assets/module.yaml @@ -0,0 +1,41 @@ +code: devlog +name: "Devlog" +description: "Daily engineering devlog: write entries, summarize history, and consult Clio the Historian." +default_selected: false + +# Variables from Core Config available: +## user_name +## output_folder + +devlog_path: + prompt: "Where should daily devlog entries be stored?" + default: "{output_folder}/devlog" + result: "{project-root}/{value}" + +entry_format: + prompt: + - "How should entry filenames be formatted?" + - "Affects how the summarize skill walks history." + scope: user + default: "iso" + result: "{value}" + single-select: + - value: "iso" + label: "ISO 8601 — 2026-05-21.md" + - value: "weekly" + label: "ISO week — 2026-W21.md (one file per week)" + - value: "monthly" + label: "Year-month — 2026-05.md (one file per month, append entries)" + +# Directories to create during installation +directories: + - "{devlog_path}" + +# Agent roster — essence only. Persona and behavior live in customize.toml. +agents: + - code: bmad-agent-historian + name: Clio + title: Devlog Historian + icon: "🕰️" + team: knowledge-management + description: "Channels the patient eye of an archivist and the narrative nose of a journalist. Surfaces patterns across entries, never invents context, always cites the date." diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-summarize/SKILL.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-summarize/SKILL.md new file mode 100644 index 000000000..969f90fb6 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-summarize/SKILL.md @@ -0,0 +1,63 @@ +--- +name: bmad-devlog-summarize +description: Summarize devlog entries across a date range. Use when the user says "summarize devlog", "what happened last week", or "devlog summary ". +--- + +# Devlog Summarize + +Walks devlog entries in a date range and produces a structured summary: themes, recurring blockers, decisions, open questions. + +## EXECUTION + +### Step 1: Resolve config + +Read `{project-root}/_bmad/devlog/config.yaml`. If missing, run `/bmad-devlog-setup` first. + +### Step 2: Parse the range argument + +Accept these forms: + +- `today` / `yesterday` +- `last-week` / `last-month` / `last-quarter` +- ISO date: `2026-05-21` +- ISO range: `2026-05-01..2026-05-21` +- ISO week: `2026-W21` +- ISO month: `2026-05` + +If no argument, ask the user. + +### Step 3: Collect entries + +Enumerate all entries under `devlog_path` whose date falls in the range. For `weekly`/`monthly` formats, parse sub-sections by their date heading. + +If zero entries match, report "No entries in ." and stop. + +### Step 4: Summarize + +For long ranges (>14 days), delegate per-week summarization to the `changelog-archivist` Claude subagent (fan-out). For short ranges, summarize inline. + +Produce: + +``` +# Devlog summary — + +## Themes +- _patterns across entries_ + +## Blockers (recurring) +- _what came up more than once_ + +## Decisions +- _commitments visible in entries_ + +## Open questions +- _still unresolved at end of range_ + +## By the numbers +- Entries: +- Days with no entry: +``` + +### Step 5: Optionally save + +Ask: "Save to `/_summaries/.md`?" Write if yes. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-write/SKILL.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-write/SKILL.md new file mode 100644 index 000000000..3a4583f8f --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-write/SKILL.md @@ -0,0 +1,50 @@ +--- +name: bmad-devlog-write +description: Write today's devlog entry from the bundled template. Use when the user says "write devlog", "today's entry", or "log this". +--- + +# Devlog Write + +Creates or appends today's devlog entry under the configured devlog path. + +## EXECUTION + +### Step 1: Resolve config + +Read `{project-root}/_bmad/devlog/config.yaml`. Expect: + +- `devlog_path` (absolute path) +- `entry_format` (`iso` | `weekly` | `monthly`) + +If config is missing, run `/bmad-devlog-setup` first. + +### Step 2: Determine the entry file + +- `iso` → `/.md` +- `weekly` → `/-W.md` +- `monthly` → `/.md` + +### Step 3: Initialize if absent + +If the file doesn't exist, copy `./assets/template.md` to the target path. Substitute `{{date}}`, `{{author}}` (from `user_name`), and `{{week}}`/`{{month}}` placeholders. + +### Step 4: Collect entry content + +Ask the user: + +1. **What did you ship today?** (bullet list) +2. **What blocked you?** (bullet list; "nothing" is valid) +3. **Open questions?** (bullet list; "none" is valid) +4. **One sentence summary.** + +For `weekly`/`monthly` formats, append a dated sub-section (e.g. `## 2026-05-21`) rather than overwriting. + +### Step 5: Write and confirm + +Write the entry, print: + +``` +Wrote / +``` + +If the file existed and you appended, print "Appended to …" instead. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-write/assets/template.md b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-write/assets/template.md new file mode 100644 index 000000000..a7c8d9528 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/skills/bmad-devlog-write/assets/template.md @@ -0,0 +1,19 @@ +# Devlog — {{date}} + +**Author:** {{author}} + +## Shipped + +- _what landed today_ + +## Blockers + +- _what got in the way (or "nothing")_ + +## Open questions + +- _decisions deferred, things to chase tomorrow (or "none")_ + +## Summary + +_one sentence_ diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/.claude-plugin/plugin.json b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/.claude-plugin/plugin.json new file mode 100644 index 000000000..220f250cf --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/.claude-plugin/plugin.json @@ -0,0 +1,14 @@ +{ + "name": "acme-md-lint", + "version": "0.1.0", + "description": "Lints markdown headings and link rot in BMad projects.", + "license": "MIT", + "author": { "name": "Acme Corp" }, + "skills": ["./skills/acme-md-lint"], + "bmad": { + "specVersion": "1.0.0", + "code": "mdlint", + "category": "developer-tools", + "compatibility": { "bmadMethod": ">=6.6.0" } + } +} diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/LICENSE b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/LICENSE new file mode 100644 index 000000000..5c1942827 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Acme Corp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/README.md b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/README.md new file mode 100644 index 000000000..789ec6c5c --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/README.md @@ -0,0 +1,37 @@ +# acme-md-lint + +A minimal BMAD module: one skill that lints markdown files under `_bmad/` for heading-hierarchy mistakes and broken relative links. + +This is the **smallest valid module** that conforms to the [BMAD Module Manifest Specification](https://github.com/bmad-code-org/bmad-marketplace/blob/main/docs/spec.md). Use it as a starting template. + +## Install + +``` +bmad-module install acme/acme-md-lint +``` + +Installs to `_bmad/mdlint/`. + +## Use + +After install, invoke from any Claude Code session: + +``` +/acme-md-lint +``` + +The skill walks every `.md` file under `_bmad/` and reports: + +- Heading-level skips (e.g. `##` → `####`) +- Missing H1 +- Relative links whose targets don't exist on disk + +## Uninstall + +``` +bmad-module remove mdlint +``` + +## License + +MIT. See `LICENSE`. diff --git a/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/skills/acme-md-lint/SKILL.md b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/skills/acme-md-lint/SKILL.md new file mode 100644 index 000000000..efb274599 --- /dev/null +++ b/src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/skills/acme-md-lint/SKILL.md @@ -0,0 +1,61 @@ +--- +name: acme-md-lint +description: Lints all markdown files under _bmad/ for heading hierarchy errors and broken relative links. Use when the user says "lint markdown", "check links", or "audit docs". +--- + +# acme-md-lint + +A small lint skill for the markdown content shipped with installed BMAD modules. + +## CRITICAL RULES + +- DO NOT modify any file — this skill is read-only. +- DO NOT follow external URLs; only check relative paths on disk. +- HALT and report cleanly if `_bmad/` is not present in the current working directory. + +## EXECUTION + +### Step 1: Locate the BMAD tree + +Confirm `_bmad/` exists under the current working directory. If not, report: + +> No `_bmad/` directory found. Run `bmad install` first. + +…and stop. + +### Step 2: Enumerate markdown files + +Walk `_bmad/` recursively. Collect every `.md` file path. Skip files under `_bmad/_config/` (those are CSV/YAML generated by the installer). + +### Step 3: Check heading hierarchy + +For each file: + +1. Parse headings line-by-line (`#`, `##`, `###`, …). +2. Require an H1 as the first heading (warn if absent). +3. Flag any heading that jumps more than one level deeper than the previous heading (e.g. `##` followed by `####`). + +Report each violation with `file:line — message`. + +### Step 4: Check relative links + +For each file, find Markdown links `[text](path)` where `path` does not start with `http://`, `https://`, `mailto:`, or `#`. Resolve the path relative to the file's directory and verify it exists on disk. If not, report: + +> `file:line — broken link → path` + +External URLs are skipped entirely. + +### Step 5: Summarize + +Print: + +``` +Scanned N files. M heading issues, K broken links. +``` + +If `M + K == 0`, end with "All clean." If non-zero, end with "Review the issues above." + +## Notes + +- The skill operates on installed `_bmad/` content, not on the module source. It is intended as a post-install or pre-PR sanity check. +- This is a pedagogical reference. Production lint behavior would warrant a dedicated tool (e.g. `markdownlint`); this skill demonstrates the smallest valid module shape. diff --git a/src/core-skills/bmad-module/tests/integration.test.sh b/src/core-skills/bmad-module/tests/integration.test.sh index 120fb94b4..8f677861e 100755 --- a/src/core-skills/bmad-module/tests/integration.test.sh +++ b/src/core-skills/bmad-module/tests/integration.test.sh @@ -2,9 +2,9 @@ # integration.test.sh — end-to-end smoke test for the bmad-module skill. # # Hermetic: fabricates a minimal _bmad/_config/manifest.yaml skeleton in a -# tmp dir and exercises every verb against the local reference modules and -# negative fixtures. Does NOT require BMAD-METHOD's installer; the upstream -# patch (§5) is verified separately. +# tmp dir and exercises every verb against the vendored reference modules +# (tests/fixtures/examples/) and negative fixtures. Does NOT require +# BMAD-METHOD's installer; the upstream patch (§5) is verified separately. # # Run from anywhere: # bash src/core-skills/bmad-module/tests/integration.test.sh @@ -15,9 +15,10 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SKILL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" -REPO_DIR="$(cd "${SKILL_DIR}/../../.." && pwd)" MODULE_JS="${SKILL_DIR}/scripts/bmad-module.mjs" -EXAMPLES="${REPO_DIR}/examples" +# Reference modules are vendored under tests/fixtures/examples/ so the suite is +# self-contained — it does not depend on a sibling bmad-marketplace checkout. +EXAMPLES="${SCRIPT_DIR}/fixtures/examples" FIXTURES="${SCRIPT_DIR}/fixtures" WORKDIR="$(mktemp -d)" @@ -166,7 +167,8 @@ assert_exit 0 "install comprehensive" assert_path_exists "_bmad/devlog/skills/bmad-devlog-write/SKILL.md" assert_path_exists "_bmad/devlog/skills/bmad-devlog-setup/SKILL.md" assert_path_exists "_bmad/devlog/agents/changelog-archivist.md" -assert_path_exists "_bmad/devlog/hooks/hooks.json" +# hooks/mcpServers are flattened to canonical root slots (see rewriteManifestPaths) +assert_path_exists "_bmad/devlog/hooks.json" assert_path_exists "_bmad/devlog/.mcp.json" # install.ignore excludes docs/ and tests/ and README.md / CHANGELOG.md assert_path_absent "_bmad/devlog/docs"