format-docs
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.
When to Use
- Before running
orbit confluence publishfor the first time on a docs directory - When adding new markdown files to an existing published docs tree
- When docs render poorly in Confluence and need structural fixes
- When migrating docs from another system (GitHub wiki, Notion export, etc.)
Process
1. Assess the Scope
Determine whether the user is asking about a single file or a directory.
- Single file: Read it and apply the file-level checks below.
- Directory: List the full tree, then work through both directory-level and file-level checks.
2. Directory-Level Checks
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.
docs/
INDEX.md ← Required: parent page for docs/
overview.md
api/
INDEX.md ← Required: parent page for api/
endpoints.md
If an INDEX.md is missing, create one with:
- Frontmatter (title from directory name, today's date)
- A brief intro line
- A properties report directive (see below)
- Child page tables wrapped in confluence ignore blocks
INDEX.md structure — Every INDEX.md must follow this pattern:
---
title: "Section Title"
# ... full frontmatter ...
confluence_labels:
- my-label
---
# Section Title
> Brief intro summarizing the section.
---
<!-- confluence:properties-report cql="ancestor = currentContent() AND label = 'my-label'" firstcolumn="Title" headings="Owner,Status,Version,Reviewed on" -->
<!-- confluence:ignore-start -->
## Subsection Name
| Document | Version | Summary |
|----------|---------|---------|
| [Child Page](./child-page.md) | v1.0 | Brief description |
<!-- confluence:ignore-end -->
Key rules for INDEX.md files:
- Properties report directive — Add a
<!-- 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. Useancestor = currentContent()to scope to child pages, and match the label fromconfluence_labels. - Confluence ignore blocks — Wrap all child page listing content (section headings, tables, links) between
<!-- 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 alignment — The
labelvalue in the CQL query must match one of theconfluence_labelsdefined in the child pages' frontmatter. Use the same label across all siblings so the report captures them all. - Report headings — Include at minimum:
Owner,Status,Version,Reviewed on. These must match field names in the children'sconfluence_properties.
File naming — Rename files that would cause URL issues:
- Use lowercase with hyphens:
api-reference.mdnotAPI Reference.md - No spaces, underscores, or special characters in filenames
- No version numbers in filenames — track versions in frontmatter instead
Flat 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.
3. File-Level Checks
For each markdown file, check and fix the following. Read the formatting reference for detailed rules on each item.
Frontmatter
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:
---
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
---
When adding or completing frontmatter:
- Derive
titlefrom the first# headingif present, otherwise from the filename - Set
dateto today's date - Derive
authorfrom inline metadata if present, otherwise from existing sibling files or ask the user - Derive
subtitlefrom document context (e.g.,"ADR — Project v1.0","Guide — Team Docs") - Suggest
confluence_labelsbased on the directory name and content - Always include
confluence_propertieswith at minimum:Owner,Classification,Status,Version, andReviewed on - Populate property values from inline metadata found in the document body when available
- Set
confluence_ignore: falseby default. Only set totruewhen the user explicitly wants to exclude a file from Confluence publishing (previously published pages will be deleted on next sync) - Never overwrite existing
confluence_page_idorconfluence_url
Remove Redundant Inline Metadata
After 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:
**Document Version**: 1.0
**Status**: Draft (Proposal)
**Classification**: Internal
**Last Updated**: March 7, 2026
**Author**: Engineering Team
**Owner**: Platform Team
Also detect and remove metadata presented as:
- Key-value lines:
Version: 1.0orStatus: Draft - Small two-column tables with metadata-like headers (e.g.,
| Field | Value |) - Blockquote metadata:
> **Version**: 1.0
Rules for removal:
- Only remove metadata lines/blocks where the information is already captured in frontmatter fields or
confluence_propertiesfields - If an inline metadata block contains values not yet in frontmatter, absorb them into frontmatter first, then remove the block
- Preserve any surrounding content — only strip the metadata lines themselves
- If the metadata block is followed by a blank line or horizontal rule, remove the separator too to avoid orphaned whitespace
Heading Hierarchy
The 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:
- Multiple
#headings — Keep only the first one (it becomes the title). Convert subsequent#to##. - Heading gaps — Don't jump from
##to####. Fill in the hierarchy. - No
#heading — If the file has no#heading but has atitlein frontmatter, that's fine. If it has neither, add a#heading derived from the filename.
Document Structure
Well-structured documents follow this pattern:
# 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...
Apply these structural improvements:
- Add a TOC if the document has 3+ sections (
##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. - Add horizontal rules (
---) between major sections for visual separation. - Add a summary blockquote after the title if the document jumps straight into content without context.
Cross-References
If the file is part of a directory being formatted, add a Cross-References section near the bottom linking to related sibling documents:
## Cross-References
| Document | Relevance |
|----------|-----------|
| [Related Doc](./related-doc.md) | Brief note on why it's relevant |
Use relative paths so links resolve correctly both locally and in Confluence.
Revision History
For documents that will be actively maintained, add a revision history table at the bottom:
## Revision History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-03-09 | Initial document |
Only add this if the document doesn't already have one.
4. Content Formatting
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 |
5. Diagram Formatting
Fenced code blocks with diagram languages (mermaid, plantuml, graphviz, d2, etc.) are rendered as PNG images via kroki.io during Confluence publishing. Orbit auto-sanitizes common issues, but source diagrams should follow these rules for best results.
Auto-fixed by orbit (no manual action needed):
<br/>tags in participant names, notes, and messages → stripped- Parenthesized suffixes in participant aliases:
Worker (queue)→Worker - queue - Trailing
()on participant names → removed - Port numbers after colons:
API:8000→API - Reverse arrows:
Client<<--API: msg→API-->>Client: msg
Must 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.
6. Confluence-Specific Enhancements
These are optional improvements that use Confluence features:
- Status badges — Use
{status:Color|Text}syntax in property fields (e.g.,{status:Green|Published}). Emoji shortcodes (:green_circle: Green) are also supported. - Confluence ignore blocks — Wrap sections that should only appear in markdown (not Confluence) with
<!-- confluence:ignore-start -->and<!-- confluence:ignore-end -->. In INDEX.md files, all child page tables must be wrapped (see Directory-Level Checks above). - Properties report — Every INDEX.md must include a properties report directive. See the INDEX.md structure in Directory-Level Checks for the exact pattern.
7. Dry Run
After making changes, suggest the user verify with:
orbit confluence publish <directory> --space <SPACE> --parent <PAGE_ID> --dry-run -p <profile>
This previews what would be published without making changes.
Rules
- Never delete content — only restructure and add metadata.
- Never overwrite
confluence_page_idorconfluence_url— these are managed byorbit confluence publish. - Preserve existing frontmatter fields — add missing ones, don't remove existing ones.
- When in doubt about a title, derive it from the
# headingfirst, then from the filename. - Keep changes minimal — don't rewrite prose, don't reorganize sections unless the heading hierarchy is broken.
- Show the user a summary of changes before applying them to a large directory.
More from jorgemuza/orbit
gitlab
Create and manage GitLab projects, merge requests, pipelines, issues, branches, and more using the orbit CLI. Use this skill whenever the user asks about GitLab repositories, MRs (merge requests), CI/CD pipelines, branches, tags, commits, issues, groups, or project members. Trigger on phrases like 'list MRs', 'check the pipeline', 'create a branch', 'open a merge request', 'view the latest commits', 'list projects in group X', 'retry the CI', 'close the issue', 'who are the members', or any GitLab-related task — even casual references like 'what's running in CI', 'show me the MRs', 'tag a release', 'check if it merged', or 'list repos'. Also trigger when the user mentions PR/pull request in a GitLab context (GitLab calls them merge requests). The orbit CLI alias is `gl`.
97jira
Interact with Jira using the orbit CLI to create, list, view, edit, and transition issues, manage sprints and epics, export epic hierarchies to markdown, manage dashboards and gadgets, manage saved filters, manage custom fields and screen configurations, list statuses and issue types, and write properly formatted descriptions using Jira wiki markup. Use this skill whenever the user asks about Jira tasks, tickets, issues, sprints, epics, dashboards, filters, gadgets, or needs to manage project work items using orbit. Also trigger when the user says things like 'create a ticket', 'create epics', 'move this to done', 'assign the issue', 'update the description', 'format for Jira', 'create a custom field', 'add field to screen', 'list statuses', 'configure Jira', 'create a dashboard', 'add a gadget', 'list filters', 'search filters', 'export epic', 'dump epic hierarchy', or any Jira-related workflow — even casual references like 'update Jira', 'what tickets are in this sprint', 'add a comment to PROJ-123', 'set up AI tracking fields', 'show me the dashboards', or 'create a metrics dashboard'. Trigger especially when descriptions need proper formatting (headings, bullets, tables, links) since Jira Server uses wiki markup, not markdown.
95confluence
Manage Confluence pages using the orbit CLI — create, update, view, publish markdown directories, check page hierarchy, and control page width. Use this skill whenever the user asks about Confluence pages, wiki content, publishing documentation, uploading markdown to Confluence, syncing docs, checking page hierarchy or ancestors, or managing page trees using orbit. Trigger on phrases like 'create a Confluence page', 'update the wiki', 'publish these docs to Confluence', 'upload markdown', 'set page width', 'view page', 'list child pages', 'show hierarchy', 'check page tree', 'what are the ancestors', or any Confluence-related task — even casual references like 'push this to Confluence', 'sync the docs', 'check what pages are under X', or 'show me the page structure'. Also trigger when the user needs to convert markdown to Confluence storage format or wants to track which markdown files map to which Confluence pages via frontmatter metadata (confluence_page_id, confluence_url).
94draxarp
Manage Draxarp Intelligence — projects, tasks, specs, docs, memories, sprints, knowledge graph, context captures, and task decomposition via orbit CLI
68github
Create and manage GitHub repositories, pull requests, issues, releases, branches, secrets, and more using the orbit CLI. Use this skill whenever the user asks about GitHub repositories, PRs (pull requests), GitHub Actions workflow runs, branches, tags, commits, issues, releases, secrets, or organization repos. Trigger on phrases like 'list PRs', 'check the actions', 'watch the workflow', 'create a secret', 'open a pull request', 'view the latest commits', 'list repos in org X', 'rerun the workflow', 'close the issue', 'latest release', 'set a GitHub secret', or any GitHub-related task — even casual references like 'what's running in CI', 'show me the PRs', 'tag a release', 'check if it merged', 'list repos', 'is the build passing', or 'add a deploy key secret'. Also trigger when the user wants to monitor CI/CD progress, manage Actions secrets for deployments, or debug failing workflows. The orbit CLI alias is `gh`.
61bitbucket
Manage Bitbucket repositories, pull requests, branches, tags, commits, projects, and admin settings using the orbit CLI. Use this skill whenever the user asks about Bitbucket repos, PRs (pull requests), branches, tags, commits, code review, project management, default reviewer conditions, required approvals, merge restrictions, or PR approvals on Bitbucket Server/Data Center or Bitbucket Cloud. Trigger on phrases like 'list PRs', 'show pull requests', 'create a branch', 'open a PR', 'view the latest commits', 'list repos in project X', 'merge the PR', 'decline the PR', 'approve the PR', 'unapprove', 'request changes', 'needs work', 'mark as needs work', 'reject the PR', 'block the merge', 'check PR activity', 'bypass merge check', 'required approvals', 'reviewer conditions', 'who needs to approve', or any Bitbucket-related task — even casual references like 'what PRs are open', 'show me the repos', 'tag a release', 'check if it merged', 'who approved it', 'list branches', or 'why can't I merge'. Also trigger when the user provides a Bitbucket Server URL (e.g., https://git.example.com/projects/PROJ/repos/my-repo/) or mentions Bitbucket Data Center. The orbit CLI alias is `bb`.
58