Push and pull markdown to Google Docs and Confluence from a single CLI
Project description
docspan
Push and pull markdown to Google Docs and Confluence from a single CLI. docspan provides bidirectional sync with three-way merge conflict detection, structural diff push that preserves comments on unchanged paragraphs, and a simple YAML-based configuration file.
The config file is named markgate.yaml — this name is preserved for backward compatibility and will be renamed in v0.2.0.
Supported Backends
| Backend | Push | Pull |
|---|---|---|
| Google Docs | yes | yes |
| Confluence | yes | yes |
Install
pip install docspan
Quick start
1. Create markgate.yaml:
backends:
google_docs:
credentials_path: /path/to/service-account.json
mappings:
- local: docs/design-doc.md
backend: google_docs
remote_id: YOUR_GOOGLE_DOC_ID
direction: both
2. Set up authentication:
docspan auth setup google_docs
# or
docspan auth setup confluence
3. Push and pull:
docspan push # push all mappings
docspan pull # pull all mappings
docspan status # show mapping table
4. Resolve conflicts (if any):
docspan conflicts list
docspan conflicts resolve docs/design-doc.md --accept remote
Configuration (markgate.yaml)
backends:
google_docs:
credentials_path: /path/to/service-account.json # or use env ACCOUNT_A_CREDENTIALS_PATH
confluence:
base_url: https://yourorg.atlassian.net
username: you@example.com
api_token: your-api-token # or env CONFLUENCE_API_TOKEN
mappings:
- local: docs/notes.md
backend: google_docs
remote_id: YOUR_GOOGLE_DOC_ID
direction: both # push | pull | both
- local: docs/page.md
backend: confluence
remote_id: YOUR_CONFLUENCE_PAGE_ID
direction: both
Note: markgate.yaml is gitignored by default because it may contain API tokens. Commit a markgate.yaml.example template alongside it.
Command Reference
docspan push
docspan push [FILES]... [--dry-run] [--config PATH]
Push local markdown files to remote docs. Skips mappings with direction = "pull". Accepts an optional list of local file paths to restrict which mappings are pushed.
docspan pull
docspan pull [FILES]... [--dry-run] [--config PATH]
Pull remote documents into local markdown files with three-way merge. Writes conflict markers to the file if automatic merge fails.
docspan status
docspan status [--config PATH]
Display all configured mappings in a table showing local file, backend, remote ID, and direction.
docspan auth setup
docspan auth setup BACKEND [--config PATH]
Interactive authentication setup. BACKEND is one of google_docs or confluence.
For Google Docs, prints step-by-step service account setup instructions. For Confluence, prompts for base URL, username, and API token, then prints a YAML snippet to add to markgate.yaml.
docspan conflicts list
docspan conflicts list [--config PATH]
Scan all tracked files for unresolved merge conflict markers (<<<<<<< ). Prints a table of conflicted files and conflict block counts.
docspan conflicts resolve
docspan conflicts resolve FILE --accept remote|local|merged [--config PATH]
Resolve a merge conflict in a tracked file.
| Strategy | Behavior |
|---|---|
remote |
Re-fetch the remote version and overwrite the local file |
local |
Restore the pre-merge local content from the .orig backup |
merged |
Accept the current file contents as the resolved version (conflict markers must be removed first) |
Configuration Reference
backends.google_docs
| Field | Type | Default | Description |
|---|---|---|---|
credentials_path |
string | null | Path to Google service account JSON key |
token_path |
string | .markgate/google_token.json |
OAuth token storage path |
Environment variable alternatives:
ACCOUNT_A_CREDENTIALS_PATH— path to service account JSONACCOUNT_A_CREDENTIALS— inline service account JSON string
backends.confluence
| Field | Type | Default | Description |
|---|---|---|---|
base_url |
string | null | Confluence base URL, e.g. https://yourorg.atlassian.net |
username |
string | null | Atlassian account email |
api_token |
string | null | API token from id.atlassian.com |
Environment variable alternatives:
CONFLUENCE_BASE_URLATLASSIAN_USER_NAMECONFLUENCE_API_TOKEN
mappings[]
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
local |
string | — | yes | Relative path to local markdown file |
backend |
string | — | yes | "google_docs" or "confluence" |
remote_id |
string | — | yes | Google Doc ID or Confluence page ID |
direction |
enum | "both" |
no | "push", "pull", or "both" |
State Files
docspan generates these files in your project directory after first sync:
| File | Description |
|---|---|
.markgate-state.json |
Sync state tracking (content hashes, remote versions) |
.markgate-base/ |
Content-addressed store of merge bases |
{file}.orig |
Backup of local file before merge; deleted after conflict resolution |
{file}.comments.md |
Confluence comment sidecar; written during pull if comments exist |
Known Limitations
[!NOTE] Known limitations in v0.1.0
- Google Docs: comments on edited paragraphs are lost on push (paragraph-level structural diff; comments on unchanged paragraphs are preserved)
- Push: no image support — local images cannot be pushed to Google Docs or Confluence
- Push: no table support — markdown tables are not rendered in Google Docs
- Confluence: requires an Atlassian API token; no OAuth flow
- Confluence: the comment sidecar (
{file}.comments.md) is informational only; comments cannot be pushed back
License
MIT. See LICENSE for details.
For contribution guidelines, see CONTRIBUTING.md. For the full change history, see CHANGELOG.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docspan-0.1.0.tar.gz.
File metadata
- Download URL: docspan-0.1.0.tar.gz
- Upload date:
- Size: 360.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f96225937da1234d7b1e0bcd792ce23ee892e0fdf53819afaa102d4f9211d1c
|
|
| MD5 |
221f3c28142b86f2314e38eb0c4bd559
|
|
| BLAKE2b-256 |
a1d97cf4d5a31e9475d6abc181df7d81abbea3bee9d945ab9b61cb92b53dd248
|
Provenance
The following attestation bundles were made for docspan-0.1.0.tar.gz:
Publisher:
publish.yml on tstapler/docspan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docspan-0.1.0.tar.gz -
Subject digest:
0f96225937da1234d7b1e0bcd792ce23ee892e0fdf53819afaa102d4f9211d1c - Sigstore transparency entry: 1769750878
- Sigstore integration time:
-
Permalink:
tstapler/docspan@81d9c9925767800b41dbbbd317ddcd17ffaf6b39 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tstapler
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@81d9c9925767800b41dbbbd317ddcd17ffaf6b39 -
Trigger Event:
release
-
Statement type:
File details
Details for the file docspan-0.1.0-py3-none-any.whl.
File metadata
- Download URL: docspan-0.1.0-py3-none-any.whl
- Upload date:
- Size: 148.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56c2eea2066050ed3814c843884a3fed29acff8a9ad88fa9157ecc1ffcdf556b
|
|
| MD5 |
81b274b8cbc8f6397370452683b98bc7
|
|
| BLAKE2b-256 |
80d22df7e6d60caf7706034c73767853d07dc1924dc4831931c11c52edbdbef0
|
Provenance
The following attestation bundles were made for docspan-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on tstapler/docspan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docspan-0.1.0-py3-none-any.whl -
Subject digest:
56c2eea2066050ed3814c843884a3fed29acff8a9ad88fa9157ecc1ffcdf556b - Sigstore transparency entry: 1769750915
- Sigstore integration time:
-
Permalink:
tstapler/docspan@81d9c9925767800b41dbbbd317ddcd17ffaf6b39 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tstapler
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@81d9c9925767800b41dbbbd317ddcd17ffaf6b39 -
Trigger Event:
release
-
Statement type: