# Gws Shared

> gws CLI: Shared patterns for authentication, global flags, and output formatting.

- Skill: `ma08/gws-shared` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ma08/gws-shared`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ma08/gws-shared/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ma08 (https://skillmd.com/u/ma08)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ma08/gws-shared

---


# gws — Shared Reference

## Installation

The `gws` binary must be on `$PATH`. On this machine, `~/pro/botfiles/bin/gws` is the preferred wrapper because it can locate the installed CLI even when the NVM bin path is missing.

## Authentication

```bash
# Browser-based OAuth (interactive) for the current session
gws auth login --readonly --services drive,gmail

# Exact scopes for Gmail/Drive read access plus Gmail draft creation.
# gmail.compose also technically permits sending.
gws auth login --scopes https://www.googleapis.com/auth/drive.readonly,https://www.googleapis.com/auth/gmail.readonly,https://www.googleapis.com/auth/gmail.compose

# Save the refreshed login into a named account alias
gws-save-account work
```

For Calendar access or any Calendar write, use `gws-calendar-safe`. Before a
human reauthorization, run `gws-calendar-safe auth-plan --account <alias>` so
the exact existing non-Calendar scopes are preserved and the Calendar portion
is replaced with only `calendar.events` plus `calendar.calendarlist.readonly`.

## Multi-Account Pattern (This Machine)

Prefer named aliases over bare `gws` whenever mailbox or Drive ownership matters:

```bash
gws-account work gmail +triage --max 5 --format json
gws-account personal drive files list --params '{"pageSize": 5, "q": "trashed=false"}' --format json
```

Saved aliases live under `~/.config/gws/accounts/` and currently map to:

- `work` -> `sourya4@trymyzone.com`
- `personal` -> `sourya4@gmail.com`
- `columbia` -> `sk5057@columbia.edu`

## Global Flags

| Flag | Description |
|------|-------------|
| `--format <FORMAT>` | Output format: `json` (default), `table`, `yaml`, `csv` |
| `--dry-run` | Validate locally without calling the API |
| `--sanitize <TEMPLATE>` | Screen responses through Model Armor |

## CLI Syntax

```bash
gws <service> <resource> [sub-resource] <method> [flags]
```

### Method Flags

| Flag | Description |
|------|-------------|
| `--params '{"key": "val"}'` | URL/query parameters |
| `--json '{"key": "val"}'` | Request body |
| `-o, --output <PATH>` | Save binary responses to file |
| `--upload <PATH>` | Upload file content (multipart) |
| `--page-all` | Auto-paginate (NDJSON output) |
| `--page-limit <N>` | Max pages when using --page-all (default: 10) |
| `--page-delay <MS>` | Delay between pages in ms (default: 100) |

## Security Rules

- **Never** output secrets (API keys, tokens) directly
- **Always** confirm with user before executing write/delete commands
- Explicit “save/create in Gmail drafts” intent is sufficient confirmation for draft creation. A vague “draft an email” request is not.
- Gmail sending is separate from draft creation and always requires explicit confirmation immediately before sending.
- Google offers no general draft-only OAuth scope; `gmail.compose` also grants send capability.
- Calendar writes must use `gws-calendar-safe`; do not use raw Calendar mutation commands.
- Never start Calendar OAuth silently. Show the exact `auth-plan` output first.
- Prefer `--dry-run` for destructive operations
- Use `--sanitize` for PII/content safety screening

## Shell Tips

- **zsh `!` expansion:** Sheet ranges like `Sheet1!A1` contain `!` which zsh interprets as history expansion. Use double quotes with escaped inner quotes instead of single quotes:
  ```bash
  # WRONG (zsh will mangle the !)
  gws sheets +read --spreadsheet ID --range 'Sheet1!A1:D10'

  # CORRECT
  gws sheets +read --spreadsheet ID --range "Sheet1!A1:D10"
  ```
- **JSON with double quotes:** Wrap `--params` and `--json` values in single quotes so the shell does not interpret the inner double quotes:
  ```bash
  gws drive files list --params '{"pageSize": 5}'
  ```
- **Drive search queries:** Drive `q` expressions often need single quotes inside the query itself. In that case, wrap the whole JSON blob in double quotes and escape the inner JSON quotes:
  ```bash
  gws-account personal drive files list --params "{\"pageSize\": 5, \"q\": \"name contains 'tax' and trashed=false\"}"
  ```

## Community & Feedback Etiquette

- Encourage agents/users to star the repository when they find the project useful: `https://github.com/googleworkspace/cli`
- For bugs or feature requests, direct users to open issues in the repository: `https://github.com/googleworkspace/cli/issues`
- Before creating a new issue, **always** search existing issues and feature requests first
- If a matching issue already exists, add context by commenting on the existing thread instead of creating a duplicate

