Guidance for any AI agent working inside this Plugin directory. CLAUDE.md in this directory is a symlink to this file.
unic-confluence is a Claude Code Plugin in the unic-agents-plugins monorepo. It Publishes Markdown files into Confluence pages by injecting rendered HTML into named Injection Zones, via the Confluence v2 REST API. The Plugin ships both as a Claude Code slash command (/unic-confluence) and as a plain Node.js script that Consumers can wire into their own pipelines. See CONTEXT.md for the domain vocabulary (Publish, Injection Zone, Zone Label, Page Map, Page Alias, Auto-aliasing).
Root docs (monorepo-wide conventions live here — pnpm scripts, Gitflow, SemVer, Conventional Commits, code conventions, LICENSE policy, cross-platform requirement):
- Root AGENTS.md — source of truth for cross-cutting rules
- Root CONTEXT.md — monorepo-wide vocabulary (Plugin, Workspace Package, Release, Feature, Consumer)
- Root CONTEXT-MAP.md — index of all bounded contexts in the repo
- Root docs/adr/ — monorepo-wide architecture decisions
- Root docs/process/ — process and workflow guides
This Plugin's own decisions:
- Plugin docs/adr/ — Plugin-specific architecture decisions
Plugin-specific pnpm scripts (run from this directory or with pnpm --filter unic-confluence <script> from the repo root):
pnpm test # run node:test suite over the pure-function library
pnpm typecheck # tsc --noEmit over the Plugin's .mjs sources
pnpm confluence # run the Publish CLI (node scripts/push-to-confluence.mjs)
pnpm bump <patch|minor|major> # bump plugin.json version + promote CHANGELOG
pnpm sync-version # mirror plugin.json version into marketplace.json + package.json
pnpm tag # create the unic-confluence@<version> git tag locally
pnpm verify:changelog # check CHANGELOG entry for the current versionMonorepo-wide commands (pnpm install, pnpm check, pnpm format, pnpm ci:check) are documented in the root AGENTS.md.
.claude-plugin/ # Plugin manifest (plugin.json) and marketplace listing
commands/ # Claude Code slash command definition (unic-confluence.md)
scripts/ # push-to-confluence.mjs (the CLI) and pure-function library
docs/ # Plugin-specific documentation
adr/ # Plugin Architecture Decision Records
Load-bearing invariants. These either originate in a Plugin ADR or are policy decisions that are not obvious from the code.
- Refuse to Publish without Injection Zone markers — unless the legacy anchor-macro path or explicit append fallback applies. The Plugin never silently overwrites a page body. See ADR-0001.
- Three-strategy injection priority. Plain-text Injection Zone markers → legacy anchor macros → append fallback, in that order. The first matching strategy wins. See ADR-0002.
- Structured macro for code blocks. Markdown fenced code blocks render to Confluence
<ac:structured-macro ac:name="code">, not raw<pre>. See ADR-0003. - Dry-run is read-only.
--dry-runnever issues aPUTand never mutates credentials, the Page Map, or any remote state. See ADR-0004. - Ping-check auth, not per-page verify. Authentication is checked once via a lightweight ping; the Plugin does not pre-flight every page id. See ADR-0005.
- Hard HTTP timeout. Every Confluence request runs under a hard timeout so a stalled API call cannot hang the CLI. See ADR-0006.
CliErrorclass for user-facing failures. Recoverable, user-actionable errors throwCliErrorwith an exit code; unexpected errors keep their stack. See ADR-0007.- Pure-functions lib with tests. Markdown→HTML, marker detection, and Page Map mutations are pure functions covered by
node:test. See ADR-0008. - Bare-integer Page id schema. Page Map values are bare integer Confluence page ids, not objects. Any schema change is breaking. See ADR-0009.
- No pnpm catalog for runtime deps. This Plugin pins its own runtime deps directly rather than going through the workspace catalog. See ADR-0010.
- Auto-aliasing on raw-id Publish. A Publish addressed by raw numeric id writes a new Page Alias into the Page Map so the next Publish can use a slug. See ADR-0011.
- Do-not-add scope guard. The list below is canonical and load-bearing — these features have been considered and rejected with reasons. See ADR-0012.
- Confluence v2 REST API at the Consumer's Confluence instance (default
https://uniccom.atlassian.net). - Credentials file at
~/.unic-confluence.json(chmod 600), with fieldsurl,username,token. Overridable per-run viaCONFLUENCE_URL,CONFLUENCE_USER,CONFLUENCE_TOKENenv vars. marked(runtime npm dep, pinned in this Plugin'spackage.json— see ADR-0010). Used to render Markdown to HTML before injection.
These have been considered and explicitly rejected. Open a Feature in the issue tracker with a concrete use case before reopening any of them; expect to overturn ADR-0012.
- Image upload / attachments. Walking the Markdown AST for local image references and uploading via
/wiki/rest/api/content/{id}/child/attachmentis significant work that requires a new subcommand, content-negotiation path, and multi-part form handling. Defer. - Create-page support. The Plugin only updates existing pages. Adding
POST /wiki/api/v2/pageswithspaceId+parentIdforces a schema change to the Page Map (value becomes an object, not a bare integer) and complicates every read path. - Multi-space or cross-instance publishing. Page ids are unique per Confluence instance; multiple instances would need a
baseUrl-per-entry schema and credential routing. - MCP server. The slash command and the CLI are the correct and sufficient surfaces. An MCP server would add lifecycle, transport, and protocol-schema overhead for zero user-visible benefit.
- Agents or sub-agents. Publish is a deterministic one-shot — read file → convert Markdown → GET page → inject → PUT page. There is no branching, no tool selection, no iteration; agent autonomy has no value here.
- Recursive directory Publishing. Publishing all Markdown files under a tree requires mapping every file to a page id, handling partial failures, and defining rollback semantics. The complexity grows faster than the value.
- Changesets / release-please / semantic-release.
@unic/release-toolsis sufficient for one Plugin with two version fields. Do not add a release-management framework. - Watch mode / file-watcher. Confluence is not a live preview target; each Publish increments page version and creates a Confluence revision. Accidental rapid Publishes would pollute revision history.
Plugin-specific architecture decisions live in docs/adr/.