[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71JCZ6XPQBY95JD3WNAPR5F":3,"skill-same:01M71JCZ6XPQBY95JD3WNAPR5F":97},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":66,"install":67,"resources":80},"01M71JCZ6XPQBY95JD3WNAPR5F","google-workspace",null,"Gmail, Calendar, Drive, Contacts, Sheets, and Docs integration for Hermes. Uses Hermes-managed OAuth2 setup, prefers the Google Workspace CLI (`gws`) when available for broader API coverage, and falls back to the Python client libraries otherwise.","xuanxuan1983\u002Fhermes-skills-backup","xuanxuan1983","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F151701653?v=4","01M71HCZNB5H19QJ6YBF98W2WH","01M71HCZP14T0921BD0TC9EPD3",1,"MIT","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"google workspace","workspace","google","python","sheets","for","email","gmail","hermes-agent","calendar","google workspace cli","cli","libraries","gws","contacts","api","when","managed","coverage","back","2026-11-10 10:12:30",false,"---\nname: google-workspace\ndescription: Gmail, Calendar, Drive, Contacts, Sheets, and Docs integration for Hermes. Uses Hermes-managed OAuth2 setup, prefers the Google Workspace CLI (`gws`) when available for broader API coverage, and falls back to the Python client libraries otherwise.\nversion: 1.0.0\nauthor: Nous Research\nlicense: MIT\nmetadata:\n  hermes:\n    tags: [Google, Gmail, Calendar, Drive, Sheets, Docs, Contacts, Email, OAuth]\n    homepage: https:\u002F\u002Fgithub.com\u002FNousResearch\u002Fhermes-agent\n    related_skills: [himalaya]\n---\n\n# Google Workspace\n\nGmail, Calendar, Drive, Contacts, Sheets, and Docs — through Hermes-managed OAuth and a thin CLI wrapper. When `gws` is installed, the skill uses it as the execution backend for broader Google Workspace coverage; otherwise it falls back to the bundled Python client implementation.\n\n## References\n\n- `references\u002Fgmail-search-syntax.md` — Gmail search operators (is:unread, from:, newer_than:, etc.)\n\n## Scripts\n\n- `scripts\u002Fsetup.py` — OAuth2 setup (run once to authorize)\n- `scripts\u002Fgoogle_api.py` — compatibility wrapper CLI. It prefers `gws` for operations when available, while preserving Hermes' existing JSON output contract.\n\n## First-Time Setup\n\nThe setup is fully non-interactive — you drive it step by step so it works\non CLI, Telegram, Discord, or any platform.\n\nDefine a shorthand first:\n\n```bash\nGSETUP=\"python ${HERMES_HOME:-$HOME\u002F.hermes}\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Fscripts\u002Fsetup.py\"\n```\n\n### Step 0: Check if already set up\n\n```bash\n$GSETUP --check\n```\n\nIf it prints `AUTHENTICATED`, skip to Usage — setup is already done.\n\n### Step 1: Triage — ask the user what they need\n\nBefore starting OAuth setup, ask the user TWO questions:\n\n**Question 1: \"What Google services do you need? Just email, or also\nCalendar\u002FDrive\u002FSheets\u002FDocs?\"**\n\n- **Email only** → They don't need this skill at all. Use the `himalaya` skill\n  instead — it works with a Gmail App Password (Settings → Security → App\n  Passwords) and takes 2 minutes to set up. No Google Cloud project needed.\n  Load the himalaya skill and follow its setup instructions.\n\n- **Email + Calendar** → Continue with this skill, but use\n  `--services email,calendar` during auth so the consent screen only asks for\n  the scopes they actually need.\n\n- **Calendar\u002FDrive\u002FSheets\u002FDocs only** → Continue with this skill and use a\n  narrower `--services` set like `calendar,drive,sheets,docs`.\n\n- **Full Workspace access** → Continue with this skill and use the default\n  `all` service set.\n\n**Question 2: \"Does your Google account use Advanced Protection (hardware\nsecurity keys required to sign in)? If you're not sure, you probably don't\n— it's something you would have explicitly enrolled in.\"**\n\n- **No \u002F Not sure** → Normal setup. Continue below.\n- **Yes** → Their Workspace admin must add the OAuth client ID to the org's\n  allowed apps list before Step 4 will work. Let them know upfront.\n\n### Step 2: Create OAuth credentials (one-time, ~5 minutes)\n\nTell the user:\n\n> You need a Google Cloud OAuth client. This is a one-time setup:\n>\n> 1. Create or select a project:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fprojectselector2\u002Fhome\u002Fdashboard\n> 2. Enable the required APIs from the API Library:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fapis\u002Flibrary\n>    Enable: Gmail API, Google Calendar API, Google Drive API,\n>    Google Sheets API, Google Docs API, People API\n> 3. Create the OAuth client here:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fapis\u002Fcredentials\n>    Credentials → Create Credentials → OAuth 2.0 Client ID\n> 4. Application type: \"Desktop app\" → Create\n> 5. If the app is still in Testing, add the user's Google account as a test user here:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fauth\u002Faudience\n>    Audience → Test users → Add users\n> 6. Download the JSON file and tell me the file path\n>\n> Important Hermes CLI note: if the file path starts with `\u002F`, do NOT send only the bare path as its own message in the CLI, because it can be mistaken for a slash command. Send it in a sentence instead, like:\n> `The JSON file path is: \u002Fhome\u002Fuser\u002FDownloads\u002Fclient_secret_....json`\n\nOnce they provide the path:\n\n```bash\n$GSETUP --client-secret \u002Fpath\u002Fto\u002Fclient_secret.json\n```\n\nIf they paste the raw client ID \u002F client secret values instead of a file path,\nwrite a valid Desktop OAuth JSON file for them yourself, save it somewhere\nexplicit (for example `~\u002FDownloads\u002Fhermes-google-client-secret.json`), then run\n`--client-secret` against that file.\n\n### Step 3: Get authorization URL\n\nUse the service set chosen in Step 1. Examples:\n\n```bash\n$GSETUP --auth-url --services email,calendar --format json\n$GSETUP --auth-url --services calendar,drive,sheets,docs --format json\n$GSETUP --auth-url --services all --format json\n```\n\nThis returns JSON with an `auth_url` field and also saves the exact URL to\n`~\u002F.hermes\u002Fgoogle_oauth_last_url.txt`.\n\nAgent rules for this step:\n- Extract the `auth_url` field and send that exact URL to the user as a single line.\n- Tell the user that the browser will likely fail on `http:\u002F\u002Flocalhost:1` after approval, and that this is expected.\n- Tell them to copy the ENTIRE redirected URL from the browser address bar.\n- If the user gets `Error 403: access_denied`, send them directly to `https:\u002F\u002Fconsole.cloud.google.com\u002Fauth\u002Faudience` to add themselves as a test user.\n\n### Step 4: Exchange the code\n\nThe user will paste back either a URL like `http:\u002F\u002Flocalhost:1\u002F?code=4\u002F0A...&scope=...`\nor just the code string. Either works. The `--auth-url` step stores a temporary\npending OAuth session locally so `--auth-code` can complete the PKCE exchange\nlater, even on headless systems:\n\n```bash\n$GSETUP --auth-code \"THE_URL_OR_CODE_THE_USER_PASTED\" --format json\n```\n\nIf `--auth-code` fails because the code expired, was already used, or came from\nan older browser tab, it now returns a fresh `fresh_auth_url`. In that case,\nimmediately send the new URL to the user and have them retry with the newest\nbrowser redirect only.\n\n### Step 5: Verify\n\n```bash\n$GSETUP --check\n```\n\nShould print `AUTHENTICATED`. Setup is complete — token refreshes automatically from now on.\n\n### Notes\n\n- Token is stored at `~\u002F.hermes\u002Fgoogle_token.json` and auto-refreshes.\n- Pending OAuth session state\u002Fverifier are stored temporarily at `~\u002F.hermes\u002Fgoogle_oauth_pending.json` until exchange completes.\n- If `gws` is installed, `google_api.py` points it at the same `~\u002F.hermes\u002Fgoogle_token.json` credentials file. Users do not need to run a separate `gws auth login` flow.\n- To revoke: `$GSETUP --revoke`\n\n## Usage\n\nAll commands go through the API script. Set `GAPI` as a shorthand:\n\n```bash\nGAPI=\"python ${HERMES_HOME:-$HOME\u002F.hermes}\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Fscripts\u002Fgoogle_api.py\"\n```\n\n### Gmail\n\n```bash\n# Search (returns JSON array with id, from, subject, date, snippet)\n$GAPI gmail search \"is:unread\" --max 10\n$GAPI gmail search \"from:boss@company.com newer_than:1d\"\n$GAPI gmail search \"has:attachment filename:pdf newer_than:7d\"\n\n# Read full message (returns JSON with body text)\n$GAPI gmail get MESSAGE_ID\n\n# Send\n$GAPI gmail send --to user@example.com --subject \"Hello\" --body \"Message text\"\n$GAPI gmail send --to user@example.com --subject \"Report\" --body \"\u003Ch1>Q4\u003C\u002Fh1>\u003Cp>Details...\u003C\u002Fp>\" --html\n$GAPI gmail send --to user@example.com --subject \"Hello\" --from '\"Research Agent\" \u003Cuser@example.com>' --body \"Message text\"\n\n# Reply (automatically threads and sets In-Reply-To)\n$GAPI gmail reply MESSAGE_ID --body \"Thanks, that works for me.\"\n$GAPI gmail reply MESSAGE_ID --from '\"Support Bot\" \u003Cuser@example.com>' --body \"Thanks\"\n\n# Labels\n$GAPI gmail labels\n$GAPI gmail modify MESSAGE_ID --add-labels LABEL_ID\n$GAPI gmail modify MESSAGE_ID --remove-labels UNREAD\n```\n\n### Calendar\n\n```bash\n# List events (defaults to next 7 days)\n$GAPI calendar list\n$GAPI calendar list --start 2026-03-01T00:00:00Z --end 2026-03-07T23:59:59Z\n\n# Create event (ISO 8601 with timezone required)\n$GAPI calendar create --summary \"Team Standup\" --start 2026-03-01T10:00:00-06:00 --end 2026-03-01T10:30:00-06:00\n$GAPI calendar create --summary \"Lunch\" --start 2026-03-01T12:00:00Z --end 2026-03-01T13:00:00Z --location \"Cafe\"\n$GAPI calendar create --summary \"Review\" --start 2026-03-01T14:00:00Z --end 2026-03-01T15:00:00Z --attendees \"alice@co.com,bob@co.com\"\n\n# Delete event\n$GAPI calendar delete EVENT_ID\n```\n\n### Drive\n\n```bash\n$GAPI drive search \"quarterly report\" --max 10\n$GAPI drive search \"mimeType='application\u002Fpdf'\" --raw-query --max 5\n```\n\n### Contacts\n\n```bash\n$GAPI contacts list --max 20\n```\n\n### Sheets\n\n```bash\n# Read\n$GAPI sheets get SHEET_ID \"Sheet1!A1:D10\"\n\n# Write\n$GAPI sheets update SHEET_ID \"Sheet1!A1:B2\" --values '[[\"Name\",\"Score\"],[\"Alice\",\"95\"]]'\n\n# Append rows\n$GAPI sheets append SHEET_ID \"Sheet1!A:C\" --values '[[\"new\",\"row\",\"data\"]]'\n```\n\n### Docs\n\n```bash\n$GAPI docs get DOC_ID\n```\n\n## Output Format\n\nAll commands return JSON. Parse with `jq` or read directly. Key fields:\n\n- **Gmail search**: `[{id, threadId, from, to, subject, date, snippet, labels}]`\n- **Gmail get**: `{id, threadId, from, to, subject, date, labels, body}`\n- **Gmail send\u002Freply**: `{status: \"sent\", id, threadId}`\n- **Calendar list**: `[{id, summary, start, end, location, description, htmlLink}]`\n- **Calendar create**: `{status: \"created\", id, summary, htmlLink}`\n- **Drive search**: `[{id, name, mimeType, modifiedTime, webViewLink}]`\n- **Contacts list**: `[{name, emails: [...], phones: [...]}]`\n- **Sheets get**: `[[cell, cell, ...], ...]`\n\n## Rules\n\n1. **Never send email or create\u002Fdelete events without confirming with the user first.** Show the draft content and ask for approval.\n2. **Check auth before first use** — run `setup.py --check`. If it fails, guide the user through setup.\n3. **Use the Gmail search syntax reference** for complex queries — load it with `skill_view(\"google-workspace\", file_path=\"references\u002Fgmail-search-syntax.md\")`.\n4. **Calendar times must include timezone** — always use ISO 8601 with offset (e.g., `2026-03-01T10:00:00-06:00`) or UTC (`Z`).\n5. **Respect rate limits** — avoid rapid-fire sequential API calls. Batch reads when possible.\n\n## Troubleshooting\n\n| Problem | Fix |\n|---------|-----|\n| `NOT_AUTHENTICATED` | Run setup Steps 2-5 above |\n| `REFRESH_FAILED` | Token revoked or expired — redo Steps 3-5 |\n| `HttpError 403: Insufficient Permission` | Missing API scope — `$GSETUP --revoke` then redo Steps 3-5 |\n| `HttpError 403: Access Not Configured` | API not enabled — user needs to enable it in Google Cloud Console |\n| `ModuleNotFoundError` | Run `$GSETUP --install-deps` |\n| Advanced Protection blocks auth | Workspace admin must allowlist the OAuth client ID |\n\n## Revoking Access\n\n```bash\n$GSETUP --revoke\n```\n","# Google Workspace\n\nGmail, Calendar, Drive, Contacts, Sheets, and Docs — through Hermes-managed OAuth and a thin CLI wrapper. When `gws` is installed, the skill uses it as the execution backend for broader Google Workspace coverage; otherwise it falls back to the bundled Python client implementation.\n\n## References\n\n- `references\u002Fgmail-search-syntax.md` — Gmail search operators (is:unread, from:, newer_than:, etc.)\n\n## Scripts\n\n- `scripts\u002Fsetup.py` — OAuth2 setup (run once to authorize)\n- `scripts\u002Fgoogle_api.py` — compatibility wrapper CLI. It prefers `gws` for operations when available, while preserving Hermes' existing JSON output contract.\n\n## First-Time Setup\n\nThe setup is fully non-interactive — you drive it step by step so it works\non CLI, Telegram, Discord, or any platform.\n\nDefine a shorthand first:\n\n```bash\nGSETUP=\"python ${HERMES_HOME:-$HOME\u002F.hermes}\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Fscripts\u002Fsetup.py\"\n```\n\n### Step 0: Check if already set up\n\n```bash\n$GSETUP --check\n```\n\nIf it prints `AUTHENTICATED`, skip to Usage — setup is already done.\n\n### Step 1: Triage — ask the user what they need\n\nBefore starting OAuth setup, ask the user TWO questions:\n\n**Question 1: \"What Google services do you need? Just email, or also\nCalendar\u002FDrive\u002FSheets\u002FDocs?\"**\n\n- **Email only** → They don't need this skill at all. Use the `himalaya` skill\n  instead — it works with a Gmail App Password (Settings → Security → App\n  Passwords) and takes 2 minutes to set up. No Google Cloud project needed.\n  Load the himalaya skill and follow its setup instructions.\n\n- **Email + Calendar** → Continue with this skill, but use\n  `--services email,calendar` during auth so the consent screen only asks for\n  the scopes they actually need.\n\n- **Calendar\u002FDrive\u002FSheets\u002FDocs only** → Continue with this skill and use a\n  narrower `--services` set like `calendar,drive,sheets,docs`.\n\n- **Full Workspace access** → Continue with this skill and use the default\n  `all` service set.\n\n**Question 2: \"Does your Google account use Advanced Protection (hardware\nsecurity keys required to sign in)? If you're not sure, you probably don't\n— it's something you would have explicitly enrolled in.\"**\n\n- **No \u002F Not sure** → Normal setup. Continue below.\n- **Yes** → Their Workspace admin must add the OAuth client ID to the org's\n  allowed apps list before Step 4 will work. Let them know upfront.\n\n### Step 2: Create OAuth credentials (one-time, ~5 minutes)\n\nTell the user:\n\n> You need a Google Cloud OAuth client. This is a one-time setup:\n>\n> 1. Create or select a project:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fprojectselector2\u002Fhome\u002Fdashboard\n> 2. Enable the required APIs from the API Library:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fapis\u002Flibrary\n>    Enable: Gmail API, Google Calendar API, Google Drive API,\n>    Google Sheets API, Google Docs API, People API\n> 3. Create the OAuth client here:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fapis\u002Fcredentials\n>    Credentials → Create Credentials → OAuth 2.0 Client ID\n> 4. Application type: \"Desktop app\" → Create\n> 5. If the app is still in Testing, add the user's Google account as a test user here:\n>    https:\u002F\u002Fconsole.cloud.google.com\u002Fauth\u002Faudience\n>    Audience → Test users → Add users\n> 6. Download the JSON file and tell me the file path\n>\n> Important Hermes CLI note: if the file path starts with `\u002F`, do NOT send only the bare path as its own message in the CLI, because it can be mistaken for a slash command. Send it in a sentence instead, like:\n> `The JSON file path is: \u002Fhome\u002Fuser\u002FDownloads\u002Fclient_secret_....json`\n\nOnce they provide the path:\n\n```bash\n$GSETUP --client-secret \u002Fpath\u002Fto\u002Fclient_secret.json\n```\n\nIf they paste the raw client ID \u002F client secret values instead of a file path,\nwrite a valid Desktop OAuth JSON file for them yourself, save it somewhere\nexplicit (for example `~\u002FDownloads\u002Fhermes-google-client-secret.json`), then run\n`--client-secret` against that file.\n\n### Step 3: Get authorization URL\n\nUse the service set chosen in Step 1. Examples:\n\n```bash\n$GSETUP --auth-url --services email,calendar --format json\n$GSETUP --auth-url --services calendar,drive,sheets,docs --format json\n$GSETUP --auth-url --services all --format json\n```\n\nThis returns JSON with an `auth_url` field and also saves the exact URL to\n`~\u002F.hermes\u002Fgoogle_oauth_last_url.txt`.\n\nAgent rules for this step:\n- Extract the `auth_url` field and send that exact URL to the user as a single line.\n- Tell the user that the browser will likely fail on `http:\u002F\u002Flocalhost:1` after approval, and that this is expected.\n- Tell them to copy the ENTIRE redirected URL from the browser address bar.\n- If the user gets `Error 403: access_denied`, send them directly to `https:\u002F\u002Fconsole.cloud.google.com\u002Fauth\u002Faudience` to add themselves as a test user.\n\n### Step 4: Exchange the code\n\nThe user will paste back either a URL like `http:\u002F\u002Flocalhost:1\u002F?code=4\u002F0A...&scope=...`\nor just the code string. Either works. The `--auth-url` step stores a temporary\npending OAuth session locally so `--auth-code` can complete the PKCE exchange\nlater, even on headless systems:\n\n```bash\n$GSETUP --auth-code \"THE_URL_OR_CODE_THE_USER_PASTED\" --format json\n```\n\nIf `--auth-code` fails because the code expired, was already used, or came from\nan older browser tab, it now returns a fresh `fresh_auth_url`. In that case,\nimmediately send the new URL to the user and have them retry with the newest\nbrowser redirect only.\n\n### Step 5: Verify\n\n```bash\n$GSETUP --check\n```\n\nShould print `AUTHENTICATED`. Setup is complete — token refreshes automatically from now on.\n\n### Notes\n\n- Token is stored at `~\u002F.hermes\u002Fgoogle_token.json` and auto-refreshes.\n- Pending OAuth session state\u002Fverifier are stored temporarily at `~\u002F.hermes\u002Fgoogle_oauth_pending.json` until exchange completes.\n- If `gws` is installed, `google_api.py` points it at the same `~\u002F.hermes\u002Fgoogle_token.json` credentials file. Users do not need to run a separate `gws auth login` flow.\n- To revoke: `$GSETUP --revoke`\n\n## Usage\n\nAll commands go through the API script. Set `GAPI` as a shorthand:\n\n```bash\nGAPI=\"python ${HERMES_HOME:-$HOME\u002F.hermes}\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Fscripts\u002Fgoogle_api.py\"\n```\n\n### Gmail\n\n```bash\n# Search (returns JSON array with id, from, subject, date, snippet)\n$GAPI gmail search \"is:unread\" --max 10\n$GAPI gmail search \"from:boss@company.com newer_than:1d\"\n$GAPI gmail search \"has:attachment filename:pdf newer_than:7d\"\n\n# Read full message (returns JSON with body text)\n$GAPI gmail get MESSAGE_ID\n\n# Send\n$GAPI gmail send --to user@example.com --subject \"Hello\" --body \"Message text\"\n$GAPI gmail send --to user@example.com --subject \"Report\" --body \"\u003Ch1>Q4\u003C\u002Fh1>\u003Cp>Details...\u003C\u002Fp>\" --html\n$GAPI gmail send --to user@example.com --subject \"Hello\" --from '\"Research Agent\" \u003Cuser@example.com>' --body \"Message text\"\n\n# Reply (automatically threads and sets In-Reply-To)\n$GAPI gmail reply MESSAGE_ID --body \"Thanks, that works for me.\"\n$GAPI gmail reply MESSAGE_ID --from '\"Support Bot\" \u003Cuser@example.com>' --body \"Thanks\"\n\n# Labels\n$GAPI gmail labels\n$GAPI gmail modify MESSAGE_ID --add-labels LABEL_ID\n$GAPI gmail modify MESSAGE_ID --remove-labels UNREAD\n```\n\n### Calendar\n\n```bash\n# List events (defaults to next 7 days)\n$GAPI calendar list\n$GAPI calendar list --start 2026-03-01T00:00:00Z --end 2026-03-07T23:59:59Z\n\n# Create event (ISO 8601 with timezone required)\n$GAPI calendar create --summary \"Team Standup\" --start 2026-03-01T10:00:00-06:00 --end 2026-03-01T10:30:00-06:00\n$GAPI calendar create --summary \"Lunch\" --start 2026-03-01T12:00:00Z --end 2026-03-01T13:00:00Z --location \"Cafe\"\n$GAPI calendar create --summary \"Review\" --start 2026-03-01T14:00:00Z --end 2026-03-01T15:00:00Z --attendees \"alice@co.com,bob@co.com\"\n\n# Delete event\n$GAPI calendar delete EVENT_ID\n```\n\n### Drive\n\n```bash\n$GAPI drive search \"quarterly report\" --max 10\n$GAPI drive search \"mimeType='application\u002Fpdf'\" --raw-query --max 5\n```\n\n### Contacts\n\n```bash\n$GAPI contacts list --max 20\n```\n\n### Sheets\n\n```bash\n# Read\n$GAPI sheets get SHEET_ID \"Sheet1!A1:D10\"\n\n# Write\n$GAPI sheets update SHEET_ID \"Sheet1!A1:B2\" --values '[[\"Name\",\"Score\"],[\"Alice\",\"95\"]]'\n\n# Append rows\n$GAPI sheets append SHEET_ID \"Sheet1!A:C\" --values '[[\"new\",\"row\",\"data\"]]'\n```\n\n### Docs\n\n```bash\n$GAPI docs get DOC_ID\n```\n\n## Output Format\n\nAll commands return JSON. Parse with `jq` or read directly. Key fields:\n\n- **Gmail search**: `[{id, threadId, from, to, subject, date, snippet, labels}]`\n- **Gmail get**: `{id, threadId, from, to, subject, date, labels, body}`\n- **Gmail send\u002Freply**: `{status: \"sent\", id, threadId}`\n- **Calendar list**: `[{id, summary, start, end, location, description, htmlLink}]`\n- **Calendar create**: `{status: \"created\", id, summary, htmlLink}`\n- **Drive search**: `[{id, name, mimeType, modifiedTime, webViewLink}]`\n- **Contacts list**: `[{name, emails: [...], phones: [...]}]`\n- **Sheets get**: `[[cell, cell, ...], ...]`\n\n## Rules\n\n1. **Never send email or create\u002Fdelete events without confirming with the user first.** Show the draft content and ask for approval.\n2. **Check auth before first use** — run `setup.py --check`. If it fails, guide the user through setup.\n3. **Use the Gmail search syntax reference** for complex queries — load it with `skill_view(\"google-workspace\", file_path=\"references\u002Fgmail-search-syntax.md\")`.\n4. **Calendar times must include timezone** — always use ISO 8601 with offset (e.g., `2026-03-01T10:00:00-06:00`) or UTC (`Z`).\n5. **Respect rate limits** — avoid rapid-fire sequential API calls. Batch reads when possible.\n\n## Troubleshooting\n\n| Problem | Fix |\n|---------|-----|\n| `NOT_AUTHENTICATED` | Run setup Steps 2-5 above |\n| `REFRESH_FAILED` | Token revoked or expired — redo Steps 3-5 |\n| `HttpError 403: Insufficient Permission` | Missing API scope — `$GSETUP --revoke` then redo Steps 3-5 |\n| `HttpError 403: Access Not Configured` | API not enabled — user needs to enable it in Google Cloud Console |\n| `ModuleNotFoundError` | Run `$GSETUP --install-deps` |\n| Advanced Protection blocks auth | Workspace admin must allowlist the OAuth client ID |\n\n## Revoking Access\n\n```bash\n$GSETUP --revoke\n```\n",{"name":5,"author":43,"license":14,"version":44,"metadata":45,"description":7},"Nous Research","1.0.0",{"hermes":46},{"tags":47,"homepage":57,"related_skills":58},[48,49,50,51,52,53,54,55,56],"Google","Gmail","Calendar","Drive","Sheets","Docs","Contacts","Email","OAuth","https:\u002F\u002Fgithub.com\u002FNousResearch\u002Fhermes-agent",[59],"himalaya","main","17ee50c38aefa9426a89d7e8ee167fdc4c184fb7","skills\u002Fproductivity\u002Fgoogle-workspace",0,"https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983","2026-05-24 00:14:48",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add xuanxuan1983\u002Fhermes-skills-backup --skill google-workspace",{"tool":73,"command":74},"bunx","bunx skills add xuanxuan1983\u002Fhermes-skills-backup --skill google-workspace",{"tool":76,"command":77},"pnpm","pnpm dlx skills add xuanxuan1983\u002Fhermes-skills-backup --skill google-workspace","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002FSKILL.md",true,[81,87,93],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"references\u002Fgmail-search-syntax.md","REFERENCE","参考文档",2150,"https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Freferences\u002Fgmail-search-syntax.md",{"path":88,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":91,"sourceHtmlUrl":92},"scripts\u002Fgoogle_api.py","SCRIPT","脚本",29848,"https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Fscripts\u002Fgoogle_api.py",{"path":94,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":95,"sourceHtmlUrl":96},"scripts\u002Fsetup.py",15138,"https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fproductivity\u002Fgoogle-workspace\u002Fscripts\u002Fsetup.py",[98,139,167,183,205,226],{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":120,"publishedAt":38},"01M71JFHVW1W4XE013TY9ZYN9P","writing-plans","Use when you have a spec or requirements for a multi-step task. Creates comprehensive implementation plans with bite-sized tasks, exact file paths, and complete code examples.","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fsoftware-development\u002Fwriting-plans\u002FSKILL.md",[104,109,112,117],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":110,"categoryName":111,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":113,"categoryName":114,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",{"categoryNo":118,"categoryName":119,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000036","内容创作者",[121,122,123,124,125,126,127,34,128,129,130,131,132,133,134,135,136,137,138,23],"writing","writing plans","plans","test-driven","test-driven-development","superpowers","design","workflow","you","code","tasks","subagent","code-review","review","documentation","paths","planning","development",{"skillNo":140,"name":125,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":152,"publishedAt":38},"01M71JFF859RV0XGWS206X1TMB","Use when implementing any feature or bugfix, before writing implementation code. Enforces RED-GREEN-REFACTOR cycle with test-first approach.","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fsoftware-development\u002Ftest-driven-development\u002FSKILL.md",[144,147,150,151],{"categoryNo":145,"categoryName":146,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":148,"categoryName":149,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":110,"categoryName":111,"taxonomyType":107,"taxonomyTypeDesc":108},{"categoryNo":118,"categoryName":119,"taxonomyType":115,"taxonomyTypeDesc":116},[153,138,154,155,156,157,158,159,160,161,126,121,162,34,130,132,163,164,165,166],"test driven development","test","driven","test-first","green","cycle","red-green-refactor","testing","implementing","debugging","systematic","bugfix","refactor","systematic-debugging",{"skillNo":168,"name":166,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":173,"publishedAt":38},"01M71JFCA5S48PZ5M7DG31R8K5","Use when encountering any bug, test failure, or unexpected behavior. 4-phase root cause investigation — NO fixes without understanding the problem first.","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fsoftware-development\u002Fsystematic-debugging\u002FSKILL.md",[172],{"categoryNo":148,"categoryName":149,"taxonomyType":107,"taxonomyTypeDesc":108},[174,162,163,124,175,176,125,126,121,34,132,177,178,138,179,180,123,181,182,154],"systematic debugging","problem","problem-solving","phase","bug","fixes","root cause","use","root-cause",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":198,"publishedAt":38},"01M71JF9RQ092KM5ZXCBBT6FS1","subagent-driven-development","Use when executing implementation plans with independent tasks. Dispatches fresh delegate_task per task with two-stage review (spec compliance then code quality).","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fsoftware-development\u002Fsubagent-driven-development\u002FSKILL.md",[189,190,193,194,195],{"categoryNo":110,"categoryName":111,"taxonomyType":107,"taxonomyTypeDesc":108},{"categoryNo":191,"categoryName":192,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":113,"categoryName":114,"taxonomyType":115,"taxonomyTypeDesc":116},{"categoryNo":118,"categoryName":119,"taxonomyType":115,"taxonomyTypeDesc":116},{"categoryNo":196,"categoryName":197,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000037","律师与法务",[199,132,138,155,124,125,200,201,126,121,34,128,130,131,133,134,202,203,204,123],"subagent driven development","delegate","delegation","fresh","parallel","code quality",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":209,"categories":210,"keywords":213,"publishedAt":38},"01M71JF76DA8ARZ4JRYR4VBRWM","requesting-code-review","Pre-commit verification pipeline — static security scan, baseline-aware quality gates, independent reviewer subagent, and auto-fix loop. Use after code changes and before committing, pushing, or opening a PR.","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fsoftware-development\u002Frequesting-code-review\u002FSKILL.md",[211,212],{"categoryNo":145,"categoryName":146,"taxonomyType":107,"taxonomyTypeDesc":108},{"categoryNo":113,"categoryName":114,"taxonomyType":115,"taxonomyTypeDesc":116},[214,215,130,134,124,216,217,125,218,219,126,220,121,221,222,223,132,133,224,225],"code review","requesting code review","pipeline","static","fix","auto-fix","auto","loop","security scan","commit","reviewer","verification",{"skillNo":227,"name":228,"nameZh":6,"description":229,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":230,"categories":231,"keywords":232,"publishedAt":38},"01M71JF52HZT5VQXFVF9K2H76K","plan","Plan mode for Hermes — inspect context, write a markdown plan into the active workspace's `.hermes\u002Fplans\u002F` directory, and do not execute the work.","https:\u002F\u002Fgithub.com\u002Fxuanxuan1983\u002Fhermes-skills-backup\u002Fblob\u002Fmain\u002Fskills\u002Fsoftware-development\u002Fplan\u002FSKILL.md",[],[228,233,234,137,138,23,235,236,123,121,128,132,237,238,239,240,19,241,242,243],"plan-mode","do","inspect","mode","work","markdown","active","directory","plan mode","write","implementation"]