Skip to content

feat(docs): add read and edit commands for Google Docs#370

Open
danhayman wants to merge 1 commit intosteipete:mainfrom
danhayman:feat/docs-read-edit
Open

feat(docs): add read and edit commands for Google Docs#370
danhayman wants to merge 1 commit intosteipete:mainfrom
danhayman:feat/docs-read-edit

Conversation

@danhayman
Copy link

@danhayman danhayman commented Feb 25, 2026

Summary

  • Add gog docs read — reads a Google Doc as plain text with character-based --offset and --limit
    for paging through large documents
  • Rewrite gog docs edit — find-and-replace with --old/--new that requires the match to be unique by
    default, preventing accidental edits (use --replace-all to override). Adds --dry-run, escape sequences,
    and --no-match-case.

Motivation

My family uses Google Docs for shared lists and notes, and when I tried using an AI agent to help manage them
via gog, it struggled — there was no structured way to read a doc with pagination or safely edit specific
text. The existing find-replace replaces all occurrences with no uniqueness check, which is risky for
automated use.

These commands are modelled on ox-cli (my CLI for editing local Office
documents) so that agents can use a consistent interface across both local and Google Docs. read gives you
plain text with character-based pagination for large documents, and edit requires a unique match so you
don't accidentally change the wrong thing.

This PR complements #359 (docs sed) rather than replacing it — edit is the simple "Find and Replace" for
agents that just need --old "X" --new "Y", while sed is the power tool for regex and multi-operation
pipelines.

New commands

## Read document content
gog docs read <docId>

## Page through a large doc (character-based offset/limit)
gog docs read <docId> --offset 5000 --limit 2000

## Read as JSON (includes totalChars for pagination logic)
gog docs read <docId> --json

## Safe edit — errors if "old text" isn't unique
gog docs edit <docId> --old "old text" --new "new text"

## Replace all occurrences
gog docs edit <docId> --old "foo" --new "bar" --replace-all

## Preview without modifying
gog docs edit <docId> --old "foo" --new "bar" --dry-run

## Case-insensitive matching
gog docs edit <docId> --old "Hello" --new "hi" --no-match-case --replace-all

## Escape sequences in --old/--new
gog docs edit <docId> --old "line1" --new "line1\nline2"

## Delete text (empty --new)
gog docs edit <docId> --old "remove this" --new ""

Test plan

  • Unit tests for helpers (applyCharWindow, countOccurrences, unescapeString)
  • Integration tests for read (plain text, character offset/limit, offset-only, limit-only, offset past
    end, JSON output)
  • Integration tests for edit (unique replacement, not-unique error, not-found error, --replace-all,
    JSON output, --dry-run, --dry-run JSON, deletion, escape sequences, --no-match-case)
  • All existing docs tests pass (no regressions)
  • Updated upstream docs_edit_test.go field references to match renamed struct fields

@visionik
Copy link
Collaborator

Hi Dan - Thank you for the contribution.

Can you take a look at #359 which I wrote (and just merged). It adds a flexible sed-syntax based document editing and formatting tool to gogcli. It's designed to be consistent across Google docs, sheets, slides, etc; and also across mogcli (the microsoft version of gogcli) and sogcli (the standards version of gogcli)

I'm trying to 1. keep gog from have 5 different ways to edit docs and 2. have document editing features which will work across all three plugins.

I'd like your opinion on what you think would be best:

  1. You think the above sed PR removes the need for your changes
  2. You think your PR should be re-written to use the PR's sed/sedmat capabilities underneath
  3. You think I should still merge your PR as-is.

Very much appreciated!

@danhayman
Copy link
Author

Sorry @visionik, I lost this amongst all my work noise
Great you were thinking about the same problem. I'll get back to you asap

- Add `docs read` with character-based --offset/--limit pagination
- Rewrite `docs edit` to use --old/--new with uniqueness enforcement,
  --replace-all, --dry-run, escape sequences, and --no-match-case
- Align error messages and output format with ox-cli
- Fix upstream test references to renamed struct fields
@danhayman danhayman force-pushed the feat/docs-read-edit branch from f759477 to aef903e Compare March 3, 2026 07:22
@danhayman
Copy link
Author

Thanks for the thoughtful response
I was actually working on this branch this as I had some further thoughts on it which is why I finally noticed it

Your PR is really interesting. I might look at adding it to another tool I'm working on.

I was trying to make add commands agents need to work effectively

docs read is entirely new — sed doesn't cover reading at all. Pagination (--offset/--limit)
is important for AI agents to be able to find the context they want without having to take everything

I think docs edit complements sed rather than competing with it — they serve different audiences. edit is the "Find
and Replace" dialog; sed is sed. For an AI agent that just needs to swap one string for another, --old "foo"
--new "bar" is much safer than constructing s/foo/bar/ where you have to worry about delimiter escaping and
regex metacharacters. The uniqueness enforcement and --dry-run are designed for automated use
where you want to fail loudly rather than silently replace the wrong thing.

On the consolidation concern — I agree you don't want 5 ways to edit docs. I'd argue edit could replace the existing find-replace hat way the count stays
the same rather than growing.

I'm all for reusing code, but I don't see too much scope for this building on top of sed. Edit has to fetch the doc first for uniqueness checking.

I've updated the PR description and rebased onto current main.

Let me know your thoughts. And thanks for your time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants