Skip to content
Productivity
Skill

/publish-to-confluence

Publish any markdown file from the vault to Confluence with format conversion and approval gate

BOOST
From plugin
cog-second-brain
1.3k36 skills10 agents
Install
$ npx -y skills add huytieu/COG-second-brain --skill publish-to-confluence --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/publish-to-confluence

Context preview

The summary Claude sees to decide when to auto-load this skill.

Publish any markdown file from the vault to Confluence with format conversion and approval gate

SKILL.md

publish-to-confluence.SKILL.md
name: publish-to-confluence
description: Publish any markdown file from the vault to Confluence with format conversion and approval gate
roles: [product-manager, engineering-lead, founder]
integrations: [confluence]

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 f

Read more
Ships withcog-second-brain

Cognition + Obsidian + Git — A self-evolving second brain powered by AI agents, markdown files, and version control. No database, no vendor lock-in — just .md files that think.

Get the whole plugin

Other skills on cog-second-brain.