Claude Code plugin for publishing markdown files to Confluence pages via the Confluence v2 API.
Part of the unic-claude-code-* plugin family for Unic-internal Claude Code tooling.
/unic-confluence <page-key-or-id> <markdown-file>
Examples:
/unic-confluence my-page-key docs/features/my-spec.md
/unic-confluence 804848595 docs/features/my-spec.md # raw page ID also worksThe <page-key-or-id> argument accepts either a raw numeric Confluence page ID or a short key defined in confluence-pages.json. Place this file at your repo root:
{
"my-docs": 123456789,
"another-page": 987654321
}Then publish using the key:
pnpm confluence my-docs docs/my-file.mdPublishing by raw numeric page ID auto-saves a slugified alias derived from the Confluence page's title into confluence-pages.json at the current working directory. Subsequent publishes can reference the page by its alias.
- The slug is lowercased, ASCII-only, dash-separated, max 60 chars.
- If the slug collides with another alias,
-2,-3, … is appended. - If the page ID is already aliased, no write happens (the existing alias is reported).
- Pass
--no-saveto skip auto-saving for a single run.
List all aliases:
node scripts/push-to-confluence.mjs --listKnown limitation: the file write is not atomic. Two concurrent publishes against the same confluence-pages.json may race; one update will be lost.
The script injects your Markdown content into a Confluence page rather than replacing the whole page. To control where the content lands, add injection markers directly to the Confluence page body.
- Open the target Confluence page and click Edit.
- Place your cursor where you want the injected content to appear.
- Type the start marker on its own line:
[AUTO_INSERT_START: my-docs] - Leave a blank line (optional placeholder text helps with visual orientation):
(Claude Code will inject content here) - Type the end marker on its own line:
[AUTO_INSERT_END: my-docs] - Save the page.
Full copy-paste block:
[AUTO_INSERT_START: my-docs]
(Claude Code will inject content here)
[AUTO_INSERT_END: my-docs]
- The label (
my-docsabove) is case-sensitive.My-Docsandmy-docsare different labels. - The label in
[AUTO_INSERT_START:label]must exactly match the label in[AUTO_INSERT_END:label]. - Whitespace around the label is trimmed —
[AUTO_INSERT_START: my-docs]and[AUTO_INSERT_START:my-docs]are equivalent. - A page can have only one marker pair. Multiple pairs are not supported.
If the page has no markers, the script currently appends the new HTML after all existing content. Running the publish command twice will double the content. A future update (spec 03) will change this to an explicit error with a --replace-all opt-out flag.
Pages set up before text markers were introduced may use Confluence anchor macros instead:
- Start anchor: macro named
md-start - End anchor: macro named
md-end
This fallback is still supported but deprecated. Migrate legacy pages to text markers when convenient.
# Register the Unic plugin marketplace (once per machine)
claude plugins marketplace add unic https://raw.githubusercontent.com/unic/unic-agents-plugins/main/.claude-plugin/marketplace.json
# Install the plugin
claude plugins install unic-confluence@unicnpm install -D git+ssh://git@github.com:unic/unic-agents-pluginsor
pnpm install -w -D git+ssh://git@github.com:unic/unic-agents-pluginsThen add to your repo's package.json scripts:
"confluence": "node node_modules/unic-confluence/scripts/push-to-confluence.mjs"{
"_comment": "Map human-readable keys to Confluence page IDs",
"my-page-key": 000000000
}Replace 000000000 with the actual Confluence page ID (find it in the Confluence URL or page info).
pnpm confluence --setupOr set environment variables instead:
CONFLUENCE_URL=https://yourorg.atlassian.net
CONFLUENCE_USER=your@email.com
CONFLUENCE_TOKEN=your-api-tokenpnpm confluence --verifyGenerate a new token at https://id.atlassian.com → Security → API tokens. Tokens created before 2025 may have expired even if the Atlassian interface shows them as active. After generating, re-run setup:
pnpm confluence --setup
# or, if running the script directly:
node scripts/push-to-confluence.mjs --setupYour API token does not have Edit permission for this Confluence page or space. Ask a Confluence space admin to grant your account Edit access, then retry.
The page ID in confluence-pages.json is incorrect, or the page has been deleted or moved.
Verify the ID by opening the page in Confluence and checking the URL — the numeric ID appears after /pages/.
Run pnpm confluence --verify to test all IDs in confluence-pages.json at once.
Someone edited the Confluence page between the time this script read the current version (GET) and tried to write the new version (PUT). Re-run the same command — the script will fetch the current version and retry cleanly.
Make sure you are connected to the Unic VPN.
The Confluence instance (https://uniccom.atlassian.net) is not reachable from the public internet.
The Markdown source file may be empty, or it may contain only a YAML frontmatter block with no body content below the closing ---.
Check the file path you passed as the second argument.
Either create confluence-pages.json at your repository root (see Per-repo setup → Create confluence-pages.json above), or pass the numeric Confluence page ID directly as the first argument instead of a key name.
Run pnpm confluence --setup (or node scripts/push-to-confluence.mjs --setup) to store your Confluence URL, email, and API token in ~/.unic-confluence.json.
Alternatively, set the environment variables CONFLUENCE_URL, CONFLUENCE_USER, and CONFLUENCE_TOKEN.
# Update Claude Code plugin
claude plugins marketplace update unic
claude plugins install unic-confluence@unic
# Update npm package
npm install -D git+ssh://git@github.com:unic/unic-agents-plugins
# Or
pnpm install -w -D git+ssh://git@github.com:unic/unic-agents-pluginsThis plugin follows the Unic Claude Code plugin naming convention:
| Surface | Value |
|---|---|
| GitHub repo | unic-claude-code-<service> |
| Plugin identifier (Claude Code) | unic-<service> |
| npm package name | unic-<service> |
Every feat(spec-NN) / fix(spec-NN) commit includes its own version bump and CHANGELOG entry via pnpm bump. No separate "release commit" is needed.
Per change (every commit):
- Add one bullet under the matching subsection of
## [Unreleased]inCHANGELOG.md(### Breaking,### Added, or### Fixed). pnpm bump <patch|minor|major>— bumpsplugin.json, mirrors intomarketplace.json, promotes[Unreleased]→ a dated version section.git add -A && git commit -m "feat(spec-NN): <description> (vX.Y.Z)".
SemVer policy:
| Change type | Bump |
|---|---|
| Breaking change to CLI flags, exit codes, or on-disk contracts | major |
| New flag, subcommand, or user-visible feature | minor |
| Bug fix, refactor, docs, internal tooling | patch |
To tag and push a release boundary (optional, periodic):
pnpm tag # creates local git tag vX.Y.Z
git push --follow-tags # pushes tag to GitHubOptional — enable the local pre-push changelog check:
git config core.hooksPath .githooksSee CONTRIBUTING.md for the spec-driven development workflow, how to write specs, and how to run Ralph Orchestrator.
Copyright © 2026 Unic. Licensed under the LGPL-3.0-or-later.