Files
claude-engineering-plugin/plugins/compound-engineering/skills/sync-confluence/SKILL.md
John Lamb fe3b1eee16 Merge upstream v2.67.0 with fork customizations preserved
Synced 79 commits from EveryInc/compound-engineering-plugin upstream while
preserving fork-specific customizations (Python/FastAPI pivot, Zoominfo-internal
review agents, deploy-wiring operational lessons, custom personas).

## Triage decisions (15 conflicts resolved)

Keep deleted (7) -- fork already removed these in prior cleanups:
- agents/design/{design-implementation-reviewer,design-iterator,figma-design-sync}
  (no fork successor; backend-Python focus doesn't need UI/Figma agents)
- agents/docs/ankane-readme-writer (replaced by python-package-readme-writer)
- agents/review/{data-migration-expert,performance-oracle,security-sentinel}
  (replaced by *-reviewer naming convention: data-migrations-reviewer,
  performance-reviewer, security-reviewer)

Keep local (1):
- agents/workflow/lint.md (Python tooling: ruff/mypy/djlint/bandit; upstream
  deleted the file). Fixed pre-existing duplicate "2." numbering bug.

Restore from upstream (1):
- agents/review/data-integrity-guardian.md (kept for GDPR/CCPA privacy
  compliance angle not covered by data-migrations-reviewer)

Merge both (6) -- upstream structural wins layered with fork intent:
- agents/research/best-practices-researcher.md (upstream <examples> removal +
  fork's Rails/Ruby -> Python/FastAPI translations)
- skills/ce-brainstorm/SKILL.md (universal-brainstorming routing + Slack
  context + non-obvious angles + fork's Deploy wiring flag)
- skills/ce-plan/SKILL.md (universal-planning routing + planning-bootstrap +
  fork's two Deploy wiring check bullets)
- skills/ce-review/SKILL.md (Run ID, model tiering haiku->sonnet, compact-JSON
  artifact contract, file-type awareness, cli-readiness-reviewer + fork's
  zip-agent-validator, design-conformance-reviewer, Stage 6 Zip Agent
  Validation)
- skills/ce-review/references/persona-catalog.md (cli-readiness row + adversarial
  refinement + fork's Language & Framework Conditional layer; 22 personas total)
- skills/ce-work/SKILL.md (Parallel Safety Check, parallel-subagent constraints,
  Phase 3-4 compression + fork's deploy-values self-review row, with duplicate
  checklist bullet collapsed to single occurrence)

## Auto-applied (no triage needed)

- 225 remote-only files: accepted as-is (new docs, brainstorms, plans,
  upstream skills, tests, scripts)
- 70 local-only files: 46 preserved as-is (kieran-python, tiangolo-fastapi,
  zip-agent-validator, design-conformance-reviewer, essay/proof commands,
  excalidraw-png-export, etc.); 24 stayed deleted (dhh-rails-style,
  andrew-kane-gem-writer, dspy-ruby Ruby skills no longer needed)

## README updated

- Removed Design section (3 deleted agents)
- Removed deleted Review entries (data-migration-expert, dhh-rails-reviewer,
  kieran-rails-reviewer, performance-oracle, security-sentinel)
- Added new Review entries: design-conformance-reviewer, previous-comments-reviewer,
  tiangolo-fastapi-reviewer, zip-agent-validator
- Workflow: added lint
- Docs: replaced ankane-readme-writer with python-package-readme-writer

## Known issues (not introduced by merge decisions)

- 9 detect-project-type.sh tests fail on macOS bash 3.2 (script uses
  `declare -A` which requires bash 4+). Upstream regression in commit 070092d
  (#568). Resolution: install bash 4+ via `brew install bash` locally;
  upstream fix tracked separately.
- 2 review-skill-contract tests reference deleted agents (dhh-rails-reviewer,
  data-migration-expert). Pre-existing fork inconsistency, not new.

bun run release:validate: passes (46 agents, 51 skills, 0 MCP servers)
2026-04-17 17:24:41 -05:00

5.8 KiB

name, description, allowed-tools
name description allowed-tools
sync-confluence This skill should be used when syncing local markdown documentation to Confluence Cloud pages. It handles first-time setup (creating mapping files and docs directories), pushing updates to existing pages, and creating new pages with interactive destination prompts. Triggers on "sync to confluence", "push docs to confluence", "update confluence pages", "create a confluence page", or any request to publish markdown content to Confluence. Read, Bash(find *), Bash(source *), Bash(uv run *)

Sync Confluence

Sync local markdown files to Confluence Cloud pages via REST API. Handles the full lifecycle: first-time project setup, page creation, and bulk updates.

Prerequisites

Two environment variables must be set (typically in ~/.zshrc):

  • CONFLUENCE_EMAIL — Atlassian account email
  • CONFLUENCE_API_TOKEN_WRITE — Atlassian API token with write scope (falls back to CONFLUENCE_API_TOKEN)

Generate tokens at: https://id.atlassian.com/manage-profile/security/api-tokens

The script requires uv to be installed. Dependencies (markdown, requests, truststore) are declared inline via PEP 723 and resolved automatically by uv run.

Workflow

1. Check for Mapping File

Before running the sync script, check whether a .confluence-mapping.json exists in the project:

find "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" -name ".confluence-mapping.json" -maxdepth 3 2>/dev/null
  • If found — skip to step 3 (Sync).
  • If not found — proceed to step 2 (First-Time Setup).

2. First-Time Setup

When no mapping file exists, gather configuration interactively via AskUserQuestion:

  1. Confluence base URL — e.g., https://myorg.atlassian.net/wiki
  2. Space key — short identifier in Confluence URLs (e.g., ZR, ENG)
  3. Parent page ID — the page under which synced pages nest. Tell the user: "Open the parent page in Confluence — the page ID is the number in the URL."
  4. Parent page title — prefix for generated page titles (e.g., ATS Platform)
  5. Docs directory — where markdown files live relative to repo root (default: docs/)

Then create the docs directory and mapping file:

import json
from pathlib import Path

config = {
    "confluence": {
        "cloudId": "<domain>.atlassian.net",
        "spaceId": "",
        "spaceKey": "<SPACE_KEY>",
        "baseUrl": "<BASE_URL>"
    },
    "parentPage": {
        "id": "<PARENT_PAGE_ID>",
        "title": "<PARENT_TITLE>",
        "url": "<BASE_URL>/spaces/<SPACE_KEY>/pages/<PARENT_PAGE_ID>"
    },
    "pages": {},
    "unmapped": [],
    "lastSynced": ""
}

docs_dir = Path("<REPO_ROOT>") / "<DOCS_DIR>"
docs_dir.mkdir(parents=True, exist_ok=True)
mapping_path = docs_dir / ".confluence-mapping.json"
mapping_path.write_text(json.dumps(config, indent=2) + "\n")

To discover spaceId (required for page creation), run:

source ~/.zshrc && curl -s -u "${CONFLUENCE_EMAIL}:${CONFLUENCE_API_TOKEN_WRITE}" \
  -H "X-Atlassian-Token: no-check" \
  "<BASE_URL>/rest/api/space/<SPACE_KEY>" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])"

Update the mapping file with the discovered spaceId before proceeding.

3. Sync — Running the Script

The sync script is at ${CLAUDE_PLUGIN_ROOT}/skills/sync-confluence/scripts/sync_confluence.py.

Always source shell profile before running to load env vars:

source ~/.zshrc && uv run ${CLAUDE_PLUGIN_ROOT}/skills/sync-confluence/scripts/sync_confluence.py [options]

Common Operations

Command What it does
(no flags) Sync all markdown files in docs dir
--dry-run Preview changes without API calls
--file docs/my-doc.md Sync a single file
--update-only Only update existing pages, skip unmapped files
--create-only Only create new pages, skip existing
--mapping-file path/to/file Use a specific mapping file
--docs-dir path/to/dir Override docs directory

4. Creating a New Confluence Page

When the user wants to create a new page:

  1. Ask for the page topic/title
  2. Create the markdown file in the docs directory with a # Title heading and content
  3. Run the sync script with --file pointing to the new file
  4. The script detects the unmapped file, creates the page, and updates the mapping

Title resolution order: First # H1 from the markdown → filename-derived title → raw filename. Titles are prefixed with the parent page title (e.g., My Project: New Page).

5. Mapping File Structure

{
  "confluence": {
    "cloudId": "myorg.atlassian.net",
    "spaceId": "1234567890",
    "spaceKey": "ZR",
    "baseUrl": "https://myorg.atlassian.net/wiki"
  },
  "parentPage": {
    "id": "123456789",
    "title": "My Project",
    "url": "https://..."
  },
  "pages": {
    "my-doc.md": {
      "pageId": "987654321",
      "title": "My Project: My Doc",
      "url": "https://..."
    }
  },
  "unmapped": [],
  "lastSynced": "2026-03-03"
}

The script updates this file after each successful sync. Do not manually edit page entries unless correcting a known error.

Technical Notes

  • Auth: Confluence REST API v1 with Basic Auth + X-Atlassian-Token: no-check. Some Cloud instances block v2 or require this XSRF bypass.
  • Content format: Markdown converted to Confluence storage format (XHTML) via Python markdown library with tables, fenced code, and TOC extensions.
  • SSL: truststore delegates cert verification to the OS trust store, handling corporate SSL proxies (Zscaler, etc.).
  • Rate limiting: Automatic retry with backoff on 429 and 5xx responses.
  • Sync timestamp: > **Last synced to Confluence**: YYYY-MM-DD injected into the Confluence copy only. Local files are untouched.
  • Versioning: Page versions auto-increment. The script GETs the current version before PUTting.