test(bmad-module): make integration suite self-contained
The suite resolved its reference modules from `<repo>/examples`, which existed only in the sibling bmad-marketplace checkout — so after the skill moved into BMAD-METHOD core every install/list/remove assertion failed with "local source not a directory". Vendor the two reference modules (acme-md-lint, acme-devlog) under tests/fixtures/examples/ and point EXAMPLES there; drop the now-unused REPO_DIR. Also correct the comprehensive-install assertion: hooks are flattened to the canonical root slot (hooks.json), matching .mcp.json and rewriteManifestPaths — not a hooks/ subdir. Suite now passes 41/41. Note: these fixtures are copies of the bmad-marketplace examples and must be re-synced if those reference modules change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dfae0291ca
commit
bd63b83f72
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/CHANGELOG.md
vendored
Normal file
24
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/CHANGELOG.md
vendored
Normal file
|
|
@ -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.
|
||||
21
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/LICENSE
vendored
Normal file
21
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/LICENSE
vendored
Normal file
|
|
@ -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.
|
||||
43
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/README.md
vendored
Normal file
43
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/README.md
vendored
Normal file
|
|
@ -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`.
|
||||
|
|
@ -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:
|
||||
|
||||
```
|
||||
### <week-label>
|
||||
|
||||
**Shipped.** <one paragraph, 2-4 sentences, prose not bullets>
|
||||
|
||||
**Blockers.** <one sentence; "none recurring" if absent>
|
||||
|
||||
**Decisions.** <one sentence; "none" if absent>
|
||||
```
|
||||
|
||||
## 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.
|
||||
56
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/docs/index.md
vendored
Normal file
56
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/docs/index.md
vendored
Normal file
|
|
@ -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`.
|
||||
15
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/hooks/hooks.json
vendored
Normal file
15
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/hooks/hooks.json
vendored
Normal file
|
|
@ -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\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
32
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/scripts/fetch-git-history.sh
vendored
Executable file
32
src/core-skills/bmad-module/tests/fixtures/examples/comprehensive/acme-devlog/scripts/fetch-git-history.sh
vendored
Executable file
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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."
|
||||
|
|
@ -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: <resolved>
|
||||
entry_format: <resolved>
|
||||
Try `/bmad-devlog-write` to create today's entry.
|
||||
```
|
||||
|
|
@ -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 <range>` (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".
|
||||
|
Can't render this file because it has a wrong number of fields in line 3.
|
|
|
@ -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."
|
||||
|
|
@ -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 <range>".
|
||||
---
|
||||
|
||||
# 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 <range>." 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 — <range>
|
||||
|
||||
## 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: <N>
|
||||
- Days with no entry: <M>
|
||||
```
|
||||
|
||||
### Step 5: Optionally save
|
||||
|
||||
Ask: "Save to `<devlog_path>/_summaries/<range>.md`?" Write if yes.
|
||||
|
|
@ -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` → `<devlog_path>/<YYYY-MM-DD>.md`
|
||||
- `weekly` → `<devlog_path>/<YYYY>-W<NN>.md`
|
||||
- `monthly` → `<devlog_path>/<YYYY-MM>.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 <devlog_path>/<filename>
|
||||
```
|
||||
|
||||
If the file existed and you appended, print "Appended to …" instead.
|
||||
|
|
@ -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_
|
||||
|
|
@ -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" }
|
||||
}
|
||||
}
|
||||
21
src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/LICENSE
vendored
Normal file
21
src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/LICENSE
vendored
Normal file
|
|
@ -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.
|
||||
37
src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/README.md
vendored
Normal file
37
src/core-skills/bmad-module/tests/fixtures/examples/minimal/acme-md-lint/README.md
vendored
Normal file
|
|
@ -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`.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue