# Gdoc Writer

> Creates, edits, formats, and collaborates on Google Docs with consistent typography. Use when the user says "create a google doc", "write a doc", "make a new doc", "clean up this doc", "format this google doc", "edit my doc", "fix the styling", "make it look consistent", "update my internship progress", "update progress document", "add to my progress doc", "push this to a doc", "share this draft", "check for comments", "any comments on the doc", "reply to comments", pastes a Google Doc URL and wants changes, or describes content that should become a styled Google Doc. Also use when someone says "bold the important parts", "fix the headings", "apply Red Hat styling", or "which tabs does this doc have". This skill handles creation, editing, multi-tab navigation, typography presets, and collaborative commenting workflows. The internship progress document is at ID 1cgCFOBVf54Mf-bLbUlWHa6BK12AeCR6mQHx25i7npM8 and uses the redhat-formal preset.

- Skill: `jaquevan/gdoc-writer` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add jaquevan/gdoc-writer`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jaquevan/gdoc-writer/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: jaquevan (https://skillmd.com/u/jaquevan)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/jaquevan/gdoc-writer

---


# Google Doc Writer

You create, edit, and format Google Docs with consistent, professional
typography. You use a Python script (`scripts/gdoc_writer.py` relative to
this skill) that calls the Google Docs API directly for full control over
text insertion, formatting, tab navigation, and style application.

The user's input is: **$ARGUMENTS**

---

## Input Detection

1. **Create mode**: User describes content for a new doc. Phrases: "create
   a doc about...", "write up a doc for...", "make a new doc".
2. **Edit mode**: User pastes a Google Doc URL or names a doc they want
   changed. Phrases: "edit my doc", "add this to the doc", "update the doc".
3. **Format/Clean mode**: User wants formatting fixed without content changes.
   Phrases: "format this doc", "clean up the styling", "fix the headings".
4. **Ambiguous**: Ask: "Are you looking to create a new doc, edit an existing
   one, or just clean up the formatting?"

---

## Style Presets

| Preset | When to use | Headings | Body |
|--------|-------------|----------|------|
| `redhat-formal` | Reports, progress docs, official deliverables | Red Hat Display 14/12/11pt bold | Red Hat Text 11pt |
| `integration-proposal` | Integration plans, tiger team docs, stakeholder deliverables | Red Hat Display 16/14/12pt bold | Red Hat Text 11pt |
| `casual-notes` | Meeting notes, working docs, quick captures | Arial 14/12pt bold | Arial 11pt |
| `meeting-doc` | Agendas, action items, decision logs | Arial 13/11pt bold, tight spacing | Arial 11pt |
| `presentation-notes` | Speaker notes, outlines for slide decks | Arial 16/14pt | Arial 12pt generous spacing |

**Auto-selection rules:**
- Mentions "report", "progress", "Red Hat", "formal" -> `redhat-formal`
- Mentions "proposal", "integration plan", "tiger team", "ADLC" -> `integration-proposal`
- Mentions "meeting", "agenda", "actions", "decisions" -> `meeting-doc`
- Mentions "notes", "quick", "working doc" -> `casual-notes`
- Mentions "presentation", "slides", "outline", "talk" -> `presentation-notes`
- Default if unclear: `casual-notes`

---

## Create Mode

1. Determine preset (auto-select or ask)
2. Transform input into structured markdown matching the preset's content
   template below. Every section needs a `## ` or `### ` heading. Use
   label patterns from the preset's `bold_patterns` list as section openers
   (e.g., "Goal:", "Tasks:", "Decision:") so auto-bold can target them.
   Raw notes, agent context, or second brain pages must be restructured
   into the template, not dumped as-is.
3. Write content to `/tmp/gdoc_content.md`
4. Run the script:

```bash
python3 <SKILL_DIR>/scripts/gdoc_writer.py create \
  --title "<document title>" \
  --preset <preset_name> \
  --content-file /tmp/gdoc_content.md
```

5. Report the URL and preset used

### Content Templates

Use these as the structural skeleton when writing `/tmp/gdoc_content.md`.
Fill in brackets, add/remove sections as needed, but preserve heading
levels and label patterns exactly.

**redhat-formal:**

```
# [Document Title]

## [Section Title]

Status: [current state]
Owner: [person responsible]

[Body paragraph with context.]

Deliverable: [what this section produces]

* [Bullet point]
* [Bullet point]

## [Next Section Title]

Decision: [what was decided and why]
Action: [concrete next step]
Key Learning: [insight worth preserving]
```

**integration-proposal:**

```
# [Tool/Feature Name] Integration Plan
Red Hat AI ADLC // [JIRA-KEY]

## Phase 1: [Phase Name]

Goal: [One paragraph describing the desired end state]

Tasks:
- [Task with owner in parentheses]
- [Task]

Success:
- [Measurable outcome (target: date)]

## Phase 2: [Phase Name]

Goal: [End state for this phase]

Tasks:
- [Task]

Success:
- [Measurable outcome (target: date)]
```

**casual-notes:**

```
# [Title]

## [Topic]

[Paragraph of content.]

Owner: [if applicable]
Date: [if applicable]

* [Key points as bullets]
```

**meeting-doc:**

```
# [Meeting Title] - [Date]

## Attendees

[Comma-separated names]

## Agenda

* [Topic 1]
* [Topic 2]

## Notes

Decision: [what was decided]
Action: [who does what by when]
Blocker: [what's stuck and why]

## Next Steps:

* [Action item with owner]
```

**presentation-notes:**

```
# [Talk Title]

## [Section/Slide Group]

Key Point: [the one thing the audience should remember]

[Supporting detail or talking points.]

Transition: [how you bridge to the next section]

## Demo: [Demo Title]

[What to show and in what order.]
```

---

## Edit Mode

1. Extract doc ID from URL (segment after `/d/` and before `/`) or search
   Drive. Check [references/known-documents.md](references/known-documents.md)
   for frequently-used docs before searching.
2. Read current content and list tabs:

```python
import sys
sys.path.insert(0, "<SKILL_DIR>/scripts")
from gdoc_writer import read_doc, list_tabs

tabs = list_tabs(doc_id)  # [{id, title}]
content = read_doc(doc_id, tab_id=TAB_ID)
```

3. Apply edits (insert text, bold items, fix headings, replace sections)
4. Report what changed

---

## Format/Clean Mode

1. Read the document structure including all tabs
2. Determine target preset (auto-detect or ask)
3. Run format (two-phase process):

```python
from gdoc_writer import format_doc
changes = format_doc(doc_id, preset="redhat-formal", tab_id=None)
```

4. Report changes made

### Format Phases

**Phase 1: Markdown cleanup.** Detects raw markdown artifacts left from
content generation and converts them to native Docs formatting:
- `**text**` becomes native bold (asterisks removed)
- `[text](url)` becomes a clickable hyperlink with blue link color
- `---` horizontal rules are removed

**Phase 2: Preset application.** Applies fonts, sizing, spacing, and
auto-bold patterns per the selected preset.

### Spacing Rules

- H1/Title: 14pt above, 6pt below
- H2/H3: 10pt above, 6pt below
- Body paragraphs: 2pt above, 4pt below
- This gives headings visual weight and separates body content from headers

### Metadata Block Handling

When a document starts with a block of label:value lines (e.g., "Internship
Period:", "Team:", "Manager:"), convert it to a clean 2-column table with
the label in column 1 (bold) and the value in column 2. This separates
metadata from body content visually.

### Dash Rules

- Em dashes in headings: leave alone (these are often part of the document's
  naming convention, e.g., "Business Impact — Incremental Impact")
- Em/en dashes in body text: only flag if the skill is WRITING new content.
  When formatting an existing doc, do not modify dashes in body text unless
  the user specifically asks.

---

## Rebuild Mode

Use when the markdown source is authoritative and the doc should match it
exactly (structure, tables, sections). This replaces all content in the doc
while preserving the same URL.

**When to use rebuild vs insert_text:**
- `rebuild_doc`: Full document updates, adding tables, restructuring sections,
  or when the local markdown file is the source of truth
- `insert_text`: Small inline text additions that don't involve tables or
  new structural elements

1. Ensure the local markdown file has the correct content
2. Run rebuild:

```bash
python3 <SKILL_DIR>/scripts/gdoc_writer.py rebuild \
  --doc-id "<ID_or_URL>" \
  --preset <preset_name> \
  --content-file /tmp/gdoc_content.md \
  --landscape  # optional: sets landscape orientation
```

3. Report that the doc was rebuilt and the URL

**Important:** Rebuild replaces all existing content. Always confirm the
markdown source is complete before running.

### Landscape Mode

Add `--landscape` flag to `rebuild` when the document contains wide tables
(3+ columns with evidence/description text). Landscape sets 11x8.5" page
with 0.5" margins for maximum table readability.

### Table Level Coloring

After rebuild, `style_level_tables()` automatically scans all tables for
cells containing skill level keywords and applies background colors:
- "Advanced" -> light green background
- "Intermediate" -> light orange background
- "Beginner" / "Learner" -> light peach background

This applies to competency documents, skill matrices, and any table with
proficiency levels.

---

## Tab Navigation

1. `list_tabs(doc_id)` returns all tab IDs and titles
2. `read_doc(doc_id, tab_id=TAB_ID)` reads a specific tab
3. All edit/format functions accept optional `tab_id`
4. Default: operates on first tab if none specified

---

## Examples

### GOOD: Create from notes (input transformation)

Raw input from second brain or agent context:

> talked to zack about the prototype eval pipeline. he wants us to
> track accuracy per persona and compare across prototypes. andy said
> the figma integration is blocked on API access. need to figure out
> the scoring normalization before next sprint.

Content file the agent writes (`/tmp/gdoc_content.md`):

```
# Prototype Evaluation Pipeline

## Scoring Framework

Status: In progress
Owner: Evan Jaquez

Decision: Track accuracy per persona and compare across prototypes
(confirmed with <YOUR_MANAGER> in 1:1).

Key Learning: Scoring normalization must be resolved before sprint
kickoff to avoid compounding errors across evaluation runs.

## Figma Integration

Status: Blocked
Owner: <COLLEAGUE_1>

Action: Obtain Figma API access credentials from platform team.

## Open Items

* Scoring normalization approach (options: min-max, z-score, percentile)
* Sprint timeline for persona-level accuracy tracking
```

Agent response:

> "Created Prototype Evaluation Pipeline with redhat-formal preset.
> 2 sections + open items, 4 labels bolded (Status, Owner, Decision,
> Action). View: [url]"

### BAD: Create from notes (raw dump)

Content file the agent writes:

```
talked to zack about the prototype eval pipeline. he wants us to
track accuracy per persona and compare across prototypes. andy said
the figma integration is blocked on API access. need to figure out
the scoring normalization before next sprint.
```

Why bad: Dumps raw notes without restructuring. No headings for the preset
to target, no label patterns for auto-bold, no separation into sections.
The formatting engine has nothing to grab onto so the doc comes out as a
wall of unstyled body text.

### GOOD: Formatting report

> "Formatted Prototype Creator Evals. Applied redhat-formal styling:
> 4 headings normalized to Red Hat Display, 12 label patterns bolded,
> 3 Jira keys linked. View: [url]"

### BAD: Formatting report (too verbose)

> "I've gone through the document and found several formatting
> inconsistencies. The headings were using different font sizes so I
> normalized them. I also found some labels that should be bold..."

Why bad: reads the whole document back instead of summarizing changes concisely.

### GOOD: Edit confirmation

> "Added July 7 entry to Daily Progress tab. Styled date as H3,
> bolded section labels (What Was Done:, Decisions Made:, Open Items:)."

### BAD: Edit confirmation (creates duplicate)

> "I created a new Google Doc called 'Daily Progress July 7' with..."

Why bad: creates a new doc instead of editing the existing one. Always check
if the user wants to edit an existing doc first.

---

## Collaboration Mode

Uses `scripts/gdoc_sync.py`. **Safety rule:** Every action visible to others
requires explicit user approval. Never auto-push, auto-share, or auto-reply.

1. **Push**: Dry run first, show preview, wait for approval, then `--confirm`
2. **Check comments**: `gdoc_sync.py pull <file>`, present grouped by commenter
3. **Reply**: Draft reply, wait for approval, then `--confirm`
4. **Update**: Warn about comment anchor loss, wait for approval

---

## Gemini Transcript Processing

See [references/known-documents.md](references/known-documents.md) for the
Daily Progress entry format and transcript processing modes.

---

## Reference Files

- [references/known-documents.md](references/known-documents.md): Doc IDs,
  shortcuts, and progress document conventions
- [references/formatting-rules.md](references/formatting-rules.md): Auto-bold
  patterns, color conventions, integration-proposal structure

---

## What NOT to Do

- Do not read the entire document content back to the user. Summarize changes.
- Do not apply formatting without determining the target preset first.
- Do not create duplicate docs when a doc with that title exists.
- Do not modify tabs the user did not ask about.
- Do not change content when the user only asked for formatting.
- Do not use dashes (em or en) in any NEW text written to documents.
- Do not apply blue color to text without also adding a hyperlink.
- Do not use heading sizes larger than 16pt for any preset.
- Do not leave raw markdown syntax (`**bold**`, `[text](url)`, `---`) in a
  formatted document. The format phase must convert these to native formatting.
- Do not dump raw notes/agent context as-is into a content file. Always
  restructure into the preset's content template with headings and labels.
- Do not remove em dashes from headings in existing documents (they may be
  part of an established naming convention like "Scope — Task").

---

## Error Handling

| Error | Response |
|-------|----------|
| Invalid URL | "That doesn't look like a Google Doc URL. Can you paste the full link?" |
| Permission denied | "I don't have edit access. Make sure it's shared with your Google account." |
| Token expired | "Auth token expired. Run `python3 gdoc_writer.py --setup` to re-authenticate." |
| Doc not found | "Couldn't find a doc matching that. Can you paste the URL directly?" |
| Tab missing | "That tab doesn't exist. Available tabs: [list]" |

