gdsync Docs

gdsync Documentation

Everything you need to read and edit Google Docs from the command line — built for AI agents, usable by anyone.

Overview

gdsync mirrors a Google Doc to a local file. You (or an AI agent) edit that file, run one command, and the changes appear in the live document. The sync engine handles all the Google Docs API complexity — character indexes, named ranges, formatting, tables, lists, images, and comments.

gdsync fetch    # pull the Google Doc into content.txt
# edit content.txt
gdsync commit   # push your changes to the live doc, and verify

Your documents are accessed through your own Google Cloud project — gdsync's infrastructure never has ongoing access to your files. The only setup cost is a one-time, guided project creation.

New to gdsync? Work top-to-bottom: InstallSet upAuthenticateOpen a docEdit.

Install

npm install -g @gdsync/gdsync

Requires Node.js 18 or newer. Verify the install:

gdsync --version

1. Set up a GCP project

gdsync accesses Google Docs through a Google Cloud project that belongs to you. Run the guided wizard once:

gdsync setup          # prints a setup URL, then exits
gdsync setup check    # confirm setup is complete

The wizard opens in your browser and walks you through:

  1. Signing in with a Google account (we recommend a dedicated agent account, e.g. my-agent@gmail.com).
  2. Creating (or reusing) a Google Cloud project and enabling the Docs & Drive APIs.
  3. Creating an OAuth client — choose Web application and add https://auth.gdsync.dev/callback as an authorized redirect URI. When the credentials pop up, click Download JSON, then OK, and paste/upload them into the wizard.
Exit codes for setup check: 0 = complete, 1 = still pending (finish the browser steps), 2 = the session expired (run gdsync setup again).

Manual setup

Prefer to do it entirely by hand, or already have a project? Use the step-by-step guide:

gdsync setup manual

This never touches your Google Cloud account automatically — it just shows you what to create, and detects credentials you place at ~/.gdsync/client_secret.json or set via the GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET environment variables.

2. Authenticate

Once setup is done, sign in for document access:

gdsync auth           # prints a sign-in URL, then exits
gdsync auth check     # validate the sign-in (checks the live token)
gdsync logout         # sign out — clears the token, keeps your setup

Sign in with the account you want the agent to act as. It can only access documents that are shared with that account. Document access uses your own project's OAuth client — gdsync's app is never in the loop for your document data.

Sign-ins expire periodically — Google revokes OAuth refresh tokens after 7 days for apps still in "Testing" publishing status. When that happens, gdsync auth check reports it and gdsync clears the dead token automatically; just run gdsync auth again to reconnect (no manual reset). Use gdsync auth --force to re-authenticate at any time.

3. Open a document

List the documents your account can reach, then initialize a sync session:

gdsync docs                     # list accessible docs
gdsync docs --search "keyword"  # filter by name
gdsync init --doc <documentId>  # start editing (auth + first fetch)

The document ID is the long string in the doc's URL: https://docs.google.com/document/d/THIS_PART/edit.

If a doc isn't listed, share it with the account you authenticated as.

init creates a working directory layout:

content.txt        ← the file you edit
comments.txt       ← open comment threads (read-only)
assets/            ← images live here
.gdsync            ← doc config
.gdsync-session    ← block map & sync state

The editing loop

Every edit follows the same four steps, in order:

  1. Fetchgdsync fetch pulls the latest document state into content.txt. Always fetch before editing.
  2. Edit — change content.txt with any editor.
  3. Commitgdsync commit pushes your changes and re-verifies against the live doc.
  4. Confirm — commit reports what changed and whether verification passed.

Check pending changes any time with gdsync status. If things ever look out of sync, gdsync reset clears local state and re-fetches clean.

One fetch–edit–commit cycle at a time. Don't leave edits uncommitted across fetches.

Content file format

After a fetch, content.txt is a sequence of blocks. Each block is a paragraph, list item, table, or image, separated by a delimiter line:

---blk_1 paragraph---
# Document Title

---blk_2 paragraph---
A normal paragraph with **bold** and *italic* text.

---blk_3 list_item---
- First bullet

---blk_4 table---
| Name | Role |
| --- | --- |
| Alice | Engineer |

The blk_N IDs and type tokens are assigned by gdsync. You edit the content between delimiters. To change the structure:

ActionHow
Edit contentChange the text under a block's delimiter.
Add a blockInsert a bare --- delimiter (no ID) where you want new content.
Delete a blockRemove its delimiter and content.
ReorderMove a block's delimiter + content to a new position.
Don't change the type tokens or assign your own block IDs — use a bare --- for new blocks and let gdsync assign IDs.

Paragraphs & headings

Plain text is a paragraph. Prefix with # markers for headings:

---
# Heading 1

---
## Heading 2

---
### Heading 3

---
Just a normal paragraph.

Inline formatting

These work anywhere text appears — paragraphs, list items, and table cells:

SyntaxResult
**bold**bold
*italic*italic
`code`monospace / code
[text](https://url)a link

Lists

Use - for bullets and 1. for numbered lists. Each item is its own block. Indent by two spaces per level to nest:

---
- Top-level bullet

---
- Another bullet
  - Nested bullet

---
1. First numbered item

---
2. Second numbered item

Tables

Tables use standard markdown: a header row, a | --- | separator, then data rows.

---
| Name | Role | Team |
| --- | --- | --- |
| Alice | Engineer | Core |
| Bob | Designer | UX |

Editing cells

Just change the cell text and commit. You can edit one cell, several, or all at once.

Formatting inside cells

Cells support the same inline formatting as everywhere else:

| Field | Value |
| --- | --- |
| **bold label** | plain value |
| link | [docs](https://gdsync.dev/docs) |

Adding & removing rows and columns

Edit the markdown grid directly — add or delete rows and columns, and gdsync applies the new shape (existing cell content and formatting are preserved):

# add a column and a row:
| Name | Role | Team |          →   | Name | Role | Team | Location |
| --- | --- | --- |               | --- | --- | --- | --- |
| Alice | Engineer | Core |        | Alice | Engineer | Core | NYC |
                                    | Bob | Designer | UX | LA |

Pipes in cell text

To include a literal | inside a cell, escape it as \|:

| Expression | Meaning |
| --- | --- |
| a \| b | a or b |
Complex tables (merged cells, multi-paragraph cells, nested tables) are marked readonly and can't be edited through gdsync — edit those directly in Google Docs.

Images

Images appear as markdown image references pointing into the assets/ folder:

---
![alt text](assets/img_001.png)

To add an image, place the file in assets/ first, then reference it. The file must exist before you commit.

Comments

Open comment threads appear in comments.txt (read-only) after a fetch, each with a thread ID, the block it's anchored to, and the highlighted text:

[#AAAABx3k0Bw | blk_2 | "the highlighted text"]
Reviewer (2026-07-20): Can you add a citation here?

Act on comments with CLI commands:

gdsync comment reply <threadId> "Done — added the citation."
gdsync comment create <blockId> "Needs a source." --anchor "grew 40%"
gdsync comment resolve <threadId> --reply "Fixed."
Recommended for agents: reply, don't resolve — let the human review and resolve in Google Docs. Enable gdsync config comment_filter on to only see threads that @mention the agent's account.

Edit modes

Auto (default) applies changes directly to the document. Suggestions mode is a visual review preview — old/removed text is struck through and new text is shown in red. The Google Docs API can't create native suggestions, so this is a simulation, not Google's "Suggesting" mode (there are no Accept/Reject buttons).

gdsync config mode suggestions
gdsync config mode auto
After a suggestions commit, the document shows both versions. On the next fetch, the struck-through old text appears as ~~...~~ in content.txt. To accept a change, delete the struck-through block; to reject it, delete the new text.

Configuration

gdsync config                      # view current settings
gdsync config mode auto            # or: suggestions
gdsync config comment_filter on    # or: off (only @mentioned comments)

CLI reference

CommandDescription
gdsync setupSet up your GCP project (guided wizard)
gdsync setup manualManual GCP project setup guide
gdsync setup checkCheck whether setup is complete
gdsync authAuthenticate for document access (auto re-auths if the token is revoked; --force to always re-auth)
gdsync auth checkValidate the sign-in (detects a revoked/expired token)
gdsync logoutSign out — clear stored credentials (keeps your setup; --backup to save a copy)
gdsync docsList accessible Google Docs
gdsync docs --search "x"Search docs by name
gdsync init --doc <id>Initialize a sync session (auth + fetch)
gdsync fetchPull the latest doc into content.txt
gdsync commitPush content.txt changes and verify
gdsync statusShow pending changes and sync state
gdsync resetClear local state and re-fetch clean
gdsync configView or change settings
gdsync comment reply <id> "msg"Reply to a comment thread
gdsync comment create <blk> "msg"Create a comment (optionally --anchor)
gdsync comment resolve <id>Resolve a thread (optionally --reply)

Error recovery

ProblemFix
"Not set up"Run gdsync setup, then gdsync setup check.
"Not authenticated"Run gdsync auth, then gdsync auth check.
Sign-in expired / revokedGoogle expires refresh tokens after 7 days for apps in "Testing" status. gdsync auto-clears the dead token — just run gdsync auth again (or gdsync logout then gdsync auth). No setup needed.
OAuth client removed / deleted_clientThe OAuth client itself was deleted — re-run gdsync setup then gdsync auth.
Commit failedRead the error, fix the content, and gdsync commit again.
Content looks wronggdsync fetch to pull the current state, or gdsync reset to start clean.
Doc not listedShare the document with the authenticated account.
Table won't edit (readonly)It's a complex table — edit it directly in Google Docs.

For AI agents

gdsync is designed to be driven by an AI agent. The agent runs the CLI itself and only hands a URL to a human for the browser-gated steps (project setup and sign-in). Because setup and auth print a URL and exit — no blocking processes — the agent can surface the link, wait, then continue.

The quickest way to teach an agent the full workflow is the skill package:

Download gdsync-skill.zip — add it to Claude Code or any agent that supports skills.

The local file format (blocks, delimiters, IDs) is agent-internal — agents should talk to users about the Google Doc, not about content.txt.