Skip to content

feat: add --meta flag for document metadata#5

Open
ScotterC wants to merge 1 commit intofamasya:mainfrom
ScotterC:feature/meta-flag
Open

feat: add --meta flag for document metadata#5
ScotterC wants to merge 1 commit intofamasya:mainfrom
ScotterC:feature/meta-flag

Conversation

@ScotterC
Copy link
Copy Markdown
Contributor

@ScotterC ScotterC commented Apr 7, 2026

Summary

  • Adds --meta flag that displays document title, ID, revision ID, and all tabs (with nesting and emoji support)
  • Primary use case: discovering tab IDs so you can fetch specific tabs with ?tab=t.xxx
  • Additional metadata (owner, dates) would require expanding OAuth scopes to include Drive API, which felt out of scope for the value gained

Usage

gdocs-cli --meta --url="https://docs.google.com/document/d/DOC_ID/edit"
Title:       My Document
Document ID: 1Ro-tGD0QIELOvSnImOjXYHVJVFOKIM2W1US0U9K7-M4
Revision ID: AMHacu6CKySB2WsaQ67lgu...

Tabs (3):
  The Expert      (tab=t.0)
  The Operator    (tab=t.6gq1zo4mqqxa)
  The Builder     (tab=t.1im74sm5cgwv)

Test plan

  • All existing tests pass
  • --meta correctly lists tabs for multi-tab documents
  • Documents with no emoji on tabs render cleanly
  • Backward compatible — no changes to existing flags

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Introduced a --meta flag that displays document metadata (title, document ID, and revision ID) instead of converting to markdown.
    • Tab information now displays with visual formatting including indentation levels and emoji indicators for improved document navigation.

Adds a --meta flag that displays document title, ID, revision, and all
tabs with their IDs. Useful for discovering tab IDs before fetching
specific tab content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

A new --meta flag enables document metadata display without standard conversion. The feature fetches Google Docs content and renders title, document ID, revision ID, and a hierarchical tab list with formatting. Supporting infrastructure adds tab metadata extraction and traversal utilities to the client package.

Changes

Cohort / File(s) Summary
Metadata CLI Interface
cmd/gdocs-cli/main.go
Introduces --meta flag that bypasses normal --url validation and invokes showMeta(...) function to fetch and render document metadata including title, document ID, revision ID, and formatted tab hierarchy with emoji indicators.
Tab Metadata Structures and Functions
internal/gdocs/client.go
Adds exported TabInfo struct to represent tab metadata (ID, Title, Emoji, Depth) and ListTabs(...) function to traverse document tab tree and return flat slice of tab entries with nesting depth, including recursive helper collectTabs.

Sequence Diagram

sequenceDiagram
    participant User as User/CLI
    participant Main as main.showMeta
    participant Auth as OAuth Authenticator
    participant Docs as Google Docs API
    participant Client as gdocs.Client
    participant Render as Tab Renderer

    User->>Main: --meta flag with URL
    Main->>Main: Extract document ID from URL
    Main->>Auth: Create authenticator & client
    Auth->>Docs: OAuth flow
    Docs-->>Auth: Auth token
    Auth-->>Main: Ready
    Main->>Client: Fetch document
    Client->>Docs: Get document
    Docs-->>Client: Document with tabs
    Client-->>Main: docs.Document
    Main->>Render: ListTabs(document)
    Render->>Render: collectTabs (recursive)
    Render-->>Main: []TabInfo
    Main->>Main: Format & print metadata
    Main-->>User: Display title, ID, tabs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: add support for Google Docs tabs #3: Adds complementary tab-handling utilities (FindTab, GetFirstTab) and URL tab extraction/conversion support that work alongside the new ListTabs metadata extraction introduced here.

Poem

🐰 A meta flag hops into view,
Tabs now dance in structured groove,
Emoji-marked with depth so true,
Metadata blooms, the docs approve! 📄✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a --meta flag for displaying document metadata. It is concise, clear, and directly related to the primary feature introduced in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
cmd/gdocs-cli/main.go (1)

197-249: Move metadata fetch/format logic out of main.go.

showMeta currently performs business logic (data shaping + rendering loop) inside the CLI entrypoint file. Consider moving this to an internal package/service and keeping main.go focused on orchestration.

As per coding guidelines: "CLI entry point should contain no business logic, only flag parsing and orchestration".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/gdocs-cli/main.go` around lines 197 - 249, The showMeta function in
main.go contains business logic (fetching, shaping and rendering metadata) that
should be moved into an internal package; create a new service (e.g.,
internal/gdocmeta) that encapsulates the flow currently in showMeta: extract
document ID (gdocs.ExtractDocumentID), authenticate (auth.NewAuthenticator /
GetClient), create Docs client (gdocs.NewClient), fetch the document
(client.FetchDocument) and produce a formatted representation (use
gdocs.ListTabs to build tabs with Depth/Emoji/Title/ID) and expose a single
function such as FetchAndFormatMeta(ctx, httpClient, docID) or
FormatMetaFromDoc(doc) that returns a plain string or structured DTO; then
replace showMeta in main.go with orchestration-only code that calls the new
package function and prints its result, keeping main.go free of data-shaping and
rendering loops.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/gdocs-cli/main.go`:
- Around line 70-77: Make --clean and --meta mutually exclusive by validating
flags early: if *cleanFlag && *metaFlag then print a clear error to stderr and
exit non-zero. Update main's flag-handling logic so the exclusivity check runs
before any branch (before calling showMeta or the normal output path), and
ensure showMeta is never called when cleanFlag is set; use the existing
metaFlag, cleanFlag, and showMeta symbols to locate the code to change.

---

Nitpick comments:
In `@cmd/gdocs-cli/main.go`:
- Around line 197-249: The showMeta function in main.go contains business logic
(fetching, shaping and rendering metadata) that should be moved into an internal
package; create a new service (e.g., internal/gdocmeta) that encapsulates the
flow currently in showMeta: extract document ID (gdocs.ExtractDocumentID),
authenticate (auth.NewAuthenticator / GetClient), create Docs client
(gdocs.NewClient), fetch the document (client.FetchDocument) and produce a
formatted representation (use gdocs.ListTabs to build tabs with
Depth/Emoji/Title/ID) and expose a single function such as
FetchAndFormatMeta(ctx, httpClient, docID) or FormatMetaFromDoc(doc) that
returns a plain string or structured DTO; then replace showMeta in main.go with
orchestration-only code that calls the new package function and prints its
result, keeping main.go free of data-shaping and rendering loops.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d0bda4b4-4fdc-4717-953a-32751b0f49a3

📥 Commits

Reviewing files that changed from the base of the PR and between 6de2c79 and 4b9c99e.

📒 Files selected for processing (2)
  • cmd/gdocs-cli/main.go
  • internal/gdocs/client.go

Comment thread cmd/gdocs-cli/main.go
Comment on lines +70 to +77
// Handle meta mode
if *metaFlag {
if err := showMeta(*urlFlag, configPath); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
return
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

--clean and --meta should be mutually exclusive.

At Line 38, --clean promises markdown-only stdout, but Line 72 routes to showMeta, which prints non-markdown output. This breaks clean-mode piping expectations.

💡 Proposed fix
 	// Handle clean mode - suppress all logs
 	if *cleanFlag {
 		log.SetOutput(io.Discard)
 	}
+
+	// Validate incompatible output modes
+	if *cleanFlag && *metaFlag {
+		fmt.Fprintln(os.Stderr, "Error: --clean and --meta cannot be used together")
+		os.Exit(1)
+	}

As per coding guidelines: "The --clean flag should only output markdown to stdout, making it easy to pipe output directly into AI systems or other tools".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Handle meta mode
if *metaFlag {
if err := showMeta(*urlFlag, configPath); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
return
}
// Handle clean mode - suppress all logs
if *cleanFlag {
log.SetOutput(io.Discard)
}
// Validate incompatible output modes
if *cleanFlag && *metaFlag {
fmt.Fprintln(os.Stderr, "Error: --clean and --meta cannot be used together")
os.Exit(1)
}
// Handle meta mode
if *metaFlag {
if err := showMeta(*urlFlag, configPath); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
return
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/gdocs-cli/main.go` around lines 70 - 77, Make --clean and --meta mutually
exclusive by validating flags early: if *cleanFlag && *metaFlag then print a
clear error to stderr and exit non-zero. Update main's flag-handling logic so
the exclusivity check runs before any branch (before calling showMeta or the
normal output path), and ensure showMeta is never called when cleanFlag is set;
use the existing metaFlag, cleanFlag, and showMeta symbols to locate the code to
change.

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.

1 participant