publish-to-confluence
publish-to-confluence converts markdown documents from a user's vault into Confluence-compatible format and uploads them to a specified space and parent page. Use this skill when a user wants to share generated documents like product requirements, release notes, or knowledge articles with their team on Confluence, provided the integration is configured in their active integrations list.
git clone --depth 1 https://github.com/huytieu/COG-second-brain /tmp/publish-to-confluence && cp -r /tmp/publish-to-confluence/.claude/skills/publish-to-confluence ~/.claude/skills/publish-to-confluenceSKILL.md
# COG Publish to Confluence Skill
## When to Invoke
- User wants to publish a document to Confluence
- User says "publish to Confluence", "push to wiki", "send to Confluence", "confluence publish"
- User has a markdown file they want to share with the team on Confluence
- After generating a PRD, release notes, or other document that should go to the wiki
## Agent Mode Awareness
**Check `agent_mode` in `00-inbox/MY-PROFILE.md` frontmatter:**
- If `agent_mode: team` — no significant benefit for this skill (single sequential operation)
- If `agent_mode: solo` — standard execution
## Command: `/publish-to-confluence`
## Pre-Flight Check
1. **Read `00-inbox/MY-INTEGRATIONS.md`** — Confluence MUST be listed under Active Integrations
- If Confluence is **not active**: Inform the user and stop.
```
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 upload
```
- If Confluence is **disabled**: Skip silently per COG conventions. Suggest alternative publishing (HackMD, Notion) if active.
2. **Get current timestamp:** Run `date '+%Y-%m-%d %H:%M'` using Bash
---
## Execution Strategy
### Phase 1: Identify the Source Document
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 choose
```
**Option C: Just-generated document**
If this skill is invoked right after generating a PRD, release notes, or other document, use that document.
### Phase 2: Configure Publishing Target
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 selection
```
### Phase 3: Convert Markdown to Confluence Format
Convert 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:**
- Strip YAML frontmatter — it should not appear in the Confluence page
- Preserve table structure carefully
- Convert relative vault links to plain text (they won't work in Confluence)
- Handle nested lists properly
- Preserve emoji characters as-is
### Phase 4: Preview and Approval Gate
**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.**
### Phase 5: Publish
#### Create New Page
```
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]" }
]
}
}
```
#### Update Existing Page
```
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"
}
}
}
```
### Phase 6: Confirm and Update Vault
After successful publishing:
1. **Confirm to the user:**
```
Published successfully!
Page: [Title]
URL: [Confluence page URL]
Space: [Space Key]
Version: [version number]
```
2. **Update the source vault file** (add published metadata to frontmatter):
```yaml
confluence_url: "[page URL]"
confluence_page_id: "[page ID]"
confluence_space: "[space key]"
published_at: "[timestamp]"
confluence_version: [version nUpdate people profiles in 05-knowledge/people/ with new information from brief data, meetings, or Slack
Collect data from GitHub, Slack, Jira, Linear, or file system. Structured extraction only — no synthesis.
Execute pre-approved mutations — Jira transitions, Linear updates, API calls, build commands.
Read, write, and organize vault files. Metadata updates, file moves, profile updates.
Execute publishing operations — Slack, Confluence, Notion, webhooks. Receives final content and posts it.
Web research agent. Searches, fetches URLs, extracts facts and evidence. No synthesis — just structured findings.
Deep strategic research engine — decomposes questions into parallel research threads, spawns multiple agents, and synthesizes into actionable strategic analysis
Quick capture of raw thoughts with intelligent domain classification and competitive intelligence extraction