garrytan/gbrain

google-loops

Set up and operate the Gmail/Calendar/Contacts connector and the open-loop needed to respond. Covers painless BYO OAuth setup (exactly two user interactions), the daily `gbrain waiting` digest, loop closing/muting, and troubleshooting via the typed error catalog.

Installation

$ npx skills add garrytan/gbrain --skill google-loops

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from garrytan/gbrain · top by installs.

npx skills add garrytan/gbrain

Browse all from garrytan/gbrain

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 29.7K
License LICENSE
Default branch master
Open issues 107
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,885 B
  • docs SUMMARY.md 355 B

History

  1. First recorded snapshot · 3 installs

SKILL.md

Google Loops — Setup and Daily Operation

The connector ingests Gmail threads, calendar events, and contacts into the brain and maintains the open-loop record behind gbrain waiting. Full references: docs/guides/google-connect.md (setup + every error and its fix) and docs/guides/open-loops.md (how detection works).

Contract for the harness (read first)

  1. Relay [SHOW USER] blocks verbatim. Setup commands print fenced

[SHOW USER] ... [/SHOW USER] blocks — numbered steps with deep links. Pass them to the user unchanged (paraphrasing loses load-bearing detail like "Desktop app, NOT Web application"). Batch everything into ONE message per block.

  1. The whole setup is exactly two user interactions. (1) The Google

Cloud checklist + the user hands back the downloaded client JSON. (2) The user clicks one consent URL. If you find yourself asking a third question, re-read the block you skipped.

  1. Never put secrets in argv or chat when avoidable. When the user drops

clientsecret*.json into chat, save it to a file (mode 0600) and pass the path: gbrain google connect --client-json <path>. Env (GOOGLECLIENTID/GOOGLECLIENTSECRET) also works. Raw --client-id/--client-secret flags are the last resort.

  1. Every command speaks JSON. Add --json and read

{ ok, status, nextaction: { command, usermessage }, error }. When nextaction.usermessage is present, that IS the message to show the user; when nextaction.command is present, that is your next call. Errors carry { code, problem, cause, fix, docurl } — show the user problem + fix, nothing else.

  1. Re-running is always safe. gbrain google connect and

gbrain google setup are idempotent state machines — the documented fix for most errors is "run it again."

Setup (the one command)

gbrain google setup --json

Handles: credential intake (prints the GCP checklist when nothing is on file) → consent (loopback locally; auto paste-back over SSH/headless — non-TTY flows complete via a second call: gbrain google connect --code "<pasted-redirect-url>") → source registration → a budgeted first sync (newest mail first; the deep backfill resumes on later syncs automatically) → the first gbrain waiting digest.

Multiple accounts: repeat with --account [email protected].

Already holding Google access another way (a Google CLI with its own auth, gcloud, a credential gateway that mints tokens)? Skip OAuth and point the source at it — no credential enters gbrain:

gbrain sources add gmail-work --kind google --account [email protected] \
  --access command --token-command "<command that prints an access token>"

(--access env --token-env <VAR> reads an externally-refreshed token from the environment instead.) Then gbrain sync --source gmail-work and gbrain waiting work identically.

Verify health afterwards: gbrain google status --json (per-account refresh probe) — and gbrain doctor carries a google_oauth check that warns once a Testing-mode account goes 5+ days without a successful refresh. An actively-syncing account gets no pre-warning before the 7-day Testing-mode expiry — publishing to Production is the real fix.

Daily operation

gbrain waiting --json        # the killer output: ranked people waiting
gbrain loops done <id>       # user handled it
gbrain loops drop <id>       # user is not going to do it
gbrain loops mute sender <email>   # never track this sender again
  • waiting REFUSES on stale data (no successful sync in 24h) and names the

exact fix (gbrain sync --source <id>). Run the sync, then retry. Only use --stale-ok when the user explicitly accepts stale results.

  • When presenting loops, show: the counterparty, what's owed (summary), the

evidence quote, the deep link (opens the exact Gmail thread in the right account), and the due date when present. The trusted-local result already carries a paste-ready text digest — reuse it.

  • For "context to respond": each group carries the counterparty's entity

card (summary, recent history, other open threads). Need more, call context_pack with the counterparty slug.

  • After the user says they replied/handled something, close the loop

(loops done) — thread loops also self-close on the next sync when the reply is visible in Gmail.

Continuous ingestion

Google sources sync like any source: autopilot and gbrain sync --all pick them up automatically. No cron of its own. A bare un-targeted gbrain sync does NOT reach them — use --source <id> or --all.

Troubleshooting

Every failure has a typed code with the fix attached — docs/guides/google-connect.md#troubleshooting is the canonical table. The three the user will actually hit:

  • "Google hasn't verified this app" during consent → expected; it's the

user's own app: Advanced → Continue. Warn them BEFORE they click the URL.

  • accessdeniedtest_user → they forgot to add themselves as a test

user (the error carries the deep link).

  • invalidgranttesting_expiry (everything silently stopped ~day 7) →

their consent screen is still in Testing; publish to Production, then gbrain google connect --reauth <email>.

Cost honesty

Commitment extraction sends recent email text (≤30 days, ≤50 threads/sweep) to the configured chat provider. Tell the user once during setup; the off switch is gbrain config set loops.extraction_enabled false. The unanswered-thread detector is free and unaffected.

Output Format

When relaying gbrain waiting, present per counterparty, most urgent first:

## <Counterparty> (<N> open)
- [<loop_type>] <what's owed> (<age>) — due <date if any>
  > "<evidence quote>"
  <Gmail deep link>

The trusted-local --json result already carries this as a paste-ready text field — prefer relaying it over re-rendering. For setup commands, relay [SHOW USER] blocks verbatim and error.problem + error.fix on failures; never dump raw JSON envelopes at the user.

Anti-Patterns

  • Paraphrasing a [SHOW USER] block. The checklists carry load-bearing

detail ("Desktop app, NOT Web application", the test-user step). Relay verbatim, one message per block.

  • Asking the user for clientid/clientsecret as chat text. Take the

downloaded JSON as a 0600 file (--client-json <path>) or env vars; secrets in argv/chat are the last resort, never the default.

  • Answering "who is waiting on me" from query/search. The open-loop

record is open_loops / gbrain waiting — search results have no loop-state semantics and will happily surface answered threads.

  • Bypassing the staleness refusal with --stale-ok silently. Run the

named gbrain sync --source <id> first; only pass --stale-ok when the user explicitly accepts possibly-outdated loops.

  • Marking loops done for the user. Close (gbrain loops done <id>) only

after the user says it's handled; thread loops self-close on the next sync when the reply is visible in Gmail.