Sync
Bidirectional synchronization between local markdown files and Confluence pages.
Prerequisites
Section titled “Prerequisites”- Authenticated profile with Confluence access (
atlcli auth login) - Space permission: View for pull, Edit for push operations
- Initialized sync directory (
atlcli wiki docs init)
Overview
Section titled “Overview”atlcli provides powerful sync capabilities:
- Watch: Real-time bidirectional sync with file watching and remote polling
- Pull: Download Confluence pages as markdown
- Push: Upload local changes to Confluence
- Conflict resolution: Three-way merge with automatic and manual resolution
Initialize
Section titled “Initialize”Set up a directory for sync:
atlcli wiki docs init ./docs --space TEAMOptions:
| Flag | Description |
|---|---|
--space | Space key (required) |
--page-id | Sync single page by ID |
--ancestor | Sync tree under specific page |
Scope Options
Section titled “Scope Options”# Sync entire spaceatlcli wiki docs init ./docs --space TEAM
# Sync specific page treeatlcli wiki docs init ./docs --ancestor 12345
# Sync single page onlyatlcli wiki docs init ./docs --page-id 12345Watch Mode
Section titled “Watch Mode”The most powerful sync mode - automatically syncs changes in real-time using file watching and remote polling:
atlcli wiki docs sync ./docsHow Watch Mode Works
Section titled “How Watch Mode Works”Watch mode combines two mechanisms for bidirectional sync:
- Local file watching: Detects changes to local markdown files instantly
- Remote polling: Periodically checks Confluence for remote changes
sequenceDiagram participant L as Local Files participant A as atlcli sync participant C as Confluence
Note over L,C: Bidirectional Sync Flow
L->>A: File changed (watched) A->>C: Push to remote C-->>A: OK
loop Every 30s (configurable) A->>C: Poll for changes C-->>A: Changed pages end
A->>L: Pull if changedSync Command Options
Section titled “Sync Command Options”atlcli wiki docs sync <dir> [options]| Flag | Description |
|---|---|
--space <key> | Sync entire space |
--ancestor <id> | Sync page tree under parent ID |
--page-id <id> | Sync single page |
--poll-interval <ms> | Remote polling interval (default: 30000) |
--no-poll | Disable remote polling (local watch only) |
--no-watch | Disable file watching (poll only) |
--on-conflict <mode> | Conflict handling: merge, local, remote |
--auto-create | Auto-create pages for new local files |
--label <label> | Only sync pages with this label |
--dry-run | Preview changes without syncing |
--json | JSON line output for scripting |
Polling
Section titled “Polling”The poller periodically checks Confluence for changes. Efficiency depends on sync scope:
| Scope | API Calls | Best For |
|---|---|---|
--page-id | Minimal (1 page) | Editing single document |
--ancestor | Moderate (tree) | Working on a section |
--space | Higher (all pages) | Full documentation sync |
# Poll single page (most efficient)atlcli wiki docs sync ./docs --page-id 12345
# Poll page treeatlcli wiki docs sync ./docs --ancestor 12345
# Poll entire spaceatlcli wiki docs sync ./docs --space TEAMPolling Events
Section titled “Polling Events”The poller detects three types of remote changes:
| Event | Description | Action |
|---|---|---|
created | New page added in scope | Pull to local |
changed | Page content or title updated | Pull or merge |
deleted | Page removed from scope | Notify user |
Configuring Poll Interval
Section titled “Configuring Poll Interval”# Fast polling (every 10 seconds) - more API callsatlcli wiki docs sync ./docs --poll-interval 10000
# Slow polling (every 2 minutes) - fewer API callsatlcli wiki docs sync ./docs --poll-interval 120000
# Disable remote polling entirelyatlcli wiki docs sync ./docs --no-pollNote: Lower intervals mean faster remote change detection but more API requests. The default (30 seconds) balances responsiveness with API usage.
Webhooks
Section titled “Webhooks”For instant remote change detection without polling overhead, use webhooks:
atlcli wiki docs sync ./docs \ --webhook-port 8080 \ --webhook-url https://your-server.com:8080/webhook| Flag | Description |
|---|---|
--webhook-port | Local webhook server port |
--webhook-url | Public URL to register with Confluence |
Webhook Events:
The webhook server handles these Confluence events:
| Event | Description |
|---|---|
page_created | New page created |
page_updated | Page content changed |
page_removed | Page deleted |
page_trashed | Page moved to trash |
page_restored | Page restored from trash |
page_moved | Page moved to different parent |
Webhooks vs Polling:
| Feature | Polling | Webhooks |
|---|---|---|
| Latency | 0-30s (configurable) | Instant |
| Setup | None | Requires public URL |
| API usage | Regular requests | On-demand only |
| Reliability | Always works | Requires connectivity |
| Filtering | By scope | By page ID and space |
For local development, use polling. For production servers with public URLs, webhooks provide better performance.
Auto-Create Pages
Section titled “Auto-Create Pages”Create Confluence pages automatically for new local files:
atlcli wiki docs sync ./docs --space TEAM --auto-createAuto-create triggers in two scenarios:
- During initial sync: atlcli creates untracked local files (no frontmatter ID) as new pages
- During file watching: New files added while sync is running are automatically created
How it works:
| Aspect | Behavior |
|---|---|
| Title | From frontmatter title, or filename converted to title case |
| Parent | Space home page (for --space) or ancestor (for --ancestor) |
| Content | Full markdown content converted to Confluence storage format |
Example workflow:
# Start sync with auto-createatlcli wiki docs sync ./docs --space TEAM --auto-create
# In another terminal, create a new fileecho "# My New Feature" > ./docs/my-new-feature.md
# Sync automatically:# 1. Detects new file# 2. Creates page "My New Feature" in Confluence# 3. Updates local file with frontmatter containing page IDAfter auto-create, the file is updated with frontmatter:
---atlcli: id: "12345678" title: "My New Feature"---
# My New FeatureLock File
Section titled “Lock File”When sync runs, atlcli creates a lock file at .atlcli/.sync.lock. This:
- Prevents concurrent sync operations
- Signals to other tools that sync is active
- Is automatically removed on clean shutdown
Download pages from Confluence to local markdown files:
atlcli wiki docs pull ./docsOptions:
| Flag | Description |
|---|---|
--space | Filter by space key |
--page-id | Pull specific page |
--ancestor | Pull page tree |
--label | Filter by label |
--force | Overwrite local modifications |
--comments | Export comments to sidecar files |
--no-attachments | Skip downloading attachments |
--limit <n> | Maximum pages to pull |
Examples
Section titled “Examples”# Pull using saved scope from initatlcli wiki docs pull ./docs
# Pull pages with specific labelatlcli wiki docs pull ./docs --label api-docs
# Pull with comments exportedatlcli wiki docs pull ./docs --comments
# Force pull (overwrite local changes)atlcli wiki docs pull ./docs --force
# Pull without attachmentsatlcli wiki docs pull ./docs --no-attachmentsComments Export
Section titled “Comments Export”When using --comments, page comments are saved to sidecar files:
docs/├── architecture.md├── architecture.comments.json # Comments for architecture.md└── api-reference.mdThe comments file contains both footer comments and inline comments with their full thread hierarchy.
Upload local changes to Confluence:
atlcli wiki docs push ./docsOptions:
| Flag | Description |
|---|---|
--page-id <id> | Push specific page by ID |
--validate | Run validation before push |
--strict | Treat warnings as errors |
--json | JSON output |
Examples
Section titled “Examples”# Push all tracked filesatlcli wiki docs push ./docs
# Push single fileatlcli wiki docs push ./docs/page.md
# Push by page IDatlcli wiki docs push --page-id 12345
# Validate before pushingatlcli wiki docs push ./docs --validate
# Strict validation (fail on warnings)atlcli wiki docs push ./docs --validate --strictValidation
Section titled “Validation”Pre-push validation checks for:
| Check | Severity | Description |
|---|---|---|
| Broken links | Error | Target file not found |
| Untracked pages | Warning | Link to page without ID |
| Unclosed macros | Error | :::info without closing ::: |
| Page size | Warning | Content exceeds 500KB |
# Run validation separatelyatlcli wiki docs check ./docs
# Strict mode (warnings are errors)atlcli wiki docs check ./docs --strict
# JSON output for CI/scriptsatlcli wiki docs check ./docs --jsonAdd a new local file to Confluence tracking:
atlcli wiki docs add <file> [options]| Flag | Description |
|---|---|
--title <t> | Page title (default: from H1 or filename) |
--parent <id> | Parent page ID |
--template <name> | Use template for initial content |
# Add file with auto-detected titleatlcli wiki docs add ./docs/new-page.md
# Add with specific parentatlcli wiki docs add ./docs/guide.md --parent 12345
# Add using a templateatlcli wiki docs add ./docs/meeting.md --template meeting-notesCompare local file with remote Confluence page:
atlcli wiki docs diff <file>Shows unified diff with colored output:
- Green: additions (local has, remote doesn’t)
- Red: deletions (remote has, local doesn’t)
- Cyan: file headers and hunk markers
# Compare single fileatlcli wiki docs diff ./docs/api-reference.md
# JSON output with statisticsatlcli wiki docs diff ./docs/api-reference.md --jsonConflict Resolution
Section titled “Conflict Resolution”Detection
Section titled “Detection”atlcli detects conflicts when:
- Local file was modified since last sync
- Remote page was modified since last sync
Conflict detected: docs/api.md Local: Modified 2025-01-14 10:30 (version 5 → local changes) Remote: Modified 2025-01-14 10:35 (version 5 → version 6)Resolution Strategies
Section titled “Resolution Strategies”Control how conflicts are handled in sync mode:
atlcli wiki docs sync ./docs --on-conflict <strategy>| Strategy | Behavior |
|---|---|
merge | Attempt three-way merge (default) |
local | Keep local version, overwrite remote |
remote | Keep remote version, overwrite local |
Three-Way Merge
Section titled “Three-Way Merge”With --on-conflict merge, atlcli attempts automatic merging:
- Uses the common ancestor (base) version
- Computes diffs from both local and remote
- Merges non-conflicting changes
- Marks conflicting sections with markers
Conflict Markers
Section titled “Conflict Markers”When merge cannot auto-resolve, conflict markers are inserted:
## API Reference
<<<<<<< LOCALThis endpoint returns user data in JSON format.=======This endpoint returns user data. Response format is JSON.>>>>>>> REMOTE
### AuthenticationResolving Conflicts
Section titled “Resolving Conflicts”# Edit file to resolve conflicts manuallyvim docs/api.md
# Then resolve with chosen strategyatlcli wiki docs resolve docs/api.md --accept localatlcli wiki docs resolve docs/api.md --accept remoteatlcli wiki docs resolve docs/api.md --accept merged # After manual editStatus
Section titled “Status”Check sync status of all tracked files:
atlcli wiki docs status ./docsOutput:
Sync status for ./docs:
synced: 12 files local-modified: 2 files remote-modified: 1 files conflict: 1 files untracked: 3 files
Last sync: 2025-01-14T10:30:00Z
Modified: api-reference.md (local changes) getting-started.md (remote changes)
Conflicts: troubleshooting.mdOptions:
| Flag | Description |
|---|---|
--json | JSON output |
Ignore Patterns
Section titled “Ignore Patterns”Create .atlcliignore to exclude files from sync:
# .atlcliignore (gitignore syntax)
# Ignore draftsdrafts/*.draft.md
# Ignore specific filesinternal-notes.md
# Ignore by patterntemp-*.md
# Negation (include despite earlier rule)!important-draft.mdDefault ignores (always excluded):
.atlcli/- sync state directory*.meta.json- legacy metadata files*.base- base versions for merge.git/- git directorynode_modules/- node dependencies
Note: Patterns from .gitignore are also respected and merged with .atlcliignore.
Directory Structure
Section titled “Directory Structure”After init and pull:
docs/├── .atlcli/│ ├── config.json # Sync configuration│ ├── state.json # Sync state (versions, timestamps)│ ├── .sync.lock # Lock file (when sync running)│ └── cache/ # Base versions for 3-way merge│ └── 12345.md # Base content by page ID├── getting-started.md├── api-reference.md├── api-reference.attachments/│ └── diagram.png # Attachments for api-reference.md├── guides/│ ├── installation.md│ └── configuration.md├── .atlcliignore # Ignore patterns└── .gitignore # Git ignore (also respected)State File
Section titled “State File”.atlcli/state.json tracks sync state per page:
{ "lastSync": "2025-01-14T10:00:00Z", "pages": { "12345": { "path": "api-reference.md", "title": "API Reference", "version": 5, "localHash": "abc123", "remoteHash": "abc123", "baseHash": "abc123", "syncState": "synced", "parentId": "12340", "ancestors": ["12340", "12300"] } }}File Format
Section titled “File Format”Local files use YAML frontmatter with the atlcli namespace:
---atlcli: id: "12345" title: "API Reference"---
# API Reference
Content here...The frontmatter fields:
| Field | Required | Description |
|---|---|---|
id | Yes | Confluence page ID (set automatically on pull/create) |
title | No | Page title override (defaults to first H1 heading) |
See File Format for details.
Hierarchy Handling
Section titled “Hierarchy Handling”atlcli maps Confluence page hierarchy to directory structure:
Confluence: Local:├── Parent Page ├── parent-page.md│ ├── Child A ├── parent-page/│ │ └── Grandchild │ ├── child-a.md│ └── Child B │ ├── child-a/ │ │ └── grandchild.md │ └── child-b.mdWhen pages move in Confluence, sync detects this and moves local files to match.
Folders
Section titled “Folders”atlcli supports Confluence Cloud folders (introduced September 2024):
Confluence: Local:├── My Folder (folder) ├── my-folder/│ ├── Page A │ ├── index.md (type: folder)│ └── Page B │ ├── page-a.md │ └── page-b.mdatlcli represents folders as directories with an index.md file containing type: folder in frontmatter. See Folders for full details on folder support and limitations.
JSON Output
Section titled “JSON Output”Most commands support --json for scripting:
atlcli wiki docs status ./docs --json{ "schemaVersion": "1", "dir": "./docs", "stats": { "synced": 12, "localModified": 2, "remoteModified": 1, "conflict": 1, "untracked": 3 }, "lastSync": "2025-01-14T10:00:00Z"}Sync command emits JSON lines (one event per line):
atlcli wiki docs sync ./docs --json{"schemaVersion":"1","type":"status","message":"Starting initial sync..."}{"schemaVersion":"1","type":"pull","file":"api-reference.md","pageId":"12345","message":"Pulled: API Reference"}{"schemaVersion":"1","type":"push","file":"guide.md","pageId":"12346","message":"Pushed: Guide"}Best Practices
Section titled “Best Practices”- Use watch mode for real-time collaboration on documentation
- Use labels to sync subsets of pages (
--label architecture) - Enable webhooks for production servers with public URLs
- Commit to Git - track markdown files in Git for version history
- Use
.atlcliignorefor drafts and local-only content - Run validation before pushing (
--validate)
Troubleshooting
Section titled “Troubleshooting”Lock File Issues
Section titled “Lock File Issues”If sync fails due to lock:
# Check if sync is runningps aux | grep "atlcli wiki docs sync"
# Force remove stale lock (only if no sync is active)rm ./docs/.atlcli/.sync.lockMerge Conflicts
Section titled “Merge Conflicts”If you get stuck in merge conflicts:
# Reset to remote versionatlcli wiki docs pull ./docs --force
# Or force push local versionatlcli wiki docs resolve ./docs/file.md --accept localatlcli wiki docs push ./docsPermission Errors
Section titled “Permission Errors”Error: You don't have permission to edit page 12345Check your Confluence permissions for the space/page.
Rate Limiting
Section titled “Rate Limiting”If you see 429 errors, increase poll interval:
atlcli wiki docs sync ./docs --poll-interval 60000Related Topics
Section titled “Related Topics”- File Format - Frontmatter structure and directory conventions
- Ignore Patterns - Exclude files from sync with
.atlcliignore - Validation - Pre-push validation rules
- Attachments - Sync images and file attachments
- Webhooks - Real-time sync without polling
- Pages - Direct page operations (create, move, delete)