Workspace Docs Skill
Create and edit real Google Docs, Google Sheets, Google Slides, and Google Forms inside the user's Google Drive. Use this whenever the user wants a Doc, Sheet, Slide deck, presentation, spreadsheet, form, or survey that lives in Google Drive — even if they just say "create a deck" or "make a doc". Returns a shareable Drive link, not a downloadable file. Do NOT use for static PDF/PNG output (use canvas-design) or HTML artifacts (use web-artifacts-builder).
Google Workspace Docs
Edit documents, spreadsheets, presentations, and forms via bridge google. The bridge automatically resolves credentials from the claw owner's Google connection.
Scope model — read this first
This skill operates entirely under the drive.file scope (non-sensitive). The Docs / Sheets / Slides / Forms APIs all accept drive.file as a cross-API scope, so a single permission grant covers create, read, edit, and delete for every Workspace surface — as long as the file was created by WorkClaw (or the user explicitly opened it via the Picker).
The visibility rule: drive.file only grants access to files this app touched. If the user asks you to read or edit a file they created directly in Drive (not via WorkClaw), the call will fail with a permissions error.
When that happens:
- Don't apologise vaguely. Tell the user what's actually going on:
"I can only read/edit Workspace files that WorkClaw created with you. The file you mentioned looks like one you created directly in Drive — to work with it I'd need broader Drive access. Want me to request that?"
- If the user agrees, route the read action through the
drive-filesskill instead — it handlesdrive.readonly/driveescalation for pre-existing files viadrive.files.export+drive.files.get. - For edits on a pre-existing file, suggest the user open it via Picker first (which gives the app
drive.fileaccess to that specific file) — that's the cleanest path and keeps the verification surface minimal.
Scope error handling
Call the bridge command for the user's actual request directly — do not pre-flight a verifier call first. JIT will surface the right signal if a permission is missing; adding a verifier just triggers an unrelated extra consent prompt the user shouldn't have to grant.
MUST: when any bridge google command returns a JSON object with a "reason" field (no_connection, scope_required, team_claw_unsupported, expired) instead of API data, paste the entire JSON line verbatim in your reply on its own line. Paraphrasing, summarising, or omitting any field means the inline Connect button does not render and the user is stuck with no way to grant the permission. After the JSON line add one short sentence telling the user what's missing. Never offer browser walkthroughs, settings-page navigation, "open it in your browser" links, or other manual workarounds — the inline button is the only supported path.
Google Docs
Read a doc
bridge google --skill workspace-docs docs documents get --params '{"documentId":"DOC_ID"}'
Create a new doc
bridge google --skill workspace-docs docs documents create --params '{}' --json '{
"title": "Q4 Planning Doc"
}'
Append text to a doc
bridge google --skill workspace-docs docs documents batchUpdate --params '{"documentId":"DOC_ID"}' --json '{
"requests": [
{"insertText": {"location": {"index": 1}, "text": "New section content\n"}}
]
}'
Google Sheets
Read a range
bridge google --skill workspace-docs sheets spreadsheets values get --params '{"spreadsheetId":"SHEET_ID","range":"Sheet1!A1:D50"}'
Update a range
bridge google --skill workspace-docs sheets spreadsheets values update --params '{"spreadsheetId":"SHEET_ID","range":"Sheet1!A1","valueInputOption":"USER_ENTERED"}' --json '{
"values": [["Header 1", "Header 2"], ["Row 1 col 1", "Row 1 col 2"]]
}'
Append rows
bridge google --skill workspace-docs sheets spreadsheets values append --params '{"spreadsheetId":"SHEET_ID","range":"Sheet1!A1","valueInputOption":"USER_ENTERED"}' --json '{
"values": [["new row col 1", "new row col 2"]]
}'
Create a new spreadsheet
bridge google --skill workspace-docs sheets spreadsheets create --params '{}' --json '{
"properties": {"title": "Q4 Metrics"}
}'
Google Slides
Read deck structure
bridge google --skill workspace-docs slides presentations get --params '{"presentationId":"DECK_ID"}'
Create a deck
bridge google --skill workspace-docs slides presentations create --params '{}' --json '{
"title": "Quarterly Review"
}'
Insert a slide
bridge google --skill workspace-docs slides presentations batchUpdate --params '{"presentationId":"DECK_ID"}' --json '{
"requests": [
{"createSlide": {"slideLayoutReference": {"predefinedLayout": "TITLE_AND_BODY"}}}
]
}'
Google Forms
Read a form definition
bridge google --skill workspace-docs forms forms get --params '{"formId":"FORM_ID"}'
List responses
bridge google --skill workspace-docs forms forms responses list --params '{"formId":"FORM_ID"}'
Create a form
bridge google --skill workspace-docs forms forms create --params '{}' --json '{
"info": {"title": "Customer Feedback Survey", "documentTitle": "Customer Feedback Survey"}
}'
Add a question to a form
bridge google --skill workspace-docs forms forms batchUpdate --params '{"formId":"FORM_ID"}' --json '{
"requests": [
{"createItem": {
"item": {"title": "How satisfied are you?", "questionItem": {"question": {"required": true, "scaleQuestion": {"low": 1, "high": 5}}}},
"location": {"index": 0}
}}
]
}'
Safety
- Always confirm before overwriting cells, deleting slides, or replacing doc content
- For Sheets
update, prefer narrow ranges (e.g.A1:B2) over whole-sheet updates - For destructive batch updates, summarize each request to the user first
- Don't dump full doc/sheet contents into chat — show the relevant section or a link