Merge pull request #314 from alirezarezvani/feat/google-workspace-cli
feat(engineering): add google-workspace-cli skill
This commit is contained in:
@@ -4,11 +4,11 @@
|
||||
"name": "Alireza Rezvani",
|
||||
"url": "https://alirezarezvani.com"
|
||||
},
|
||||
"description": "151 production-ready skill packages for Claude AI across 9 domains: marketing (43), engineering (23+25), C-level advisory (28), regulatory/QMS (12), product (8), project management (6), business growth (4), and finance (2). Includes 245 Python tools, 344 reference documents, 14 agents, and 14 slash commands.",
|
||||
"description": "173 production-ready skill packages for Claude AI across 9 domains: marketing (43), engineering (24+25), C-level advisory (28), regulatory/QMS (12), product (8), project management (6), business growth (4), and finance (2). Includes 250 Python tools, 347 reference documents, 15 agents, and 15 slash commands.",
|
||||
"homepage": "https://github.com/alirezarezvani/claude-skills",
|
||||
"repository": "https://github.com/alirezarezvani/claude-skills",
|
||||
"metadata": {
|
||||
"description": "151 production-ready skill packages across 9 domains with 245 Python tools, 344 reference documents, 14 agents, and 14 slash commands. Compatible with Claude Code, Codex CLI, Gemini CLI, and OpenClaw.",
|
||||
"description": "173 production-ready skill packages across 9 domains with 250 Python tools, 347 reference documents, 15 agents, and 15 slash commands. Compatible with Claude Code, Codex CLI, Gemini CLI, and OpenClaw.",
|
||||
"version": "2.1.2"
|
||||
},
|
||||
"plugins": [
|
||||
@@ -82,7 +82,7 @@
|
||||
{
|
||||
"name": "engineering-skills",
|
||||
"source": "./engineering-team",
|
||||
"description": "23 engineering skills: architecture, frontend, backend, fullstack, QA, DevOps, security, AI/ML, data engineering, Playwright (9 sub-skills), self-improving agent, Stripe integration, TDD guide, tech stack evaluator.",
|
||||
"description": "24 engineering skills: architecture, frontend, backend, fullstack, QA, DevOps, security, AI/ML, data engineering, Playwright (9 sub-skills), self-improving agent, Stripe integration, TDD guide, tech stack evaluator, Google Workspace CLI.",
|
||||
"version": "2.1.2",
|
||||
"author": {
|
||||
"name": "Alireza Rezvani"
|
||||
@@ -97,7 +97,12 @@
|
||||
"ai",
|
||||
"ml",
|
||||
"data",
|
||||
"playwright"
|
||||
"playwright",
|
||||
"google-workspace",
|
||||
"gws",
|
||||
"gmail",
|
||||
"google-drive",
|
||||
"google-sheets"
|
||||
],
|
||||
"category": "development"
|
||||
},
|
||||
@@ -345,6 +350,25 @@
|
||||
"scanner"
|
||||
],
|
||||
"category": "development"
|
||||
},
|
||||
{
|
||||
"name": "google-workspace-cli",
|
||||
"source": "./engineering-team/google-workspace-cli",
|
||||
"description": "Google Workspace administration via the gws CLI. Install, authenticate, and automate Gmail, Drive, Sheets, Calendar, Docs, Chat, and Tasks. 5 Python tools, 3 reference guides, 43 built-in recipes, 10 persona bundles.",
|
||||
"version": "2.1.2",
|
||||
"author": {
|
||||
"name": "Alireza Rezvani"
|
||||
},
|
||||
"keywords": [
|
||||
"google-workspace",
|
||||
"gws",
|
||||
"gmail",
|
||||
"google-drive",
|
||||
"google-sheets",
|
||||
"google-calendar",
|
||||
"workspace-admin"
|
||||
],
|
||||
"category": "development"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "claude-code-skills",
|
||||
"description": "Production-ready skill packages for AI agents - Marketing, Engineering, Product, C-Level, PM, and RA/QM",
|
||||
"repository": "https://github.com/alirezarezvani/claude-skills",
|
||||
"total_skills": 151,
|
||||
"total_skills": 152,
|
||||
"skills": [
|
||||
{
|
||||
"name": "contract-and-proposal-writer",
|
||||
@@ -215,6 +215,12 @@
|
||||
"category": "engineering",
|
||||
"description": "Email Template Builder"
|
||||
},
|
||||
{
|
||||
"name": "google-workspace-cli",
|
||||
"source": "../../engineering-team/google-workspace-cli",
|
||||
"category": "engineering",
|
||||
"description": "Google Workspace administration via the gws CLI. Install, authenticate, and automate Gmail, Drive, Sheets, Calendar, Docs, Chat, and Tasks. Run security audits, execute 43 built-in recipes, and use 10 persona bundles. Use for Google Workspace admin, gws CLI setup, Gmail automation, Drive management, or Calendar scheduling."
|
||||
},
|
||||
{
|
||||
"name": "incident-commander",
|
||||
"source": "../../engineering-team/incident-commander",
|
||||
@@ -924,7 +930,7 @@
|
||||
"description": "Executive leadership and advisory skills"
|
||||
},
|
||||
"engineering": {
|
||||
"count": 23,
|
||||
"count": 24,
|
||||
"source": "../../engineering-team",
|
||||
"description": "Software engineering and technical skills"
|
||||
},
|
||||
|
||||
1
.codex/skills/google-workspace-cli
Symbolic link
1
.codex/skills/google-workspace-cli
Symbolic link
@@ -0,0 +1 @@
|
||||
../../engineering-team/google-workspace-cli
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"name": "gemini-cli-skills",
|
||||
"total_skills": 208,
|
||||
"total_skills": 211,
|
||||
"skills": [
|
||||
{
|
||||
"name": "cs-agile-product-owner",
|
||||
@@ -73,6 +73,11 @@
|
||||
"category": "agent",
|
||||
"description": "UX research agent for research planning, persona generation, journey mapping, and usability test analysis"
|
||||
},
|
||||
{
|
||||
"name": "cs-workspace-admin",
|
||||
"category": "agent",
|
||||
"description": "Google Workspace administration agent using the gws CLI. Orchestrates workspace setup, Gmail/Drive/Sheets/Calendar automation, security audits, and recipe execution. Spawn when users need Google Workspace automation, gws CLI help, or workspace administration."
|
||||
},
|
||||
{
|
||||
"name": "business-growth-bundle",
|
||||
"category": "business-growth",
|
||||
@@ -283,6 +288,11 @@
|
||||
"category": "command",
|
||||
"description": "Run financial ratio analysis, DCF valuation, budget variance analysis, and rolling forecasts. Usage: /financial-health <ratios|dcf|budget|forecast> <data.json>"
|
||||
},
|
||||
{
|
||||
"name": "google-workspace",
|
||||
"category": "command",
|
||||
"description": "Google Workspace CLI operations: setup diagnostics, security audit, recipe discovery, and output analysis. Usage: /google-workspace <setup|audit|recipe|analyze> [options]"
|
||||
},
|
||||
{
|
||||
"name": "okr",
|
||||
"category": "command",
|
||||
@@ -383,6 +393,11 @@
|
||||
"category": "engineering",
|
||||
"description": ">-"
|
||||
},
|
||||
{
|
||||
"name": "google-workspace-cli",
|
||||
"category": "engineering",
|
||||
"description": "Google Workspace administration via the gws CLI. Install, authenticate, and automate Gmail, Drive, Sheets, Calendar, Docs, Chat, and Tasks. Run security audits, execute 43 built-in recipes, and use 10 persona bundles. Use for Google Workspace admin, gws CLI setup, Gmail automation, Drive management, or Calendar scheduling."
|
||||
},
|
||||
{
|
||||
"name": "incident-commander",
|
||||
"category": "engineering",
|
||||
@@ -1046,7 +1061,7 @@
|
||||
],
|
||||
"categories": {
|
||||
"agent": {
|
||||
"count": 14,
|
||||
"count": 15,
|
||||
"description": "Agent resources"
|
||||
},
|
||||
"business-growth": {
|
||||
@@ -1058,11 +1073,11 @@
|
||||
"description": "C-level resources"
|
||||
},
|
||||
"command": {
|
||||
"count": 14,
|
||||
"count": 15,
|
||||
"description": "Command resources"
|
||||
},
|
||||
"engineering": {
|
||||
"count": 38,
|
||||
"count": 39,
|
||||
"description": "Engineering resources"
|
||||
},
|
||||
"engineering-advanced": {
|
||||
|
||||
1
.gemini/skills/cs-workspace-admin/SKILL.md
Symbolic link
1
.gemini/skills/cs-workspace-admin/SKILL.md
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../agents/engineering-team/cs-workspace-admin.md
|
||||
1
.gemini/skills/google-workspace-cli/SKILL.md
Symbolic link
1
.gemini/skills/google-workspace-cli/SKILL.md
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../engineering-team/google-workspace-cli/SKILL.md
|
||||
1
.gemini/skills/google-workspace/SKILL.md
Symbolic link
1
.gemini/skills/google-workspace/SKILL.md
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../commands/google-workspace.md
|
||||
16
CLAUDE.md
16
CLAUDE.md
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
This is a **comprehensive skills library** for Claude AI and Claude Code - reusable, production-ready skill packages that bundle domain expertise, best practices, analysis tools, and strategic frameworks. The repository provides modular skills that teams can download and use directly in their workflows.
|
||||
|
||||
**Current Scope:** 172 production-ready skills across 9 domains with 245 Python automation tools, 344 reference guides, 14 agents, and 14 slash commands.
|
||||
**Current Scope:** 173 production-ready skills across 9 domains with 250 Python automation tools, 347 reference guides, 15 agents, and 15 slash commands.
|
||||
|
||||
**Key Distinction**: This is NOT a traditional application. It's a library of skill packages meant to be extracted and deployed by users into their own Claude workflows.
|
||||
|
||||
@@ -36,9 +36,9 @@ This repository uses **modular documentation**. For domain-specific guidance, se
|
||||
```
|
||||
claude-code-skills/
|
||||
├── .claude-plugin/ # Plugin registry (marketplace.json)
|
||||
├── agents/ # 14 cs-* prefixed agents across all domains
|
||||
├── commands/ # 14 slash commands (changelog, tdd, saas-health, etc.)
|
||||
├── engineering-team/ # 23 core engineering skills + Playwright Pro + Self-Improving Agent
|
||||
├── agents/ # 15 cs-* prefixed agents across all domains
|
||||
├── commands/ # 15 slash commands (changelog, tdd, saas-health, workspace, etc.)
|
||||
├── engineering-team/ # 24 core engineering skills + Playwright Pro + Self-Improving Agent
|
||||
├── engineering/ # 25 POWERFUL-tier advanced skills
|
||||
├── product-team/ # 8 product skills + Python tools
|
||||
├── marketing-skill/ # 43 marketing skills (7 pods) + Python tools
|
||||
@@ -148,9 +148,9 @@ See [standards/git/git-workflow-standards.md](standards/git/git-workflow-standar
|
||||
|
||||
## Roadmap
|
||||
|
||||
**Phase 1-2 Complete:** 172 production-ready skills deployed across 9 domains
|
||||
- Engineering Core (23), Engineering POWERFUL (25), Product (8), Marketing (42), PM (6), C-Level (28), RA/QM (12), Business & Growth (4), Finance (2)
|
||||
- 245 Python automation tools, 344 reference guides, 14 agents, 14 commands
|
||||
**Phase 1-2 Complete:** 173 production-ready skills deployed across 9 domains
|
||||
- Engineering Core (24), Engineering POWERFUL (25), Product (8), Marketing (42), PM (6), C-Level (28), RA/QM (12), Business & Growth (4), Finance (2)
|
||||
- 250 Python automation tools, 347 reference guides, 15 agents, 15 commands
|
||||
- Complete enterprise coverage from engineering through regulatory compliance, sales, customer success, and finance
|
||||
- MkDocs Material docs site with 206 indexed pages for SEO
|
||||
|
||||
@@ -203,4 +203,4 @@ This repository publishes skills to **ClawHub** (clawhub.com) as the distributio
|
||||
|
||||
**Last Updated:** March 10, 2026
|
||||
**Version:** v2.1.2
|
||||
**Status:** 172 skills deployed across 9 domains, 19 marketplace plugins, docs site live
|
||||
**Status:** 173 skills deployed across 9 domains, 19 marketplace plugins, docs site live
|
||||
|
||||
16
README.md
16
README.md
@@ -1,11 +1,11 @@
|
||||
# Claude Code Skills & Plugins
|
||||
|
||||
**172 production-ready skills and plugins for Claude Code, OpenAI Codex, Gemini CLI, and OpenClaw** — reusable expertise bundles that transform AI coding agents into specialized professionals across engineering, product, marketing, compliance, and more.
|
||||
**173 production-ready skills and plugins for Claude Code, OpenAI Codex, Gemini CLI, and OpenClaw** — reusable expertise bundles that transform AI coding agents into specialized professionals across engineering, product, marketing, compliance, and more.
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](#skills-overview)
|
||||
[](#agents)
|
||||
[](#commands)
|
||||
[](#skills-overview)
|
||||
[](#agents)
|
||||
[](#commands)
|
||||
[](https://github.com/alirezarezvani/claude-skills/stargazers)
|
||||
[](https://getskillcheck.com)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
Skills are modular instruction packages (plugins) that give AI coding agents domain expertise they don't have out of the box. Each skill includes a `SKILL.md` (instructions + workflows), Python CLI tools, and reference documentation — everything the agent needs to perform like a specialist.
|
||||
|
||||
**One repo, four platforms:** Works natively as Claude Code plugins, OpenAI Codex CLI and agents, Gemini CLI skills, and OpenClaw skills. All 237 Python tools are stdlib-only and verified working.
|
||||
**One repo, four platforms:** Works natively as Claude Code plugins, OpenAI Codex CLI and agents, Gemini CLI skills, and OpenClaw skills. All 250 Python tools are stdlib-only and verified working.
|
||||
|
||||
---
|
||||
|
||||
@@ -44,7 +44,7 @@ cd claude-skills
|
||||
/plugin marketplace add alirezarezvani/claude-skills
|
||||
|
||||
# Install by domain
|
||||
/plugin install engineering-skills@claude-code-skills # 23 core engineering
|
||||
/plugin install engineering-skills@claude-code-skills # 24 core engineering
|
||||
/plugin install engineering-advanced-skills@claude-code-skills # 25 POWERFUL-tier
|
||||
/plugin install product-skills@claude-code-skills # 8 product skills
|
||||
/plugin install marketing-skills@claude-code-skills # 43 marketing skills
|
||||
@@ -85,11 +85,11 @@ git clone https://github.com/alirezarezvani/claude-skills.git
|
||||
|
||||
## Skills Overview
|
||||
|
||||
**172 skills across 9 domains:**
|
||||
**173 skills across 9 domains:**
|
||||
|
||||
| Domain | Skills | Highlights | Details |
|
||||
|--------|--------|------------|---------|
|
||||
| **🔧 Engineering — Core** | 23 | Architecture, frontend, backend, fullstack, QA, DevOps, SecOps, AI/ML, data, Playwright, self-improving agent | [engineering-team/](engineering-team/) |
|
||||
| **🔧 Engineering — Core** | 24 | Architecture, frontend, backend, fullstack, QA, DevOps, SecOps, AI/ML, data, Playwright, self-improving agent, Google Workspace CLI | [engineering-team/](engineering-team/) |
|
||||
| **🎭 Playwright Pro** | 9+3 | Test generation, flaky fix, Cypress/Selenium migration, TestRail, BrowserStack, 55 templates | [engineering-team/playwright-pro](engineering-team/playwright-pro/) |
|
||||
| **🧠 Self-Improving Agent** | 5+2 | Auto-memory curation, pattern promotion, skill extraction, memory health | [engineering-team/self-improving-agent](engineering-team/self-improving-agent/) |
|
||||
| **⚡ Engineering — POWERFUL** | 25 | Agent designer, RAG architect, database designer, CI/CD builder, security auditor, MCP builder | [engineering/](engineering/) |
|
||||
|
||||
@@ -24,7 +24,7 @@ When skills are published to **ClawHub** (clawhub.com):
|
||||
|
||||
### Production Agents
|
||||
|
||||
**5 Agents Currently Available** (as of November 5, 2025):
|
||||
**6 Agents Currently Available**:
|
||||
|
||||
| Agent | Domain | Description | Skills Used | Lines |
|
||||
|-------|--------|-------------|-------------|-------|
|
||||
@@ -33,8 +33,9 @@ When skills are published to **ClawHub** (clawhub.com):
|
||||
| [cs-ceo-advisor](c-level/cs-ceo-advisor.md) | C-Level | Strategic leadership advisor for CEOs covering vision, strategy, board management | ceo-advisor | 360 |
|
||||
| [cs-cto-advisor](c-level/cs-cto-advisor.md) | C-Level | Technical leadership advisor for CTOs covering tech strategy and team scaling | cto-advisor | 412 |
|
||||
| [cs-product-manager](product/cs-product-manager.md) | Product | Product management agent for RICE prioritization and customer discovery | product-manager-toolkit | 407 |
|
||||
| [cs-workspace-admin](engineering-team/cs-workspace-admin.md) | Engineering | Google Workspace administration via gws CLI — setup, automation, security audits, recipes | google-workspace-cli | 120 |
|
||||
|
||||
**Total**: 1,795 lines of comprehensive agent documentation
|
||||
**Total**: ~1,915 lines of comprehensive agent documentation
|
||||
|
||||
**Template Available**: [templates/agent-template.md](../templates/agent-template.md) (318 lines) - Use this to create new agents
|
||||
|
||||
|
||||
160
agents/engineering-team/cs-workspace-admin.md
Normal file
160
agents/engineering-team/cs-workspace-admin.md
Normal file
@@ -0,0 +1,160 @@
|
||||
---
|
||||
name: cs-workspace-admin
|
||||
description: Google Workspace administration agent using the gws CLI. Orchestrates workspace setup, Gmail/Drive/Sheets/Calendar automation, security audits, and recipe execution. Spawn when users need Google Workspace automation, gws CLI help, or workspace administration.
|
||||
skills: engineering-team/google-workspace-cli
|
||||
domain: engineering
|
||||
model: opus
|
||||
tools: [Read, Write, Bash, Grep, Glob]
|
||||
---
|
||||
|
||||
# cs-workspace-admin
|
||||
|
||||
## Role & Expertise
|
||||
|
||||
Google Workspace administration specialist orchestrating the gws CLI for email automation, file management, calendar scheduling, security auditing, and cross-service workflows. Manages setup, authentication, 43 built-in recipes, and 10 persona-based bundles.
|
||||
|
||||
## Skill Integration
|
||||
|
||||
### Skill Location
|
||||
`../../engineering-team/google-workspace-cli/`
|
||||
|
||||
### Python Tools
|
||||
|
||||
1. **GWS Doctor**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/gws_doctor.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/gws_doctor.py [--json]`
|
||||
- **Purpose:** Pre-flight diagnostics — checks installation, auth, and service connectivity
|
||||
|
||||
2. **Auth Setup Guide**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --guide oauth`
|
||||
- **Purpose:** Guided auth setup, scope listing, .env generation, validation
|
||||
|
||||
3. **Recipe Runner**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --list`
|
||||
- **Purpose:** Catalog, search, and execute 43 built-in recipes with persona filtering
|
||||
|
||||
4. **Workspace Audit**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/workspace_audit.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/workspace_audit.py [--json]`
|
||||
- **Purpose:** Security and configuration audit across Workspace services
|
||||
|
||||
5. **Output Analyzer**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/output_analyzer.py`
|
||||
- **Usage:** `gws ... --json | python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --count`
|
||||
- **Purpose:** Parse, filter, and aggregate JSON/NDJSON output from any gws command
|
||||
|
||||
### Knowledge Bases
|
||||
|
||||
1. **Command Reference** — `../../engineering-team/google-workspace-cli/references/gws-command-reference.md`
|
||||
- 18 services, 22 helpers, global flags, environment variables
|
||||
2. **Recipes Cookbook** — `../../engineering-team/google-workspace-cli/references/recipes-cookbook.md`
|
||||
- 43 recipes organized by category with persona mapping
|
||||
3. **Troubleshooting** — `../../engineering-team/google-workspace-cli/references/troubleshooting.md`
|
||||
- Common errors, auth issues, platform-specific fixes
|
||||
|
||||
### Templates
|
||||
|
||||
1. **Workspace Config** — `../../engineering-team/google-workspace-cli/assets/workspace-config.json`
|
||||
- Automation config template with auth, defaults, scheduled tasks
|
||||
2. **Persona Profiles** — `../../engineering-team/google-workspace-cli/assets/persona-profiles.md`
|
||||
- 10 role-based workflow bundles
|
||||
|
||||
## Core Workflows
|
||||
|
||||
### 1. Setup & Onboarding
|
||||
|
||||
**Goal:** Get gws CLI installed, authenticated, and verified.
|
||||
|
||||
**Steps:**
|
||||
1. Run `gws_doctor.py` to check installation and existing auth
|
||||
2. If not installed, guide through installation (npm/cargo/binary)
|
||||
3. Run `auth_setup_guide.py --guide oauth` for auth instructions
|
||||
4. Run `auth_setup_guide.py --scopes <services>` to identify required scopes
|
||||
5. Run `auth_setup_guide.py --validate` to verify all services
|
||||
6. Generate `.env` template with `auth_setup_guide.py --generate-env`
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_doctor.py
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --guide oauth
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --validate --json
|
||||
```
|
||||
|
||||
### 2. Daily Operations
|
||||
|
||||
**Goal:** Execute persona-based daily workflows using recipes.
|
||||
|
||||
**Steps:**
|
||||
1. Identify user's role and select persona with `gws_recipe_runner.py --personas`
|
||||
2. List relevant recipes with `gws_recipe_runner.py --persona <role> --list`
|
||||
3. Execute recipes with `gws_recipe_runner.py --run <name>` (use `--dry-run` first)
|
||||
4. Pipe output through `output_analyzer.py` for filtering and analysis
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --persona pm --list
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --run standup-report --dry-run
|
||||
gws recipes standup-report --json | python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --format table
|
||||
```
|
||||
|
||||
### 3. Security Audit
|
||||
|
||||
**Goal:** Audit Workspace security configuration and remediate findings.
|
||||
|
||||
**Steps:**
|
||||
1. Run `workspace_audit.py` for full security assessment
|
||||
2. Review findings, prioritizing FAIL items
|
||||
3. Filter findings through `output_analyzer.py` for actionable items
|
||||
4. Execute remediation commands from audit output
|
||||
5. Re-run audit to verify fixes
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/workspace_audit.py --json
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/workspace_audit.py --json | \
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --filter "status=FAIL"
|
||||
```
|
||||
|
||||
### 4. Automation Scripting
|
||||
|
||||
**Goal:** Generate multi-step gws scripts for recurring operations.
|
||||
|
||||
**Steps:**
|
||||
1. Identify the workflow from recipe templates
|
||||
2. Use `gws_recipe_runner.py --describe <name>` for command sequences
|
||||
3. Customize commands with user-specific parameters
|
||||
4. Test with `--dry-run` flag
|
||||
5. Combine into shell scripts or scheduled tasks using `workspace-config.json` template
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --describe morning-briefing
|
||||
# Customize and test
|
||||
gws helpers morning-briefing --json | python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --select "type,summary,time" --format table
|
||||
```
|
||||
|
||||
## Output Standards
|
||||
|
||||
- Diagnostic reports: structured PASS/WARN/FAIL per check with fixes
|
||||
- Audit reports: scored findings with risk ratings and remediation commands
|
||||
- Recipe output: JSON piped through output_analyzer.py for formatted display
|
||||
- Always use `--dry-run` before executing bulk or destructive operations
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- **Setup Time:** gws installed and authenticated in under 10 minutes
|
||||
- **Audit Coverage:** All critical security checks pass (Grade A or B)
|
||||
- **Automation:** Daily workflows automated via recipes and scheduled tasks
|
||||
- **Troubleshooting:** Common errors resolved using troubleshooting reference
|
||||
|
||||
## Related Agents
|
||||
|
||||
- [cs-engineering-lead](cs-engineering-lead.md) — Engineering team coordination
|
||||
- [cs-senior-engineer](../engineering/cs-senior-engineer.md) — Architecture and CI/CD
|
||||
|
||||
## References
|
||||
|
||||
- [Skill Documentation](../../engineering-team/google-workspace-cli/SKILL.md)
|
||||
- [gws CLI Repository](https://github.com/googleworkspace/cli)
|
||||
77
commands/google-workspace.md
Normal file
77
commands/google-workspace.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
name: google-workspace
|
||||
description: "Google Workspace CLI operations: setup diagnostics, security audit, recipe discovery, and output analysis. Usage: /google-workspace <setup|audit|recipe|analyze> [options]"
|
||||
---
|
||||
|
||||
# /google-workspace
|
||||
|
||||
Google Workspace CLI administration via the `gws` CLI. Run setup diagnostics, security audits, browse and execute recipes, and analyze command output.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/google-workspace setup [--json]
|
||||
/google-workspace audit [--services gmail,drive,calendar] [--json]
|
||||
/google-workspace recipe list [--persona <role>] [--json]
|
||||
/google-workspace recipe search <keyword> [--json]
|
||||
/google-workspace recipe run <name> [--dry-run]
|
||||
/google-workspace recipe describe <name>
|
||||
/google-workspace analyze [--filter <field=value>] [--group-by <field>] [--stats <field>] [--format table|csv|json]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
/google-workspace setup
|
||||
/google-workspace audit --services gmail,drive --json
|
||||
/google-workspace recipe list --persona pm
|
||||
/google-workspace recipe search "email"
|
||||
/google-workspace recipe run standup-report --dry-run
|
||||
/google-workspace recipe describe morning-briefing
|
||||
/google-workspace analyze --filter "mimeType=pdf" --select "name,size" --format table
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
- `engineering-team/google-workspace-cli/scripts/gws_doctor.py` — Pre-flight diagnostics
|
||||
- `engineering-team/google-workspace-cli/scripts/auth_setup_guide.py` — Auth setup guide
|
||||
- `engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py` — Recipe catalog & runner
|
||||
- `engineering-team/google-workspace-cli/scripts/workspace_audit.py` — Security audit
|
||||
- `engineering-team/google-workspace-cli/scripts/output_analyzer.py` — JSON/NDJSON analyzer
|
||||
|
||||
## Subcommands
|
||||
|
||||
### setup
|
||||
Run pre-flight diagnostics and auth validation.
|
||||
```bash
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_doctor.py [--json]
|
||||
python3 engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --validate [--json]
|
||||
```
|
||||
|
||||
### audit
|
||||
Run security and configuration audit.
|
||||
```bash
|
||||
python3 engineering-team/google-workspace-cli/scripts/workspace_audit.py [--services gmail,drive,calendar] [--json]
|
||||
```
|
||||
|
||||
### recipe
|
||||
Browse, search, and execute the 43 built-in gws recipes.
|
||||
```bash
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --list [--persona <role>] [--json]
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --search <keyword> [--json]
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --describe <name>
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --run <name> [--dry-run]
|
||||
```
|
||||
|
||||
### analyze
|
||||
Parse, filter, and aggregate JSON output from any gws command.
|
||||
```bash
|
||||
gws <command> --json | python3 engineering-team/google-workspace-cli/scripts/output_analyzer.py [options]
|
||||
python3 engineering-team/google-workspace-cli/scripts/output_analyzer.py --demo --format table
|
||||
```
|
||||
|
||||
## Skill Reference
|
||||
-> `engineering-team/google-workspace-cli/SKILL.md`
|
||||
|
||||
## Related Commands
|
||||
- No direct dependencies (self-contained Google Workspace skill)
|
||||
163
docs/agents/cs-workspace-admin.md
Normal file
163
docs/agents/cs-workspace-admin.md
Normal file
@@ -0,0 +1,163 @@
|
||||
---
|
||||
title: "cs-workspace-admin"
|
||||
description: "cs-workspace-admin - Claude Code agent for Engineering - Core."
|
||||
---
|
||||
|
||||
# cs-workspace-admin
|
||||
|
||||
**Type:** Agent | **Domain:** Engineering - Core | **Source:** [`agents/engineering-team/cs-workspace-admin.md`](https://github.com/alirezarezvani/claude-skills/tree/main/agents/engineering-team/cs-workspace-admin.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
# cs-workspace-admin
|
||||
|
||||
## Role & Expertise
|
||||
|
||||
Google Workspace administration specialist orchestrating the gws CLI for email automation, file management, calendar scheduling, security auditing, and cross-service workflows. Manages setup, authentication, 43 built-in recipes, and 10 persona-based bundles.
|
||||
|
||||
## Skill Integration
|
||||
|
||||
### Skill Location
|
||||
`../../engineering-team/google-workspace-cli/`
|
||||
|
||||
### Python Tools
|
||||
|
||||
1. **GWS Doctor**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/gws_doctor.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/gws_doctor.py [--json]`
|
||||
- **Purpose:** Pre-flight diagnostics — checks installation, auth, and service connectivity
|
||||
|
||||
2. **Auth Setup Guide**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --guide oauth`
|
||||
- **Purpose:** Guided auth setup, scope listing, .env generation, validation
|
||||
|
||||
3. **Recipe Runner**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --list`
|
||||
- **Purpose:** Catalog, search, and execute 43 built-in recipes with persona filtering
|
||||
|
||||
4. **Workspace Audit**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/workspace_audit.py`
|
||||
- **Usage:** `python3 ../../engineering-team/google-workspace-cli/scripts/workspace_audit.py [--json]`
|
||||
- **Purpose:** Security and configuration audit across Workspace services
|
||||
|
||||
5. **Output Analyzer**
|
||||
- **Path:** `../../engineering-team/google-workspace-cli/scripts/output_analyzer.py`
|
||||
- **Usage:** `gws ... --json | python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --count`
|
||||
- **Purpose:** Parse, filter, and aggregate JSON/NDJSON output from any gws command
|
||||
|
||||
### Knowledge Bases
|
||||
|
||||
1. **Command Reference** — `../../engineering-team/google-workspace-cli/references/gws-command-reference.md`
|
||||
- 18 services, 22 helpers, global flags, environment variables
|
||||
2. **Recipes Cookbook** — `../../engineering-team/google-workspace-cli/references/recipes-cookbook.md`
|
||||
- 43 recipes organized by category with persona mapping
|
||||
3. **Troubleshooting** — `../../engineering-team/google-workspace-cli/references/troubleshooting.md`
|
||||
- Common errors, auth issues, platform-specific fixes
|
||||
|
||||
### Templates
|
||||
|
||||
1. **Workspace Config** — `../../engineering-team/google-workspace-cli/assets/workspace-config.json`
|
||||
- Automation config template with auth, defaults, scheduled tasks
|
||||
2. **Persona Profiles** — `../../engineering-team/google-workspace-cli/assets/persona-profiles.md`
|
||||
- 10 role-based workflow bundles
|
||||
|
||||
## Core Workflows
|
||||
|
||||
### 1. Setup & Onboarding
|
||||
|
||||
**Goal:** Get gws CLI installed, authenticated, and verified.
|
||||
|
||||
**Steps:**
|
||||
1. Run `gws_doctor.py` to check installation and existing auth
|
||||
2. If not installed, guide through installation (npm/cargo/binary)
|
||||
3. Run `auth_setup_guide.py --guide oauth` for auth instructions
|
||||
4. Run `auth_setup_guide.py --scopes <services>` to identify required scopes
|
||||
5. Run `auth_setup_guide.py --validate` to verify all services
|
||||
6. Generate `.env` template with `auth_setup_guide.py --generate-env`
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_doctor.py
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --guide oauth
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --validate --json
|
||||
```
|
||||
|
||||
### 2. Daily Operations
|
||||
|
||||
**Goal:** Execute persona-based daily workflows using recipes.
|
||||
|
||||
**Steps:**
|
||||
1. Identify user's role and select persona with `gws_recipe_runner.py --personas`
|
||||
2. List relevant recipes with `gws_recipe_runner.py --persona <role> --list`
|
||||
3. Execute recipes with `gws_recipe_runner.py --run <name>` (use `--dry-run` first)
|
||||
4. Pipe output through `output_analyzer.py` for filtering and analysis
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --persona pm --list
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --run standup-report --dry-run
|
||||
gws recipes standup-report --json | python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --format table
|
||||
```
|
||||
|
||||
### 3. Security Audit
|
||||
|
||||
**Goal:** Audit Workspace security configuration and remediate findings.
|
||||
|
||||
**Steps:**
|
||||
1. Run `workspace_audit.py` for full security assessment
|
||||
2. Review findings, prioritizing FAIL items
|
||||
3. Filter findings through `output_analyzer.py` for actionable items
|
||||
4. Execute remediation commands from audit output
|
||||
5. Re-run audit to verify fixes
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/workspace_audit.py --json
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/workspace_audit.py --json | \
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --filter "status=FAIL"
|
||||
```
|
||||
|
||||
### 4. Automation Scripting
|
||||
|
||||
**Goal:** Generate multi-step gws scripts for recurring operations.
|
||||
|
||||
**Steps:**
|
||||
1. Identify the workflow from recipe templates
|
||||
2. Use `gws_recipe_runner.py --describe <name>` for command sequences
|
||||
3. Customize commands with user-specific parameters
|
||||
4. Test with `--dry-run` flag
|
||||
5. Combine into shell scripts or scheduled tasks using `workspace-config.json` template
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
python3 ../../engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --describe morning-briefing
|
||||
# Customize and test
|
||||
gws helpers morning-briefing --json | python3 ../../engineering-team/google-workspace-cli/scripts/output_analyzer.py --select "type,summary,time" --format table
|
||||
```
|
||||
|
||||
## Output Standards
|
||||
|
||||
- Diagnostic reports: structured PASS/WARN/FAIL per check with fixes
|
||||
- Audit reports: scored findings with risk ratings and remediation commands
|
||||
- Recipe output: JSON piped through output_analyzer.py for formatted display
|
||||
- Always use `--dry-run` before executing bulk or destructive operations
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- **Setup Time:** gws installed and authenticated in under 10 minutes
|
||||
- **Audit Coverage:** All critical security checks pass (Grade A or B)
|
||||
- **Automation:** Daily workflows automated via recipes and scheduled tasks
|
||||
- **Troubleshooting:** Common errors resolved using troubleshooting reference
|
||||
|
||||
## Related Agents
|
||||
|
||||
- [cs-engineering-lead](cs-engineering-lead.md) — Engineering team coordination
|
||||
- [cs-senior-engineer](../engineering/cs-senior-engineer.md) — Architecture and CI/CD
|
||||
|
||||
## References
|
||||
|
||||
- [Skill Documentation](../../engineering-team/google-workspace-cli/SKILL.md)
|
||||
- [gws CLI Repository](https://github.com/googleworkspace/cli)
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
title: "Agents"
|
||||
description: "All 14 Claude Code agents — multi-skill orchestrators across domains."
|
||||
description: "All 15 Claude Code agents — multi-skill orchestrators across domains."
|
||||
---
|
||||
|
||||
# Agents
|
||||
|
||||
14 agents that orchestrate skills across domains.
|
||||
15 agents that orchestrate skills across domains.
|
||||
|
||||
| Agent | Domain |
|
||||
|-------|--------|
|
||||
@@ -14,6 +14,7 @@ description: "All 14 Claude Code agents — multi-skill orchestrators across dom
|
||||
| [CTO Advisor Agent](cs-cto-advisor.md) | C-Level Advisory |
|
||||
| [cs-senior-engineer](cs-senior-engineer.md) | Engineering - POWERFUL |
|
||||
| [cs-engineering-lead](cs-engineering-lead.md) | Engineering - Core |
|
||||
| [cs-workspace-admin](cs-workspace-admin.md) | Engineering - Core |
|
||||
| [cs-financial-analyst](cs-financial-analyst.md) | Finance |
|
||||
| [Content Creator Agent](cs-content-creator.md) | Marketing |
|
||||
| [Demand Generation Specialist Agent](cs-demand-gen-specialist.md) | Marketing |
|
||||
|
||||
84
docs/commands/google-workspace.md
Normal file
84
docs/commands/google-workspace.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: "/google-workspace"
|
||||
description: "/google-workspace — Claude Code slash command."
|
||||
---
|
||||
|
||||
# /google-workspace
|
||||
|
||||
**Type:** Slash Command | **Source:** [`commands/google-workspace.md`](https://github.com/alirezarezvani/claude-skills/tree/main/commands/google-workspace.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
# /google-workspace
|
||||
|
||||
Google Workspace CLI administration via the `gws` CLI. Run setup diagnostics, security audits, browse and execute recipes, and analyze command output.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/google-workspace setup [--json]
|
||||
/google-workspace audit [--services gmail,drive,calendar] [--json]
|
||||
/google-workspace recipe list [--persona <role>] [--json]
|
||||
/google-workspace recipe search <keyword> [--json]
|
||||
/google-workspace recipe run <name> [--dry-run]
|
||||
/google-workspace recipe describe <name>
|
||||
/google-workspace analyze [--filter <field=value>] [--group-by <field>] [--stats <field>] [--format table|csv|json]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
/google-workspace setup
|
||||
/google-workspace audit --services gmail,drive --json
|
||||
/google-workspace recipe list --persona pm
|
||||
/google-workspace recipe search "email"
|
||||
/google-workspace recipe run standup-report --dry-run
|
||||
/google-workspace recipe describe morning-briefing
|
||||
/google-workspace analyze --filter "mimeType=pdf" --select "name,size" --format table
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
- `engineering-team/google-workspace-cli/scripts/gws_doctor.py` — Pre-flight diagnostics
|
||||
- `engineering-team/google-workspace-cli/scripts/auth_setup_guide.py` — Auth setup guide
|
||||
- `engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py` — Recipe catalog & runner
|
||||
- `engineering-team/google-workspace-cli/scripts/workspace_audit.py` — Security audit
|
||||
- `engineering-team/google-workspace-cli/scripts/output_analyzer.py` — JSON/NDJSON analyzer
|
||||
|
||||
## Subcommands
|
||||
|
||||
### setup
|
||||
Run pre-flight diagnostics and auth validation.
|
||||
```bash
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_doctor.py [--json]
|
||||
python3 engineering-team/google-workspace-cli/scripts/auth_setup_guide.py --validate [--json]
|
||||
```
|
||||
|
||||
### audit
|
||||
Run security and configuration audit.
|
||||
```bash
|
||||
python3 engineering-team/google-workspace-cli/scripts/workspace_audit.py [--services gmail,drive,calendar] [--json]
|
||||
```
|
||||
|
||||
### recipe
|
||||
Browse, search, and execute the 43 built-in gws recipes.
|
||||
```bash
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --list [--persona <role>] [--json]
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --search <keyword> [--json]
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --describe <name>
|
||||
python3 engineering-team/google-workspace-cli/scripts/gws_recipe_runner.py --run <name> [--dry-run]
|
||||
```
|
||||
|
||||
### analyze
|
||||
Parse, filter, and aggregate JSON output from any gws command.
|
||||
```bash
|
||||
gws <command> --json | python3 engineering-team/google-workspace-cli/scripts/output_analyzer.py [options]
|
||||
python3 engineering-team/google-workspace-cli/scripts/output_analyzer.py --demo --format table
|
||||
```
|
||||
|
||||
## Skill Reference
|
||||
-> `engineering-team/google-workspace-cli/SKILL.md`
|
||||
|
||||
## Related Commands
|
||||
- No direct dependencies (self-contained Google Workspace skill)
|
||||
@@ -1,17 +1,18 @@
|
||||
---
|
||||
title: "Commands"
|
||||
description: "All 14 slash commands for quick access to common operations."
|
||||
description: "All 15 slash commands for quick access to common operations."
|
||||
---
|
||||
|
||||
# Slash Commands
|
||||
|
||||
14 commands for quick access to common operations.
|
||||
15 commands for quick access to common operations.
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| [`/changelog`](changelog.md) | Generate Keep a Changelog entries from git history and validate commit message format. |
|
||||
| [`/competitive-matrix`](competitive-matrix.md) | Build competitive matrices with weighted scoring, gap analysis, and market positioning insights. |
|
||||
| [`/financial-health`](financial-health.md) | Analyze financial statements, build valuation models, assess budget variances, and construct forecasts. |
|
||||
| [`/google-workspace`](google-workspace.md) | Google Workspace CLI administration via the `gws` CLI. Run setup diagnostics, security audits, browse and execute recipes, and analyze command output. |
|
||||
| [`/okr`](okr.md) | Generate cascaded OKR frameworks from company-level strategy down to team-level key results. |
|
||||
| [`/persona`](persona.md) | Generate structured user personas with demographics, goals, pain points, and behavioral patterns. |
|
||||
| [`/pipeline`](pipeline.md) | Detect project stack and generate CI/CD pipeline configurations for GitHub Actions or GitLab CI. |
|
||||
|
||||
@@ -70,7 +70,7 @@ Choose your platform and follow the steps:
|
||||
|
||||
| Bundle | Install Command | Skills |
|
||||
|--------|----------------|--------|
|
||||
| **Engineering Core** | `/plugin install engineering-skills@claude-code-skills` | 23 |
|
||||
| **Engineering Core** | `/plugin install engineering-skills@claude-code-skills` | 24 |
|
||||
| **Engineering POWERFUL** | `/plugin install engineering-advanced-skills@claude-code-skills` | 25 |
|
||||
| **Product** | `/plugin install product-skills@claude-code-skills` | 8 |
|
||||
| **Marketing** | `/plugin install marketing-skills@claude-code-skills` | 43 |
|
||||
@@ -112,7 +112,7 @@ AI-augmented development. Optimize for SEO.
|
||||
|
||||
## Python Tools
|
||||
|
||||
All 245 tools use the standard library only — zero pip installs, all verified.
|
||||
All 250 tools use the standard library only — zero pip installs, all verified.
|
||||
|
||||
```bash
|
||||
# Security audit a skill before installing
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Claude Code Skills & Plugins
|
||||
description: "172 production-ready skills, 14 agents, and 14 commands for Claude Code, OpenAI Codex, Gemini CLI, and OpenClaw."
|
||||
description: "173 production-ready skills, 15 agents, and 15 commands for Claude Code, OpenAI Codex, Gemini CLI, and OpenClaw."
|
||||
hide:
|
||||
- toc
|
||||
- edit
|
||||
@@ -14,7 +14,7 @@ hide:
|
||||
|
||||
# Claude Code Skills
|
||||
|
||||
172 production-ready skills that transform AI coding agents into specialized professionals.
|
||||
173 production-ready skills that transform AI coding agents into specialized professionals.
|
||||
{ .hero-subtitle }
|
||||
|
||||
**Claude Code** | **OpenAI Codex** | **Gemini CLI** | **OpenClaw**
|
||||
@@ -27,25 +27,25 @@ hide:
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- :material-counter:{ .lg .middle } **172**
|
||||
- :material-counter:{ .lg .middle } **173**
|
||||
|
||||
---
|
||||
|
||||
Production-ready skills
|
||||
|
||||
- :material-language-python:{ .lg .middle } **245**
|
||||
- :material-language-python:{ .lg .middle } **250**
|
||||
|
||||
---
|
||||
|
||||
Python CLI tools (stdlib-only, all verified)
|
||||
|
||||
- :material-robot:{ .lg .middle } **14**
|
||||
- :material-robot:{ .lg .middle } **15**
|
||||
|
||||
---
|
||||
|
||||
[Multi-skill agents](agents/)
|
||||
|
||||
- :material-console:{ .lg .middle } **14**
|
||||
- :material-console:{ .lg .middle } **15**
|
||||
|
||||
---
|
||||
|
||||
@@ -65,7 +65,7 @@ hide:
|
||||
|
||||
Architecture, frontend, backend, fullstack, QA, DevOps, SecOps, AI/ML, data engineering, Playwright testing, self-improving agent
|
||||
|
||||
[:octicons-arrow-right-24: 23 skills](skills/engineering-team/)
|
||||
[:octicons-arrow-right-24: 24 skills](skills/engineering-team/)
|
||||
|
||||
- :material-lightning-bolt:{ .lg .middle } **Engineering — POWERFUL**
|
||||
|
||||
|
||||
380
docs/skills/engineering-team/google-workspace-cli.md
Normal file
380
docs/skills/engineering-team/google-workspace-cli.md
Normal file
@@ -0,0 +1,380 @@
|
||||
---
|
||||
title: "Google Workspace CLI"
|
||||
description: "Google Workspace CLI - Claude Code skill from the Engineering - Core domain."
|
||||
---
|
||||
|
||||
# Google Workspace CLI
|
||||
|
||||
**Domain:** Engineering - Core | **Skill:** `google-workspace-cli` | **Source:** [`engineering-team/google-workspace-cli/SKILL.md`](https://github.com/alirezarezvani/claude-skills/tree/main/engineering-team/google-workspace-cli/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
# Google Workspace CLI
|
||||
|
||||
Expert guidance and automation for Google Workspace administration using the open-source `gws` CLI. Covers installation, authentication, 18+ service APIs, 43 built-in recipes, and 10 persona bundles for role-based workflows.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Check Installation
|
||||
|
||||
```bash
|
||||
# Verify gws is installed and authenticated
|
||||
python3 scripts/gws_doctor.py
|
||||
```
|
||||
|
||||
### Send an Email
|
||||
|
||||
```bash
|
||||
gws gmail users.messages send me --to "team@company.com" \
|
||||
--subject "Weekly Update" --body "Here's this week's summary..."
|
||||
```
|
||||
|
||||
### List Drive Files
|
||||
|
||||
```bash
|
||||
gws drive files list --json --limit 20 | python3 scripts/output_analyzer.py --select "name,mimeType,modifiedTime" --format table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### npm (recommended)
|
||||
|
||||
```bash
|
||||
npm install -g @anthropic/gws
|
||||
gws --version
|
||||
```
|
||||
|
||||
### Cargo (from source)
|
||||
|
||||
```bash
|
||||
cargo install gws-cli
|
||||
gws --version
|
||||
```
|
||||
|
||||
### Pre-built Binaries
|
||||
|
||||
Download from [github.com/googleworkspace/cli/releases](https://github.com/googleworkspace/cli/releases) for macOS, Linux, or Windows.
|
||||
|
||||
### Verify Installation
|
||||
|
||||
```bash
|
||||
python3 scripts/gws_doctor.py
|
||||
# Checks: PATH, version, auth status, service connectivity
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
### OAuth Setup (Interactive)
|
||||
|
||||
```bash
|
||||
# Step 1: Create Google Cloud project and OAuth credentials
|
||||
python3 scripts/auth_setup_guide.py --guide oauth
|
||||
|
||||
# Step 2: Run auth setup
|
||||
gws auth setup
|
||||
|
||||
# Step 3: Validate
|
||||
gws auth status --json
|
||||
```
|
||||
|
||||
### Service Account (Headless/CI)
|
||||
|
||||
```bash
|
||||
# Generate setup instructions
|
||||
python3 scripts/auth_setup_guide.py --guide service-account
|
||||
|
||||
# Configure with key file
|
||||
export GWS_SERVICE_ACCOUNT_KEY=/path/to/key.json
|
||||
export GWS_DELEGATED_USER=admin@company.com
|
||||
gws auth status
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Generate .env template
|
||||
python3 scripts/auth_setup_guide.py --generate-env
|
||||
```
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `GWS_CLIENT_ID` | OAuth client ID |
|
||||
| `GWS_CLIENT_SECRET` | OAuth client secret |
|
||||
| `GWS_TOKEN_PATH` | Custom token storage path |
|
||||
| `GWS_SERVICE_ACCOUNT_KEY` | Service account JSON key path |
|
||||
| `GWS_DELEGATED_USER` | User to impersonate (service accounts) |
|
||||
| `GWS_DEFAULT_FORMAT` | Default output format (json/ndjson/table) |
|
||||
|
||||
### Validate Authentication
|
||||
|
||||
```bash
|
||||
python3 scripts/auth_setup_guide.py --validate --json
|
||||
# Tests each service endpoint
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 1: Gmail Automation
|
||||
|
||||
**Goal:** Automate email operations — send, search, label, and filter management.
|
||||
|
||||
### Send and Reply
|
||||
|
||||
```bash
|
||||
# Send a new email
|
||||
gws gmail users.messages send me --to "client@example.com" \
|
||||
--subject "Proposal" --body "Please find attached..." \
|
||||
--attachment proposal.pdf
|
||||
|
||||
# Reply to a thread
|
||||
gws gmail users.messages reply me --thread-id <THREAD_ID> \
|
||||
--body "Thanks for your feedback..."
|
||||
|
||||
# Forward a message
|
||||
gws gmail users.messages forward me --message-id <MSG_ID> \
|
||||
--to "manager@company.com"
|
||||
```
|
||||
|
||||
### Search and Filter
|
||||
|
||||
```bash
|
||||
# Search emails
|
||||
gws gmail users.messages list me --query "from:client@example.com after:2025/01/01" --json \
|
||||
| python3 scripts/output_analyzer.py --count
|
||||
|
||||
# List labels
|
||||
gws gmail users.labels list me --json
|
||||
|
||||
# Create a filter
|
||||
gws gmail users.settings.filters create me \
|
||||
--criteria '{"from":"notifications@service.com"}' \
|
||||
--action '{"addLabelIds":["Label_123"],"removeLabelIds":["INBOX"]}'
|
||||
```
|
||||
|
||||
### Bulk Operations
|
||||
|
||||
```bash
|
||||
# Archive all read emails older than 30 days
|
||||
gws gmail users.messages list me --query "is:read older_than:30d" --json \
|
||||
| python3 scripts/output_analyzer.py --select "id" --format json \
|
||||
| xargs -I {} gws gmail users.messages modify me {} --removeLabelIds INBOX
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 2: Drive & Sheets
|
||||
|
||||
**Goal:** Manage files, create spreadsheets, configure sharing, and export data.
|
||||
|
||||
### File Operations
|
||||
|
||||
```bash
|
||||
# List files
|
||||
gws drive files list --json --limit 50 \
|
||||
| python3 scripts/output_analyzer.py --select "name,mimeType,size" --format table
|
||||
|
||||
# Upload a file
|
||||
gws drive files create --name "Q1 Report" --upload report.pdf \
|
||||
--parents <FOLDER_ID>
|
||||
|
||||
# Create a Google Sheet
|
||||
gws sheets spreadsheets create --title "Budget 2026" --json
|
||||
|
||||
# Download/export
|
||||
gws drive files export <FILE_ID> --mime "application/pdf" --output report.pdf
|
||||
```
|
||||
|
||||
### Sharing
|
||||
|
||||
```bash
|
||||
# Share with user
|
||||
gws drive permissions create <FILE_ID> \
|
||||
--type user --role writer --emailAddress "colleague@company.com"
|
||||
|
||||
# Share with domain (view only)
|
||||
gws drive permissions create <FILE_ID> \
|
||||
--type domain --role reader --domain "company.com"
|
||||
|
||||
# List who has access
|
||||
gws drive permissions list <FILE_ID> --json
|
||||
```
|
||||
|
||||
### Sheets Data
|
||||
|
||||
```bash
|
||||
# Read a range
|
||||
gws sheets spreadsheets.values get <SHEET_ID> --range "Sheet1!A1:D10" --json
|
||||
|
||||
# Write data
|
||||
gws sheets spreadsheets.values update <SHEET_ID> --range "Sheet1!A1" \
|
||||
--values '[["Name","Score"],["Alice",95],["Bob",87]]'
|
||||
|
||||
# Append rows
|
||||
gws sheets spreadsheets.values append <SHEET_ID> --range "Sheet1!A1" \
|
||||
--values '[["Charlie",92]]'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 3: Calendar & Meetings
|
||||
|
||||
**Goal:** Schedule events, find available times, and generate standup reports.
|
||||
|
||||
### Event Management
|
||||
|
||||
```bash
|
||||
# Create an event
|
||||
gws calendar events insert primary \
|
||||
--summary "Sprint Planning" \
|
||||
--start "2026-03-15T10:00:00" --end "2026-03-15T11:00:00" \
|
||||
--attendees "team@company.com" \
|
||||
--location "Conference Room A"
|
||||
|
||||
# List upcoming events
|
||||
gws calendar events list primary --timeMin "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--maxResults 10 --json
|
||||
|
||||
# Quick event (natural language)
|
||||
gws helpers quick-event "Lunch with Sarah tomorrow at noon"
|
||||
```
|
||||
|
||||
### Find Available Time
|
||||
|
||||
```bash
|
||||
# Check free/busy for multiple people
|
||||
gws helpers find-time \
|
||||
--attendees "alice@co.com,bob@co.com,charlie@co.com" \
|
||||
--duration 60 --within "2026-03-15,2026-03-19" --json
|
||||
```
|
||||
|
||||
### Standup Report
|
||||
|
||||
```bash
|
||||
# Generate daily standup from calendar + tasks
|
||||
gws recipes standup-report --json \
|
||||
| python3 scripts/output_analyzer.py --format table
|
||||
|
||||
# Meeting prep (agenda + attendee info)
|
||||
gws recipes meeting-prep --event-id <EVENT_ID>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 4: Security Audit
|
||||
|
||||
**Goal:** Audit Google Workspace security configuration and generate remediation commands.
|
||||
|
||||
### Run Full Audit
|
||||
|
||||
```bash
|
||||
# Full audit across all services
|
||||
python3 scripts/workspace_audit.py --json
|
||||
|
||||
# Audit specific services
|
||||
python3 scripts/workspace_audit.py --services gmail,drive,calendar
|
||||
|
||||
# Demo mode (no gws required)
|
||||
python3 scripts/workspace_audit.py --demo
|
||||
```
|
||||
|
||||
### Audit Checks
|
||||
|
||||
| Area | Check | Risk |
|
||||
|------|-------|------|
|
||||
| Drive | External sharing enabled | Data exfiltration |
|
||||
| Gmail | Auto-forwarding rules | Data exfiltration |
|
||||
| Gmail | DMARC/SPF/DKIM records | Email spoofing |
|
||||
| Calendar | Default sharing visibility | Information leak |
|
||||
| OAuth | Third-party app grants | Unauthorized access |
|
||||
| Admin | Super admin count | Privilege escalation |
|
||||
| Admin | 2-Step verification enforcement | Account takeover |
|
||||
|
||||
### Review and Remediate
|
||||
|
||||
```bash
|
||||
# Review findings
|
||||
python3 scripts/workspace_audit.py --json | python3 scripts/output_analyzer.py \
|
||||
--filter "status=FAIL" --select "area,check,remediation"
|
||||
|
||||
# Execute remediation (example: restrict external sharing)
|
||||
gws drive about get --json # Check current settings
|
||||
# Follow remediation commands from audit output
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Python Tools
|
||||
|
||||
| Script | Purpose | Usage |
|
||||
|--------|---------|-------|
|
||||
| `gws_doctor.py` | Pre-flight diagnostics | `python3 scripts/gws_doctor.py [--json] [--services gmail,drive]` |
|
||||
| `auth_setup_guide.py` | Guided auth setup | `python3 scripts/auth_setup_guide.py --guide oauth` |
|
||||
| `gws_recipe_runner.py` | Recipe catalog & runner | `python3 scripts/gws_recipe_runner.py --list [--persona pm]` |
|
||||
| `workspace_audit.py` | Security/config audit | `python3 scripts/workspace_audit.py [--json] [--demo]` |
|
||||
| `output_analyzer.py` | JSON/NDJSON analysis | `gws ... --json \| python3 scripts/output_analyzer.py --count` |
|
||||
|
||||
All scripts are stdlib-only, support `--json` output, and include demo mode with embedded sample data.
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Security
|
||||
|
||||
1. Use OAuth with minimal scopes — request only what each workflow needs
|
||||
2. Store tokens in the system keyring, never in plain text files
|
||||
3. Rotate service account keys every 90 days
|
||||
4. Audit third-party OAuth app grants quarterly
|
||||
5. Use `--dry-run` before bulk destructive operations
|
||||
|
||||
### Automation
|
||||
|
||||
1. Pipe `--json` output through `output_analyzer.py` for filtering and aggregation
|
||||
2. Use recipes for multi-step operations instead of chaining raw commands
|
||||
3. Select a persona bundle to scope recipes to your role
|
||||
4. Use NDJSON format (`--format ndjson`) for streaming large result sets
|
||||
5. Set `GWS_DEFAULT_FORMAT=json` in your shell profile for scripting
|
||||
|
||||
### Performance
|
||||
|
||||
1. Use `--fields` to request only needed fields (reduces payload size)
|
||||
2. Use `--limit` to cap results when browsing
|
||||
3. Use `--page-all` only when you need complete datasets
|
||||
4. Batch operations with recipes rather than individual API calls
|
||||
5. Cache frequently accessed data (e.g., label IDs, folder IDs) in variables
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
| Constraint | Impact |
|
||||
|------------|--------|
|
||||
| OAuth tokens expire after 1 hour | Re-auth needed for long-running scripts |
|
||||
| API rate limits (per-user, per-service) | Bulk operations may hit 429 errors |
|
||||
| Scope requirements vary by service | Must request correct scopes during auth |
|
||||
| Pre-v1.0 CLI status | Breaking changes possible between releases |
|
||||
| Google Cloud project required | Free, but requires setup in Cloud Console |
|
||||
| Admin API needs admin privileges | Some audit checks require Workspace Admin role |
|
||||
|
||||
### Required Scopes by Service
|
||||
|
||||
```bash
|
||||
# List scopes for specific services
|
||||
python3 scripts/auth_setup_guide.py --scopes gmail,drive,calendar,sheets
|
||||
```
|
||||
|
||||
| Service | Key Scopes |
|
||||
|---------|-----------|
|
||||
| Gmail | `gmail.modify`, `gmail.send`, `gmail.labels` |
|
||||
| Drive | `drive.file`, `drive.metadata.readonly` |
|
||||
| Sheets | `spreadsheets` |
|
||||
| Calendar | `calendar`, `calendar.events` |
|
||||
| Admin | `admin.directory.user.readonly`, `admin.directory.group` |
|
||||
| Tasks | `tasks` |
|
||||
@@ -5,7 +5,7 @@ description: "All Engineering - Core skills for Claude Code, OpenAI Codex, and O
|
||||
|
||||
# Engineering - Core Skills
|
||||
|
||||
38 skills in this domain.
|
||||
39 skills in this domain.
|
||||
|
||||
| Skill | Description |
|
||||
|-------|-------------|
|
||||
@@ -13,6 +13,7 @@ description: "All Engineering - Core skills for Claude Code, OpenAI Codex, and O
|
||||
| [Code Reviewer](code-reviewer.md) | `code-reviewer` |
|
||||
| [Email Template Builder](email-template-builder.md) | `email-template-builder` |
|
||||
| [Engineering Team Skills](engineering-team.md) | `engineering-team` |
|
||||
| [Google Workspace CLI](google-workspace-cli.md) | `google-workspace-cli` |
|
||||
| [Incident Commander Skill](incident-commander.md) | `incident-commander` |
|
||||
| [Microsoft 365 Tenant Manager](ms365-tenant-manager.md) | `ms365-tenant-manager` |
|
||||
| [Playwright Pro](playwright-pro.md) | `playwright-pro` |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "engineering-skills",
|
||||
"description": "23 production-ready engineering skills: architecture, frontend, backend, fullstack, QA, DevOps, security, AI/ML, data engineering, Playwright (9 sub-skills), self-improving agent, Stripe integration, TDD guide, and more",
|
||||
"description": "24 production-ready engineering skills: architecture, frontend, backend, fullstack, QA, DevOps, security, AI/ML, data engineering, Playwright (9 sub-skills), self-improving agent, Stripe integration, TDD guide, Google Workspace CLI, and more",
|
||||
"version": "2.1.2",
|
||||
"author": {
|
||||
"name": "Alireza Rezvani",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Engineering Team Skills - Claude Code Guidance
|
||||
|
||||
This guide covers the 18 production-ready engineering skills and their Python automation tools.
|
||||
This guide covers the 24 production-ready engineering skills and their Python automation tools.
|
||||
|
||||
## Engineering Skills Overview
|
||||
|
||||
@@ -8,7 +8,7 @@ This guide covers the 18 production-ready engineering skills and their Python au
|
||||
- senior-architect, senior-frontend, senior-backend, senior-fullstack
|
||||
- senior-qa, senior-devops, senior-secops
|
||||
- code-reviewer, senior-security
|
||||
- aws-solution-architect, ms365-tenant-manager, tdd-guide, tech-stack-evaluator
|
||||
- aws-solution-architect, ms365-tenant-manager, google-workspace-cli, tdd-guide, tech-stack-evaluator
|
||||
|
||||
**AI/ML/Data (5 skills):**
|
||||
- senior-data-scientist, senior-data-engineer, senior-ml-engineer
|
||||
@@ -287,6 +287,6 @@ services:
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** November 5, 2025
|
||||
**Skills Deployed:** 18/18 engineering skills production-ready
|
||||
**Total Tools:** 30+ Python automation tools across core + AI/ML/Data
|
||||
**Last Updated:** March 11, 2026
|
||||
**Skills Deployed:** 24 engineering skills production-ready
|
||||
**Total Tools:** 35+ Python automation tools across core + AI/ML/Data
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "google-workspace-cli",
|
||||
"version": "2.1.2",
|
||||
"description": "Google Workspace administration via the gws CLI. Install, authenticate, and automate Gmail, Drive, Sheets, Calendar, Docs, Chat, and Tasks. 5 Python tools, 3 reference guides, 43 built-in recipes, 10 persona bundles.",
|
||||
"author": {
|
||||
"name": "Alireza Rezvani"
|
||||
},
|
||||
"repository": "https://github.com/alirezarezvani/claude-skills",
|
||||
"license": "MIT",
|
||||
"skills": "./",
|
||||
"homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/engineering-team/google-workspace-cli"
|
||||
}
|
||||
14
engineering-team/google-workspace-cli/.gitignore
vendored
Normal file
14
engineering-team/google-workspace-cli/.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# Auth tokens
|
||||
*.token
|
||||
*.json.bak
|
||||
.env
|
||||
.env.*
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
373
engineering-team/google-workspace-cli/SKILL.md
Normal file
373
engineering-team/google-workspace-cli/SKILL.md
Normal file
@@ -0,0 +1,373 @@
|
||||
---
|
||||
name: "google-workspace-cli"
|
||||
description: "Google Workspace administration via the gws CLI. Install, authenticate, and automate Gmail, Drive, Sheets, Calendar, Docs, Chat, and Tasks. Run security audits, execute 43 built-in recipes, and use 10 persona bundles. Use for Google Workspace admin, gws CLI setup, Gmail automation, Drive management, or Calendar scheduling."
|
||||
---
|
||||
|
||||
# Google Workspace CLI
|
||||
|
||||
Expert guidance and automation for Google Workspace administration using the open-source `gws` CLI. Covers installation, authentication, 18+ service APIs, 43 built-in recipes, and 10 persona bundles for role-based workflows.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Check Installation
|
||||
|
||||
```bash
|
||||
# Verify gws is installed and authenticated
|
||||
python3 scripts/gws_doctor.py
|
||||
```
|
||||
|
||||
### Send an Email
|
||||
|
||||
```bash
|
||||
gws gmail users.messages send me --to "team@company.com" \
|
||||
--subject "Weekly Update" --body "Here's this week's summary..."
|
||||
```
|
||||
|
||||
### List Drive Files
|
||||
|
||||
```bash
|
||||
gws drive files list --json --limit 20 | python3 scripts/output_analyzer.py --select "name,mimeType,modifiedTime" --format table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### npm (recommended)
|
||||
|
||||
```bash
|
||||
npm install -g @anthropic/gws
|
||||
gws --version
|
||||
```
|
||||
|
||||
### Cargo (from source)
|
||||
|
||||
```bash
|
||||
cargo install gws-cli
|
||||
gws --version
|
||||
```
|
||||
|
||||
### Pre-built Binaries
|
||||
|
||||
Download from [github.com/googleworkspace/cli/releases](https://github.com/googleworkspace/cli/releases) for macOS, Linux, or Windows.
|
||||
|
||||
### Verify Installation
|
||||
|
||||
```bash
|
||||
python3 scripts/gws_doctor.py
|
||||
# Checks: PATH, version, auth status, service connectivity
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
### OAuth Setup (Interactive)
|
||||
|
||||
```bash
|
||||
# Step 1: Create Google Cloud project and OAuth credentials
|
||||
python3 scripts/auth_setup_guide.py --guide oauth
|
||||
|
||||
# Step 2: Run auth setup
|
||||
gws auth setup
|
||||
|
||||
# Step 3: Validate
|
||||
gws auth status --json
|
||||
```
|
||||
|
||||
### Service Account (Headless/CI)
|
||||
|
||||
```bash
|
||||
# Generate setup instructions
|
||||
python3 scripts/auth_setup_guide.py --guide service-account
|
||||
|
||||
# Configure with key file
|
||||
export GWS_SERVICE_ACCOUNT_KEY=/path/to/key.json
|
||||
export GWS_DELEGATED_USER=admin@company.com
|
||||
gws auth status
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Generate .env template
|
||||
python3 scripts/auth_setup_guide.py --generate-env
|
||||
```
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `GWS_CLIENT_ID` | OAuth client ID |
|
||||
| `GWS_CLIENT_SECRET` | OAuth client secret |
|
||||
| `GWS_TOKEN_PATH` | Custom token storage path |
|
||||
| `GWS_SERVICE_ACCOUNT_KEY` | Service account JSON key path |
|
||||
| `GWS_DELEGATED_USER` | User to impersonate (service accounts) |
|
||||
| `GWS_DEFAULT_FORMAT` | Default output format (json/ndjson/table) |
|
||||
|
||||
### Validate Authentication
|
||||
|
||||
```bash
|
||||
python3 scripts/auth_setup_guide.py --validate --json
|
||||
# Tests each service endpoint
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 1: Gmail Automation
|
||||
|
||||
**Goal:** Automate email operations — send, search, label, and filter management.
|
||||
|
||||
### Send and Reply
|
||||
|
||||
```bash
|
||||
# Send a new email
|
||||
gws gmail users.messages send me --to "client@example.com" \
|
||||
--subject "Proposal" --body "Please find attached..." \
|
||||
--attachment proposal.pdf
|
||||
|
||||
# Reply to a thread
|
||||
gws gmail users.messages reply me --thread-id <THREAD_ID> \
|
||||
--body "Thanks for your feedback..."
|
||||
|
||||
# Forward a message
|
||||
gws gmail users.messages forward me --message-id <MSG_ID> \
|
||||
--to "manager@company.com"
|
||||
```
|
||||
|
||||
### Search and Filter
|
||||
|
||||
```bash
|
||||
# Search emails
|
||||
gws gmail users.messages list me --query "from:client@example.com after:2025/01/01" --json \
|
||||
| python3 scripts/output_analyzer.py --count
|
||||
|
||||
# List labels
|
||||
gws gmail users.labels list me --json
|
||||
|
||||
# Create a filter
|
||||
gws gmail users.settings.filters create me \
|
||||
--criteria '{"from":"notifications@service.com"}' \
|
||||
--action '{"addLabelIds":["Label_123"],"removeLabelIds":["INBOX"]}'
|
||||
```
|
||||
|
||||
### Bulk Operations
|
||||
|
||||
```bash
|
||||
# Archive all read emails older than 30 days
|
||||
gws gmail users.messages list me --query "is:read older_than:30d" --json \
|
||||
| python3 scripts/output_analyzer.py --select "id" --format json \
|
||||
| xargs -I {} gws gmail users.messages modify me {} --removeLabelIds INBOX
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 2: Drive & Sheets
|
||||
|
||||
**Goal:** Manage files, create spreadsheets, configure sharing, and export data.
|
||||
|
||||
### File Operations
|
||||
|
||||
```bash
|
||||
# List files
|
||||
gws drive files list --json --limit 50 \
|
||||
| python3 scripts/output_analyzer.py --select "name,mimeType,size" --format table
|
||||
|
||||
# Upload a file
|
||||
gws drive files create --name "Q1 Report" --upload report.pdf \
|
||||
--parents <FOLDER_ID>
|
||||
|
||||
# Create a Google Sheet
|
||||
gws sheets spreadsheets create --title "Budget 2026" --json
|
||||
|
||||
# Download/export
|
||||
gws drive files export <FILE_ID> --mime "application/pdf" --output report.pdf
|
||||
```
|
||||
|
||||
### Sharing
|
||||
|
||||
```bash
|
||||
# Share with user
|
||||
gws drive permissions create <FILE_ID> \
|
||||
--type user --role writer --emailAddress "colleague@company.com"
|
||||
|
||||
# Share with domain (view only)
|
||||
gws drive permissions create <FILE_ID> \
|
||||
--type domain --role reader --domain "company.com"
|
||||
|
||||
# List who has access
|
||||
gws drive permissions list <FILE_ID> --json
|
||||
```
|
||||
|
||||
### Sheets Data
|
||||
|
||||
```bash
|
||||
# Read a range
|
||||
gws sheets spreadsheets.values get <SHEET_ID> --range "Sheet1!A1:D10" --json
|
||||
|
||||
# Write data
|
||||
gws sheets spreadsheets.values update <SHEET_ID> --range "Sheet1!A1" \
|
||||
--values '[["Name","Score"],["Alice",95],["Bob",87]]'
|
||||
|
||||
# Append rows
|
||||
gws sheets spreadsheets.values append <SHEET_ID> --range "Sheet1!A1" \
|
||||
--values '[["Charlie",92]]'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 3: Calendar & Meetings
|
||||
|
||||
**Goal:** Schedule events, find available times, and generate standup reports.
|
||||
|
||||
### Event Management
|
||||
|
||||
```bash
|
||||
# Create an event
|
||||
gws calendar events insert primary \
|
||||
--summary "Sprint Planning" \
|
||||
--start "2026-03-15T10:00:00" --end "2026-03-15T11:00:00" \
|
||||
--attendees "team@company.com" \
|
||||
--location "Conference Room A"
|
||||
|
||||
# List upcoming events
|
||||
gws calendar events list primary --timeMin "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--maxResults 10 --json
|
||||
|
||||
# Quick event (natural language)
|
||||
gws helpers quick-event "Lunch with Sarah tomorrow at noon"
|
||||
```
|
||||
|
||||
### Find Available Time
|
||||
|
||||
```bash
|
||||
# Check free/busy for multiple people
|
||||
gws helpers find-time \
|
||||
--attendees "alice@co.com,bob@co.com,charlie@co.com" \
|
||||
--duration 60 --within "2026-03-15,2026-03-19" --json
|
||||
```
|
||||
|
||||
### Standup Report
|
||||
|
||||
```bash
|
||||
# Generate daily standup from calendar + tasks
|
||||
gws recipes standup-report --json \
|
||||
| python3 scripts/output_analyzer.py --format table
|
||||
|
||||
# Meeting prep (agenda + attendee info)
|
||||
gws recipes meeting-prep --event-id <EVENT_ID>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow 4: Security Audit
|
||||
|
||||
**Goal:** Audit Google Workspace security configuration and generate remediation commands.
|
||||
|
||||
### Run Full Audit
|
||||
|
||||
```bash
|
||||
# Full audit across all services
|
||||
python3 scripts/workspace_audit.py --json
|
||||
|
||||
# Audit specific services
|
||||
python3 scripts/workspace_audit.py --services gmail,drive,calendar
|
||||
|
||||
# Demo mode (no gws required)
|
||||
python3 scripts/workspace_audit.py --demo
|
||||
```
|
||||
|
||||
### Audit Checks
|
||||
|
||||
| Area | Check | Risk |
|
||||
|------|-------|------|
|
||||
| Drive | External sharing enabled | Data exfiltration |
|
||||
| Gmail | Auto-forwarding rules | Data exfiltration |
|
||||
| Gmail | DMARC/SPF/DKIM records | Email spoofing |
|
||||
| Calendar | Default sharing visibility | Information leak |
|
||||
| OAuth | Third-party app grants | Unauthorized access |
|
||||
| Admin | Super admin count | Privilege escalation |
|
||||
| Admin | 2-Step verification enforcement | Account takeover |
|
||||
|
||||
### Review and Remediate
|
||||
|
||||
```bash
|
||||
# Review findings
|
||||
python3 scripts/workspace_audit.py --json | python3 scripts/output_analyzer.py \
|
||||
--filter "status=FAIL" --select "area,check,remediation"
|
||||
|
||||
# Execute remediation (example: restrict external sharing)
|
||||
gws drive about get --json # Check current settings
|
||||
# Follow remediation commands from audit output
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Python Tools
|
||||
|
||||
| Script | Purpose | Usage |
|
||||
|--------|---------|-------|
|
||||
| `gws_doctor.py` | Pre-flight diagnostics | `python3 scripts/gws_doctor.py [--json] [--services gmail,drive]` |
|
||||
| `auth_setup_guide.py` | Guided auth setup | `python3 scripts/auth_setup_guide.py --guide oauth` |
|
||||
| `gws_recipe_runner.py` | Recipe catalog & runner | `python3 scripts/gws_recipe_runner.py --list [--persona pm]` |
|
||||
| `workspace_audit.py` | Security/config audit | `python3 scripts/workspace_audit.py [--json] [--demo]` |
|
||||
| `output_analyzer.py` | JSON/NDJSON analysis | `gws ... --json \| python3 scripts/output_analyzer.py --count` |
|
||||
|
||||
All scripts are stdlib-only, support `--json` output, and include demo mode with embedded sample data.
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Security
|
||||
|
||||
1. Use OAuth with minimal scopes — request only what each workflow needs
|
||||
2. Store tokens in the system keyring, never in plain text files
|
||||
3. Rotate service account keys every 90 days
|
||||
4. Audit third-party OAuth app grants quarterly
|
||||
5. Use `--dry-run` before bulk destructive operations
|
||||
|
||||
### Automation
|
||||
|
||||
1. Pipe `--json` output through `output_analyzer.py` for filtering and aggregation
|
||||
2. Use recipes for multi-step operations instead of chaining raw commands
|
||||
3. Select a persona bundle to scope recipes to your role
|
||||
4. Use NDJSON format (`--format ndjson`) for streaming large result sets
|
||||
5. Set `GWS_DEFAULT_FORMAT=json` in your shell profile for scripting
|
||||
|
||||
### Performance
|
||||
|
||||
1. Use `--fields` to request only needed fields (reduces payload size)
|
||||
2. Use `--limit` to cap results when browsing
|
||||
3. Use `--page-all` only when you need complete datasets
|
||||
4. Batch operations with recipes rather than individual API calls
|
||||
5. Cache frequently accessed data (e.g., label IDs, folder IDs) in variables
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
| Constraint | Impact |
|
||||
|------------|--------|
|
||||
| OAuth tokens expire after 1 hour | Re-auth needed for long-running scripts |
|
||||
| API rate limits (per-user, per-service) | Bulk operations may hit 429 errors |
|
||||
| Scope requirements vary by service | Must request correct scopes during auth |
|
||||
| Pre-v1.0 CLI status | Breaking changes possible between releases |
|
||||
| Google Cloud project required | Free, but requires setup in Cloud Console |
|
||||
| Admin API needs admin privileges | Some audit checks require Workspace Admin role |
|
||||
|
||||
### Required Scopes by Service
|
||||
|
||||
```bash
|
||||
# List scopes for specific services
|
||||
python3 scripts/auth_setup_guide.py --scopes gmail,drive,calendar,sheets
|
||||
```
|
||||
|
||||
| Service | Key Scopes |
|
||||
|---------|-----------|
|
||||
| Gmail | `gmail.modify`, `gmail.send`, `gmail.labels` |
|
||||
| Drive | `drive.file`, `drive.metadata.readonly` |
|
||||
| Sheets | `spreadsheets` |
|
||||
| Calendar | `calendar`, `calendar.events` |
|
||||
| Admin | `admin.directory.user.readonly`, `admin.directory.group` |
|
||||
| Tasks | `tasks` |
|
||||
223
engineering-team/google-workspace-cli/assets/persona-profiles.md
Normal file
223
engineering-team/google-workspace-cli/assets/persona-profiles.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# Google Workspace CLI Persona Profiles
|
||||
|
||||
10 role-based bundles that scope recipes and commands to your daily workflow.
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Assistant
|
||||
|
||||
**Description:** Managing schedules, emails, and communications for executives.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws helpers morning-briefing` — Start the day with schedule + inbox overview
|
||||
- `gws helpers find-time` — Find available slots for meetings
|
||||
- `gws helpers meeting-prep --event-id <id>` — Prepare meeting agenda
|
||||
- `gws gmail users.messages send me` — Send emails on behalf
|
||||
- `gws helpers eod-wrap` — End of day summary
|
||||
|
||||
**Recommended Recipes:** morning-briefing, today-schedule, find-time, send-email, reply-to-thread, meeting-prep, eod-wrap, quick-event, inbox-zero, standup-report
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Run `morning-briefing` at 8:00 AM
|
||||
2. Process inbox with `inbox-zero`
|
||||
3. Schedule meetings with `find-time` + `create-event`
|
||||
4. Prep for meetings with `meeting-prep`
|
||||
5. Close day with `eod-wrap`
|
||||
|
||||
---
|
||||
|
||||
## 2. Project Manager
|
||||
|
||||
**Description:** Tracking tasks, meetings, and project deliverables.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws recipes standup-report` — Generate standup updates
|
||||
- `gws helpers find-time` — Schedule sprint ceremonies
|
||||
- `gws tasks tasks insert` — Create and assign tasks
|
||||
- `gws sheets spreadsheets.values get` — Read project trackers
|
||||
- `gws recipes project-status` — Aggregate project status
|
||||
|
||||
**Recommended Recipes:** standup-report, create-event, find-time, task-create, task-progress, project-status, weekly-summary, share-folder, sheet-read, morning-briefing
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Run `standup-report` before standup
|
||||
2. Update project tracker via `sheet-write`
|
||||
3. Create action items with `task-create`
|
||||
4. Run `weekly-summary` on Fridays
|
||||
5. Share updates via `chat-message`
|
||||
|
||||
---
|
||||
|
||||
## 3. HR
|
||||
|
||||
**Description:** Managing people, onboarding, and team communications.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws admin users list` — List all domain users
|
||||
- `gws admin users get <email>` — Look up employee details
|
||||
- `gws docs documents create` — Create onboarding docs
|
||||
- `gws drive permissions create` — Share folders with new hires
|
||||
- `gws people people.connections list` — Export contact directory
|
||||
|
||||
**Recommended Recipes:** list-users, user-info, send-email, create-event, create-doc, share-folder, chat-message, list-groups, export-contacts, today-schedule
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Check new hire onboarding queue
|
||||
2. Create welcome docs with `create-doc`
|
||||
3. Set up 1:1s with `create-event`
|
||||
4. Share team folders with `share-folder`
|
||||
5. Send announcements via `send-email`
|
||||
|
||||
---
|
||||
|
||||
## 4. Sales
|
||||
|
||||
**Description:** Managing client communications, proposals, and scheduling.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws gmail users.messages send me` — Send proposals and follow-ups
|
||||
- `gws gmail users.messages list me --query` — Search client conversations
|
||||
- `gws helpers find-time` — Schedule client meetings
|
||||
- `gws docs documents create` — Create proposals
|
||||
- `gws sheets spreadsheets.values update` — Update pipeline tracker
|
||||
|
||||
**Recommended Recipes:** send-email, search-emails, create-event, find-time, create-doc, share-file, sheet-read, sheet-write, export-file, morning-briefing
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Run `morning-briefing` for meeting overview
|
||||
2. Search emails for client updates
|
||||
3. Update pipeline in Sheets
|
||||
4. Send proposals via `send-email` + `share-file`
|
||||
5. Schedule follow-ups with `create-event`
|
||||
|
||||
---
|
||||
|
||||
## 5. IT Admin
|
||||
|
||||
**Description:** Managing Workspace configuration, security, and user administration.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws admin users list --domain` — Audit user accounts
|
||||
- `gws admin activities list login` — Monitor login activity
|
||||
- `gws admin groups list` — Manage groups
|
||||
- `python3 workspace_audit.py` — Run security audit
|
||||
- `gws drive files list --orderBy "quotaBytesUsed desc"` — Find storage hogs
|
||||
|
||||
**Recommended Recipes:** list-users, list-groups, user-info, audit-logins, drive-activity, find-large-files, cleanup-trash, label-manager, filter-setup, share-folder
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Check `audit-logins` for suspicious activity
|
||||
2. Run `workspace_audit.py` weekly
|
||||
3. Process user provisioning requests
|
||||
4. Monitor storage with `find-large-files`
|
||||
5. Review group memberships
|
||||
|
||||
---
|
||||
|
||||
## 6. Developer
|
||||
|
||||
**Description:** Using Workspace APIs for automation and data integration.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws sheets spreadsheets.values get` — Read config/data from Sheets
|
||||
- `gws sheets spreadsheets.values update` — Write results to Sheets
|
||||
- `gws drive files create --upload` — Upload build artifacts
|
||||
- `gws chat spaces.messages create` — Post deployment notifications
|
||||
- `gws tasks tasks insert` — Create tasks from CI/CD
|
||||
|
||||
**Recommended Recipes:** sheet-read, sheet-write, sheet-append, upload-file, create-doc, chat-message, task-create, list-files, export-file, send-email
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Read config from Sheets API
|
||||
2. Run automated reports to Sheets
|
||||
3. Post updates to Chat spaces
|
||||
4. Upload artifacts to Drive
|
||||
5. Create tasks for bugs/issues
|
||||
|
||||
---
|
||||
|
||||
## 7. Marketing
|
||||
|
||||
**Description:** Managing campaigns, content creation, and team coordination.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws docs documents create` — Draft blog posts and briefs
|
||||
- `gws drive files create --upload` — Upload creative assets
|
||||
- `gws sheets spreadsheets.values append` — Log campaign metrics
|
||||
- `gws gmail users.messages send me` — Send campaign emails
|
||||
- `gws chat spaces.messages create` — Coordinate with team
|
||||
|
||||
**Recommended Recipes:** send-email, create-doc, share-file, upload-file, create-sheet, sheet-write, chat-message, create-event, email-stats, weekly-summary
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Check `email-stats` for campaign performance
|
||||
2. Create content in Docs
|
||||
3. Upload assets to shared Drive folders
|
||||
4. Update metrics in Sheets
|
||||
5. Coordinate launches via Chat
|
||||
|
||||
---
|
||||
|
||||
## 8. Finance
|
||||
|
||||
**Description:** Managing spreadsheets, financial reports, and data analysis.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws sheets spreadsheets.values get` — Pull financial data
|
||||
- `gws sheets spreadsheets.values update` — Update forecasts
|
||||
- `gws sheets spreadsheets create` — Create new reports
|
||||
- `gws drive files export` — Export reports as PDF
|
||||
- `gws drive permissions create` — Share with auditors
|
||||
|
||||
**Recommended Recipes:** sheet-read, sheet-write, sheet-append, create-sheet, export-file, share-file, send-email, find-large-files, drive-activity, weekly-summary
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Pull latest data into Sheets
|
||||
2. Update financial models
|
||||
3. Generate PDF reports with `export-file`
|
||||
4. Share reports with stakeholders
|
||||
5. Weekly summary for leadership
|
||||
|
||||
---
|
||||
|
||||
## 9. Legal
|
||||
|
||||
**Description:** Managing documents, contracts, and compliance.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws docs documents create` — Draft contracts
|
||||
- `gws drive files export` — Export final versions as PDF
|
||||
- `gws drive permissions create` — Manage document access
|
||||
- `gws gmail users.messages list me --query` — Search for compliance emails
|
||||
- `gws admin activities list` — Audit trail for compliance
|
||||
|
||||
**Recommended Recipes:** create-doc, share-file, export-file, search-emails, send-email, upload-file, list-files, drive-activity, audit-logins, find-large-files
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Draft and review documents
|
||||
2. Search email for contract references
|
||||
3. Export finalized docs as PDF
|
||||
4. Set precise sharing permissions
|
||||
5. Maintain audit trail
|
||||
|
||||
---
|
||||
|
||||
## 10. Customer Support
|
||||
|
||||
**Description:** Managing customer communications and ticket tracking.
|
||||
|
||||
**Top Commands:**
|
||||
- `gws gmail users.messages list me --query` — Search customer emails
|
||||
- `gws gmail users.messages reply me` — Reply to tickets
|
||||
- `gws gmail users.labels create` — Organize by ticket status
|
||||
- `gws tasks tasks insert` — Create follow-up tasks
|
||||
- `gws chat spaces.messages create` — Escalate to team
|
||||
|
||||
**Recommended Recipes:** search-emails, send-email, reply-to-thread, label-manager, filter-setup, task-create, chat-message, unread-digest, inbox-zero, morning-briefing
|
||||
|
||||
**Daily Workflow:**
|
||||
1. Run `morning-briefing` for ticket overview
|
||||
2. Process inbox with label-based triage
|
||||
3. Reply to open tickets
|
||||
4. Escalate via Chat for urgent issues
|
||||
5. Create follow-up tasks for pending items
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"_comment": "Google Workspace CLI automation config template. Copy and customize for your environment.",
|
||||
"auth": {
|
||||
"method": "oauth",
|
||||
"client_id": "",
|
||||
"client_secret": "",
|
||||
"token_path": "~/.config/gws/token.json",
|
||||
"service_account_key": "",
|
||||
"delegated_user": ""
|
||||
},
|
||||
"defaults": {
|
||||
"output_format": "json",
|
||||
"pagination_limit": 100,
|
||||
"timeout_ms": 30000,
|
||||
"log_level": "warn"
|
||||
},
|
||||
"persona": "developer",
|
||||
"scopes": [
|
||||
"gmail.modify",
|
||||
"gmail.send",
|
||||
"drive.file",
|
||||
"drive.metadata.readonly",
|
||||
"spreadsheets",
|
||||
"calendar",
|
||||
"calendar.events",
|
||||
"tasks"
|
||||
],
|
||||
"scheduled_tasks": [
|
||||
{
|
||||
"name": "morning-briefing",
|
||||
"recipe": "morning-briefing",
|
||||
"schedule": "0 8 * * 1-5",
|
||||
"output": "~/workspace-reports/morning-{date}.json"
|
||||
},
|
||||
{
|
||||
"name": "eod-wrap",
|
||||
"recipe": "eod-wrap",
|
||||
"schedule": "0 17 * * 1-5",
|
||||
"output": "~/workspace-reports/eod-{date}.json"
|
||||
},
|
||||
{
|
||||
"name": "weekly-summary",
|
||||
"recipe": "weekly-summary",
|
||||
"schedule": "0 9 * * 5",
|
||||
"output": "~/workspace-reports/weekly-{date}.json"
|
||||
},
|
||||
{
|
||||
"name": "security-audit",
|
||||
"command": "python3 scripts/workspace_audit.py --json",
|
||||
"schedule": "0 10 * * 1",
|
||||
"output": "~/workspace-reports/audit-{date}.json"
|
||||
}
|
||||
],
|
||||
"aliases": {
|
||||
"inbox": "gws gmail users.messages list me --query 'is:inbox' --limit 20 --json",
|
||||
"unread": "gws gmail users.messages list me --query 'is:unread' --limit 20 --json",
|
||||
"files": "gws drive files list --limit 20 --json",
|
||||
"events": "gws calendar events list primary --timeMin $(date -u +%Y-%m-%dT%H:%M:%SZ) --maxResults 10 --json",
|
||||
"tasks": "gws tasks tasks list @default --json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
# Google Workspace CLI Command Reference
|
||||
|
||||
Comprehensive reference for the `gws` CLI covering 18 services, 22 helper commands, global flags, and environment variables.
|
||||
|
||||
---
|
||||
|
||||
## Global Flags
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--json` | Output as JSON |
|
||||
| `--format ndjson` | Output as newline-delimited JSON |
|
||||
| `--dry-run` | Show what would be done without executing |
|
||||
| `--limit <n>` | Maximum results to return |
|
||||
| `--page-all` | Fetch all pages of results |
|
||||
| `--fields <spec>` | Partial response field mask |
|
||||
| `--quiet` | Suppress non-error output |
|
||||
| `--verbose` | Verbose debug output |
|
||||
| `--timeout <ms>` | Request timeout in milliseconds |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `GWS_CLIENT_ID` | OAuth client ID | — |
|
||||
| `GWS_CLIENT_SECRET` | OAuth client secret | — |
|
||||
| `GWS_TOKEN_PATH` | Token storage location | `~/.config/gws/token.json` |
|
||||
| `GWS_SERVICE_ACCOUNT_KEY` | Service account JSON key path | — |
|
||||
| `GWS_DELEGATED_USER` | User to impersonate (service accounts) | — |
|
||||
| `GWS_DEFAULT_FORMAT` | Default output format | `text` |
|
||||
| `GWS_PAGINATION_LIMIT` | Default pagination limit | `100` |
|
||||
| `GWS_LOG_LEVEL` | Logging level (debug/info/warn/error) | `warn` |
|
||||
|
||||
---
|
||||
|
||||
## Services
|
||||
|
||||
### Gmail
|
||||
|
||||
```bash
|
||||
gws gmail users.messages list me --query "<query>" --json
|
||||
gws gmail users.messages get me <messageId> --json
|
||||
gws gmail users.messages send me --to <email> --subject <subj> --body <body>
|
||||
gws gmail users.messages reply me --thread-id <id> --body <body>
|
||||
gws gmail users.messages forward me --message-id <id> --to <email>
|
||||
gws gmail users.messages modify me <id> --addLabelIds <label> --removeLabelIds INBOX
|
||||
gws gmail users.messages trash me <id>
|
||||
gws gmail users.labels list me --json
|
||||
gws gmail users.labels create me --name <name>
|
||||
gws gmail users.settings.filters create me --criteria <json> --action <json>
|
||||
gws gmail users.settings.forwardingAddresses list me --json
|
||||
gws gmail users getProfile me --json
|
||||
```
|
||||
|
||||
### Google Drive
|
||||
|
||||
```bash
|
||||
gws drive files list --json --limit <n>
|
||||
gws drive files list --query "name contains '<term>'" --json
|
||||
gws drive files list --parents <folderId> --json
|
||||
gws drive files get <fileId> --json
|
||||
gws drive files create --name <name> --upload <path> --parents <folderId>
|
||||
gws drive files create --name <name> --mimeType application/vnd.google-apps.folder
|
||||
gws drive files update <fileId> --upload <path>
|
||||
gws drive files delete <fileId>
|
||||
gws drive files export <fileId> --mime <mimeType> --output <path>
|
||||
gws drive files copy <fileId> --name <newName>
|
||||
gws drive permissions list <fileId> --json
|
||||
gws drive permissions create <fileId> --type <user|group|domain> --role <reader|writer|owner> --emailAddress <email>
|
||||
gws drive permissions delete <fileId> <permissionId>
|
||||
gws drive about get --json
|
||||
gws drive files emptyTrash
|
||||
```
|
||||
|
||||
### Google Sheets
|
||||
|
||||
```bash
|
||||
gws sheets spreadsheets create --title <title> --json
|
||||
gws sheets spreadsheets get <spreadsheetId> --json
|
||||
gws sheets spreadsheets.values get <spreadsheetId> --range <range> --json
|
||||
gws sheets spreadsheets.values update <spreadsheetId> --range <range> --values <json>
|
||||
gws sheets spreadsheets.values append <spreadsheetId> --range <range> --values <json>
|
||||
gws sheets spreadsheets.values clear <spreadsheetId> --range <range>
|
||||
gws sheets spreadsheets.values batchGet <spreadsheetId> --ranges <range1>,<range2> --json
|
||||
gws sheets spreadsheets.values batchUpdate <spreadsheetId> --data <json>
|
||||
```
|
||||
|
||||
### Google Calendar
|
||||
|
||||
```bash
|
||||
gws calendar calendarList list --json
|
||||
gws calendar calendarList get <calendarId> --json
|
||||
gws calendar events list <calendarId> --timeMin <datetime> --timeMax <datetime> --json
|
||||
gws calendar events get <calendarId> <eventId> --json
|
||||
gws calendar events insert <calendarId> --summary <title> --start <datetime> --end <datetime> --attendees <emails>
|
||||
gws calendar events update <calendarId> <eventId> --summary <title>
|
||||
gws calendar events patch <calendarId> <eventId> --start <datetime> --end <datetime>
|
||||
gws calendar events delete <calendarId> <eventId>
|
||||
gws calendar freebusy query --timeMin <start> --timeMax <end> --items <calendarId1>,<calendarId2> --json
|
||||
```
|
||||
|
||||
### Google Docs
|
||||
|
||||
```bash
|
||||
gws docs documents create --title <title> --json
|
||||
gws docs documents get <documentId> --json
|
||||
gws docs documents batchUpdate <documentId> --requests <json>
|
||||
```
|
||||
|
||||
### Google Slides
|
||||
|
||||
```bash
|
||||
gws slides presentations create --title <title> --json
|
||||
gws slides presentations get <presentationId> --json
|
||||
gws slides presentations.pages get <presentationId> <pageId> --json
|
||||
gws slides presentations.pages getThumbnail <presentationId> <pageId> --json
|
||||
```
|
||||
|
||||
### Google Chat
|
||||
|
||||
```bash
|
||||
gws chat spaces list --json
|
||||
gws chat spaces get <spaceName> --json
|
||||
gws chat spaces.messages create <spaceName> --text <message>
|
||||
gws chat spaces.messages list <spaceName> --json
|
||||
gws chat spaces.messages get <messageName> --json
|
||||
gws chat spaces.members list <spaceName> --json
|
||||
```
|
||||
|
||||
### Google Tasks
|
||||
|
||||
```bash
|
||||
gws tasks tasklists list --json
|
||||
gws tasks tasklists get <tasklistId> --json
|
||||
gws tasks tasklists insert --title <title> --json
|
||||
gws tasks tasks list <tasklistId> --json
|
||||
gws tasks tasks get <tasklistId> <taskId> --json
|
||||
gws tasks tasks insert <tasklistId> --title <title> --due <datetime>
|
||||
gws tasks tasks update <tasklistId> <taskId> --status completed
|
||||
gws tasks tasks delete <tasklistId> <taskId>
|
||||
```
|
||||
|
||||
### Admin SDK (Directory)
|
||||
|
||||
```bash
|
||||
gws admin users list --domain <domain> --json
|
||||
gws admin users get <email> --json
|
||||
gws admin users insert --primaryEmail <email> --name.givenName <first> --name.familyName <last>
|
||||
gws admin users update <email> --suspended true
|
||||
gws admin groups list --domain <domain> --json
|
||||
gws admin groups get <email> --json
|
||||
gws admin groups insert --email <email> --name <name>
|
||||
gws admin groups.members list <groupEmail> --json
|
||||
gws admin groups.members insert <groupEmail> --email <memberEmail> --role MEMBER
|
||||
gws admin orgunits list --customerId my_customer --json
|
||||
```
|
||||
|
||||
### Google Groups
|
||||
|
||||
```bash
|
||||
gws groups groups list --domain <domain> --json
|
||||
gws groups groups get <email> --json
|
||||
gws groups memberships list <groupEmail> --json
|
||||
```
|
||||
|
||||
### Google People (Contacts)
|
||||
|
||||
```bash
|
||||
gws people people.connections list me --personFields names,emailAddresses --json
|
||||
gws people people get <resourceName> --personFields names,emailAddresses,phoneNumbers --json
|
||||
gws people people searchContacts --query <term> --readMask names,emailAddresses --json
|
||||
```
|
||||
|
||||
### Google Meet
|
||||
|
||||
```bash
|
||||
gws meet spaces create --json
|
||||
gws meet spaces get <spaceName> --json
|
||||
gws meet conferenceRecords list --json
|
||||
```
|
||||
|
||||
### Google Classroom
|
||||
|
||||
```bash
|
||||
gws classroom courses list --json
|
||||
gws classroom courses get <courseId> --json
|
||||
gws classroom courses.courseWork list <courseId> --json
|
||||
gws classroom courses.students list <courseId> --json
|
||||
```
|
||||
|
||||
### Google Forms
|
||||
|
||||
```bash
|
||||
gws forms forms get <formId> --json
|
||||
gws forms forms.responses list <formId> --json
|
||||
```
|
||||
|
||||
### Google Keep
|
||||
|
||||
```bash
|
||||
gws keep notes list --json
|
||||
gws keep notes get <noteId> --json
|
||||
```
|
||||
|
||||
### Google Sites
|
||||
|
||||
```bash
|
||||
gws sites sites list --json
|
||||
gws sites sites get <siteId> --json
|
||||
```
|
||||
|
||||
### Google Vault
|
||||
|
||||
```bash
|
||||
gws vault matters list --json
|
||||
gws vault matters get <matterId> --json
|
||||
gws vault matters.holds list <matterId> --json
|
||||
```
|
||||
|
||||
### Admin Reports / Activities
|
||||
|
||||
```bash
|
||||
gws admin activities list <applicationName> --json
|
||||
gws admin activities list login --json
|
||||
gws admin activities list drive --json
|
||||
gws admin activities list admin --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Helper Commands (22)
|
||||
|
||||
| Helper | Description | Example |
|
||||
|--------|-------------|---------|
|
||||
| `send` | Quick send email | `gws helpers send --to a@b.com --subject Hi --body Hello` |
|
||||
| `reply` | Quick reply | `gws helpers reply --thread <id> --body Thanks` |
|
||||
| `forward` | Quick forward | `gws helpers forward --message <id> --to a@b.com` |
|
||||
| `upload` | Quick upload to Drive | `gws helpers upload file.pdf --folder <id>` |
|
||||
| `download` | Quick download | `gws helpers download <fileId> --output file.pdf` |
|
||||
| `share` | Quick share | `gws helpers share <fileId> --with a@b.com --role writer` |
|
||||
| `quick-event` | Natural language event | `gws helpers quick-event "Lunch tomorrow at noon"` |
|
||||
| `find-time` | Find free slots | `gws helpers find-time --attendees a,b --duration 60` |
|
||||
| `standup-report` | Daily standup | `gws helpers standup-report` |
|
||||
| `meeting-prep` | Prep for meeting | `gws helpers meeting-prep --event <id>` |
|
||||
| `weekly-summary` | Week summary | `gws helpers weekly-summary` |
|
||||
| `morning-briefing` | Morning overview | `gws helpers morning-briefing` |
|
||||
| `eod-wrap` | End of day wrap | `gws helpers eod-wrap` |
|
||||
| `inbox-zero` | Process inbox | `gws helpers inbox-zero` |
|
||||
| `search` | Cross-service search | `gws helpers search "quarterly report"` |
|
||||
| `create-task` | Quick task creation | `gws helpers create-task "Review PR" --due tomorrow` |
|
||||
| `list-tasks` | Quick task listing | `gws helpers list-tasks` |
|
||||
| `chat-send` | Quick chat message | `gws helpers chat-send --space <id> --text "Hello"` |
|
||||
| `export-pdf` | Export as PDF | `gws helpers export-pdf <fileId> --output file.pdf` |
|
||||
| `trash-old` | Trash old files | `gws helpers trash-old --older-than 365d` |
|
||||
| `audit-sharing` | Audit file sharing | `gws helpers audit-sharing --folder <id>` |
|
||||
| `backup-labels` | Backup Gmail labels | `gws helpers backup-labels --output labels.json` |
|
||||
|
||||
---
|
||||
|
||||
## Schema Introspection
|
||||
|
||||
```bash
|
||||
# View the API schema for any service method
|
||||
gws schema gmail.users.messages.list
|
||||
gws schema drive.files.create
|
||||
gws schema calendar.events.insert
|
||||
|
||||
# List all available services
|
||||
gws schema --list
|
||||
|
||||
# List methods for a service
|
||||
gws schema gmail --methods
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication Commands
|
||||
|
||||
```bash
|
||||
gws auth setup # Interactive OAuth setup
|
||||
gws auth setup --service-account # Service account setup
|
||||
gws auth status # Check current auth
|
||||
gws auth status --json # JSON auth details
|
||||
gws auth refresh # Refresh expired token
|
||||
gws auth revoke # Revoke current token
|
||||
gws auth switch <profile> # Switch auth profile
|
||||
gws auth profiles list # List saved profiles
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recipe Commands
|
||||
|
||||
```bash
|
||||
gws recipes list # List all 43 recipes
|
||||
gws recipes list --category email # Filter by category
|
||||
gws recipes describe <name> # Show recipe details
|
||||
gws recipes run <name> # Execute a recipe
|
||||
gws recipes run <name> --dry-run # Preview recipe commands
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Persona Commands
|
||||
|
||||
```bash
|
||||
gws persona list # List all 10 personas
|
||||
gws persona select <name> # Activate a persona
|
||||
gws persona show # Show active persona
|
||||
gws persona recipes # Show recipes for active persona
|
||||
```
|
||||
@@ -0,0 +1,344 @@
|
||||
# Google Workspace CLI Recipes Cookbook
|
||||
|
||||
Complete catalog of 43 built-in recipes organized by category, with command sequences and persona mapping.
|
||||
|
||||
---
|
||||
|
||||
## Recipe Categories
|
||||
|
||||
| Category | Count | Description |
|
||||
|----------|-------|-------------|
|
||||
| Email | 8 | Gmail operations — send, search, label, filter |
|
||||
| Files | 7 | Drive file management — upload, share, export |
|
||||
| Calendar | 6 | Events, scheduling, meeting prep |
|
||||
| Reporting | 5 | Activity summaries and analytics |
|
||||
| Collaboration | 5 | Chat, Docs, Tasks teamwork |
|
||||
| Data | 4 | Sheets read/write and contacts |
|
||||
| Admin | 4 | User and group management |
|
||||
| Cross-Service | 4 | Multi-service workflows |
|
||||
|
||||
---
|
||||
|
||||
## Email Recipes (8)
|
||||
|
||||
### send-email
|
||||
Send an email with optional attachments.
|
||||
```bash
|
||||
gws gmail users.messages send me --to "recipient@example.com" \
|
||||
--subject "Subject" --body "Body text" [--attachment file.pdf]
|
||||
```
|
||||
|
||||
### reply-to-thread
|
||||
Reply to an existing email thread.
|
||||
```bash
|
||||
gws gmail users.messages reply me --thread-id <THREAD_ID> --body "Reply text"
|
||||
```
|
||||
|
||||
### forward-email
|
||||
Forward an email to another recipient.
|
||||
```bash
|
||||
gws gmail users.messages forward me --message-id <MSG_ID> --to "forward@example.com"
|
||||
```
|
||||
|
||||
### search-emails
|
||||
Search emails using Gmail query syntax.
|
||||
```bash
|
||||
gws gmail users.messages list me --query "from:sender@example.com after:2025/01/01" --json
|
||||
```
|
||||
**Query examples:** `is:unread`, `has:attachment`, `label:important`, `newer_than:7d`
|
||||
|
||||
### archive-old
|
||||
Archive read emails older than N days.
|
||||
```bash
|
||||
gws gmail users.messages list me --query "is:read older_than:30d" --json
|
||||
# Extract IDs, then batch modify to remove INBOX label
|
||||
```
|
||||
|
||||
### label-manager
|
||||
Create and organize Gmail labels.
|
||||
```bash
|
||||
gws gmail users.labels list me --json
|
||||
gws gmail users.labels create me --name "Projects/Alpha"
|
||||
```
|
||||
|
||||
### filter-setup
|
||||
Create auto-labeling filters.
|
||||
```bash
|
||||
gws gmail users.settings.filters create me \
|
||||
--criteria '{"from":"notifications@service.com"}' \
|
||||
--action '{"addLabelIds":["Label_123"],"removeLabelIds":["INBOX"]}'
|
||||
```
|
||||
|
||||
### unread-digest
|
||||
Get digest of unread emails.
|
||||
```bash
|
||||
gws gmail users.messages list me --query "is:unread" --limit 20 --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files Recipes (7)
|
||||
|
||||
### upload-file
|
||||
Upload a file to Google Drive.
|
||||
```bash
|
||||
gws drive files create --name "Report Q1" --upload report.pdf --parents <FOLDER_ID>
|
||||
```
|
||||
|
||||
### create-sheet
|
||||
Create a new Google Spreadsheet.
|
||||
```bash
|
||||
gws sheets spreadsheets create --title "Budget 2026" --json
|
||||
```
|
||||
|
||||
### share-file
|
||||
Share a Drive file with a user or domain.
|
||||
```bash
|
||||
gws drive permissions create <FILE_ID> --type user --role writer --emailAddress "user@example.com"
|
||||
```
|
||||
|
||||
### export-file
|
||||
Export a Google Doc/Sheet as PDF.
|
||||
```bash
|
||||
gws drive files export <FILE_ID> --mime "application/pdf" --output report.pdf
|
||||
```
|
||||
|
||||
### list-files
|
||||
List files in a Drive folder.
|
||||
```bash
|
||||
gws drive files list --parents <FOLDER_ID> --json
|
||||
```
|
||||
|
||||
### find-large-files
|
||||
Find the largest files in Drive.
|
||||
```bash
|
||||
gws drive files list --orderBy "quotaBytesUsed desc" --limit 20 --json
|
||||
```
|
||||
|
||||
### cleanup-trash
|
||||
Empty Drive trash.
|
||||
```bash
|
||||
gws drive files emptyTrash
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Calendar Recipes (6)
|
||||
|
||||
### create-event
|
||||
Create a calendar event with attendees.
|
||||
```bash
|
||||
gws calendar events insert primary \
|
||||
--summary "Sprint Planning" \
|
||||
--start "2026-03-15T10:00:00" --end "2026-03-15T11:00:00" \
|
||||
--attendees "team@company.com" --location "Room A"
|
||||
```
|
||||
|
||||
### quick-event
|
||||
Create event from natural language.
|
||||
```bash
|
||||
gws helpers quick-event "Lunch with Sarah tomorrow at noon"
|
||||
```
|
||||
|
||||
### find-time
|
||||
Find available time slots for a meeting.
|
||||
```bash
|
||||
gws helpers find-time --attendees "alice@co.com,bob@co.com" --duration 60 \
|
||||
--within "2026-03-15,2026-03-19" --json
|
||||
```
|
||||
|
||||
### today-schedule
|
||||
Show today's calendar events.
|
||||
```bash
|
||||
gws calendar events list primary \
|
||||
--timeMin "$(date -u +%Y-%m-%dT00:00:00Z)" \
|
||||
--timeMax "$(date -u +%Y-%m-%dT23:59:59Z)" --json
|
||||
```
|
||||
|
||||
### meeting-prep
|
||||
Prepare for an upcoming meeting.
|
||||
```bash
|
||||
gws recipes meeting-prep --event-id <EVENT_ID>
|
||||
```
|
||||
**Output:** Agenda, attendee list, related Drive files, previous meeting notes.
|
||||
|
||||
### reschedule
|
||||
Move an event to a new time.
|
||||
```bash
|
||||
gws calendar events patch primary <EVENT_ID> \
|
||||
--start "2026-03-16T14:00:00" --end "2026-03-16T15:00:00"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reporting Recipes (5)
|
||||
|
||||
### standup-report
|
||||
Generate daily standup from calendar and tasks.
|
||||
```bash
|
||||
gws recipes standup-report --json
|
||||
```
|
||||
**Output:** Yesterday's events, today's schedule, pending tasks, blockers.
|
||||
|
||||
### weekly-summary
|
||||
Summarize week's emails, events, and tasks.
|
||||
```bash
|
||||
gws recipes weekly-summary --json
|
||||
```
|
||||
|
||||
### drive-activity
|
||||
Report on Drive file activity.
|
||||
```bash
|
||||
gws drive activities list --json
|
||||
```
|
||||
|
||||
### email-stats
|
||||
Email volume statistics for the past 7 days.
|
||||
```bash
|
||||
gws gmail users.messages list me --query "newer_than:7d" --json | python3 output_analyzer.py --count
|
||||
```
|
||||
|
||||
### task-progress
|
||||
Report on task completion.
|
||||
```bash
|
||||
gws tasks tasks list <TASKLIST_ID> --json | python3 output_analyzer.py --group-by "status"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Collaboration Recipes (5)
|
||||
|
||||
### share-folder
|
||||
Share a Drive folder with a team.
|
||||
```bash
|
||||
gws drive permissions create <FOLDER_ID> --type group --role writer --emailAddress "team@company.com"
|
||||
```
|
||||
|
||||
### create-doc
|
||||
Create a Google Doc with initial content.
|
||||
```bash
|
||||
gws docs documents create --title "Meeting Notes - March 15" --json
|
||||
```
|
||||
|
||||
### chat-message
|
||||
Send a message to a Google Chat space.
|
||||
```bash
|
||||
gws chat spaces.messages create <SPACE_NAME> --text "Deployment complete!"
|
||||
```
|
||||
|
||||
### list-spaces
|
||||
List Google Chat spaces.
|
||||
```bash
|
||||
gws chat spaces list --json
|
||||
```
|
||||
|
||||
### task-create
|
||||
Create a task in Google Tasks.
|
||||
```bash
|
||||
gws tasks tasks insert <TASKLIST_ID> --title "Review PR #42" --due "2026-03-16"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Recipes (4)
|
||||
|
||||
### sheet-read
|
||||
Read data from a spreadsheet range.
|
||||
```bash
|
||||
gws sheets spreadsheets.values get <SHEET_ID> --range "Sheet1!A1:D10" --json
|
||||
```
|
||||
|
||||
### sheet-write
|
||||
Write data to a spreadsheet.
|
||||
```bash
|
||||
gws sheets spreadsheets.values update <SHEET_ID> --range "Sheet1!A1" \
|
||||
--values '[["Name","Score"],["Alice",95],["Bob",87]]'
|
||||
```
|
||||
|
||||
### sheet-append
|
||||
Append rows to a spreadsheet.
|
||||
```bash
|
||||
gws sheets spreadsheets.values append <SHEET_ID> --range "Sheet1!A1" \
|
||||
--values '[["Charlie",92]]'
|
||||
```
|
||||
|
||||
### export-contacts
|
||||
Export contacts list.
|
||||
```bash
|
||||
gws people people.connections list me --personFields names,emailAddresses --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Admin Recipes (4)
|
||||
|
||||
### list-users
|
||||
List all users in the Workspace domain.
|
||||
```bash
|
||||
gws admin users list --domain company.com --json
|
||||
```
|
||||
**Prerequisites:** Admin SDK API enabled, `admin.directory.user.readonly` scope.
|
||||
|
||||
### list-groups
|
||||
List all groups in the domain.
|
||||
```bash
|
||||
gws admin groups list --domain company.com --json
|
||||
```
|
||||
|
||||
### user-info
|
||||
Get detailed user information.
|
||||
```bash
|
||||
gws admin users get user@company.com --json
|
||||
```
|
||||
|
||||
### audit-logins
|
||||
Audit recent login activity.
|
||||
```bash
|
||||
gws admin activities list login --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cross-Service Recipes (4)
|
||||
|
||||
### morning-briefing
|
||||
Today's events + unread emails + pending tasks.
|
||||
```bash
|
||||
gws recipes morning-briefing --json
|
||||
```
|
||||
**Combines:** Calendar events, Gmail unread count, Tasks pending.
|
||||
|
||||
### eod-wrap
|
||||
End-of-day summary: completed, pending, tomorrow's schedule.
|
||||
```bash
|
||||
gws recipes eod-wrap --json
|
||||
```
|
||||
|
||||
### project-status
|
||||
Aggregate project status from Drive, Sheets, Tasks.
|
||||
```bash
|
||||
gws recipes project-status --project "Project Alpha" --json
|
||||
```
|
||||
|
||||
### inbox-zero
|
||||
Process inbox to zero: label, archive, reply, or create task.
|
||||
```bash
|
||||
gws recipes inbox-zero --interactive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Persona Mapping
|
||||
|
||||
| Persona | Top Recipes |
|
||||
|---------|-------------|
|
||||
| Executive Assistant | morning-briefing, today-schedule, find-time, send-email, meeting-prep, eod-wrap |
|
||||
| Project Manager | standup-report, create-event, find-time, task-create, project-status, weekly-summary |
|
||||
| HR | list-users, user-info, send-email, create-event, create-doc, export-contacts |
|
||||
| Sales | send-email, search-emails, create-event, find-time, create-doc, share-file |
|
||||
| IT Admin | list-users, list-groups, audit-logins, drive-activity, find-large-files, cleanup-trash |
|
||||
| Developer | sheet-read, sheet-write, upload-file, chat-message, task-create, send-email |
|
||||
| Marketing | send-email, create-doc, share-file, upload-file, create-sheet, chat-message |
|
||||
| Finance | sheet-read, sheet-write, sheet-append, create-sheet, export-file, share-file |
|
||||
| Legal | create-doc, share-file, export-file, search-emails, upload-file, audit-logins |
|
||||
| Customer Support | search-emails, send-email, reply-to-thread, label-manager, task-create, inbox-zero |
|
||||
@@ -0,0 +1,323 @@
|
||||
# Google Workspace CLI Troubleshooting
|
||||
|
||||
Common errors, fixes, and platform-specific guidance for the `gws` CLI.
|
||||
|
||||
---
|
||||
|
||||
## Installation Issues
|
||||
|
||||
### gws not found on PATH
|
||||
|
||||
**Error:** `command not found: gws`
|
||||
|
||||
**Fixes:**
|
||||
```bash
|
||||
# Check if installed
|
||||
npm list -g @anthropic/gws 2>/dev/null || echo "Not installed via npm"
|
||||
which gws || echo "Not on PATH"
|
||||
|
||||
# Install via npm
|
||||
npm install -g @anthropic/gws
|
||||
|
||||
# If npm global bin not on PATH
|
||||
export PATH="$(npm config get prefix)/bin:$PATH"
|
||||
# Add to ~/.zshrc or ~/.bashrc for persistence
|
||||
```
|
||||
|
||||
### npm permission errors
|
||||
|
||||
**Error:** `EACCES: permission denied`
|
||||
|
||||
**Fixes:**
|
||||
```bash
|
||||
# Option 1: Fix npm prefix (recommended)
|
||||
mkdir -p ~/.npm-global
|
||||
npm config set prefix '~/.npm-global'
|
||||
export PATH=~/.npm-global/bin:$PATH
|
||||
|
||||
# Option 2: Use npx without installing
|
||||
npx @anthropic/gws --version
|
||||
```
|
||||
|
||||
### Cargo build failures
|
||||
|
||||
**Error:** `error[E0463]: can't find crate`
|
||||
|
||||
**Fixes:**
|
||||
```bash
|
||||
# Ensure Rust is up to date
|
||||
rustup update stable
|
||||
|
||||
# Clean build
|
||||
cargo clean && cargo install gws-cli
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication Errors
|
||||
|
||||
### Token expired
|
||||
|
||||
**Error:** `401 Unauthorized: Token has been expired or revoked`
|
||||
|
||||
**Cause:** OAuth tokens expire after 1 hour.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
gws auth refresh
|
||||
# If refresh fails:
|
||||
gws auth setup # Re-authenticate
|
||||
```
|
||||
|
||||
### Insufficient scopes
|
||||
|
||||
**Error:** `403 Forbidden: Request had insufficient authentication scopes`
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check current scopes
|
||||
gws auth status --json | grep scopes
|
||||
|
||||
# Re-auth with additional scopes
|
||||
gws auth setup --scopes gmail,drive,calendar,sheets,tasks
|
||||
|
||||
# Or list required scopes for a service
|
||||
python3 scripts/auth_setup_guide.py --scopes gmail,drive
|
||||
```
|
||||
|
||||
### Keyring/keychain errors
|
||||
|
||||
**Error:** `Failed to access keyring` or `SecKeychainFindGenericPassword failed`
|
||||
|
||||
**Fixes:**
|
||||
```bash
|
||||
# macOS: Unlock keychain
|
||||
security unlock-keychain ~/Library/Keychains/login.keychain-db
|
||||
|
||||
# Linux: Install keyring backend
|
||||
sudo apt install gnome-keyring # or libsecret
|
||||
|
||||
# Fallback: Use file-based token storage
|
||||
export GWS_TOKEN_PATH=~/.config/gws/token.json
|
||||
gws auth setup
|
||||
```
|
||||
|
||||
### Service account delegation errors
|
||||
|
||||
**Error:** `403: Not Authorized to access this resource/api`
|
||||
|
||||
**Fix:**
|
||||
1. Verify domain-wide delegation is enabled on the service account
|
||||
2. Verify client ID is authorized in Admin Console > Security > API Controls
|
||||
3. Verify scopes match exactly (no trailing slashes)
|
||||
4. Verify `GWS_DELEGATED_USER` is a valid admin account
|
||||
|
||||
```bash
|
||||
# Debug
|
||||
echo $GWS_SERVICE_ACCOUNT_KEY # Should point to valid JSON key file
|
||||
echo $GWS_DELEGATED_USER # Should be admin@yourdomain.com
|
||||
gws auth status --json # Check auth details
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Errors
|
||||
|
||||
### Rate limit exceeded (429)
|
||||
|
||||
**Error:** `429 Too Many Requests: Rate Limit Exceeded`
|
||||
|
||||
**Cause:** Google Workspace APIs have per-user, per-service rate limits.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Add delays between bulk operations
|
||||
for id in $(cat file_ids.txt); do
|
||||
gws drive files get $id --json >> results.json
|
||||
sleep 0.5 # 500ms delay
|
||||
done
|
||||
|
||||
# Use --limit to reduce result size
|
||||
gws drive files list --limit 100 --json
|
||||
|
||||
# For admin operations, batch in groups of 50
|
||||
```
|
||||
|
||||
**Rate limits by service:**
|
||||
| Service | Limit |
|
||||
|---------|-------|
|
||||
| Gmail | 250 quota units/second/user |
|
||||
| Drive | 1,000 requests/100 seconds/user |
|
||||
| Sheets | 60 read requests/minute/user |
|
||||
| Calendar | 500 requests/100 seconds/user |
|
||||
| Admin SDK | 2,400 requests/minute |
|
||||
|
||||
### Permission denied (403)
|
||||
|
||||
**Error:** `403 Forbidden: The caller does not have permission`
|
||||
|
||||
**Causes and fixes:**
|
||||
1. **Wrong scope** — Re-auth with correct scopes
|
||||
2. **Not the file owner** — Request access from the owner
|
||||
3. **Domain policy** — Check Admin Console sharing policies
|
||||
4. **API not enabled** — Enable the API in Google Cloud Console
|
||||
|
||||
```bash
|
||||
# Check which APIs are enabled
|
||||
gws schema --list
|
||||
|
||||
# Enable an API
|
||||
# Go to: console.cloud.google.com > APIs & Services > Library
|
||||
```
|
||||
|
||||
### Not found (404)
|
||||
|
||||
**Error:** `404 Not Found: File not found`
|
||||
|
||||
**Causes:**
|
||||
1. File was deleted or moved to trash
|
||||
2. File ID is incorrect
|
||||
3. No permission to see the file
|
||||
|
||||
```bash
|
||||
# Check trash
|
||||
gws drive files list --query "trashed=true and name='filename'" --json
|
||||
|
||||
# Verify file ID
|
||||
gws drive files get <fileId> --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Output Parsing Issues
|
||||
|
||||
### NDJSON vs JSON array
|
||||
|
||||
**Problem:** Output format varies between commands and versions.
|
||||
|
||||
```bash
|
||||
# Force JSON array output
|
||||
gws drive files list --json
|
||||
|
||||
# Force NDJSON output
|
||||
gws drive files list --format ndjson
|
||||
|
||||
# Handle both in output_analyzer.py (automatic detection)
|
||||
gws drive files list --json | python3 scripts/output_analyzer.py --count
|
||||
```
|
||||
|
||||
### Pagination
|
||||
|
||||
**Problem:** Only partial results returned.
|
||||
|
||||
```bash
|
||||
# Fetch all pages
|
||||
gws drive files list --page-all --json
|
||||
|
||||
# Or set a high limit
|
||||
gws drive files list --limit 1000 --json
|
||||
|
||||
# Check if more pages exist (look for nextPageToken in output)
|
||||
gws drive files list --limit 100 --json | grep nextPageToken
|
||||
```
|
||||
|
||||
### Empty response
|
||||
|
||||
**Problem:** Command returns empty or `{}`.
|
||||
|
||||
```bash
|
||||
# Check auth
|
||||
gws auth status
|
||||
|
||||
# Try with verbose output
|
||||
gws drive files list --verbose --json
|
||||
|
||||
# Check if the service is accessible
|
||||
gws drive about get --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Platform-Specific Issues
|
||||
|
||||
### macOS
|
||||
|
||||
**Keychain access prompts:**
|
||||
```bash
|
||||
# Allow gws to access keychain without repeated prompts
|
||||
# In Keychain Access.app, find "gws" entries and set "Allow all applications"
|
||||
|
||||
# Or use file-based storage
|
||||
export GWS_TOKEN_PATH=~/.config/gws/token.json
|
||||
```
|
||||
|
||||
**Browser not opening for OAuth:**
|
||||
```bash
|
||||
# If default browser doesn't open
|
||||
gws auth setup --no-browser
|
||||
# Copy the URL manually and paste in browser
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
**Headless OAuth (no browser):**
|
||||
```bash
|
||||
# Use out-of-band flow
|
||||
gws auth setup --no-browser
|
||||
# Prints a URL — open on another machine, paste code back
|
||||
|
||||
# Or use service account (no browser needed)
|
||||
export GWS_SERVICE_ACCOUNT_KEY=/path/to/key.json
|
||||
export GWS_DELEGATED_USER=admin@domain.com
|
||||
```
|
||||
|
||||
**Missing keyring backend:**
|
||||
```bash
|
||||
# Install a keyring backend
|
||||
sudo apt install gnome-keyring libsecret-1-dev
|
||||
|
||||
# Or use file-based storage
|
||||
export GWS_TOKEN_PATH=~/.config/gws/token.json
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
**PATH issues:**
|
||||
```powershell
|
||||
# Add npm global bin to PATH
|
||||
$env:PATH += ";$(npm config get prefix)\bin"
|
||||
|
||||
# Or use npx
|
||||
npx @anthropic/gws --version
|
||||
```
|
||||
|
||||
**PowerShell quoting:**
|
||||
```powershell
|
||||
# Use single quotes for JSON arguments
|
||||
gws gmail users.settings.filters create me `
|
||||
--criteria '{"from":"test@example.com"}' `
|
||||
--action '{"addLabelIds":["Label_1"]}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
```bash
|
||||
# General help
|
||||
gws --help
|
||||
gws <service> --help
|
||||
gws <service> <resource> --help
|
||||
|
||||
# API schema for a method
|
||||
gws schema gmail.users.messages.send
|
||||
|
||||
# Version info
|
||||
gws --version
|
||||
|
||||
# Debug mode
|
||||
gws --verbose <command>
|
||||
|
||||
# Report issues
|
||||
# https://github.com/googleworkspace/cli/issues
|
||||
```
|
||||
@@ -0,0 +1,390 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Google Workspace CLI Auth Setup Guide — Guided authentication configuration.
|
||||
|
||||
Prints step-by-step instructions for OAuth and service account setup,
|
||||
generates .env templates, lists required scopes, and validates auth.
|
||||
|
||||
Usage:
|
||||
python3 auth_setup_guide.py --guide oauth
|
||||
python3 auth_setup_guide.py --guide service-account
|
||||
python3 auth_setup_guide.py --scopes gmail,drive,calendar
|
||||
python3 auth_setup_guide.py --generate-env
|
||||
python3 auth_setup_guide.py --validate [--json]
|
||||
python3 auth_setup_guide.py --check [--json]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Dict
|
||||
|
||||
|
||||
SERVICE_SCOPES: Dict[str, List[str]] = {
|
||||
"gmail": [
|
||||
"https://www.googleapis.com/auth/gmail.modify",
|
||||
"https://www.googleapis.com/auth/gmail.send",
|
||||
"https://www.googleapis.com/auth/gmail.labels",
|
||||
"https://www.googleapis.com/auth/gmail.settings.basic",
|
||||
],
|
||||
"drive": [
|
||||
"https://www.googleapis.com/auth/drive",
|
||||
"https://www.googleapis.com/auth/drive.file",
|
||||
"https://www.googleapis.com/auth/drive.metadata.readonly",
|
||||
],
|
||||
"sheets": [
|
||||
"https://www.googleapis.com/auth/spreadsheets",
|
||||
],
|
||||
"calendar": [
|
||||
"https://www.googleapis.com/auth/calendar",
|
||||
"https://www.googleapis.com/auth/calendar.events",
|
||||
],
|
||||
"tasks": [
|
||||
"https://www.googleapis.com/auth/tasks",
|
||||
],
|
||||
"chat": [
|
||||
"https://www.googleapis.com/auth/chat.spaces.readonly",
|
||||
"https://www.googleapis.com/auth/chat.messages",
|
||||
],
|
||||
"docs": [
|
||||
"https://www.googleapis.com/auth/documents",
|
||||
],
|
||||
"admin": [
|
||||
"https://www.googleapis.com/auth/admin.directory.user.readonly",
|
||||
"https://www.googleapis.com/auth/admin.directory.group",
|
||||
"https://www.googleapis.com/auth/admin.directory.orgunit.readonly",
|
||||
],
|
||||
"meet": [
|
||||
"https://www.googleapis.com/auth/meetings.space.created",
|
||||
],
|
||||
}
|
||||
|
||||
OAUTH_GUIDE = """
|
||||
=== Google Workspace CLI: OAuth Setup Guide ===
|
||||
|
||||
Step 1: Create a Google Cloud Project
|
||||
1. Go to https://console.cloud.google.com/
|
||||
2. Click "Select a project" -> "New Project"
|
||||
3. Name it (e.g., "gws-cli-access") and click Create
|
||||
4. Note the Project ID
|
||||
|
||||
Step 2: Enable Required APIs
|
||||
1. Go to APIs & Services -> Library
|
||||
2. Search and enable each API you need:
|
||||
- Gmail API
|
||||
- Google Drive API
|
||||
- Google Sheets API
|
||||
- Google Calendar API
|
||||
- Tasks API
|
||||
- Admin SDK API (for admin operations)
|
||||
|
||||
Step 3: Configure OAuth Consent Screen
|
||||
1. Go to APIs & Services -> OAuth consent screen
|
||||
2. Select "Internal" (for Workspace) or "External" (for personal)
|
||||
3. Fill in app name, support email
|
||||
4. Add scopes for the services you need
|
||||
5. Save and continue
|
||||
|
||||
Step 4: Create OAuth Credentials
|
||||
1. Go to APIs & Services -> Credentials
|
||||
2. Click "Create Credentials" -> "OAuth client ID"
|
||||
3. Application type: "Desktop app"
|
||||
4. Name it "gws-cli"
|
||||
5. Download the JSON file
|
||||
|
||||
Step 5: Configure gws CLI
|
||||
1. Set environment variables:
|
||||
export GWS_CLIENT_ID=<your-client-id>
|
||||
export GWS_CLIENT_SECRET=<your-client-secret>
|
||||
|
||||
2. Or place the credentials JSON:
|
||||
mv client_secret_*.json ~/.config/gws/credentials.json
|
||||
|
||||
Step 6: Authenticate
|
||||
gws auth setup
|
||||
# Opens browser for consent, stores token in system keyring
|
||||
|
||||
Step 7: Verify
|
||||
gws auth status
|
||||
gws gmail users getProfile me
|
||||
"""
|
||||
|
||||
SERVICE_ACCOUNT_GUIDE = """
|
||||
=== Google Workspace CLI: Service Account Setup Guide ===
|
||||
|
||||
Step 1: Create a Google Cloud Project
|
||||
(Same as OAuth Step 1)
|
||||
|
||||
Step 2: Create a Service Account
|
||||
1. Go to IAM & Admin -> Service Accounts
|
||||
2. Click "Create Service Account"
|
||||
3. Name: "gws-cli-service"
|
||||
4. Grant roles as needed (no role needed for Workspace API access)
|
||||
5. Click "Done"
|
||||
|
||||
Step 3: Create Key
|
||||
1. Click on the service account
|
||||
2. Go to "Keys" tab
|
||||
3. Add Key -> Create new key -> JSON
|
||||
4. Download and store securely
|
||||
|
||||
Step 4: Enable Domain-Wide Delegation
|
||||
1. On the service account page, click "Edit"
|
||||
2. Check "Enable Google Workspace domain-wide delegation"
|
||||
3. Save
|
||||
4. Note the Client ID (numeric)
|
||||
|
||||
Step 5: Authorize in Google Admin
|
||||
1. Go to admin.google.com
|
||||
2. Security -> API Controls -> Domain-wide Delegation
|
||||
3. Add new:
|
||||
- Client ID: <numeric client ID from Step 4>
|
||||
- Scopes: (paste required scopes)
|
||||
4. Authorize
|
||||
|
||||
Step 6: Configure gws CLI
|
||||
export GWS_SERVICE_ACCOUNT_KEY=/path/to/service-account-key.json
|
||||
export GWS_DELEGATED_USER=admin@yourdomain.com
|
||||
|
||||
Step 7: Verify
|
||||
gws auth status
|
||||
gws gmail users getProfile me
|
||||
"""
|
||||
|
||||
ENV_TEMPLATE = """# Google Workspace CLI Configuration
|
||||
# Copy to .env and fill in values
|
||||
|
||||
# OAuth Credentials (for interactive auth)
|
||||
GWS_CLIENT_ID=
|
||||
GWS_CLIENT_SECRET=
|
||||
GWS_TOKEN_PATH=~/.config/gws/token.json
|
||||
|
||||
# Service Account (for headless/CI auth)
|
||||
# GWS_SERVICE_ACCOUNT_KEY=/path/to/key.json
|
||||
# GWS_DELEGATED_USER=admin@yourdomain.com
|
||||
|
||||
# Defaults
|
||||
GWS_DEFAULT_FORMAT=json
|
||||
GWS_PAGINATION_LIMIT=100
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class ValidationResult:
|
||||
service: str
|
||||
status: str # PASS, FAIL
|
||||
message: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ValidationReport:
|
||||
auth_method: str = ""
|
||||
user: str = ""
|
||||
results: List[dict] = field(default_factory=list)
|
||||
summary: str = ""
|
||||
demo_mode: bool = False
|
||||
|
||||
|
||||
DEMO_VALIDATION = ValidationReport(
|
||||
auth_method="oauth",
|
||||
user="admin@company.com",
|
||||
results=[
|
||||
{"service": "gmail", "status": "PASS", "message": "Gmail API accessible"},
|
||||
{"service": "drive", "status": "PASS", "message": "Drive API accessible"},
|
||||
{"service": "calendar", "status": "PASS", "message": "Calendar API accessible"},
|
||||
{"service": "sheets", "status": "PASS", "message": "Sheets API accessible"},
|
||||
{"service": "tasks", "status": "FAIL", "message": "Scope not authorized"},
|
||||
],
|
||||
summary="4/5 services validated (demo mode)",
|
||||
demo_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def check_auth_status() -> dict:
|
||||
"""Check current gws auth status."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["gws", "auth", "status", "--json"],
|
||||
capture_output=True, text=True, timeout=15
|
||||
)
|
||||
if result.returncode == 0:
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except json.JSONDecodeError:
|
||||
return {"status": "authenticated", "raw": result.stdout.strip()}
|
||||
return {"status": "not_authenticated", "error": result.stderr.strip()[:200]}
|
||||
except (FileNotFoundError, OSError):
|
||||
return {"status": "gws_not_found"}
|
||||
|
||||
|
||||
def validate_services(services: List[str]) -> ValidationReport:
|
||||
"""Validate auth by testing each service."""
|
||||
report = ValidationReport()
|
||||
|
||||
auth = check_auth_status()
|
||||
if auth.get("status") == "gws_not_found":
|
||||
report.summary = "gws CLI not installed"
|
||||
return report
|
||||
if auth.get("status") == "not_authenticated":
|
||||
report.auth_method = "none"
|
||||
report.summary = "Not authenticated"
|
||||
return report
|
||||
|
||||
report.auth_method = auth.get("method", "oauth")
|
||||
report.user = auth.get("user", auth.get("email", "unknown"))
|
||||
|
||||
service_cmds = {
|
||||
"gmail": ["gws", "gmail", "users", "getProfile", "me", "--json"],
|
||||
"drive": ["gws", "drive", "files", "list", "--limit", "1", "--json"],
|
||||
"calendar": ["gws", "calendar", "calendarList", "list", "--limit", "1", "--json"],
|
||||
"sheets": ["gws", "sheets", "spreadsheets", "get", "test", "--json"],
|
||||
"tasks": ["gws", "tasks", "tasklists", "list", "--limit", "1", "--json"],
|
||||
}
|
||||
|
||||
for svc in services:
|
||||
cmd = service_cmds.get(svc)
|
||||
if not cmd:
|
||||
report.results.append(asdict(
|
||||
ValidationResult(svc, "WARN", f"No test available for {svc}")
|
||||
))
|
||||
continue
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
|
||||
if result.returncode == 0:
|
||||
report.results.append(asdict(
|
||||
ValidationResult(svc, "PASS", f"{svc.title()} API accessible")
|
||||
))
|
||||
else:
|
||||
report.results.append(asdict(
|
||||
ValidationResult(svc, "FAIL", result.stderr.strip()[:100])
|
||||
))
|
||||
except (subprocess.TimeoutExpired, OSError) as e:
|
||||
report.results.append(asdict(
|
||||
ValidationResult(svc, "FAIL", str(e)[:100])
|
||||
))
|
||||
|
||||
passed = sum(1 for r in report.results if r["status"] == "PASS")
|
||||
total = len(report.results)
|
||||
report.summary = f"{passed}/{total} services validated"
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Guided authentication setup for Google Workspace CLI (gws)",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s --guide oauth # OAuth setup instructions
|
||||
%(prog)s --guide service-account # Service account setup
|
||||
%(prog)s --scopes gmail,drive # Show required scopes
|
||||
%(prog)s --generate-env # Generate .env template
|
||||
%(prog)s --check # Check current auth status
|
||||
%(prog)s --validate --json # Validate all services (JSON)
|
||||
""",
|
||||
)
|
||||
parser.add_argument("--guide", choices=["oauth", "service-account"],
|
||||
help="Print setup guide")
|
||||
parser.add_argument("--scopes", help="Comma-separated services to show scopes for")
|
||||
parser.add_argument("--generate-env", action="store_true",
|
||||
help="Generate .env template")
|
||||
parser.add_argument("--check", action="store_true",
|
||||
help="Check current auth status")
|
||||
parser.add_argument("--validate", action="store_true",
|
||||
help="Validate auth by testing services")
|
||||
parser.add_argument("--services", default="gmail,drive,calendar,sheets,tasks",
|
||||
help="Services to validate (default: gmail,drive,calendar,sheets,tasks)")
|
||||
parser.add_argument("--json", action="store_true", help="Output JSON")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not any([args.guide, args.scopes, args.generate_env, args.check, args.validate]):
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
if args.guide:
|
||||
if args.guide == "oauth":
|
||||
print(OAUTH_GUIDE)
|
||||
else:
|
||||
print(SERVICE_ACCOUNT_GUIDE)
|
||||
return
|
||||
|
||||
if args.scopes:
|
||||
services = [s.strip() for s in args.scopes.split(",") if s.strip()]
|
||||
if args.json:
|
||||
output = {}
|
||||
for svc in services:
|
||||
output[svc] = SERVICE_SCOPES.get(svc, [])
|
||||
print(json.dumps(output, indent=2))
|
||||
else:
|
||||
print(f"\n{'='*60}")
|
||||
print(f" REQUIRED OAUTH SCOPES")
|
||||
print(f"{'='*60}\n")
|
||||
for svc in services:
|
||||
scopes = SERVICE_SCOPES.get(svc, [])
|
||||
print(f" {svc.upper()}:")
|
||||
if scopes:
|
||||
for scope in scopes:
|
||||
print(f" - {scope}")
|
||||
else:
|
||||
print(f" (no scopes defined for '{svc}')")
|
||||
print()
|
||||
# Print combined for easy copy-paste
|
||||
all_scopes = []
|
||||
for svc in services:
|
||||
all_scopes.extend(SERVICE_SCOPES.get(svc, []))
|
||||
if all_scopes:
|
||||
print(f" COMBINED (for consent screen):")
|
||||
print(f" {','.join(all_scopes)}")
|
||||
print(f"\n{'='*60}\n")
|
||||
return
|
||||
|
||||
if args.generate_env:
|
||||
print(ENV_TEMPLATE)
|
||||
return
|
||||
|
||||
if args.check:
|
||||
if shutil.which("gws"):
|
||||
status = check_auth_status()
|
||||
else:
|
||||
status = {"status": "gws_not_found",
|
||||
"note": "Install gws first: cargo install gws-cli OR https://github.com/googleworkspace/cli/releases"}
|
||||
if args.json:
|
||||
print(json.dumps(status, indent=2))
|
||||
else:
|
||||
print(f"\nAuth Status: {status.get('status', 'unknown')}")
|
||||
for k, v in status.items():
|
||||
if k != "status":
|
||||
print(f" {k}: {v}")
|
||||
print()
|
||||
return
|
||||
|
||||
if args.validate:
|
||||
services = [s.strip() for s in args.services.split(",") if s.strip()]
|
||||
if not shutil.which("gws"):
|
||||
report = DEMO_VALIDATION
|
||||
else:
|
||||
report = validate_services(services)
|
||||
|
||||
if args.json:
|
||||
print(json.dumps(asdict(report), indent=2))
|
||||
else:
|
||||
print(f"\n{'='*60}")
|
||||
print(f" AUTH VALIDATION REPORT")
|
||||
if report.demo_mode:
|
||||
print(f" (DEMO MODE)")
|
||||
print(f"{'='*60}\n")
|
||||
if report.user:
|
||||
print(f" User: {report.user}")
|
||||
print(f" Method: {report.auth_method}\n")
|
||||
for r in report.results:
|
||||
icon = "PASS" if r["status"] == "PASS" else "FAIL"
|
||||
print(f" [{icon}] {r['service']}: {r['message']}")
|
||||
print(f"\n {report.summary}")
|
||||
print(f"\n{'='*60}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
245
engineering-team/google-workspace-cli/scripts/gws_doctor.py
Normal file
245
engineering-team/google-workspace-cli/scripts/gws_doctor.py
Normal file
@@ -0,0 +1,245 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Google Workspace CLI Doctor — Pre-flight diagnostics for gws CLI.
|
||||
|
||||
Checks installation, version, authentication status, and service
|
||||
connectivity. Runs in demo mode with embedded sample data when gws
|
||||
is not installed.
|
||||
|
||||
Usage:
|
||||
python3 gws_doctor.py
|
||||
python3 gws_doctor.py --json
|
||||
python3 gws_doctor.py --services gmail,drive,calendar
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class Check:
|
||||
name: str
|
||||
status: str # PASS, WARN, FAIL
|
||||
message: str
|
||||
fix: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class DiagnosticReport:
|
||||
gws_installed: bool = False
|
||||
gws_version: str = ""
|
||||
auth_status: str = ""
|
||||
checks: List[dict] = field(default_factory=list)
|
||||
summary: str = ""
|
||||
demo_mode: bool = False
|
||||
|
||||
|
||||
DEMO_CHECKS = [
|
||||
Check("gws-installed", "PASS", "gws v0.9.2 found at /usr/local/bin/gws"),
|
||||
Check("gws-version", "PASS", "Version 0.9.2 (latest)"),
|
||||
Check("auth-status", "PASS", "Authenticated as admin@company.com"),
|
||||
Check("token-expiry", "WARN", "Token expires in 23 minutes",
|
||||
"Run 'gws auth refresh' to extend token lifetime"),
|
||||
Check("gmail-access", "PASS", "Gmail API accessible — user profile retrieved"),
|
||||
Check("drive-access", "PASS", "Drive API accessible — root folder listed"),
|
||||
Check("calendar-access", "PASS", "Calendar API accessible — primary calendar found"),
|
||||
Check("sheets-access", "PASS", "Sheets API accessible"),
|
||||
Check("tasks-access", "FAIL", "Tasks API not authorized",
|
||||
"Run 'gws auth setup' and add 'tasks' scope"),
|
||||
]
|
||||
|
||||
SERVICE_TEST_COMMANDS = {
|
||||
"gmail": ["gws", "gmail", "users", "getProfile", "me", "--json"],
|
||||
"drive": ["gws", "drive", "files", "list", "--limit", "1", "--json"],
|
||||
"calendar": ["gws", "calendar", "calendarList", "list", "--limit", "1", "--json"],
|
||||
"sheets": ["gws", "sheets", "spreadsheets", "get", "test", "--json"],
|
||||
"tasks": ["gws", "tasks", "tasklists", "list", "--limit", "1", "--json"],
|
||||
"chat": ["gws", "chat", "spaces", "list", "--limit", "1", "--json"],
|
||||
"docs": ["gws", "docs", "documents", "get", "test", "--json"],
|
||||
}
|
||||
|
||||
|
||||
def check_installation() -> Check:
|
||||
"""Check if gws is installed and on PATH."""
|
||||
path = shutil.which("gws")
|
||||
if path:
|
||||
return Check("gws-installed", "PASS", f"gws found at {path}")
|
||||
return Check("gws-installed", "FAIL", "gws not found on PATH",
|
||||
"Install via: cargo install gws-cli OR download from https://github.com/googleworkspace/cli/releases")
|
||||
|
||||
|
||||
def check_version() -> Check:
|
||||
"""Get gws version."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["gws", "--version"], capture_output=True, text=True, timeout=10
|
||||
)
|
||||
version = result.stdout.strip()
|
||||
if version:
|
||||
return Check("gws-version", "PASS", f"Version: {version}")
|
||||
return Check("gws-version", "WARN", "Could not parse version output")
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
|
||||
return Check("gws-version", "FAIL", f"Version check failed: {e}")
|
||||
|
||||
|
||||
def check_auth() -> Check:
|
||||
"""Check authentication status."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["gws", "auth", "status", "--json"],
|
||||
capture_output=True, text=True, timeout=15
|
||||
)
|
||||
if result.returncode == 0:
|
||||
try:
|
||||
data = json.loads(result.stdout)
|
||||
user = data.get("user", data.get("email", "unknown"))
|
||||
return Check("auth-status", "PASS", f"Authenticated as {user}")
|
||||
except json.JSONDecodeError:
|
||||
return Check("auth-status", "PASS", "Authenticated (could not parse details)")
|
||||
return Check("auth-status", "FAIL", "Not authenticated",
|
||||
"Run 'gws auth setup' to configure authentication")
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
|
||||
return Check("auth-status", "FAIL", f"Auth check failed: {e}",
|
||||
"Run 'gws auth setup' to configure authentication")
|
||||
|
||||
|
||||
def check_service(service: str) -> Check:
|
||||
"""Test connectivity to a specific service."""
|
||||
cmd = SERVICE_TEST_COMMANDS.get(service)
|
||||
if not cmd:
|
||||
return Check(f"{service}-access", "WARN", f"No test command for {service}")
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
|
||||
if result.returncode == 0:
|
||||
return Check(f"{service}-access", "PASS", f"{service.title()} API accessible")
|
||||
stderr = result.stderr.strip()[:100]
|
||||
if "403" in stderr or "permission" in stderr.lower():
|
||||
return Check(f"{service}-access", "FAIL",
|
||||
f"{service.title()} API permission denied",
|
||||
f"Add '{service}' scope: gws auth setup --scopes {service}")
|
||||
return Check(f"{service}-access", "FAIL",
|
||||
f"{service.title()} API error: {stderr}",
|
||||
f"Check scope and permissions for {service}")
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
|
||||
return Check(f"{service}-access", "FAIL", f"{service.title()} test failed: {e}")
|
||||
|
||||
|
||||
def run_diagnostics(services: List[str]) -> DiagnosticReport:
|
||||
"""Run all diagnostic checks."""
|
||||
report = DiagnosticReport()
|
||||
checks = []
|
||||
|
||||
# Installation check
|
||||
install_check = check_installation()
|
||||
checks.append(install_check)
|
||||
report.gws_installed = install_check.status == "PASS"
|
||||
|
||||
if not report.gws_installed:
|
||||
report.checks = [asdict(c) for c in checks]
|
||||
report.summary = "FAIL: gws is not installed"
|
||||
return report
|
||||
|
||||
# Version check
|
||||
version_check = check_version()
|
||||
checks.append(version_check)
|
||||
if version_check.status == "PASS":
|
||||
report.gws_version = version_check.message.replace("Version: ", "")
|
||||
|
||||
# Auth check
|
||||
auth_check = check_auth()
|
||||
checks.append(auth_check)
|
||||
report.auth_status = auth_check.status
|
||||
|
||||
if auth_check.status != "PASS":
|
||||
report.checks = [asdict(c) for c in checks]
|
||||
report.summary = "FAIL: Authentication not configured"
|
||||
return report
|
||||
|
||||
# Service checks
|
||||
for svc in services:
|
||||
checks.append(check_service(svc))
|
||||
|
||||
report.checks = [asdict(c) for c in checks]
|
||||
|
||||
# Summary
|
||||
fails = sum(1 for c in checks if c.status == "FAIL")
|
||||
warns = sum(1 for c in checks if c.status == "WARN")
|
||||
passes = sum(1 for c in checks if c.status == "PASS")
|
||||
if fails > 0:
|
||||
report.summary = f"ISSUES FOUND: {passes} passed, {warns} warnings, {fails} failures"
|
||||
elif warns > 0:
|
||||
report.summary = f"MOSTLY OK: {passes} passed, {warns} warnings"
|
||||
else:
|
||||
report.summary = f"ALL CLEAR: {passes}/{passes} checks passed"
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def run_demo() -> DiagnosticReport:
|
||||
"""Return demo report with embedded sample data."""
|
||||
report = DiagnosticReport(
|
||||
gws_installed=True,
|
||||
gws_version="0.9.2",
|
||||
auth_status="PASS",
|
||||
checks=[asdict(c) for c in DEMO_CHECKS],
|
||||
summary="MOSTLY OK: 7 passed, 1 warning, 1 failure (demo mode)",
|
||||
demo_mode=True,
|
||||
)
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Pre-flight diagnostics for Google Workspace CLI (gws)",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s # Run all checks
|
||||
%(prog)s --json # JSON output
|
||||
%(prog)s --services gmail,drive # Check specific services only
|
||||
%(prog)s --demo # Demo mode (no gws required)
|
||||
""",
|
||||
)
|
||||
parser.add_argument("--json", action="store_true", help="Output JSON")
|
||||
parser.add_argument(
|
||||
"--services", default="gmail,drive,calendar,sheets,tasks",
|
||||
help="Comma-separated services to check (default: gmail,drive,calendar,sheets,tasks)"
|
||||
)
|
||||
parser.add_argument("--demo", action="store_true", help="Run with demo data")
|
||||
args = parser.parse_args()
|
||||
|
||||
services = [s.strip() for s in args.services.split(",") if s.strip()]
|
||||
|
||||
# Use demo mode if requested or gws not installed
|
||||
if args.demo or not shutil.which("gws"):
|
||||
report = run_demo()
|
||||
else:
|
||||
report = run_diagnostics(services)
|
||||
|
||||
if args.json:
|
||||
print(json.dumps(asdict(report), indent=2))
|
||||
else:
|
||||
print(f"\n{'='*60}")
|
||||
print(f" GWS CLI DIAGNOSTIC REPORT")
|
||||
if report.demo_mode:
|
||||
print(f" (DEMO MODE — sample data)")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
for c in report.checks:
|
||||
icon = {"PASS": "PASS", "WARN": "WARN", "FAIL": "FAIL"}.get(c["status"], "????")
|
||||
print(f" [{icon}] {c['name']}: {c['message']}")
|
||||
if c.get("fix") and c["status"] != "PASS":
|
||||
print(f" -> {c['fix']}")
|
||||
|
||||
print(f"\n {'-'*56}")
|
||||
print(f" {report.summary}")
|
||||
print(f"\n{'='*60}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,399 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Google Workspace CLI Recipe Runner — Catalog, search, and execute gws recipes.
|
||||
|
||||
Browse 43 built-in recipes, filter by persona, search by keyword,
|
||||
and run with dry-run support.
|
||||
|
||||
Usage:
|
||||
python3 gws_recipe_runner.py --list
|
||||
python3 gws_recipe_runner.py --search "email"
|
||||
python3 gws_recipe_runner.py --describe standup-report
|
||||
python3 gws_recipe_runner.py --run standup-report --dry-run
|
||||
python3 gws_recipe_runner.py --persona pm --list
|
||||
python3 gws_recipe_runner.py --list --json
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class Recipe:
|
||||
name: str
|
||||
description: str
|
||||
category: str
|
||||
services: List[str]
|
||||
commands: List[str]
|
||||
prerequisites: str = ""
|
||||
|
||||
|
||||
RECIPES: Dict[str, Recipe] = {
|
||||
# Email (8)
|
||||
"send-email": Recipe("send-email", "Send an email with optional attachments", "email",
|
||||
["gmail"], ["gws gmail users.messages send me --to {to} --subject {subject} --body {body}"]),
|
||||
"reply-to-thread": Recipe("reply-to-thread", "Reply to an existing email thread", "email",
|
||||
["gmail"], ["gws gmail users.messages reply me --thread-id {thread_id} --body {body}"]),
|
||||
"forward-email": Recipe("forward-email", "Forward an email to another recipient", "email",
|
||||
["gmail"], ["gws gmail users.messages forward me --message-id {msg_id} --to {to}"]),
|
||||
"search-emails": Recipe("search-emails", "Search emails with Gmail query syntax", "email",
|
||||
["gmail"], ["gws gmail users.messages list me --query {query} --json"]),
|
||||
"archive-old": Recipe("archive-old", "Archive read emails older than N days", "email",
|
||||
["gmail"], [
|
||||
"gws gmail users.messages list me --query 'is:read older_than:{days}d' --json",
|
||||
"# Pipe IDs to batch modify to remove INBOX label",
|
||||
]),
|
||||
"label-manager": Recipe("label-manager", "Create, list, and organize Gmail labels", "email",
|
||||
["gmail"], ["gws gmail users.labels list me --json", "gws gmail users.labels create me --name {name}"]),
|
||||
"filter-setup": Recipe("filter-setup", "Create email filters for auto-labeling", "email",
|
||||
["gmail"], ["gws gmail users.settings.filters create me --criteria {criteria} --action {action}"]),
|
||||
"unread-digest": Recipe("unread-digest", "Get digest of unread emails", "email",
|
||||
["gmail"], ["gws gmail users.messages list me --query 'is:unread' --limit 20 --json"]),
|
||||
|
||||
# Files (7)
|
||||
"upload-file": Recipe("upload-file", "Upload a file to Google Drive", "files",
|
||||
["drive"], ["gws drive files create --name {name} --upload {path} --parents {folder_id}"]),
|
||||
"create-sheet": Recipe("create-sheet", "Create a new Google Spreadsheet", "files",
|
||||
["sheets"], ["gws sheets spreadsheets create --title {title} --json"]),
|
||||
"share-file": Recipe("share-file", "Share a Drive file with a user or domain", "files",
|
||||
["drive"], ["gws drive permissions create {file_id} --type user --role writer --emailAddress {email}"]),
|
||||
"export-file": Recipe("export-file", "Export a Google Doc/Sheet as PDF", "files",
|
||||
["drive"], ["gws drive files export {file_id} --mime application/pdf --output {output}"]),
|
||||
"list-files": Recipe("list-files", "List files in a Drive folder", "files",
|
||||
["drive"], ["gws drive files list --parents {folder_id} --json"]),
|
||||
"find-large-files": Recipe("find-large-files", "Find largest files in Drive", "files",
|
||||
["drive"], ["gws drive files list --orderBy 'quotaBytesUsed desc' --limit 20 --json"]),
|
||||
"cleanup-trash": Recipe("cleanup-trash", "Empty Drive trash", "files",
|
||||
["drive"], ["gws drive files emptyTrash"]),
|
||||
|
||||
# Calendar (6)
|
||||
"create-event": Recipe("create-event", "Create a calendar event with attendees", "calendar",
|
||||
["calendar"], [
|
||||
"gws calendar events insert primary --summary {title} "
|
||||
"--start {start} --end {end} --attendees {attendees}"
|
||||
]),
|
||||
"quick-event": Recipe("quick-event", "Create event from natural language", "calendar",
|
||||
["calendar"], ["gws helpers quick-event {text}"]),
|
||||
"find-time": Recipe("find-time", "Find available time slots for a meeting", "calendar",
|
||||
["calendar"], ["gws helpers find-time --attendees {attendees} --duration {minutes} --within {date_range}"]),
|
||||
"today-schedule": Recipe("today-schedule", "Show today's calendar events", "calendar",
|
||||
["calendar"], ["gws calendar events list primary --timeMin {today_start} --timeMax {today_end} --json"]),
|
||||
"meeting-prep": Recipe("meeting-prep", "Prepare for an upcoming meeting (agenda + attendees)", "calendar",
|
||||
["calendar"], ["gws recipes meeting-prep --event-id {event_id}"]),
|
||||
"reschedule": Recipe("reschedule", "Move an event to a new time", "calendar",
|
||||
["calendar"], ["gws calendar events patch primary {event_id} --start {new_start} --end {new_end}"]),
|
||||
|
||||
# Reporting (5)
|
||||
"standup-report": Recipe("standup-report", "Generate daily standup from calendar and tasks", "reporting",
|
||||
["calendar", "tasks"], ["gws recipes standup-report --json"]),
|
||||
"weekly-summary": Recipe("weekly-summary", "Summarize week's emails, events, and tasks", "reporting",
|
||||
["gmail", "calendar", "tasks"], ["gws recipes weekly-summary --json"]),
|
||||
"drive-activity": Recipe("drive-activity", "Report on Drive file activity", "reporting",
|
||||
["drive"], ["gws drive activities list --json"]),
|
||||
"email-stats": Recipe("email-stats", "Email volume statistics", "reporting",
|
||||
["gmail"], [
|
||||
"gws gmail users.messages list me --query 'newer_than:7d' --json",
|
||||
"# Pipe through output_analyzer.py --count",
|
||||
]),
|
||||
"task-progress": Recipe("task-progress", "Report on task completion", "reporting",
|
||||
["tasks"], ["gws tasks tasks list {tasklist_id} --json"]),
|
||||
|
||||
# Collaboration (5)
|
||||
"share-folder": Recipe("share-folder", "Share a Drive folder with a team", "collaboration",
|
||||
["drive"], ["gws drive permissions create {folder_id} --type group --role writer --emailAddress {group}"]),
|
||||
"create-doc": Recipe("create-doc", "Create a Google Doc with initial content", "collaboration",
|
||||
["docs"], ["gws docs documents create --title {title} --json"]),
|
||||
"chat-message": Recipe("chat-message", "Send a message to a Google Chat space", "collaboration",
|
||||
["chat"], ["gws chat spaces.messages create {space} --text {message}"]),
|
||||
"list-spaces": Recipe("list-spaces", "List Google Chat spaces", "collaboration",
|
||||
["chat"], ["gws chat spaces list --json"]),
|
||||
"task-create": Recipe("task-create", "Create a task in Google Tasks", "collaboration",
|
||||
["tasks"], ["gws tasks tasks insert {tasklist_id} --title {title} --due {due_date}"]),
|
||||
|
||||
# Data (4)
|
||||
"sheet-read": Recipe("sheet-read", "Read data from a spreadsheet range", "data",
|
||||
["sheets"], ["gws sheets spreadsheets.values get {sheet_id} --range {range} --json"]),
|
||||
"sheet-write": Recipe("sheet-write", "Write data to a spreadsheet", "data",
|
||||
["sheets"], ["gws sheets spreadsheets.values update {sheet_id} --range {range} --values {data}"]),
|
||||
"sheet-append": Recipe("sheet-append", "Append rows to a spreadsheet", "data",
|
||||
["sheets"], ["gws sheets spreadsheets.values append {sheet_id} --range {range} --values {data}"]),
|
||||
"export-contacts": Recipe("export-contacts", "Export contacts list", "data",
|
||||
["people"], ["gws people people.connections list me --personFields names,emailAddresses --json"]),
|
||||
|
||||
# Admin (4)
|
||||
"list-users": Recipe("list-users", "List all users in the Workspace domain", "admin",
|
||||
["admin"], ["gws admin users list --domain {domain} --json"],
|
||||
"Requires Admin SDK API and admin.directory.user.readonly scope"),
|
||||
"list-groups": Recipe("list-groups", "List all groups in the domain", "admin",
|
||||
["admin"], ["gws admin groups list --domain {domain} --json"]),
|
||||
"user-info": Recipe("user-info", "Get detailed user information", "admin",
|
||||
["admin"], ["gws admin users get {email} --json"]),
|
||||
"audit-logins": Recipe("audit-logins", "Audit recent login activity", "admin",
|
||||
["admin"], ["gws admin activities list login --json"]),
|
||||
|
||||
# Cross-Service (4)
|
||||
"morning-briefing": Recipe("morning-briefing", "Today's events + unread emails + pending tasks", "cross-service",
|
||||
["gmail", "calendar", "tasks"], [
|
||||
"gws calendar events list primary --timeMin {today} --maxResults 10 --json",
|
||||
"gws gmail users.messages list me --query 'is:unread' --limit 10 --json",
|
||||
"gws tasks tasks list {default_tasklist} --json",
|
||||
]),
|
||||
"eod-wrap": Recipe("eod-wrap", "End-of-day wrap up: summarize completed, pending, tomorrow", "cross-service",
|
||||
["calendar", "tasks"], [
|
||||
"gws calendar events list primary --timeMin {today_start} --timeMax {today_end} --json",
|
||||
"gws tasks tasks list {default_tasklist} --json",
|
||||
]),
|
||||
"project-status": Recipe("project-status", "Aggregate project status from Drive, Sheets, Tasks", "cross-service",
|
||||
["drive", "sheets", "tasks"], [
|
||||
"gws drive files list --query 'name contains {project}' --json",
|
||||
"gws tasks tasks list {tasklist_id} --json",
|
||||
]),
|
||||
"inbox-zero": Recipe("inbox-zero", "Process inbox to zero: label, archive, reply, task", "cross-service",
|
||||
["gmail", "tasks"], [
|
||||
"gws gmail users.messages list me --query 'is:inbox' --json",
|
||||
"# Process each: label, archive, or create task",
|
||||
]),
|
||||
}
|
||||
|
||||
PERSONAS: Dict[str, Dict] = {
|
||||
"executive-assistant": {
|
||||
"description": "Executive assistant managing schedules, emails, and communications",
|
||||
"recipes": ["morning-briefing", "today-schedule", "find-time", "send-email", "reply-to-thread",
|
||||
"standup-report", "meeting-prep", "eod-wrap", "quick-event", "inbox-zero"],
|
||||
},
|
||||
"pm": {
|
||||
"description": "Project manager tracking tasks, meetings, and deliverables",
|
||||
"recipes": ["standup-report", "create-event", "find-time", "task-create", "task-progress",
|
||||
"project-status", "weekly-summary", "share-folder", "sheet-read", "morning-briefing"],
|
||||
},
|
||||
"hr": {
|
||||
"description": "HR managing people, onboarding, and communications",
|
||||
"recipes": ["list-users", "user-info", "send-email", "create-event", "create-doc",
|
||||
"share-folder", "chat-message", "list-groups", "export-contacts", "today-schedule"],
|
||||
},
|
||||
"sales": {
|
||||
"description": "Sales rep managing client communications and proposals",
|
||||
"recipes": ["send-email", "search-emails", "create-event", "find-time", "create-doc",
|
||||
"share-file", "sheet-read", "sheet-write", "export-file", "morning-briefing"],
|
||||
},
|
||||
"it-admin": {
|
||||
"description": "IT administrator managing Workspace configuration and security",
|
||||
"recipes": ["list-users", "list-groups", "user-info", "audit-logins", "drive-activity",
|
||||
"find-large-files", "cleanup-trash", "label-manager", "filter-setup", "share-folder"],
|
||||
},
|
||||
"developer": {
|
||||
"description": "Developer using Workspace APIs for automation",
|
||||
"recipes": ["sheet-read", "sheet-write", "sheet-append", "upload-file", "create-doc",
|
||||
"chat-message", "task-create", "list-files", "export-file", "send-email"],
|
||||
},
|
||||
"marketing": {
|
||||
"description": "Marketing team member managing campaigns and content",
|
||||
"recipes": ["send-email", "create-doc", "share-file", "upload-file", "create-sheet",
|
||||
"sheet-write", "chat-message", "create-event", "email-stats", "weekly-summary"],
|
||||
},
|
||||
"finance": {
|
||||
"description": "Finance team managing spreadsheets and reports",
|
||||
"recipes": ["sheet-read", "sheet-write", "sheet-append", "create-sheet", "export-file",
|
||||
"share-file", "send-email", "find-large-files", "drive-activity", "weekly-summary"],
|
||||
},
|
||||
"legal": {
|
||||
"description": "Legal team managing documents and compliance",
|
||||
"recipes": ["create-doc", "share-file", "export-file", "search-emails", "send-email",
|
||||
"upload-file", "list-files", "drive-activity", "audit-logins", "find-large-files"],
|
||||
},
|
||||
"support": {
|
||||
"description": "Customer support managing tickets and communications",
|
||||
"recipes": ["search-emails", "send-email", "reply-to-thread", "label-manager", "filter-setup",
|
||||
"task-create", "chat-message", "unread-digest", "inbox-zero", "morning-briefing"],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def list_recipes(persona: Optional[str], output_json: bool):
|
||||
"""List all recipes, optionally filtered by persona."""
|
||||
if persona:
|
||||
if persona not in PERSONAS:
|
||||
print(f"Unknown persona: {persona}. Available: {', '.join(PERSONAS.keys())}")
|
||||
sys.exit(1)
|
||||
recipe_names = PERSONAS[persona]["recipes"]
|
||||
recipes = {k: v for k, v in RECIPES.items() if k in recipe_names}
|
||||
title = f"Recipes for {persona.upper()}: {PERSONAS[persona]['description']}"
|
||||
else:
|
||||
recipes = RECIPES
|
||||
title = "All 43 Google Workspace CLI Recipes"
|
||||
|
||||
if output_json:
|
||||
output = []
|
||||
for name, r in recipes.items():
|
||||
output.append(asdict(r))
|
||||
print(json.dumps(output, indent=2))
|
||||
return
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f" {title}")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
by_category: Dict[str, list] = {}
|
||||
for name, r in recipes.items():
|
||||
by_category.setdefault(r.category, []).append(r)
|
||||
|
||||
for cat, cat_recipes in sorted(by_category.items()):
|
||||
print(f" {cat.upper()} ({len(cat_recipes)})")
|
||||
for r in cat_recipes:
|
||||
svcs = ",".join(r.services)
|
||||
print(f" {r.name:<24} {r.description:<40} [{svcs}]")
|
||||
print()
|
||||
|
||||
print(f" Total: {len(recipes)} recipes")
|
||||
print(f"\n{'='*60}\n")
|
||||
|
||||
|
||||
def search_recipes(keyword: str, output_json: bool):
|
||||
"""Search recipes by keyword."""
|
||||
keyword_lower = keyword.lower()
|
||||
matches = {k: v for k, v in RECIPES.items()
|
||||
if keyword_lower in k.lower()
|
||||
or keyword_lower in v.description.lower()
|
||||
or keyword_lower in v.category.lower()
|
||||
or any(keyword_lower in s for s in v.services)}
|
||||
|
||||
if output_json:
|
||||
print(json.dumps([asdict(r) for r in matches.values()], indent=2))
|
||||
return
|
||||
|
||||
print(f"\n Search results for '{keyword}': {len(matches)} matches\n")
|
||||
for name, r in matches.items():
|
||||
print(f" {r.name:<24} {r.description}")
|
||||
print()
|
||||
|
||||
|
||||
def describe_recipe(name: str, output_json: bool):
|
||||
"""Show full details for a recipe."""
|
||||
recipe = RECIPES.get(name)
|
||||
if not recipe:
|
||||
print(f"Unknown recipe: {name}")
|
||||
print(f"Use --list to see available recipes")
|
||||
sys.exit(1)
|
||||
|
||||
if output_json:
|
||||
print(json.dumps(asdict(recipe), indent=2))
|
||||
return
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f" Recipe: {recipe.name}")
|
||||
print(f"{'='*60}\n")
|
||||
print(f" Description: {recipe.description}")
|
||||
print(f" Category: {recipe.category}")
|
||||
print(f" Services: {', '.join(recipe.services)}")
|
||||
if recipe.prerequisites:
|
||||
print(f" Prerequisites: {recipe.prerequisites}")
|
||||
print(f"\n Commands:")
|
||||
for i, cmd in enumerate(recipe.commands, 1):
|
||||
print(f" {i}. {cmd}")
|
||||
print(f"\n{'='*60}\n")
|
||||
|
||||
|
||||
def run_recipe(name: str, dry_run: bool):
|
||||
"""Execute a recipe (or print commands in dry-run mode)."""
|
||||
recipe = RECIPES.get(name)
|
||||
if not recipe:
|
||||
print(f"Unknown recipe: {name}")
|
||||
sys.exit(1)
|
||||
|
||||
if dry_run:
|
||||
print(f"\n [DRY RUN] Recipe: {recipe.name}\n")
|
||||
for i, cmd in enumerate(recipe.commands, 1):
|
||||
print(f" {i}. {cmd}")
|
||||
print(f"\n (No commands executed)")
|
||||
return
|
||||
|
||||
print(f"\n Executing recipe: {recipe.name}\n")
|
||||
for cmd in recipe.commands:
|
||||
if cmd.startswith("#"):
|
||||
print(f" {cmd}")
|
||||
continue
|
||||
print(f" $ {cmd}")
|
||||
try:
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
|
||||
if result.stdout:
|
||||
print(result.stdout)
|
||||
if result.returncode != 0 and result.stderr:
|
||||
print(f" Error: {result.stderr.strip()[:200]}")
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f" Timeout after 30s")
|
||||
except OSError as e:
|
||||
print(f" Execution error: {e}")
|
||||
|
||||
|
||||
def list_personas(output_json: bool):
|
||||
"""List all available personas."""
|
||||
if output_json:
|
||||
print(json.dumps(PERSONAS, indent=2))
|
||||
return
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f" 10 PERSONA BUNDLES")
|
||||
print(f"{'='*60}\n")
|
||||
for name, p in PERSONAS.items():
|
||||
print(f" {name:<24} {p['description']}")
|
||||
print(f" {'':24} Recipes: {', '.join(p['recipes'][:5])}...")
|
||||
print()
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Catalog, search, and execute Google Workspace CLI recipes",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s --list # List all 43 recipes
|
||||
%(prog)s --list --persona pm # Recipes for project managers
|
||||
%(prog)s --search "email" # Search by keyword
|
||||
%(prog)s --describe standup-report # Full recipe details
|
||||
%(prog)s --run standup-report --dry-run # Preview recipe commands
|
||||
%(prog)s --personas # List all 10 personas
|
||||
%(prog)s --list --json # JSON output
|
||||
""",
|
||||
)
|
||||
parser.add_argument("--list", action="store_true", help="List all recipes")
|
||||
parser.add_argument("--search", help="Search recipes by keyword")
|
||||
parser.add_argument("--describe", help="Show full details for a recipe")
|
||||
parser.add_argument("--run", help="Execute a recipe")
|
||||
parser.add_argument("--dry-run", action="store_true", help="Print commands without executing")
|
||||
parser.add_argument("--persona", help="Filter recipes by persona")
|
||||
parser.add_argument("--personas", action="store_true", help="List all personas")
|
||||
parser.add_argument("--json", action="store_true", help="Output JSON")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not any([args.list, args.search, args.describe, args.run, args.personas]):
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
if args.personas:
|
||||
list_personas(args.json)
|
||||
return
|
||||
|
||||
if args.list:
|
||||
list_recipes(args.persona, args.json)
|
||||
return
|
||||
|
||||
if args.search:
|
||||
search_recipes(args.search, args.json)
|
||||
return
|
||||
|
||||
if args.describe:
|
||||
describe_recipe(args.describe, args.json)
|
||||
return
|
||||
|
||||
if args.run:
|
||||
run_recipe(args.run, args.dry_run)
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
332
engineering-team/google-workspace-cli/scripts/output_analyzer.py
Normal file
332
engineering-team/google-workspace-cli/scripts/output_analyzer.py
Normal file
@@ -0,0 +1,332 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Google Workspace CLI Output Analyzer — Parse, filter, and aggregate JSON/NDJSON output.
|
||||
|
||||
Reads JSON arrays or NDJSON streams from stdin or file, applies filters,
|
||||
projections, sorting, grouping, and outputs in table/csv/json format.
|
||||
|
||||
Usage:
|
||||
gws drive files list --json | python3 output_analyzer.py --count
|
||||
gws drive files list --json | python3 output_analyzer.py --filter "mimeType=application/pdf"
|
||||
gws drive files list --json | python3 output_analyzer.py --select "name,size" --format table
|
||||
python3 output_analyzer.py --input results.json --group-by "mimeType"
|
||||
python3 output_analyzer.py --demo --select "name,mimeType,size" --format table
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import io
|
||||
import json
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Dict, Any, Optional
|
||||
|
||||
|
||||
DEMO_DATA = [
|
||||
{"id": "1", "name": "Q1 Report.pdf", "mimeType": "application/pdf", "size": "245760",
|
||||
"modifiedTime": "2026-03-10T14:30:00Z", "shared": True, "owners": [{"displayName": "Alice"}]},
|
||||
{"id": "2", "name": "Budget 2026.xlsx", "mimeType": "application/vnd.google-apps.spreadsheet",
|
||||
"size": "0", "modifiedTime": "2026-03-09T09:15:00Z", "shared": True,
|
||||
"owners": [{"displayName": "Bob"}]},
|
||||
{"id": "3", "name": "Meeting Notes.docx", "mimeType": "application/vnd.google-apps.document",
|
||||
"size": "0", "modifiedTime": "2026-03-08T16:00:00Z", "shared": False,
|
||||
"owners": [{"displayName": "Alice"}]},
|
||||
{"id": "4", "name": "Logo.png", "mimeType": "image/png", "size": "102400",
|
||||
"modifiedTime": "2026-03-07T11:00:00Z", "shared": False,
|
||||
"owners": [{"displayName": "Charlie"}]},
|
||||
{"id": "5", "name": "Presentation.pptx", "mimeType": "application/vnd.google-apps.presentation",
|
||||
"size": "0", "modifiedTime": "2026-03-06T10:00:00Z", "shared": True,
|
||||
"owners": [{"displayName": "Alice"}]},
|
||||
{"id": "6", "name": "Invoice-001.pdf", "mimeType": "application/pdf", "size": "89000",
|
||||
"modifiedTime": "2026-03-05T08:30:00Z", "shared": False,
|
||||
"owners": [{"displayName": "Bob"}]},
|
||||
{"id": "7", "name": "Project Plan.xlsx", "mimeType": "application/vnd.google-apps.spreadsheet",
|
||||
"size": "0", "modifiedTime": "2026-03-04T13:45:00Z", "shared": True,
|
||||
"owners": [{"displayName": "Charlie"}]},
|
||||
{"id": "8", "name": "Contract Draft.docx", "mimeType": "application/vnd.google-apps.document",
|
||||
"size": "0", "modifiedTime": "2026-03-03T09:00:00Z", "shared": False,
|
||||
"owners": [{"displayName": "Alice"}]},
|
||||
]
|
||||
|
||||
|
||||
def read_input(input_file: Optional[str]) -> List[Dict[str, Any]]:
|
||||
"""Read JSON array or NDJSON from file or stdin."""
|
||||
if input_file:
|
||||
with open(input_file, "r") as f:
|
||||
text = f.read().strip()
|
||||
else:
|
||||
if sys.stdin.isatty():
|
||||
return []
|
||||
text = sys.stdin.read().strip()
|
||||
|
||||
if not text:
|
||||
return []
|
||||
|
||||
# Try JSON array first
|
||||
try:
|
||||
data = json.loads(text)
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
if isinstance(data, dict):
|
||||
# Some gws commands wrap results in a key
|
||||
for key in ("files", "messages", "events", "items", "results",
|
||||
"spreadsheets", "spaces", "tasks", "users", "groups"):
|
||||
if key in data and isinstance(data[key], list):
|
||||
return data[key]
|
||||
return [data]
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
# Try NDJSON
|
||||
records = []
|
||||
for line in text.split("\n"):
|
||||
line = line.strip()
|
||||
if line:
|
||||
try:
|
||||
records.append(json.loads(line))
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
return records
|
||||
|
||||
|
||||
def get_nested(obj: Dict, path: str) -> Any:
|
||||
"""Get a nested value by dot-separated path."""
|
||||
parts = path.split(".")
|
||||
current = obj
|
||||
for part in parts:
|
||||
if isinstance(current, dict):
|
||||
current = current.get(part)
|
||||
elif isinstance(current, list) and part.isdigit():
|
||||
idx = int(part)
|
||||
current = current[idx] if idx < len(current) else None
|
||||
else:
|
||||
return None
|
||||
if current is None:
|
||||
return None
|
||||
return current
|
||||
|
||||
|
||||
def apply_filter(records: List[Dict], filter_expr: str) -> List[Dict]:
|
||||
"""Filter records by field=value expression."""
|
||||
if "=" not in filter_expr:
|
||||
return records
|
||||
field_path, value = filter_expr.split("=", 1)
|
||||
result = []
|
||||
for rec in records:
|
||||
rec_val = get_nested(rec, field_path)
|
||||
if rec_val is None:
|
||||
continue
|
||||
rec_str = str(rec_val).lower()
|
||||
if rec_str == value.lower() or value.lower() in rec_str:
|
||||
result.append(rec)
|
||||
return result
|
||||
|
||||
|
||||
def apply_select(records: List[Dict], fields: str) -> List[Dict]:
|
||||
"""Project specific fields from records."""
|
||||
field_list = [f.strip() for f in fields.split(",")]
|
||||
result = []
|
||||
for rec in records:
|
||||
projected = {}
|
||||
for f in field_list:
|
||||
projected[f] = get_nested(rec, f)
|
||||
result.append(projected)
|
||||
return result
|
||||
|
||||
|
||||
def apply_sort(records: List[Dict], sort_field: str, reverse: bool = False) -> List[Dict]:
|
||||
"""Sort records by a field."""
|
||||
def sort_key(rec):
|
||||
val = get_nested(rec, sort_field)
|
||||
if val is None:
|
||||
return ""
|
||||
if isinstance(val, (int, float)):
|
||||
return val
|
||||
try:
|
||||
return float(val)
|
||||
except (ValueError, TypeError):
|
||||
return str(val).lower()
|
||||
return sorted(records, key=sort_key, reverse=reverse)
|
||||
|
||||
|
||||
def apply_group_by(records: List[Dict], field: str) -> Dict[str, int]:
|
||||
"""Group records by a field and count."""
|
||||
groups: Dict[str, int] = {}
|
||||
for rec in records:
|
||||
val = get_nested(rec, field)
|
||||
key = str(val) if val is not None else "(null)"
|
||||
groups[key] = groups.get(key, 0) + 1
|
||||
return dict(sorted(groups.items(), key=lambda x: x[1], reverse=True))
|
||||
|
||||
|
||||
def compute_stats(records: List[Dict], field: str) -> Dict[str, Any]:
|
||||
"""Compute min/max/avg/sum for a numeric field."""
|
||||
values = []
|
||||
for rec in records:
|
||||
val = get_nested(rec, field)
|
||||
if val is not None:
|
||||
try:
|
||||
values.append(float(val))
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
if not values:
|
||||
return {"field": field, "count": 0, "error": "No numeric values found"}
|
||||
return {
|
||||
"field": field,
|
||||
"count": len(values),
|
||||
"min": min(values),
|
||||
"max": max(values),
|
||||
"sum": sum(values),
|
||||
"avg": sum(values) / len(values),
|
||||
}
|
||||
|
||||
|
||||
def format_table(records: List[Dict]) -> str:
|
||||
"""Format records as an aligned text table."""
|
||||
if not records:
|
||||
return "(no records)"
|
||||
|
||||
headers = list(records[0].keys())
|
||||
# Calculate column widths
|
||||
widths = {h: len(h) for h in headers}
|
||||
for rec in records:
|
||||
for h in headers:
|
||||
val = str(rec.get(h, ""))
|
||||
if len(val) > 60:
|
||||
val = val[:57] + "..."
|
||||
widths[h] = max(widths[h], len(val))
|
||||
|
||||
# Header
|
||||
header_line = " ".join(h.ljust(widths[h]) for h in headers)
|
||||
sep_line = " ".join("-" * widths[h] for h in headers)
|
||||
lines = [header_line, sep_line]
|
||||
|
||||
# Rows
|
||||
for rec in records:
|
||||
row = []
|
||||
for h in headers:
|
||||
val = str(rec.get(h, ""))
|
||||
if len(val) > 60:
|
||||
val = val[:57] + "..."
|
||||
row.append(val.ljust(widths[h]))
|
||||
lines.append(" ".join(row))
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def format_csv_output(records: List[Dict]) -> str:
|
||||
"""Format records as CSV."""
|
||||
if not records:
|
||||
return ""
|
||||
output = io.StringIO()
|
||||
writer = csv.DictWriter(output, fieldnames=records[0].keys())
|
||||
writer.writeheader()
|
||||
writer.writerows(records)
|
||||
return output.getvalue()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Parse, filter, and aggregate JSON/NDJSON from gws CLI output",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
gws drive files list --json | %(prog)s --count
|
||||
gws drive files list --json | %(prog)s --filter "mimeType=pdf" --select "name,size"
|
||||
gws drive files list --json | %(prog)s --group-by "mimeType" --format table
|
||||
gws drive files list --json | %(prog)s --sort "size" --reverse --format table
|
||||
gws drive files list --json | %(prog)s --stats "size"
|
||||
%(prog)s --input results.json --select "name,mimeType" --format csv
|
||||
%(prog)s --demo --select "name,mimeType,size" --format table
|
||||
""",
|
||||
)
|
||||
parser.add_argument("--input", help="Input file (default: stdin)")
|
||||
parser.add_argument("--demo", action="store_true", help="Use demo data")
|
||||
parser.add_argument("--count", action="store_true", help="Count records")
|
||||
parser.add_argument("--filter", help="Filter by field=value")
|
||||
parser.add_argument("--select", help="Comma-separated fields to project")
|
||||
parser.add_argument("--sort", help="Sort by field")
|
||||
parser.add_argument("--reverse", action="store_true", help="Reverse sort order")
|
||||
parser.add_argument("--group-by", help="Group by field and count")
|
||||
parser.add_argument("--stats", help="Compute stats for a numeric field")
|
||||
parser.add_argument("--format", choices=["json", "table", "csv"], default="json",
|
||||
help="Output format (default: json)")
|
||||
parser.add_argument("--json", action="store_true",
|
||||
help="Shorthand for --format json")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.json:
|
||||
args.format = "json"
|
||||
|
||||
# Read input
|
||||
if args.demo:
|
||||
records = DEMO_DATA[:]
|
||||
else:
|
||||
records = read_input(args.input)
|
||||
|
||||
if not records and not args.demo:
|
||||
# If no pipe input and no file, use demo
|
||||
records = DEMO_DATA[:]
|
||||
print("(No input detected, using demo data)\n", file=sys.stderr)
|
||||
|
||||
# Apply operations in order
|
||||
if args.filter:
|
||||
records = apply_filter(records, args.filter)
|
||||
|
||||
if args.sort:
|
||||
records = apply_sort(records, args.sort, args.reverse)
|
||||
|
||||
# Count
|
||||
if args.count:
|
||||
if args.format == "json":
|
||||
print(json.dumps({"count": len(records)}))
|
||||
else:
|
||||
print(f"Count: {len(records)}")
|
||||
return
|
||||
|
||||
# Group by
|
||||
if args.group_by:
|
||||
groups = apply_group_by(records, args.group_by)
|
||||
if args.format == "json":
|
||||
print(json.dumps(groups, indent=2))
|
||||
elif args.format == "csv":
|
||||
print(f"{args.group_by},count")
|
||||
for k, v in groups.items():
|
||||
print(f"{k},{v}")
|
||||
else:
|
||||
print(f"\n Group by: {args.group_by}\n")
|
||||
for k, v in groups.items():
|
||||
print(f" {k:<50} {v}")
|
||||
print(f"\n Total groups: {len(groups)}")
|
||||
return
|
||||
|
||||
# Stats
|
||||
if args.stats:
|
||||
stats = compute_stats(records, args.stats)
|
||||
if args.format == "json":
|
||||
print(json.dumps(stats, indent=2))
|
||||
else:
|
||||
print(f"\n Stats for '{args.stats}':")
|
||||
for k, v in stats.items():
|
||||
if isinstance(v, float):
|
||||
print(f" {k}: {v:,.2f}")
|
||||
else:
|
||||
print(f" {k}: {v}")
|
||||
return
|
||||
|
||||
# Select fields
|
||||
if args.select:
|
||||
records = apply_select(records, args.select)
|
||||
|
||||
# Output
|
||||
if args.format == "json":
|
||||
print(json.dumps(records, indent=2))
|
||||
elif args.format == "csv":
|
||||
print(format_csv_output(records))
|
||||
else:
|
||||
print(f"\n{format_table(records)}\n")
|
||||
print(f" ({len(records)} records)\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
309
engineering-team/google-workspace-cli/scripts/workspace_audit.py
Normal file
309
engineering-team/google-workspace-cli/scripts/workspace_audit.py
Normal file
@@ -0,0 +1,309 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Google Workspace Security Audit — Audit Workspace configuration for security risks.
|
||||
|
||||
Checks Drive external sharing, Gmail forwarding rules, OAuth app grants,
|
||||
Calendar visibility, admin settings, and generates remediation commands.
|
||||
Runs in demo mode with embedded sample data when gws is not installed.
|
||||
|
||||
Usage:
|
||||
python3 workspace_audit.py
|
||||
python3 workspace_audit.py --json
|
||||
python3 workspace_audit.py --services gmail,drive,calendar
|
||||
python3 workspace_audit.py --demo
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class AuditFinding:
|
||||
area: str
|
||||
check: str
|
||||
status: str # PASS, WARN, FAIL
|
||||
message: str
|
||||
risk: str = ""
|
||||
remediation: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class AuditReport:
|
||||
findings: List[dict] = field(default_factory=list)
|
||||
score: int = 0
|
||||
max_score: int = 100
|
||||
grade: str = ""
|
||||
summary: str = ""
|
||||
demo_mode: bool = False
|
||||
|
||||
|
||||
DEMO_FINDINGS = [
|
||||
AuditFinding("drive", "External sharing", "WARN",
|
||||
"External sharing is enabled for the domain",
|
||||
"Data exfiltration via shared links",
|
||||
"Review sharing settings in Admin Console > Apps > Google Workspace > Drive"),
|
||||
AuditFinding("drive", "Link sharing defaults", "FAIL",
|
||||
"Default link sharing is set to 'Anyone with the link'",
|
||||
"Sensitive files accessible without authentication",
|
||||
"gws admin settings update drive --defaultLinkSharing restricted"),
|
||||
AuditFinding("gmail", "Auto-forwarding", "PASS",
|
||||
"No auto-forwarding rules detected for admin accounts"),
|
||||
AuditFinding("gmail", "SPF record", "PASS",
|
||||
"SPF record configured correctly"),
|
||||
AuditFinding("gmail", "DMARC record", "WARN",
|
||||
"DMARC policy is set to 'none' (monitoring only)",
|
||||
"Email spoofing not actively blocked",
|
||||
"Update DMARC DNS record: v=DMARC1; p=quarantine; rua=mailto:dmarc@company.com"),
|
||||
AuditFinding("gmail", "DKIM signing", "PASS",
|
||||
"DKIM signing is enabled"),
|
||||
AuditFinding("calendar", "Default visibility", "WARN",
|
||||
"Calendar default visibility is 'See all event details'",
|
||||
"Meeting details visible to all domain users",
|
||||
"Admin Console > Apps > Calendar > Sharing settings > Set to 'Free/Busy'"),
|
||||
AuditFinding("calendar", "External sharing", "PASS",
|
||||
"External calendar sharing is restricted"),
|
||||
AuditFinding("oauth", "Third-party apps", "FAIL",
|
||||
"12 third-party OAuth apps with broad access detected",
|
||||
"Unauthorized data access via OAuth grants",
|
||||
"Review: Admin Console > Security > API controls > App access control"),
|
||||
AuditFinding("oauth", "High-risk apps", "WARN",
|
||||
"3 apps have Drive full access scope",
|
||||
"Apps can read/modify all Drive files",
|
||||
"Audit each app: gws admin tokens list --json | filter by scope"),
|
||||
AuditFinding("admin", "Super admin count", "WARN",
|
||||
"4 super admin accounts detected (recommended: 2-3)",
|
||||
"Increased attack surface for privilege escalation",
|
||||
"Reduce super admins: gws admin users list --query 'isAdmin=true' --json"),
|
||||
AuditFinding("admin", "2-Step verification", "PASS",
|
||||
"2-Step verification enforced for all users"),
|
||||
AuditFinding("admin", "Password policy", "PASS",
|
||||
"Minimum password length: 12 characters"),
|
||||
AuditFinding("admin", "Login challenges", "PASS",
|
||||
"Suspicious login challenges enabled"),
|
||||
]
|
||||
|
||||
|
||||
def run_gws_command(cmd: List[str]) -> Optional[str]:
|
||||
"""Run a gws command and return stdout, or None on failure."""
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=20)
|
||||
if result.returncode == 0:
|
||||
return result.stdout
|
||||
return None
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def audit_drive() -> List[AuditFinding]:
|
||||
"""Audit Drive sharing and security settings."""
|
||||
findings = []
|
||||
|
||||
# Check sharing settings
|
||||
output = run_gws_command(["gws", "drive", "about", "get", "--json"])
|
||||
if output:
|
||||
try:
|
||||
data = json.loads(output)
|
||||
# Check if external sharing is enabled
|
||||
if data.get("canShareOutsideDomain", True):
|
||||
findings.append(AuditFinding(
|
||||
"drive", "External sharing", "WARN",
|
||||
"External sharing is enabled",
|
||||
"Data exfiltration via shared links",
|
||||
"Review Admin Console > Apps > Drive > Sharing settings"
|
||||
))
|
||||
else:
|
||||
findings.append(AuditFinding(
|
||||
"drive", "External sharing", "PASS",
|
||||
"External sharing is restricted"
|
||||
))
|
||||
except json.JSONDecodeError:
|
||||
findings.append(AuditFinding(
|
||||
"drive", "External sharing", "WARN",
|
||||
"Could not parse Drive settings"
|
||||
))
|
||||
else:
|
||||
findings.append(AuditFinding(
|
||||
"drive", "External sharing", "WARN",
|
||||
"Could not retrieve Drive settings"
|
||||
))
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
def audit_gmail() -> List[AuditFinding]:
|
||||
"""Audit Gmail forwarding and email security."""
|
||||
findings = []
|
||||
|
||||
# Check forwarding rules
|
||||
output = run_gws_command(["gws", "gmail", "users.settings.forwardingAddresses", "list", "me", "--json"])
|
||||
if output:
|
||||
try:
|
||||
data = json.loads(output)
|
||||
addrs = data if isinstance(data, list) else data.get("forwardingAddresses", [])
|
||||
if addrs:
|
||||
findings.append(AuditFinding(
|
||||
"gmail", "Auto-forwarding", "WARN",
|
||||
f"{len(addrs)} forwarding addresses configured",
|
||||
"Data exfiltration via email forwarding",
|
||||
"Review: gws gmail users.settings.forwardingAddresses list me --json"
|
||||
))
|
||||
else:
|
||||
findings.append(AuditFinding(
|
||||
"gmail", "Auto-forwarding", "PASS",
|
||||
"No forwarding addresses configured"
|
||||
))
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
else:
|
||||
findings.append(AuditFinding(
|
||||
"gmail", "Auto-forwarding", "WARN",
|
||||
"Could not check forwarding settings"
|
||||
))
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
def audit_calendar() -> List[AuditFinding]:
|
||||
"""Audit Calendar sharing settings."""
|
||||
findings = []
|
||||
|
||||
output = run_gws_command(["gws", "calendar", "calendarList", "get", "primary", "--json"])
|
||||
if output:
|
||||
findings.append(AuditFinding(
|
||||
"calendar", "Primary calendar", "PASS",
|
||||
"Primary calendar accessible"
|
||||
))
|
||||
else:
|
||||
findings.append(AuditFinding(
|
||||
"calendar", "Primary calendar", "WARN",
|
||||
"Could not access primary calendar"
|
||||
))
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
def run_live_audit(services: List[str]) -> AuditReport:
|
||||
"""Run live audit against actual gws installation."""
|
||||
report = AuditReport()
|
||||
all_findings = []
|
||||
|
||||
audit_map = {
|
||||
"drive": audit_drive,
|
||||
"gmail": audit_gmail,
|
||||
"calendar": audit_calendar,
|
||||
}
|
||||
|
||||
for svc in services:
|
||||
fn = audit_map.get(svc)
|
||||
if fn:
|
||||
all_findings.extend(fn())
|
||||
|
||||
report.findings = [asdict(f) for f in all_findings]
|
||||
report = calculate_score(report)
|
||||
return report
|
||||
|
||||
|
||||
def run_demo_audit() -> AuditReport:
|
||||
"""Return demo audit report with embedded sample data."""
|
||||
report = AuditReport(
|
||||
findings=[asdict(f) for f in DEMO_FINDINGS],
|
||||
demo_mode=True,
|
||||
)
|
||||
report = calculate_score(report)
|
||||
return report
|
||||
|
||||
|
||||
def calculate_score(report: AuditReport) -> AuditReport:
|
||||
"""Calculate audit score and grade."""
|
||||
total = len(report.findings)
|
||||
if total == 0:
|
||||
report.score = 0
|
||||
report.grade = "N/A"
|
||||
report.summary = "No checks performed"
|
||||
return report
|
||||
|
||||
passes = sum(1 for f in report.findings if f["status"] == "PASS")
|
||||
warns = sum(1 for f in report.findings if f["status"] == "WARN")
|
||||
fails = sum(1 for f in report.findings if f["status"] == "FAIL")
|
||||
|
||||
# Score: PASS=100, WARN=50, FAIL=0
|
||||
score = int(((passes * 100) + (warns * 50)) / total)
|
||||
report.score = score
|
||||
report.max_score = 100
|
||||
|
||||
if score >= 90:
|
||||
report.grade = "A"
|
||||
elif score >= 75:
|
||||
report.grade = "B"
|
||||
elif score >= 60:
|
||||
report.grade = "C"
|
||||
elif score >= 40:
|
||||
report.grade = "D"
|
||||
else:
|
||||
report.grade = "F"
|
||||
|
||||
report.summary = f"{passes} passed, {warns} warnings, {fails} failures — Score: {score}/100 (Grade: {report.grade})"
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Security and configuration audit for Google Workspace",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s # Full audit (or demo if gws not installed)
|
||||
%(prog)s --json # JSON output
|
||||
%(prog)s --services gmail,drive # Audit specific services
|
||||
%(prog)s --demo # Demo mode with sample data
|
||||
""",
|
||||
)
|
||||
parser.add_argument("--json", action="store_true", help="Output JSON")
|
||||
parser.add_argument("--services", default="gmail,drive,calendar",
|
||||
help="Comma-separated services to audit (default: gmail,drive,calendar)")
|
||||
parser.add_argument("--demo", action="store_true", help="Run with demo data")
|
||||
args = parser.parse_args()
|
||||
|
||||
services = [s.strip() for s in args.services.split(",") if s.strip()]
|
||||
|
||||
if args.demo or not shutil.which("gws"):
|
||||
report = run_demo_audit()
|
||||
else:
|
||||
report = run_live_audit(services)
|
||||
|
||||
if args.json:
|
||||
print(json.dumps(asdict(report), indent=2))
|
||||
else:
|
||||
print(f"\n{'='*60}")
|
||||
print(f" GOOGLE WORKSPACE SECURITY AUDIT")
|
||||
if report.demo_mode:
|
||||
print(f" (DEMO MODE — sample data)")
|
||||
print(f"{'='*60}\n")
|
||||
print(f" Score: {report.score}/{report.max_score} (Grade: {report.grade})\n")
|
||||
|
||||
current_area = ""
|
||||
for f in report.findings:
|
||||
if f["area"] != current_area:
|
||||
current_area = f["area"]
|
||||
print(f"\n {current_area.upper()}")
|
||||
print(f" {'-'*40}")
|
||||
|
||||
icon = {"PASS": "PASS", "WARN": "WARN", "FAIL": "FAIL"}.get(f["status"], "????")
|
||||
print(f" [{icon}] {f['check']}: {f['message']}")
|
||||
if f.get("risk") and f["status"] != "PASS":
|
||||
print(f" Risk: {f['risk']}")
|
||||
if f.get("remediation") and f["status"] != "PASS":
|
||||
print(f" Fix: {f['remediation']}")
|
||||
|
||||
print(f"\n {'='*56}")
|
||||
print(f" {report.summary}")
|
||||
print(f"\n{'='*60}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,6 +1,6 @@
|
||||
site_name: Claude Code Skills & Plugins
|
||||
site_url: https://alirezarezvani.github.io/claude-skills
|
||||
site_description: "172 production-ready skills, 14 agents, and 14 commands for Claude Code, OpenAI Codex, Gemini CLI, and OpenClaw. Reusable expertise for engineering, product, marketing, compliance, and more."
|
||||
site_url: https://alirezarezvani.github.io/claude-skills/
|
||||
site_description: "173 production-ready skills, 15 agents, and 15 commands for Claude Code, OpenAI Codex, Gemini CLI, and OpenClaw. Reusable expertise for engineering, product, marketing, compliance, and more."
|
||||
site_author: Alireza Rezvani
|
||||
repo_url: https://github.com/alirezarezvani/claude-skills
|
||||
repo_name: alirezarezvani/claude-skills
|
||||
@@ -124,6 +124,7 @@ nav:
|
||||
- "Code Reviewer": skills/engineering-team/code-reviewer.md
|
||||
- "Email Template Builder": skills/engineering-team/email-template-builder.md
|
||||
- "Incident Commander": skills/engineering-team/incident-commander.md
|
||||
- "Google Workspace CLI": skills/engineering-team/google-workspace-cli.md
|
||||
- "Microsoft 365 Tenant Manager": skills/engineering-team/ms365-tenant-manager.md
|
||||
- Playwright Pro:
|
||||
- "Playwright Pro": skills/engineering-team/playwright-pro.md
|
||||
@@ -322,6 +323,7 @@ nav:
|
||||
- "CS Financial Analyst": agents/cs-financial-analyst.md
|
||||
- "CS Growth Strategist": agents/cs-growth-strategist.md
|
||||
- "CS Product Manager": agents/cs-product-manager.md
|
||||
- "CS Workspace Admin": agents/cs-workspace-admin.md
|
||||
- "CS Product Strategist": agents/cs-product-strategist.md
|
||||
- "CS Project Manager": agents/cs-project-manager.md
|
||||
- "CS Quality & Regulatory": agents/cs-quality-regulatory.md
|
||||
@@ -343,3 +345,4 @@ nav:
|
||||
- "/tdd": commands/tdd.md
|
||||
- "/tech-debt": commands/tech-debt.md
|
||||
- "/user-story": commands/user-story.md
|
||||
- "/google-workspace": commands/google-workspace.md
|
||||
|
||||
Reference in New Issue
Block a user