npx skills add ...
npx skills add jorgemuza/orbit --skill format-docs
Format and restructure markdown documents so they publish cleanly to Confluence via `orbit confluence publish`. Use this skill whenever the user wants to prepare docs for Confluence, fix markdown formatting for wiki publishing, add frontmatter to docs, restructure a docs directory, or ensure markdown files follow Confluence-friendly conventions. Also trigger when the user says things like 'format these docs', 'prepare docs for Confluence', 'fix the frontmatter', 'restructure the docs folder', 'make these docs publishable', 'clean up the markdown', or any task involving making markdown Confluence-ready — even if they just say 'format this' or 'prep for wiki' without mentioning Confluence explicitly. If the user has a docs/ directory and mentions publishing or syncing, this skill applies.
npx skills add jorgemuza/orbit --skill format-docs
Prepare markdown documents for clean Confluence publishing via orbit confluence publish. This skill analyzes and transforms markdown files — individually or as a directory tree — to follow the conventions that Confluence expects.
orbit confluence publish for the first time on a docs directoryDetermine whether the user is asking about a single file or a directory.
If formatting a directory, verify and fix these structural issues:
INDEX.md files — Every directory that contains markdown files needs an INDEX.md. This file becomes the parent page in Confluence for all sibling .md files.
If an INDEX.md is missing, create one with:
INDEX.md structure — Every INDEX.md must follow this pattern:
Key rules for INDEX.md files:
<!-- confluence:properties-report --> directive after the intro content. This generates a dynamic table on Confluence that pulls metadata from all child pages sharing the same label. Use ancestor = currentContent() to scope to child pages, and match the label from confluence_labels.<!-- confluence:ignore-start --> and <!-- confluence:ignore-end -->. This content is only visible in markdown viewers (GitHub, local); on Confluence, the properties report replaces it.label value in the CQL query must match one of the confluence_labels defined in the child pages' frontmatter. Use the same label across all siblings so the report captures them all.Owner,Status,Version,Reviewed on. These must match field names in the children's confluence_properties.File naming — Rename files that would cause URL issues:
api-reference.md not API Reference.mdFlat nesting — Confluence page trees work best with one level of topic directories under the root. If the directory has deeply nested subdirectories (3+ levels), suggest flattening.
For each markdown file, check and fix the following. Read the formatting reference for detailed rules on each item.
Every file needs YAML frontmatter with all standard fields populated. Frontmatter is the single source of truth for document metadata — any metadata that exists in the frontmatter must NOT be duplicated in the document body.
Always use the full frontmatter template:
When adding or completing frontmatter:
title from the first # heading if present, otherwise from the filenamedate to today's dateauthor from inline metadata if present, otherwise from existing sibling files or ask the usersubtitle from document context (e.g., "ADR — Project v1.0", "Guide — Team Docs")confluence_labels based on the directory name and contentconfluence_properties with at minimum: Owner, Classification, Status, Version, and Reviewed onconfluence_ignore: false by default. Only set to true when the user explicitly wants to exclude a file from Confluence publishing (previously published pages will be deleted on next sync)confluence_page_id or confluence_urlAfter populating the frontmatter, remove any inline metadata blocks from the document body that duplicate information already captured in the frontmatter or confluence_properties. These blocks typically appear near the top of the document as bold-key/value lines or small tables.
Patterns to detect and remove:
Also detect and remove metadata presented as:
Version: 1.0 or Status: Draft| Field | Value |)> **Version**: 1.0Rules for removal:
confluence_properties fieldsThe converter skips the first # heading (Confluence uses the page title instead), so the document body should use ## as the top-level section heading.
Fix these issues:
# headings — Keep only the first one (it becomes the title). Convert subsequent # to ##.## to ####. Fill in the hierarchy.# heading — If the file has no # heading but has a title in frontmatter, that's fine. If it has neither, add a # heading derived from the filename.Well-structured documents follow this pattern:
Apply these structural improvements:
## headings). Wrap the TOC section (heading + list) with <!-- confluence:toc-start --> / <!-- confluence:toc-end --> directives so it gets replaced with the Confluence TOC macro on publish. The markdown TOC remains visible in GitHub/local renderers.---) between major sections for visual separation.If the file is part of a directory being formatted, add a Cross-References section near the bottom linking to related sibling documents:
Use relative paths so links resolve correctly both locally and in Confluence.
For documents that will be actively maintained, add a revision history table at the bottom:
Only add this if the document doesn't already have one.
Fix markdown patterns that don't convert well to Confluence:
| Issue | Fix |
|---|---|
Inline metadata blocks (**Status**: Draft, etc.) | Absorb into frontmatter/confluence_properties, then remove from body |
| Raw HTML tags | Replace with markdown equivalents |
<br> tags | Use blank lines instead |
| Deeply nested lists (3+ levels) | Flatten to 2 levels max |
| Tables with multi-line cells | Split into simpler tables |
| Inline images with relative paths | Verify paths are correct relative to the file |
GitHub-flavored alerts (> [!NOTE]) | Keep as-is — the converter handles these |
MkDocs admonitions (!!! note) | Keep as-is — the converter handles these |
Fenced code blocks with diagram languages (mermaid, plantuml, graphviz, d2, etc.) are rendered as PNG images via Kroki during Confluence publishing (the public https://kroki.io, or a self-hosted instance the profile names). Orbit auto-sanitizes common issues, but source diagrams should follow these rules for best results.
That is the default (--diagrams kroki). Two other strategies exist and change what the rules below are worth:
| Strategy | What happens to a diagram block |
|---|---|
kroki (default) | Every diagram language → PNG from the configured Kroki instance. The auto-fixes below apply. |
markdown-macro | Mermaid → Confluence markdown macro, drawn live in the reader's browser. Every other language stays a code block. Never contacts Kroki. |
code-block | Every diagram stays preformatted text. No network call. |
Under markdown-macro the auto-fixes below are not applied — they work around the Mermaid build Kroki renders with, and the macro's app renders with its own (htmlLabels: true), so <br/> in a label is a line break rather than something to strip. The manual fixes further down still apply: they are about writing valid diagrams, not about Kroki.
Auto-fixed by orbit (no manual action needed, kroki strategy only):
<br/> tags in participant names, notes, and messages → strippedWorker (queue) → Worker - queue() on participant names → removedAPI:8000 → APIClient<<--API: msg → API-->>Client: msgMust be fixed manually when formatting docs:
| Issue | Fix |
|---|---|
ASCII box-drawing (┌┐└┘│─) | Convert to proper Mermaid/D2/PlantUML syntax |
ASCII sequence diagrams (|-- ->) | Convert to sequenceDiagram with proper arrows |
| Bare code blocks (no language tag) with diagram-like content | Add mermaid, d2, or plantuml language tag |
State transitions as plain text (DRAFT → ACTIVE → DEPRECATED) | Convert to stateDiagram-v2 |
| Very large diagrams (15+ participants, 50+ messages) | Split into smaller diagrams |
Diagram type selection:
| Content | Best format |
|---|---|
| Request/response flows | mermaid sequenceDiagram |
| State machines | mermaid stateDiagram-v2 |
| Simple flowcharts | mermaid flowchart TD/LR |
| Component trees | mermaid graph TD |
| Entity/data models | mermaid erDiagram |
| Nested architecture | d2 |
| Layered systems | d2 |
When encountering ASCII art or text-based diagrams in documents being formatted, convert them to the appropriate diagram language. If the diagram is too complex to convert confidently, leave it as a plain code block with a text language tag.
These are optional improvements that use Confluence features:
{status:Color|Text} syntax in property fields (e.g., {status:Green|Published}). Emoji shortcodes (:green_circle: Green) are also supported.<!-- confluence:ignore-start --> and <!-- confluence:ignore-end -->. In INDEX.md files, all child page tables must be wrapped (see Directory-Level Checks above).After making changes, suggest the user verify with:
This previews what would be published without making changes.
confluence_page_id or confluence_url — these are managed by orbit confluence publish.# heading first, then from the filename.---
title: API Reference
subtitle: "Reference — Project Docs v1.0"
date: "2026-03-09"
author: "Engineering Team"
confluence_ignore: false
confluence_labels:
- api
- reference
confluence_properties:
- id: status
fields:
Owner: "Engineering Team"
Classification: Internal
Status: "{status:Green|Published}"
Version: v1.0
Reviewed on: 2026-03-05
---**Document Version**: 1.0
**Status**: Draft (Proposal)
**Classification**: Internal
**Last Updated**: March 7, 2026
**Author**: Engineering Team
**Owner**: Platform Team# Title
> One-line summary of what this document covers.
<!-- confluence:toc-start -->
## Table of Contents
1. [Section One](#section-one)
2. [Section Two](#section-two)
<!-- confluence:toc-end -->
---
## Section One
Content...
---
## Section Two
Content...## Cross-References
| Document | Relevance |
|----------|-----------|
| [Related Doc](./related-doc.md) | Brief note on why it's relevant |## Revision History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-03-09 | Initial document |orbit confluence publish <directory> --space <SPACE> --parent <PAGE_ID> --dry-run -p <profile>