Help us improve
Share bugs, ideas, or general feedback.
From mermaid-event-model
Generates one markdown specification file per slice in an Event Model DSL, with auto-refreshed Model sections and preserved authored content on re-run.
npx claudepluginhub howarddierking/mermaid-event-modelHow this skill is triggered — by the user, by Claude, or both
Slash command
/mermaid-event-model:spec-slicesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Read every `slice` declaration in an Event Model DSL file and stamp out one markdown specification file per slice into a sibling directory. The specs serve as the canonical record of each slice's intent and tests, and are intended to drive both validation and code generation.
Applies C++ Core Guidelines to write, review, or refactor C++ code. Enforces modern, safe, and idiomatic practices for C++17/20/23.
Share bugs, ideas, or general feedback.
Read every slice declaration in an Event Model DSL file and stamp out one markdown specification file per slice into a sibling directory. The specs serve as the canonical record of each slice's intent and tests, and are intended to drive both validation and code generation.
The argument $ARGUMENTS is an optional DSL file path.
If absent:
blueprint_dsl.md in the project root if nothing else applies.DSL files are markdown. Each one is a .md file whose DSL lives inside a fenced ```mermaid block whose first content line is eventModel. When parsing slices, elements, and edges, look at the lines INSIDE that fence.
Locate the template. Use the Bash tool with dirname on the path to this SKILL.md to find the skill directory. The template lives at <skill-dir>/template.md. Do not hard-code an absolute path.
Read the target DSL file and parse out every slice <id>["Label"] declaration. The label may be omitted, in which case the id doubles as the label.
Compute the spec directory. Take the DSL file's basename (e.g. blueprint_dsl) and append -slices, placing the directory in the same parent directory as the DSL file. Example: for /path/to/blueprint_dsl, write to /path/to/blueprint_dsl-slices/. Create the directory if it does not exist.
For each slice, do:
Compute the spec filename by slugifying the slice's title (its label): lowercase the string, replace any run of whitespace or non-alphanumeric characters with a single -, trim leading/trailing -, and append .md. Example: View Sales Report → view-sales-report.md.
Build the slice's eventModel snippet (the body that goes into the Model section). This snippet is meant to be a self-contained, renderable view of just this slice's piece of the larger model:
ui, command, domainEvent, externalEvent, readModel, automation), lane qualifier (the actor or aggregate name after the :, if any), label, and any data section fields.ui:<Actor> and automation:<Actor> member of the slice) and which aggregates are referenced (every domainEvent:<Aggregate> member). Preserve the parent file's declaration order so the swimlane stack matches.eventModel keyword on the line above the substitution. Order:
\tactor <Name> for each referenced actor (in declaration order)\taggregate <Name> for each referenced aggregate (in declaration order)\tslice <id>["<Label>"] declaration followed by its edges, each at two tabs```mermaid block with eventModel as the first content line, will render exactly the elements and edges that belong to this slice — and nothing else.If the spec file does NOT exist: read the template, substitute placeholders, write the file.
{{SLICE_TITLE}} → the slice's label{{SLICE_ID}} → the slice's id{{SLICE_MODEL_BODY}} → the snippet built above (no eventModel header line — the template already has it)If the spec file DOES exist: the skill is re-runnable. Refresh the Model section in place, leaving Description and Tests untouched.
## Model heading. The Model section's content runs from the heading up to (but not including) the next ## heading or end-of-file.```mermaid fence containing eventModel followed by the freshly-built snippet body, ending with the closing fence. The replacement must include exactly one ## Model heading and one fenced block.## Model heading (e.g., it was generated by an older version of this skill), insert a new Model section between the slice id comment block at the top and the first existing ## section heading.Detect and resolve orphan spec files — files in the spec directory whose slice id no longer matches any current slice in the DSL. This step runs AFTER step 4 (so newly-created destination files exist and can receive moved content).
For every .md file in the spec directory:
<!-- slice id: <id> --> comment near the top.For each orphan, read the file and compare its ## Description and ## Tests sections to the corresponding sections in template.md (the same template used to stamp new files). Treat a section as unmodified when its content matches the template's body modulo whitespace. Treat it as authored otherwise — i.e., the user has written prose in the Description or replaced the placeholder test["Describe what this test verifies"] skeleton with real test declarations.
Then handle the orphan:
No authored content (both Description and Tests are unmodified placeholders): the file is just a leftover stub from a slice that no longer exists. Delete it silently and report the cleanup.
Authored content present: do NOT delete. Prompt the user with:
skip (leave the orphan as-is — it'll surface again next run) and delete (remove the file along with its content; only on explicit confirmation).If the user picks a current slice as the destination:
Process orphans one at a time so the user can give a different answer per file. When all orphans are resolved, proceed to the report.
Report the result to the user: list which spec files were created (didn't exist before), which had their Model section refreshed (existed and the Model body changed), which were unchanged (existed and the Model body was already current), which orphans were deleted (unmodified placeholder), and which orphans were merged into other slices (with destination noted). Total counts are useful too.
sliceTests DSL inside a mermaid fenced block, so it renders as a Given / When / Then test card in the model viewer alongside the slice's Model section. The template ships with a single test["…"] skeleton; the user fills in the actual preconditions, action, and outcomes. See the README's "Slice Tests" section for the grammar — in particular note that then may contain error["<message>"] entries for rejection scenarios, and that the message string is read verbatim by downstream code generation.The skill is built to be run repeatedly as the parent eventModel evolves, without ever losing data the user has authored. Each invocation:
## Model section of every existing spec file whose slice is still alive in the DSL, against the latest declarations and edges. Description, Tests, and any custom sections in those files are untouched.test["..."] declarations, or any other deliberate edit) trigger an interactive prompt: the skill shows the orphan, lists every current slice, and asks which one to move the authored content to. The user can also choose to skip (defer) or delete (with confirmation).This means you can rename a slice, split a slice into two, or swap out the underlying eventModel structure, and a re-run will leave you with: (a) every current slice having a spec file, (b) Model sections always in sync with the live DSL, (c) every line of authored prose or test you've written either still in its slice or interactively resettled into one you choose. No content is lost silently.
The template is at template.md next to this SKILL.md. Editing it changes the initial scaffold used when stamping out brand-new spec files. It does NOT retroactively rewrite the Description or Tests sections of existing specs — those are user-owned content. To rewrite an existing spec from a fresh template, delete the file and re-run the skill.