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.
|
# integration.test.sh — end-to-end smoke test for the bmad-module skill.
|
||||||
#
|
#
|
||||||
# Hermetic: fabricates a minimal _bmad/_config/manifest.yaml skeleton in a
|
# Hermetic: fabricates a minimal _bmad/_config/manifest.yaml skeleton in a
|
||||||
# tmp dir and exercises every verb against the local reference modules and
|
# tmp dir and exercises every verb against the vendored reference modules
|
||||||
# negative fixtures. Does NOT require BMAD-METHOD's installer; the upstream
|
# (tests/fixtures/examples/) and negative fixtures. Does NOT require
|
||||||
# patch (§5) is verified separately.
|
# BMAD-METHOD's installer; the upstream patch (§5) is verified separately.
|
||||||
#
|
#
|
||||||
# Run from anywhere:
|
# Run from anywhere:
|
||||||
# bash src/core-skills/bmad-module/tests/integration.test.sh
|
# 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)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
SKILL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
SKILL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
REPO_DIR="$(cd "${SKILL_DIR}/../../.." && pwd)"
|
|
||||||
MODULE_JS="${SKILL_DIR}/scripts/bmad-module.mjs"
|
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"
|
FIXTURES="${SCRIPT_DIR}/fixtures"
|
||||||
|
|
||||||
WORKDIR="$(mktemp -d)"
|
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-write/SKILL.md"
|
||||||
assert_path_exists "_bmad/devlog/skills/bmad-devlog-setup/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/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"
|
assert_path_exists "_bmad/devlog/.mcp.json"
|
||||||
# install.ignore excludes docs/ and tests/ and README.md / CHANGELOG.md
|
# install.ignore excludes docs/ and tests/ and README.md / CHANGELOG.md
|
||||||
assert_path_absent "_bmad/devlog/docs"
|
assert_path_absent "_bmad/devlog/docs"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue