---
name: confluence-publisher
description: >-
  Convert a markdown string/file to Confluence-compatible XHTML and publish it as a
  page to Confluence Cloud. Supports create, upsert, and update modes. Use when
  asked to publish to Confluence, create Confluence page, write to Confluence,
  update Confluence page from markdown.
argument-hint: 'Markdown content, page title, space key'
user-invocable: true
disable-model-invocation: false
---

## Overview

Two-step skill that converts agent-generated markdown into a Confluence Cloud
page. Step 1 converts the markdown string to Confluence storage-format XHTML
and saves it as an HTML artifact. Step 2 reads that artifact and publishes it
to Confluence Cloud via the REST API.

The agent can inspect/edit the HTML artifact between steps before publishing.

## Variables
runtime variables available to all scripts:
- **RUN_TS**: Generated once at workflow start as `YYYYMMDD_HHMMSS`. Passed to every script via `--run-ts`.
- **SKILL_NAME**: `confluence-publisher`
- **SKILL_DIR**: `$WORKSPACE_ROOT/.github/skills/confluence-publisher`
- **ARTIFACTS_DIR**: `$SKILL_DIR/artifacts`
- **WORK_LOG**: `$SKILL_DIR/work-logs/worklogs_$RUN_TS.md`

.env variables required for Confluence API access (user has to set them before running the workflow for first time):
| Variable | Source | Description |
|----------|--------|-------------|
| `CONFLUENCE_URL` | Environment variable | Confluence Cloud base URL (e.g. `https://yourorg.atlassian.net`) |
| `CONFLUENCE_EMAIL` | Environment variable | Confluence account email |
| `CONFLUENCE_API_TOKEN` | Environment variable | Confluence Cloud API token |

## Prerequisites

- Python 3.7+ (tested on 3.7 conda env) 
- Python packages installed from `requirements.txt`
- Confluence Cloud API token generated at <https://id.atlassian.com/manage/api-tokens>
- Environment variables set: `CONFLUENCE_URL`, `CONFLUENCE_EMAIL`, `CONFLUENCE_API_TOKEN`

### Install Dependencies

```powershell
pip install -r "$SKILL_DIR/script/requirements.txt"
```

## Workflow

> **Before starting**: Generate `RUN_TS` from the current datetime
> (`YYYYMMDD_HHMMSS`). All steps share the same `RUN_TS` and write to the same
> work-log file. Resolve `SKILL_DIR` via the workspace root.

> **Before starting**: Ensure the three `CONFLUENCE_*` environment variables are
> set. If not, ask the user to provide them.

---

### Step 0: Set variables

```powershell
$env:RUN_TS = Get-Date -Format "yyyyMMdd_HHmmss"
$env:SKILL_NAME = "confluence-publisher"
```

### Step 1: Convert markdown to Confluence XHTML

Run [step_01_convert.py](./script/step_01_convert.py) to convert a markdown
string into Confluence storage-format XHTML and save it as an artifact.

```powershell
python "$SKILL_DIR/script/step_01_convert.py" `
    --markdown-page-content "<MARKDOWN_STRING>" `
    --title "<PAGE_TITLE>" `
    --run-ts $env:RUN_TS `
    --skill-name $env:SKILL_NAME
```

Alternatively, for long content, use a markdown file path `--markdown-file`:

```powershell
python "$SKILL_DIR/script/step_01_convert.py" `
    --markdown-file "<PATH_TO_MD_FILE>" `
    --title "<PAGE_TITLE>" `
    --run-ts $env:RUN_TS `
    --skill-name $env:SKILL_NAME
```

- Exit code `0` = success. The artifact path is printed to stdout.
- Exit code `1` = conversion error — **stop the workflow**.

**Agent checkpoint**: Optionally read the generated HTML artifact to verify
the conversion looks correct before proceeding to Step 2.

### Step 2: Publish to Confluence Cloud

Run [step_02_publish.py](./script/step_02_publish.py) to read the HTML
artifact and publish it to Confluence.

```powershell
python "$SKILL_DIR/script/step_02_publish.py" `
    --html-file "<ARTIFACT_PATH_FROM_STEP_1>" `
    --title "<PAGE_TITLE>" `
    --space-key "<SPACE_KEY>" `
    --page-id "<PAGE_ID>" `
    --parent-page-id "<PARENT_PAGE_ID>" `
    --mode "<create|upsert|update>" `
    --run-ts $env:RUN_TS `
    --skill-name $env:SKILL_NAME
```

**Mode options**:
- `create` — Create a new page. Fails if title already exists under the same parent.
- `upsert` — Create if the page doesn't exist, update if it does (matched by title under `--parent-page-id`).
- `update` — Update an existing page by `--page-id`. Requires `--page-id`.

**Optional flags**:
- `--parent-page-id` — Parent page ID. Required for `create` and `upsert` modes.
- `--page-id` — Existing page ID. Required for `update` mode.

- Exit code `0` = success. Page URL is printed to stdout.
- Exit code `2` = API/auth error — report to user.

## Error Handling

| Exit Code | Meaning | Action |
|-----------|---------|--------|
| `0` | Success | Continue to next step |
| `1` | Conversion error (Step 1) | Check markdown input, report to user |
| `2` | API/auth error (Step 2) | Verify credentials and permissions, report to user |

Hints: if you reach Step 2 and encounter an error, first check that the `CONFLUENCE_*` environment variables are set. Next you can use the `$SKILL_DIR/script/diagnose_permissions.py` script to verify that the credentials have the necessary permissions to create/update pages in the target Confluence space.
