Publish any markdown file from the vault to Confluence with format conversion and approval gate
60
72%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.claude/skills/publish-to-confluence/SKILL.mdCheck agent_mode in 00-inbox/MY-PROFILE.md frontmatter:
agent_mode: team — no significant benefit for this skill (single sequential operation)agent_mode: solo — standard execution/publish-to-confluenceRead 00-inbox/MY-INTEGRATIONS.md — Confluence MUST be listed under Active Integrations
Confluence is not in your active integrations.
Would you like to:
a) Set up Confluence integration (I'll add it to MY-INTEGRATIONS.md)
b) Export the document in a Confluence-compatible format for manual uploadGet current timestamp: Run date '+%Y-%m-%d %H:%M' using Bash
Determine what to publish:
Option A: User specifies a file path
Read the specified file from the vault.Option B: User describes the document
Search for matching files:
1. Glob for likely matches in 04-projects/, 05-knowledge/, 01-daily/
2. Present candidates and let user chooseOption C: Just-generated document If this skill is invoked right after generating a PRD, release notes, or other document, use that document.
Ask the user (if not already provided):
Where should this be published in Confluence?
Required:
- Space key: [CUSTOMIZE: YOUR-SPACE-KEY] (or let me search for spaces)
- Parent page: [Page title or ID under which to nest this page]
Optional:
- Page title: [defaults to the document's H1 heading]
- Labels: [Confluence labels to add]
- Publish mode: "create new" or "update existing"If the user doesn't know the space or parent page:
Use WebFetch to search Confluence:
GET /wiki/rest/api/space?limit=50
- List available spaces for the user to choose
GET /wiki/rest/api/content?spaceKey=[SPACE]&type=page&limit=25
- List pages in the space for parent page selectionConvert the markdown document to Confluence storage format (XHTML):
Conversion rules:
| Markdown | Confluence Storage Format |
|---|---|
# Heading | <h1>Heading</h1> |
## Heading | <h2>Heading</h2> |
**bold** | <strong>bold</strong> |
*italic* | <em>italic</em> |
- list item | <ul><li>list item</li></ul> |
1. list item | <ol><li>list item</li></ol> |
[text](url) | <a href="url">text</a> |
`code` | <code>code</code> |
| Code blocks | <ac:structured-macro ac:name="code"><ac:plain-text-body><![CDATA[...]]></ac:plain-text-body></ac:structured-macro> |
| Tables | <table><tbody><tr><th>...</th></tr><tr><td>...</td></tr></tbody></table> |
> blockquote | <blockquote><p>quote</p></blockquote> |
--- | <hr /> |
- [ ] task | <ac:task-list><ac:task><ac:task-status>incomplete</ac:task-status><ac:task-body>task</ac:task-body></ac:task></ac:task-list> |
- [x] task | Same with complete status |
| YAML frontmatter | Strip entirely (not displayed in Confluence) |
Important conversion notes:
CRITICAL: NEVER publish without explicit user approval.
Present a summary to the user:
Ready to publish to Confluence:
Document: [filename]
Title: [page title]
Space: [space key]
Parent Page: [parent page title]
Mode: [create new / update existing]
Labels: [labels]
Content preview (first 500 chars):
[preview text]
Estimated page size: [approximate word count]
Proceed with publishing? (yes/no)Wait for explicit "yes" before proceeding.
Use WebFetch to POST to Confluence REST API:
POST [CUSTOMIZE: your-confluence-url]/wiki/rest/api/content
Headers:
Content-Type: application/json
Authorization: [from configured credentials]
Body:
{
"type": "page",
"title": "[page title]",
"space": { "key": "[SPACE_KEY]" },
"ancestors": [{ "id": "[PARENT_PAGE_ID]" }],
"body": {
"storage": {
"value": "[converted XHTML content]",
"representation": "storage"
}
},
"metadata": {
"labels": [
{ "prefix": "global", "name": "[label]" }
]
}
}First, get the current page to obtain the version number:
GET [CUSTOMIZE: your-confluence-url]/wiki/rest/api/content/[PAGE_ID]?expand=version
Then update:
PUT [CUSTOMIZE: your-confluence-url]/wiki/rest/api/content/[PAGE_ID]
Body:
{
"type": "page",
"title": "[page title]",
"version": { "number": [current_version + 1] },
"body": {
"storage": {
"value": "[converted XHTML content]",
"representation": "storage"
}
}
}After successful publishing:
Confirm to the user:
Published successfully!
Page: [Title]
URL: [Confluence page URL]
Space: [Space Key]
Version: [version number]Update the source vault file (add published metadata to frontmatter):
confluence_url: "[page URL]"
confluence_page_id: "[page ID]"
confluence_space: "[space key]"
published_at: "[timestamp]"
confluence_version: [version number]Log the publication for future reference.
If the vault file already has confluence_page_id in its frontmatter:
This document was previously published to Confluence:
URL: [confluence_url]
Last published: [published_at]
Would you like to:
a) Update the existing Confluence page (increment version)
b) Create a new page (separate copy)
c) Cancel| Scenario | Behavior |
|---|---|
| Confluence not active | Stop and inform user; suggest alternative platforms |
| Confluence API fails | Save the converted XHTML to a file so user can manually paste it |
| Authentication failure | Inform user their Confluence credentials may need refreshing |
| Page already exists (same title) | Ask user: update existing, create with different title, or cancel |
| Very large document | Warn user about page size; suggest splitting into child pages |
| Complex markdown (unsupported elements) | Convert best-effort, warn about any elements that couldn't be converted |
dfbf9e9
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.