Skip to content

Commit 30d929b

Browse files
author
Justin Poehnelt
authored
docs: fix gif, readme, etc (npm#5)
1 parent 8ab58d6 commit 30d929b

4 files changed

Lines changed: 135 additions & 174 deletions

File tree

.changeset/optimize-demo-gif.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@googleworkspace/cli": patch
3+
---
4+
5+
Optimize demo GIF and improve README

README.md

Lines changed: 116 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
# gws — Google Workspace CLI
1+
# gws
22

3-
A CLI that generates its entire command surface dynamically from Google Discovery Service JSON documents. Includes skills for AI agents.
3+
**One CLI for all of Google Workspace.** Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin — 24 services, 700+ API methods, zero boilerplate.
4+
5+
`gws` doesn't ship a static list of commands. It reads Google's own [Discovery Service](https://developers.google.com/discovery) at runtime and builds its entire command surface dynamically. When Google adds an API endpoint, `gws` picks it up automatically.
46

57
> [!IMPORTANT]
6-
> This project is currently under active development and is not yet ready for production use.
8+
> This project is under active development and is not yet ready for production use.
79
810
![Demo](https://raw.githubusercontent.com/googleworkspace/cli/refs/heads/main/demo.gif)
911

10-
## Install
12+
## Quick Start
1113

1214
```bash
1315
npm install -g @googleworkspace/cli
16+
17+
gws setup # walks you through Google Cloud project config + OAuth login
18+
gws drive files list --params '{"pageSize": 5}'
1419
```
1520

1621
Or build from source:
@@ -19,245 +24,188 @@ Or build from source:
1924
cargo install --path .
2025
```
2126

22-
## AI Agents & Skills
23-
24-
This repository includes [Agent Skills](https://github.com/vercel-labs/agent-skills) definitions (`SKILL.md`) for every supported Google Workspace API. Skills are prefixed with `gws-` to avoid namespace collisions when installed globally.
25-
26-
You can install these skills directly into your AI agent using `npx`:
27-
28-
```bash
29-
# Add all Google Workspace skills to your agent
30-
npx skills add github:googleworkspace/cli
31-
```
32-
33-
Or add specific skills by path:
34-
35-
```bash
36-
# Add the shared skill (authentication, etc.)
37-
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-shared
38-
39-
# Add only Google Drive and Gmail skills
40-
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-drive
41-
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-gmail
42-
```
43-
44-
### OpenClaw
45-
46-
Clone the repo and copy (or symlink) the skills into your OpenClaw skills directory:
47-
48-
```bash
49-
# All skills
50-
cp -r skills/gws-* ~/.openclaw/skills/
51-
52-
# Or symlink for easy updates
53-
ln -s $(pwd)/skills/gws-* ~/.openclaw/skills/
54-
```
55-
56-
Or copy only specific skills:
27+
---
5728

58-
```bash
59-
cp -r skills/gws-drive skills/gws-gmail ~/.openclaw/skills/
60-
```
29+
## Why gws?
6130

62-
The `gws-shared` skill includes an `install` block so OpenClaw can auto-install the CLI via `npm i -g @googleworkspace/cli` if the `gws` binary isn't found on PATH.
31+
**For humans** — stop writing `curl` calls against REST docs. `gws` gives you tab‑completion, `--help` on every resource, `--dry-run` to preview requests, and auto‑pagination.
6332

64-
## Usage
33+
**For AI agents** — every response is structured JSON. Pair it with the included agent skills and your LLM can manage Workspace without custom tooling.
6534

6635
```bash
67-
# List files in Drive
36+
# List the 10 most recent files
6837
gws drive files list --params '{"pageSize": 10}'
6938

70-
# Get a file's metadata
71-
gws drive files get --params '{"fileId": "abc123"}'
72-
7339
# Create a spreadsheet
74-
gws sheets spreadsheets create --json '{"properties": {"title": "My Sheet"}}'
75-
76-
# List Gmail messages
77-
gws gmail users messages list --params '{"userId": "me"}'
78-
79-
# Introspect a method's schema
80-
gws schema drive.files.list
81-
82-
# Dynamic help for any resource
83-
gws drive files --help
84-
gws drive files list --help
40+
gws sheets spreadsheets create --json '{"properties": {"title": "Q1 Budget"}}'
8541

86-
# Preview a request without sending it
42+
# Send a Chat message
8743
gws chat spaces messages create \
8844
--params '{"parent": "spaces/xyz"}' \
89-
--json '{"text": "Hello world"}' \
45+
--json '{"text": "Deploy complete."}' \
9046
--dry-run
91-
```
92-
93-
## Authentication
9447

95-
The CLI supports three primary authentication workflows depending on your environment.
48+
# Introspect any method's request/response schema
49+
gws schema drive.files.list
9650

97-
### 1. Interactive Auth (Local Desktop)
51+
# Stream paginated results as NDJSON
52+
gws drive files list --params '{"pageSize": 100}' --page-all | jq -r '.files[].name'
53+
```
9854

99-
For interactive use on your personal machine where a web browser is available.
55+
---
10056

101-
**Security**: By default, credentials and access tokens are encrypted at rest using AES-256-GCM. The encryption key is stored securely in your OS Keyring (Apple Keychain, Secret Service, or Windows Credential Manager). If a keyring is unavailable (e.g., headless Linux), it falls back to a strictly permissioned (`0600`) local key file.
57+
## Authentication
10258

103-
**Google Cloud Setup & Login:**
104-
The CLI includes a built-in setup wizard to help you configure your Google Cloud Project, enable APIs, and generate the necessary OAuth credentials. Note that this requires the [`gcloud` CLI](https://cloud.google.com/sdk/docs/install) to be installed and authenticated (`gcloud auth login`).
59+
The CLI supports multiple auth workflows so it works on your laptop, in CI, and on a server.
10560

106-
```bash
107-
# Run the interactive setup and login wizard
108-
gws setup
61+
### Interactive (local desktop)
10962

110-
# Or login directly if you already have client_secret.json configured
111-
gws auth login
63+
Credentials are encrypted at rest (AES-256-GCM) with the key stored in your OS keyring.
11264

113-
# Or login with custom scopes
114-
gws auth login --scopes "https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/gmail.readonly"
65+
```bash
66+
gws setup # one-time: creates a Cloud project, enables APIs, logs you in
67+
gws auth login # subsequent logins
11568
```
11669

117-
### 2. Headless & CI/CD Auth (Export Flow)
70+
> Requires the [`gcloud` CLI](https://cloud.google.com/sdk/docs/install) to be installed and authenticated.
11871
119-
For remote servers, SSH sessions, or CI/CD pipelines where a browser is unavailable, use the export flow.
72+
### Headless / CI (export flow)
12073

121-
1. On your **local machine** (with a browser), complete the Interactive Auth steps above.
122-
2. Export your credentials to a portable JSON format:
74+
1. Complete interactive auth on a machine with a browser.
75+
2. Export credentials:
12376
```bash
12477
gws auth export --unmasked > credentials.json
12578
```
126-
3. On your **headless machine**, securely transfer `credentials.json` and point the CLI to it. The CLI will automatically use this payload to mint fresh access tokens.
79+
3. On the headless machine:
12780
```bash
12881
export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json
129-
130-
# Commands now work headlessly!
131-
gws drive files list
82+
gws drive files list # just works
13283
```
13384

134-
*Note: You can also strictly provide a short-lived access token directly via environment variable (e.g. `export GOOGLE_WORKSPACE_CLI_TOKEN=$(gcloud auth print-access-token)`), though this token will naturally expire in ~1 hour.*
135-
136-
### 3. Service Account Auth (Server-to-Server)
85+
### Service Account (server-to-server)
13786

138-
For automated programmatic access. Point `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` to your service account JSON key file. No login step is required.
87+
Point to your key file; no login needed.
13988

14089
```bash
14190
export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json
14291
gws drive files list
14392
```
14493

145-
**Domain-Wide Delegation (Impersonation)**
146-
If your service account has Domain-Wide Delegation enabled, you can impersonate a Workspace user (e.g., an admin) to perform actions on their behalf.
94+
For Domain-Wide Delegation, add:
14795

14896
```bash
149-
export GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER=user@example.com
97+
export GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER=admin@example.com
15098
```
15199

152-
### 4. Pre-obtained Access Token (CI/CD or External)
100+
### Pre-obtained Access Token
153101

154-
The simplest way to authenticate if you already possess a short-lived access token. This is often used in CI/CD pipelines where another tool (like `gcloud`) mints the token for the environment.
102+
Useful when another tool (e.g. `gcloud`) already mints tokens for your environment.
155103

156104
```bash
157-
# Obtain a token using the gcloud CLI
158105
export GOOGLE_WORKSPACE_CLI_TOKEN=$(gcloud auth print-access-token)
159-
gws drive files list
160106
```
161-
*(Note: These raw access tokens typically expire in ~1 hour).*
107+
108+
### Precedence
109+
110+
| Priority | Source | Set via |
111+
|----------|--------|---------|
112+
| 1 | Access token | `GOOGLE_WORKSPACE_CLI_TOKEN` |
113+
| 2 | Credentials file | `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` |
114+
| 3 | Encrypted credentials (OS keyring) | `gws auth login` |
115+
| 4 | Plaintext credentials | `~/.config/gws/credentials.json` |
116+
117+
Environment variables can also live in a `.env` file.
162118

163119
---
164120

165-
### Auth Precedence Order
121+
## AI Agent Skills
166122

167-
The CLI evaluates authentication sources in the following strict order:
123+
The repo ships 40+ [Agent Skills](https://github.com/vercel-labs/agent-skills) (`SKILL.md` files) — one for every supported API, plus higher-level helpers for common workflows like sending email, triaging a Gmail inbox, or subscribing to calendar events.
168124

169-
| Priority | Source | How to set |
170-
|----------|--------|------------|
171-
| 1 (highest) | Raw access token | `GOOGLE_WORKSPACE_CLI_TOKEN` env var |
172-
| 2 | Credentials file (user or service account) | `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` env var |
173-
| 3 | Encrypted credentials & token cache | `~/.config/gws/credentials.enc` and `token_cache.json` (created by `gws auth login`, secured via OS Keyring) |
174-
| 4 | Plaintext credentials | `~/.config/gws/credentials.json` |
175-
|| No auth | Proceeds unauthenticated; shows error if the API rejects |
125+
```bash
126+
# Install all skills at once
127+
npx skills add github:googleworkspace/cli
176128

177-
*(Note: Environment variables can also be set via a `.env` file in the working directory.)*
129+
# Or pick only what you need
130+
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-drive
131+
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-gmail
132+
```
178133

179-
## Architecture
134+
<details>
135+
<summary>OpenClaw setup</summary>
180136

181-
The CLI uses a **two-phase argument parsing** strategy:
137+
```bash
138+
# Symlink all skills (stays in sync with repo)
139+
ln -s $(pwd)/skills/gws-* ~/.openclaw/skills/
140+
141+
# Or copy specific skills
142+
cp -r skills/gws-drive skills/gws-gmail ~/.openclaw/skills/
143+
```
182144

183-
1. Extract the service name from `argv[1]`
184-
2. Fetch the service's Discovery Document (cached for 24h)
185-
3. Build a dynamic `clap::Command` tree from the document's resources/methods
186-
4. Re-parse the remaining arguments against the tree
187-
5. Authenticate, construct the HTTP request, and execute
145+
The `gws-shared` skill includes an `install` block so OpenClaw auto-installs the CLI via `npm` if `gws` isn't on PATH.
188146

189-
All output (success, error, file download metadata) is structured JSON for AI agent consumption. Binary outputs require an `--output` flag.
147+
</details>
190148

191-
There are a few special behaviors to be aware of that diverge from the Discovery Service API representation:
149+
---
192150

193-
### Multipart uploads
151+
## Advanced Usage
194152

195-
For multipart uploads (e.g. Drive file uploads), use the `--upload` flag to specify the path to the file to upload.
153+
### Multipart Uploads
196154

197155
```bash
198-
gws drive files create --json '{"name": "My File"}' --upload /path/to/file
156+
gws drive files create --json '{"name": "report.pdf"}' --upload ./report.pdf
199157
```
200158

201-
### Pagination and NDJSON
202-
203-
Use `--page-all` to auto-paginate through results. Each page is emitted as a single JSON line (NDJSON), making it easy to stream into tools like `jq`.
159+
### Pagination
204160

205161
| Flag | Description | Default |
206-
| --- | --- | --- |
207-
| `--page-all` | Auto-paginate, one JSON line per page | off |
162+
|------|-------------|---------|
163+
| `--page-all` | Auto-paginate, one JSON line per page (NDJSON) | off |
208164
| `--page-limit <N>` | Max pages to fetch | 10 |
209-
| `--page-delay <MS>` | Delay between pages in ms | 100 |
165+
| `--page-delay <MS>` | Delay between pages | 100 ms |
210166

211-
```bash
212-
# Stream all Drive files as NDJSON
213-
gws drive files list --params '{"pageSize": 100}' --page-all --page-limit 5
214-
215-
# Pipe to jq to extract file names
216-
gws drive files list --params '{"pageSize": 100}' --page-all | jq -r '.files[].name'
217-
```
167+
### Model Armor (Response Sanitization)
218168

219-
## Testing & Coverage
169+
Integrate [Google Cloud Model Armor](https://cloud.google.com/model-armor) to scan API responses for prompt injection before they reach your agent.
220170

221-
Run unit tests:
222171
```bash
223-
cargo test
172+
gws gmail users messages get --params '...' \
173+
--sanitize "projects/P/locations/L/templates/T"
224174
```
225175

226-
Generate code coverage report (requires `cargo-llvm-cov`):
176+
| Variable | Description |
177+
|----------|-------------|
178+
| `GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE` | Default Model Armor template |
179+
| `GOOGLE_WORKSPACE_CLI_SANITIZE_MODE` | `warn` (default) or `block` |
180+
181+
---
182+
183+
## Architecture
184+
185+
`gws` uses a **two-phase parsing** strategy:
186+
187+
1. Read `argv[1]` to identify the service (e.g. `drive`)
188+
2. Fetch the service's Discovery Document (cached 24 h)
189+
3. Build a `clap::Command` tree from the document's resources and methods
190+
4. Re-parse the remaining arguments
191+
5. Authenticate, build the HTTP request, execute
192+
193+
All output — success, errors, download metadata — is structured JSON.
194+
195+
---
196+
197+
## Development
198+
227199
```bash
228-
./scripts/coverage.sh
200+
cargo build # dev build
201+
cargo clippy -- -D warnings # lint
202+
cargo test # unit tests
203+
./scripts/coverage.sh # HTML coverage report → target/llvm-cov/html/
229204
```
230-
The report will be available at `target/llvm-cov/html/index.html`.
231-
232-
## Security & Sanitization (Model Armor)
233-
234-
The CLI integrates with **Google Cloud Model Armor** to sanitize API responses for prompt injection risks before they reach your AI agent.
235-
236-
```bash
237-
# Sanitize a specific command
238-
gws gmail users messages get --params '...' \
239-
--sanitize "projects/P/locations/L/templates/T"
240-
```
241-
242-
This checks the *entire* JSON response against the specified Model Armor template.
243-
244-
### Configuration
245-
246-
You can set default behavior via environment variables:
247-
248-
| Variable | Description |
249-
|---|---|
250-
| `GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE` | Default Model Armor template resource name |
251-
| `GOOGLE_WORKSPACE_CLI_SANITIZE_MODE` | `warn` (default) or `block`. |
252-
253-
- **Warn mode**: Prints a warning to stderr and annotates the JSON with `_sanitization` details.
254-
- **Block mode**: Suppresses the output entirely and exits with an error if a match is found.
255-
256-
### Requirements
257-
258-
Using `--sanitize` requires the `https://www.googleapis.com/auth/cloud-platform` scope.
259-
260-
## License
205+
206+
---
207+
208+
## License
261209

262210
Apache-2.0
263211

demo.gif

-1.72 MB
Loading

0 commit comments

Comments
 (0)