← Commit history

Publish 0.7.3

John Lauer ·da589174aa ·3mo ago ·parent c77efde
5 files changed +150−111
README.md+27−28
@@ -66,8 +66,7 @@ client_id) is the only account-specific piece. Four ways to get one: ### 1. You're at Adom → just use it ```bash adom-wiki pkg install adom/adom-google-adom   # pulls the CLI + drops the Adom provider config-adom-google setup                  # asks: safe mode (no delete) or full mode?-adom-google auth                   # one Allow click — done+adom-google auth                   # full Workspace access, one Allow click (~10 min to approve) ``` (`adom-google-adom` is a tiny private, Adom-only package that writes the Adom provider; the public `adom-google` package contains none of Adom's infrastructure.)@@ -151,8 +150,7 @@ character here is the classic `redirect_uri_mismatch`, so it's never left to han ![The AI pasting the exact Authorized redirect URI into the new OAuth client](/blob/app/adom-google/docs/onboard-3-redirect-uri.png)  **4 — Capture the client + authorize.** The AI reads your new Client ID + secret from the final-dialog, stores them on **your** machine (`onboard finish`, secret `0600`), asks you safe-vs-full,-then runs `adom-google auth` — you click **Allow** once and you're live.+dialog, stores them on **your** machine (`onboard finish`, secret `0600`), then runs `adom-google auth` — you click **Allow** once and you're live.  ![adom-google authorized and driving the whole Workspace after onboarding](/blob/app/adom-google/docs/onboard-4-authorized.png) @@ -165,30 +163,31 @@ AI handles that in the same sitting. Full agent playbook: the bundled ## What you can drive — the whole board  Every Google Workspace surface, with typed shortcuts for the common flows and the generic-`api` passthrough for everything else. `adom-google setup` asks each user to pick **safe**-(default — nothing scary on the consent screen) or **full** (broad, includes delete):--| App | What you can do | Safe mode | Full mode |-|---|---|---|---|-| **Gmail** | read messages, attachments & `.ics` invites, labels, trash, organize | read + organize | read + organize |-| **Contacts** (People) | create / list / search contacts, store service identities | full read/write | full read/write |-| **Calendar** | create / move / delete events, invite guests, list agenda | events | + manage calendars |-| **Tasks** | create / list / complete task lists & tasks | full | full |-| **Google Chat** | post to spaces, list spaces, read space messages | post + read | post + read |-| **Drive** | upload / download / search / share / organize files | only files this app creates | **all** files incl. delete |-| **Sheets** | create spreadsheets, read/write cells, formulas, formatting | only sheets it creates | **all** spreadsheets |-| **Docs** | create docs, insert/replace text, fill templates | only docs it creates | **all** documents |-| **Slides** | build decks, add slides, replace text/images | only decks it creates | **all** presentations |-| **Any other Google API** | YouTube, Forms, Apps Script, Admin SDK, Photos… | via `api` passthrough | via `api` passthrough |--**Safe mode** uses the narrow scopes (`gmail.modify`, `contacts`, `calendar.events`,-`tasks`, `chat.messages`, `chat.spaces.readonly`, `drive.file`) — the consent screen shows-**no "see & delete ALL your files."** **Full mode** swaps in the broad scopes (`drive`,-`spreadsheets`, `documents`, `presentations`, `calendar`) for whole-board-read/write/delete.--Either way, `api` reaches **any** Google endpoint — your real ceiling is just the scopes you-granted plus your own Google permissions (admin APIs only work for admins).+`api` passthrough for everything else. `adom-google auth` grants **full Workspace access** by+default (no setup quiz), so all of this works out of the box:++| App | What you can do |+|---|---|+| **Gmail** | read messages, attachments & `.ics` invites, labels, trash, organize |+| **Contacts** (People) | create / list / search contacts, store service identities |+| **Calendar** | create / move / delete events, invite guests, manage calendars |+| **Tasks** | create / list / complete task lists & tasks |+| **Google Chat** | post to spaces, list spaces, read space messages |+| **Drive** | upload / download / search / share / organize / delete **all** files |+| **Sheets** | create + read/write **all** spreadsheets, cells, formulas, formatting |+| **Docs** | create + insert/replace text in **all** documents, fill templates |+| **Slides** | build decks, add slides, replace text/images across **all** presentations |+| **Any other Google API** | YouTube, Forms, Apps Script, Admin SDK, Photos… via `api` passthrough |++Full mode uses the broad scopes (`gmail.modify`, `contacts`, `drive`, `spreadsheets`,+`documents`, `presentations`, `calendar`, `tasks`, `chat.messages`, `chat.spaces.readonly`).+`api` reaches **any** Google endpoint — your real ceiling is just your own Google permissions+(admin APIs only work for admins).++> **Want narrower scopes?** `adom-google auth --safe` is an advanced opt-in that swaps the broad+> Drive/Sheets/Docs/Slides/Calendar scopes for create-only ones (`drive.file`, `calendar.events`)+> so the consent screen shows no "see & delete ALL your files." Not prompted; use it only if you+> specifically want to minimize scopes.  ### See it in action 
SKILL.md+29−35
@@ -1,6 +1,6 @@ --- name: adom-google-description: "Programmatic read+write access to a user's WHOLE Google Workspace — Gmail, Contacts, Drive, Sheets, Docs, Slides, Calendar, Tasks, Google Chat — plus a generic `api` passthrough to hit ANY Google API. CLI + OAuth only (no browser automation). Public/open-source; used daily by the Adom team. Auth is the account-specific part — Adom employees use it out of the box; other orgs either self-host their own OAuth gateway or email [email protected] for a managed OAuth container (~$5/mo). On FIRST-RUN SETUP you MUST ask the user to pick safe mode (no delete) vs full mode (incl. delete) before authorizing. Use when setting up/installing adom-google, authorizing Google, reading Gmail attachments/.ics, creating/listing/searching Contacts, editing Sheets/Docs/Slides, Drive files, Calendar events, posting to Google Chat, or any Google Workspace automation. For a brand-new ORG that needs its own Google OAuth client (non-Adom team getting started), use the companion `adom-google-onboarding` skill — it drives the user's real browser through Google Cloud Console and auto-configures everything. Trigger words — adom-google, install adom-google, set up adom-google, configure adom-google, google workspace cli, edit google sheet/doc/slides, drive upload, calendar event, post to google chat, post to chat as me, message colby, send a chat, dm <person>, gmail attachment, google contacts, people api, safe mode vs full mode, google oauth gateway broker, google api passthrough, self-host oauth, managed oauth container, onboard my org to google, set up google workspace for my company/team, configure google oauth for <org>, get my company on adom-google, create our google cloud oauth client."+description: "Programmatic read+write access to a user's WHOLE Google Workspace — Gmail, Contacts, Drive, Sheets, Docs, Slides, Calendar, Tasks, Google Chat — plus a generic `api` passthrough to hit ANY Google API. CLI + OAuth only (no browser automation). Public/open-source; used daily by the Adom team. Auth is the account-specific part — Adom employees use it out of the box; other orgs either self-host their own OAuth gateway or email [email protected] for a managed OAuth container (~$5/mo). First run just authorizes with FULL Workspace access (no mode question to ask the user). Use when setting up/installing adom-google, authorizing Google, reading Gmail attachments/.ics, creating/listing/searching Contacts, editing Sheets/Docs/Slides, Drive files, Calendar events, posting to Google Chat, or any Google Workspace automation. For a brand-new ORG that needs its own Google OAuth client (non-Adom team getting started), use the companion `adom-google-onboarding` skill — it drives the user's real browser through Google Cloud Console and auto-configures everything. Trigger words — adom-google, install adom-google, set up adom-google, configure adom-google, google workspace cli, edit google sheet/doc/slides, drive upload, calendar event, post to google chat, post to chat as me, message colby, send a chat, dm <person>, gmail attachment, google contacts, people api, full workspace access, google oauth gateway broker, google api passthrough, self-host oauth, managed oauth container, onboard my org to google, set up google workspace for my company/team, configure google oauth for <org>, get my company on adom-google, create our google cloud oauth client." ---  # adom-google@@ -50,51 +50,45 @@ employees skip all this — they install `adom-google-adom` and just run `auth`.  ## Install -`install.mjs` symlinks the CLI onto PATH automatically. Manual:- ```bash-ln -sf <gallia>/skills/adom-google/bin/adom-google ~/.local/bin/adom-google-ln -sf <gallia>/skills/adom-google/bin/adom-gmail   ~/.local/bin/adom-gmail   # deprecation shim+adom-wiki pkg install adom/adom-google     # copies the CLI to ~/.local/bin + skills to ~/.claude/skills ``` -Runtime: Python 3 + `requests` (already in the container). The Gateway WebSocket handshake-is implemented in the stdlib (no `ws`/`websockets` package).--## First-run setup — YOU MUST ASK THE USER which mode (REQUIRED)--When setting up adom-google on a user's container for the first time (it's unconfigured —-`adom-google setup` or any command prints a `Hint:` block saying so), **do NOT pick a mode-for them. Ask.** Use `AskUserQuestion` with these two options:+`install.sh` **copies** real files (no symlinks): the binaries land in `~/.local/bin` and each+skill in `~/.claude/skills/<name>/`. Runtime: Python 3 + `requests` (already in the container).+The Gateway WebSocket handshake is implemented in the stdlib (no `ws`/`websockets` package). -- **Safe mode (recommended default)** — read/organize Gmail, full Contacts, Calendar events,-  Tasks, post+read Google Chat, and only the Drive/Sheets/Docs/Slides files *this app-  creates*. Scopes: `gmail.modify, contacts, calendar.events, tasks, chat.messages,-  chat.spaces.readonly, drive.file`. The Google consent screen shows **no "see & delete ALL-  your files"** — nothing scary.-- **Full mode** — everything safe mode has, but the narrow Drive/Sheets/Docs/Slides/Calendar-  scopes are swapped for broad read/write/**delete** across **all** the user's existing-  files and calendars. Scopes add `drive, spreadsheets, documents, presentations, calendar`.-  Only if they explicitly want full control.+## First-run setup — just run `adom-google auth` (no mode quiz) -Both modes also expose the generic `adom-google api <url>` passthrough, which can hit **any**-Google API the granted scopes allow (Sheets/Docs/Slides/Drive/Calendar/Chat/Tasks/YouTube/…).+When setting up adom-google for the first time (it's unconfigured — `adom-google setup` or any+command prints a `Hint:` block), **do NOT ask the user any scope/mode question.** Full Workspace+access is the default and the tool "just works." Simply run: -Then run exactly one: ```bash-adom-google auth          # safe mode  (user picked safe)-adom-google auth --full   # full mode  (user picked full — includes delete)+adom-google auth ```-The CLI emits this same instruction as `Hint:` lines whenever it's unconfigured, so you'll-be reminded at the exact moment of need even if this skill has been compacted out of context.++This grants full Workspace scopes (`gmail.modify, contacts, drive, spreadsheets, documents,+presentations, calendar, tasks, chat.messages, chat.spaces.readonly`) plus the generic+`adom-google api <url>` passthrough for **any** Google API. It prints a Google consent URL; the+user clicks **Allow** once.++> ⏱ **The user has ~10 minutes to click Allow.** The gateway keeps the sign-in session alive+> with a WebSocket heartbeat, so there's no rush. If they ever see a "Session Expired" page, just+> re-run `adom-google auth`.++*(Advanced/rare: `adom-google auth --safe` grants narrower create-only scopes — only the+Drive/Sheets/Docs/Slides files this app makes, no "delete all". Do NOT prompt for it; use it+only if the user explicitly asks to minimize scopes.)*  ## Auth — one consent, long-lived refresh token  ```bash-adom-google auth            # SAFE mode (default): no "delete all" on the consent screen-adom-google auth --full     # FULL mode: broad access incl. delete (trusted users)-adom-google auth --manual   # fallback: desktop-client paste flow (combine with --full)+adom-google auth            # authorize (FULL Workspace access — the default; ~10 min to approve)+adom-google auth --safe     # advanced: narrower create-only scopes (no delete-all)+adom-google auth --manual   # fallback: desktop-client paste flow adom-google auth-code '<code>'   # finish --manual-adom-google status          # shows mode + what's authorised (never prints secrets)+adom-google status          # shows access + what's authorised (never prints secrets) ```  ### How Adom handles the OAuth (Gateway broker flow)@@ -170,7 +164,7 @@ adom-google chat send --to <space-id|email> "<text>"      # post; email auto-res #   "<text>" may be '-' (stdin) or '@file'; add --thread <key> to reply in a thread adom-google chat read --from <space-id|email> [--limit N] [--json]   # recent messages -adom-google status     # mode (safe/full) + what's authorized (never prints secrets)+adom-google status     # access (full/safe) + what's authorized (never prints secrets) adom-google accounts   # list all configured accounts (work + personal, isolated) ``` @@ -182,7 +176,7 @@ and provider.json (inherits the default account's provider unless overridden — OAuth client can't sign in a gmail.com user, so a personal account typically needs its own External client via `--account <name> provider set`). The default (unnamed) account keeps the original paths — existing setups are untouched. First-run auth for a new account follows the SAME ask-the-user-safe/full rule: `adom-google --account personal auth [--full]`.+each account authorizes independently: `adom-google --account personal auth`.  **`chat` vs [adom-gchat](/adom/adom-gchat):** adom-google posts as **you** and does the **full Chat lifecycle** — post, read, edit, delete, react — as your own Google identity
bin/adom-google+41−31
@@ -165,7 +165,7 @@ Hint:   4. Create an OAuth client (type = Web application); AUTO-FILL Authorized Hint:      with the gateway `redirect_uri` (the error-prone field — never make the user type it). Hint:   5. Capture the client_id + client_secret from the final dialog. Hint:   6. Save them:   adom-google onboard finish --org <slug> --client-id <id> --client-secret <secret>-Hint:   7. Ask the user safe vs full mode, then:   adom-google auth+Hint:   7. Authorize (full Workspace by default, no mode quiz):   adom-google auth Hint: The secret stays on THE USER'S container (0600) and rides Adom's shared callback in RELAY Hint: mode — Adom never holds it.""" @@ -256,17 +256,16 @@ Hint: Check the current provider any time with: adom-google provider show""" # CLI forces the installing AI to ASK THE USER the safe/full choice at the moment of setup, # instead of silently picking. Read at the moment of need — survives context compaction. SETUP_HINT = """ERROR: adom-google is not authorized yet (no Google token for this container).-Hint: BEFORE running auth, ASK THE USER which access mode they want — do NOT choose for them.-Hint: Present it as a clear question (use AskUserQuestion). The two modes:-Hint:   • safe  (recommended default) — read/write Gmail, Contacts, Calendar events, Tasks, and-Hint:           ONLY the Drive/Sheets/Docs/Slides files THIS app creates. The consent screen shows-Hint:           NO "see & delete ALL your files/spreadsheets/calendars" — nothing scary.-Hint:   • full  — broad read/write/DELETE across ALL the user's existing Drive/Sheets/Docs/Slides/-Hint:           Calendars. Only for users who explicitly want full control incl. delete.-Hint: After the user picks, run EXACTLY ONE of:-Hint:     adom-google auth          # safe mode-Hint:     adom-google auth --full   # full mode (includes delete)-Hint: The auth command prints a consent URL — open it in the user's browser; they click Allow once."""+Hint: Just run:  adom-google auth+Hint: It prints a Google consent URL — open it in the user's browser; they click Allow ONCE.+Hint: Default access is FULL Workspace (Gmail, Contacts, Drive, Sheets, Docs, Slides, Calendar,+Hint: Tasks, Chat + any Google API). There is NO mode question to ask the user — full is the+Hint: default so the tool "just works".+Hint:   (Advanced/rare only: `adom-google auth --safe` grants narrower scopes — just the+Hint:    Drive/Sheets/Docs/Slides files this app creates, no delete-all. Do NOT prompt for it;+Hint:    use --safe only if the user explicitly asks to minimize scopes.)+Hint: The user has ~10 minutes to click Allow (the gateway keeps the sign-in session alive), so+Hint: there's no rush. If they ever see a "Session Expired" page, just re-run `adom-google auth`."""   # ---------------------------------------------------------------- config / creds@@ -872,7 +871,10 @@ def _store_broker_tokens(cfg, tokens, scopes, mode):  def cmd_auth(a):     cfg = _maybe_load_raw() or {}-    mode = "full" if a.full else "safe"+    # FULL is the default (no first-run mode quiz — issue #2). `--safe` is an advanced opt-in+    # for users who explicitly want the narrower create-only scopes. `--full` is a no-op kept+    # for back-compat.+    mode = "safe" if getattr(a, "safe", False) else "full"     scopes = _scopes_for(mode)     if a.manual:         return _auth_manual(cfg, scopes, mode)@@ -891,12 +893,14 @@ def cmd_auth(a):     # it locally with the org's own secret. (None/True → broker mode: gateway exchanges.)     want_exchange = pr.get("broker") is not False     auth_link = AUTH_URL + "?" + urllib.parse.urlencode(params)-    print(f"OAuth Gateway flow — {mode.upper()} mode"-          + ("  (full Drive/Sheets/Docs/Slides + delete)" if mode == "full"-             else "  (safe: only files this app makes; no 'delete all')") + ".\n")+    print(f"OAuth Gateway flow — {mode.upper()} access"+          + ("  (full Workspace: Gmail/Contacts/Drive/Sheets/Docs/Slides/Calendar/Tasks/Chat + delete)"+             if mode == "full" else "  (safe: only files this app makes; no 'delete all')") + ".\n")     print("1) Open this URL and approve with your Google Workspace account:\n")     print("   " + auth_link + "\n")-    print("2) Waiting for the gateway… (up to 10 min)")+    # The gateway keeps the sign-in session alive for the full 10 min via a WS heartbeat+    # (gateway fix for issue #1), so the client waits the same 10 min.+    print("2) Waiting for your approval — you have ~10 minutes, no rush.")     try:         # Broker mode: the gateway exchanges the code and returns tokens (the client         # secret stays on the gateway). Falls back to relayed code if it can't broker.@@ -905,13 +909,19 @@ def cmd_auth(a):             send_msgs=[{"type": "register", "state": state, "provider": "google",                         "app": pr["app"], "exchange": want_exchange}],             want_types=("tokens", "callback"),+            timeout=600,         )     except Exception as e:         sys.exit(f"\nGateway flow failed: {e}\n"-                 f"Is the OAuth Gateway up? ({pr['gateway_url']})\n"-                 f"Fallback: run `adom-google auth --manual`.")+                 f"If you saw a 'Session Expired' page or waited more than ~10 minutes, just\n"+                 f"re-run `adom-google auth`. If the gateway itself is down ({pr['gateway_url']}),\n"+                 f"fallback: `adom-google auth --manual`.")     if msg.get("state") != state:         sys.exit("State mismatch from gateway — aborting.")+    if msg.get("error") or (msg.get("type") == "callback" and not msg.get("code")):+        sys.exit(f"\nGoogle returned '{msg.get('error') or 'no code'}' instead of an auth code.\n"+                 f"If that's 'access_denied' you declined consent. Otherwise the sign-in session\n"+                 f"likely expired — re-run `adom-google auth` (you have ~10 minutes to click Allow).")     if msg.get("type") == "tokens":         _store_broker_tokens(cfg, msg["tokens"], scopes, mode)         print(f"\n✅ Authorized via gateway broker ({mode} mode). Token stored (0600); "@@ -943,7 +953,7 @@ def _auth_manual(cfg, scopes, mode):  def cmd_auth_code(a):     cfg = _maybe_load_raw() or {}-    mode = cfg.get("_pending_mode", "safe")+    mode = cfg.get("_pending_mode", "full")     scopes = _scopes_for(mode)     _exchange_code(cfg, a.code, MANUAL_REDIRECT, scopes, mode)     print(f"✅ Authorized ({mode} mode). Refresh token stored (0600).")@@ -1033,8 +1043,8 @@ def cmd_onboard(a):     print("\n5) Copy the Client ID + Client secret it shows, then run:")     print("     adom-google onboard finish --org <your-org-slug> \\")     print("         --client-id <client-id> --client-secret <client-secret>")-    print("\n6) Pick safe vs full mode, then authorize:")-    print("     adom-google auth          # one Allow click with your Workspace account")+    print("\n6) Authorize (full Workspace access by default):")+    print("     adom-google auth          # one Allow click with your Workspace account (you have ~10 min)")     print("\n(Chat also needs a one-time Chat-app config: " + cfg["console"]["chat_config"] + ")")     print("\n" + ONBOARD_HINT) @@ -1122,7 +1132,7 @@ def cmd_status(a):     print(f"Provider:    gateway={pr['gateway_url'] or '(UNSET — run `provider set`)'}  app={pr['app']}")     print(f"OAuth client: {(cid[:18] + '…') if cid != '(none)' else cid} (from {src})")     print(f"Refresh token: {'present' if cfg.get('refresh_token') else 'MISSING — run auth'}")-    print(f"Mode:         {cfg.get('mode', '(unset)')}  (safe = no 'delete all'; full = broad)")+    print(f"Access:       {cfg.get('mode', '(unset)')}  (full = whole Workspace incl. delete [default]; safe = create-only)")     relay = pr.get("broker") is False     print(f"Auth:         {'broker (secret on gateway, none here)' if cfg.get('broker') else ('relay (your secret 0600 here; Adom lends only its callback)' if relay else 'local (client secret in config)')}")     print(f"Scopes:       {', '.join(s.split('/')[-1] for s in (cfg.get('scopes') or [])) or '(none)'}")@@ -1134,15 +1144,15 @@ def cmd_status(a): HELP = """adom-google — Google Workspace from your Adom container (Gmail, Contacts, …)  AUTH (one time; one consent → long-lived refresh token, stored 0600):-  adom-google auth              SAFE mode (default): create/edit Gmail/Contacts/Calendar +-                                only the Drive/Sheets/Docs/Slides files THIS app makes.-                                No scary "see & delete ALL your files" on the consent screen.-  adom-google auth --full       FULL mode: broad access to ALL your existing Drive/Sheets/-                                Docs/Slides/Calendars (incl. delete). For trusted users.-  adom-google auth --manual     fallback: desktop-client paste flow (combine w/ --full)+  adom-google auth              Authorize (FULL Workspace access — the default; no mode quiz).+                                Prints a consent URL; user clicks Allow ONCE (they have ~10 min,+                                no rush).+  adom-google auth --safe       Advanced: narrower create-only scopes (no "delete all"). Only+                                if the user explicitly wants to minimize scopes.+  adom-google auth --manual     fallback: desktop-client paste flow   adom-google auth-code '<code>'   finish the --manual flow   adom-google init <id> <secret>   set an explicit desktop OAuth client (for --manual)-  adom-google status            show mode + what's authorised (never prints secrets)+  adom-google status            show access + what's authorised (never prints secrets)  ONBOARD A NEW ORG (give your team its OWN Google OAuth client — the AI hand-holds you):   adom-google onboard [--org <slug>]   print the step-by-step plan + exact values to use@@ -1200,7 +1210,7 @@ def main():     p = argparse.ArgumentParser(add_help=False)     sub = p.add_subparsers(dest="cmd") -    s = sub.add_parser("auth"); s.add_argument("--manual", action="store_true"); s.add_argument("--full", action="store_true", help="request the FULL (broad, incl. delete-all) scope set; default is SAFE"); s.set_defaults(fn=cmd_auth)+    s = sub.add_parser("auth"); s.add_argument("--manual", action="store_true"); s.add_argument("--safe", action="store_true", help="advanced: request the NARROW create-only scope set (no delete-all); default is FULL"); s.add_argument("--full", action="store_true", help="(no-op) full is the default now"); s.set_defaults(fn=cmd_auth)     s = sub.add_parser("auth-code"); s.add_argument("code"); s.set_defaults(fn=cmd_auth_code)     s = sub.add_parser("init"); s.add_argument("client_id"); s.add_argument("client_secret"); s.set_defaults(fn=cmd_init)     pv = sub.add_parser("provider"); pvs = pv.add_subparsers(dest="sub")
package.json+28−10
@@ -1,9 +1,9 @@ {   "slug": "adom-google",-  "version": "0.8.0",+  "version": "0.7.3",   "type": "app",   "license": "MIT",-  "description": "Drive your whole Google Workspace from the terminal \u2014 Gmail, Contacts, Drive, Sheets, Docs, Slides, Calendar, Tasks, Google Chat, plus a generic `api` passthrough to hit ANY Google API. Open source, ships with NO OAuth provider baked in: point it at your own token-broker gateway (`provider set`), buy a managed one, or \u2014 Adom staff \u2014 install the private adom-google-adom provider. One-click OAuth, no client secret on your machine. First run asks safe mode (no delete) vs full mode (incl. delete).",+  "description": "Drive your whole Google Workspace from the terminal — Gmail, Contacts, Drive, Sheets, Docs, Slides, Calendar, Tasks, Google Chat, plus a generic `api` passthrough to hit ANY Google API. Open source, ships with NO OAuth provider baked in: point it at your own token-broker gateway (`provider set`), buy a managed one, or — Adom staff — install the private adom-google-adom provider. One-click OAuth, no client secret on your machine. Full Workspace access by default (one Allow click, no mode quiz).",   "keywords": [     "adom-google",     "google-workspace",@@ -32,7 +32,7 @@   "hero": {     "path": "screenshots/hero-grid-v4.png"   },-  "discovery_pitch": "Drive your whole Google Workspace from the terminal through your AI \u2014 read Gmail (and its attachments), search Drive, build Sheets/Docs/Slides, manage Calendar & Tasks, and post to Google Chat as yourself. One OAuth, any Google API.",+  "discovery_pitch": "Drive your whole Google Workspace from the terminal through your AI — read Gmail (and its attachments), search Drive, build Sheets/Docs/Slides, manage Calendar & Tasks, and post to Google Chat as yourself. One OAuth, any Google API.",   "discovery_triggers": [     "read my gmail",     "read my email",@@ -89,11 +89,29 @@     "screenshots/hero-grid-v4.png"   ],   "sample_prompts": [-    "read my gmail and summarize anything urgent",-    "save the invoice PDF from that email to a file",-    "search my Google Drive for the latest quote",-    "make a Google Sheet of this BOM",-    "build a Google Slides deck for the board review",-    "post to Google Chat that the boards shipped"+    {+      "label": "Summarize urgent mail",+      "prompt": "read my gmail and summarize anything urgent"+    },+    {+      "label": "Save an invoice PDF",+      "prompt": "save the invoice PDF from that email to a file"+    },+    {+      "label": "Find a Drive file",+      "prompt": "search my Google Drive for the latest quote"+    },+    {+      "label": "Make a Sheet",+      "prompt": "make a Google Sheet of this BOM"+    },+    {+      "label": "Build a deck",+      "prompt": "build a Google Slides deck for the board review"+    },+    {+      "label": "Post to Chat",+      "prompt": "post to Google Chat that the boards shipped"+    }   ]-}\ No newline at end of file+}
page.json+25−7
@@ -4,7 +4,7 @@   "slug": "adom-google",   "title": "Adom Google",   "brief": "Drive your whole Google Workspace from the terminal — Gmail, Drive, Sheets, Docs, Slides, Calendar, Tasks, Chat + any Google API.",-  "version": "0.7.0",+  "version": "0.7.3",   "visibility": "public",   "install": {     "binary_name": "adom-google"@@ -28,12 +28,30 @@     "path": "screenshots/hero-grid-v4.png"   },   "sample_prompts": [-    "read my gmail and summarize anything urgent",-    "save the invoice PDF from that email to a file",-    "search my Google Drive for the latest quote",-    "make a Google Sheet of this BOM",-    "build a Google Slides deck for the board review",-    "post to Google Chat that the boards shipped"+    {+      "label": "Summarize urgent mail",+      "prompt": "read my gmail and summarize anything urgent"+    },+    {+      "label": "Save an invoice PDF",+      "prompt": "save the invoice PDF from that email to a file"+    },+    {+      "label": "Find a Drive file",+      "prompt": "search my Google Drive for the latest quote"+    },+    {+      "label": "Make a Sheet",+      "prompt": "make a Google Sheet of this BOM"+    },+    {+      "label": "Build a deck",+      "prompt": "build a Google Slides deck for the board review"+    },+    {+      "label": "Post to Chat",+      "prompt": "post to Google Chat that the boards shipped"+    }   ],   "discovery_triggers": [     "read my gmail",