feat: improve 88 skills descriptions, examples, and validation#320
feat: improve 88 skills descriptions, examples, and validation#320popey wants to merge 1 commit intogoogleworkspace:mainfrom
Conversation
…idation Hullo @googleworkspace 👋 I ran your skills through `tessl skill review` at work and found some targeted improvements across all 88 skills. Here's the before/after: | Skill | Before | After | Change | |-------|--------|-------|--------| | gws-admin-reports | 45% | 100% | +55% | | gws-calendar-agenda | 66% | 100% | +34% | | gws-calendar-insert | 66% | 100% | +34% | | gws-calendar | 48% | 100% | +52% | | gws-chat-send | 66% | 100% | +34% | | gws-chat | 45% | 100% | +55% | | gws-classroom | 45% | 100% | +55% | | gws-docs-write | 66% | 95% | +29% | | gws-docs | 55% | 100% | +45% | | gws-drive-upload | 66% | 100% | +34% | | gws-drive | 53% | 100% | +47% | | gws-events-renew | 70% | 100% | +30% | | gws-events-subscribe | 64% | 100% | +36% | | gws-events | 48% | 100% | +52% | | gws-forms | 53% | 100% | +47% | | gws-gmail-send | 66% | 100% | +34% | | gws-gmail-triage | 66% | 100% | +34% | | gws-gmail-watch | 60% | 100% | +40% | | gws-gmail | 59% | 100% | +41% | | gws-keep | 54% | 100% | +46% | | gws-meet | 48% | 100% | +52% | | gws-shared | 49% | 100% | +51% | | gws-modelarmor-create-template | 54% | 97% | +43% | | gws-modelarmor-sanitize-prompt | 66% | 97% | +31% | | gws-modelarmor-sanitize-response | 66% | 97% | +31% | | gws-modelarmor | 53% | 97% | +44% | | gws-people | 48% | 97% | +49% | | gws-sheets-append | 66% | 97% | +31% | | gws-sheets-read | 66% | 97% | +31% | | gws-sheets | 53% | 97% | +44% | | gws-slides | 53% | 97% | +44% | | gws-tasks | 48% | 97% | +49% | | gws-workflow-email-to-task | 56% | 91% | +35% | | gws-workflow-file-announce | 60% | 97% | +37% | | gws-workflow-meeting-prep | 53% | 91% | +38% | | gws-workflow-standup-report | 59% | 97% | +38% | | gws-workflow-weekly-digest | 59% | 97% | +38% | | gws-workflow | 36% | 97% | +61% | | persona-content-creator | 41% | 100% | +59% | | persona-customer-support | 53% | 100% | +47% | | persona-event-coordinator | 53% | 100% | +47% | | persona-exec-assistant | 53% | 100% | +47% | | persona-hr-coordinator | 46% | 100% | +54% | | persona-it-admin | 43% | 100% | +57% | | persona-project-manager | 49% | 100% | +51% | | persona-researcher | 46% | 81% | +35% | | persona-sales-ops | 43% | 100% | +57% | | persona-team-lead | 49% | 100% | +51% | | recipe-backup-sheet-as-csv | 60% | 97% | +37% | | recipe-batch-invite-to-event | 75% | 97% | +22% | | recipe-block-focus-time | 60% | 97% | +37% | | recipe-bulk-download-folder | 60% | 97% | +37% | | recipe-collect-form-responses | 60% | 97% | +37% | | recipe-compare-sheet-tabs | 53% | 88% | +35% | | recipe-copy-sheet-for-new-month | 64% | 97% | +33% | | recipe-create-classroom-course | 64% | 97% | +33% | | recipe-create-doc-from-template | 65% | 97% | +32% | | recipe-create-events-from-sheet | 70% | 91% | +21% | | recipe-create-expense-tracker | 60% | 97% | +37% | | recipe-create-feedback-form | 60% | 97% | +37% | | recipe-create-gmail-filter | 85% | 97% | +12% | | recipe-create-meet-space | 60% | 97% | +37% | | recipe-create-presentation | 53% | 94% | +41% | | recipe-create-shared-drive | 60% | 97% | +37% | | recipe-create-task-list | 60% | 97% | +37% | | recipe-create-vacation-responder | 75% | 97% | +22% | | recipe-draft-email-from-doc | 53% | 97% | +44% | | recipe-email-drive-link | 60% | 97% | +37% | | recipe-find-free-time | 73% | 97% | +24% | | recipe-find-large-files | 60% | 97% | +37% | | recipe-forward-labeled-emails | 65% | 97% | +32% | | recipe-generate-report-from-sheet | 60% | 97% | +37% | | recipe-label-and-archive-emails | 64% | 97% | +33% | | recipe-log-deal-update | 69% | 97% | +28% | | recipe-organize-drive-folder | 60% | 100% | +40% | | recipe-plan-weekly-schedule | 65% | 100% | +35% | | recipe-post-mortem-setup | 65% | 100% | +35% | | recipe-reschedule-meeting | 69% | 100% | +31% | | recipe-review-meet-participants | 64% | 100% | +36% | | recipe-review-overdue-tasks | 53% | 100% | +47% | | recipe-save-email-attachments | 78% | 100% | +22% | | recipe-save-email-to-doc | 60% | 100% | +40% | | recipe-schedule-recurring-event | 66% | 100% | +34% | | recipe-send-team-announcement | 60% | 100% | +40% | | recipe-share-doc-and-notify | 65% | 100% | +35% | | recipe-share-event-materials | 64% | 100% | +36% | | recipe-share-folder-with-team | 60% | 100% | +40% | | recipe-sync-contacts-to-sheet | 56% | 100% | +44% | | recipe-watch-drive-changes | 64% | 100% | +36% | <details> <summary>Changes made</summary> The improvements fall into a few consistent categories across all 88 skills: - **Expanded frontmatter descriptions** — Added specific trigger terms and "Use when" clauses so agents can match skills to user intent more reliably (e.g. "schedule a meeting", "gcal", "book time" for calendar skills) - **Concrete examples** — Added inline command examples, expected output formats, and example JSON payloads showing how to use each skill's API calls - **Validation checkpoints** — Added verification steps between multi-step workflows (e.g. confirm document was created before sharing it, validate event ID before inviting attendees) - **Error handling guidance** — Added troubleshooting sections for common failures (permission denied, invalid IDs, empty responses) with recovery actions - **Structured workflows** — Reorganised loosely described instructions into sequenced, numbered steps with clear inputs and outputs - **Reduced redundancy** — Consolidated repeated notes (e.g. duplicate emoji disclaimers in gws-chat) into single references </details> Honest disclosure — I work at @tesslio where we build tooling around skills like these. Not a pitch - just saw room for improvement and wanted to contribute. If you want to run reviews, evals and optimizations yourself, just `npm install @tessl/cli` then run `tessl skill review path/to/your/SKILL.md`, and click [here](https://tessl.io/registry/skills/submit) to find out more. Thanks in advance 🙏
|
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the documentation and usability of 88 Google Workspace skills by expanding descriptions, providing concrete examples, adding validation checkpoints, improving error handling, and structuring workflows. These improvements aim to make the skills more reliable and easier to use. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This is an impressive and comprehensive update that significantly improves the quality and usability of all 88 skills. The expanded descriptions, concrete examples, and addition of validation and error handling guidance are excellent contributions that will make these skills much more reliable and easier for users to adopt. I've identified a few areas where the command-line examples for the --params flag are inconsistent with the documented JSON format, which could cause the commands to fail. My review focuses on correcting these examples to ensure they are consistent and functional.
| gws calendar events list \ | ||
| --params calendarId=primary \ | ||
| --params timeMin=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ | ||
| --params orderBy=startTime \ | ||
| --params singleEvents=true \ | ||
| --params maxResults=10 |
There was a problem hiding this comment.
The use of multiple --params flags with key=value arguments is inconsistent with the documented JSON format for this flag in gws-shared/SKILL.md and other examples in this pull request (e.g., in gws-sheets/SKILL.md). Using a single --params flag with a JSON object is the documented and more robust approach. The dynamic date using $(date) can also be tricky with shell quoting. I suggest using a static date and a comment to guide the user, which makes the example clearer and more consistent.
| gws calendar events list \ | |
| --params calendarId=primary \ | |
| --params timeMin=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ | |
| --params orderBy=startTime \ | |
| --params singleEvents=true \ | |
| --params maxResults=10 | |
| gws calendar events list \ | |
| --params '{ | |
| "calendarId": "primary", | |
| "timeMin": "2024-01-01T00:00:00Z", | |
| "orderBy": "startTime", | |
| "singleEvents": true, | |
| "maxResults": 10 | |
| }' |
| --json '{"userId":"student1@school.edu"}' | ||
|
|
||
| # 4. Verify student enrollment succeeded | ||
| gws classroom courses students get --params 'courseId=xyz789&userId=student1@school.edu' |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a URL query string format (key1=value1&key2=value2), which is inconsistent with the documented JSON object format ('{"key1":"value1", "key2":"value2"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| gws classroom courses students get --params 'courseId=xyz789&userId=student1@school.edu' | |
| gws classroom courses students get --params '{"courseId": "xyz789", "userId": "student1@school.edu"}' |
|
|
||
| ```bash | ||
| gws forms forms get \ | ||
| --params 'formId=<formId-from-step-1>' |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a key=value string, which is inconsistent with the documented JSON object format ('{"key":"value"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| --params 'formId=<formId-from-step-1>' | |
| --params '{"formId": "<formId-from-step-1>"}' |
|
|
||
| ```bash | ||
| gws forms forms batchUpdate \ | ||
| --params 'formId=<formId-from-step-1>' \ |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a key=value string, which is inconsistent with the documented JSON object format ('{"key":"value"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| --params 'formId=<formId-from-step-1>' \ | |
| --params '{"formId": "<formId-from-step-1>"}' \ |
|
|
||
| ```bash | ||
| gws forms responses list \ | ||
| --params 'formId=<formId>' |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a key=value string, which is inconsistent with the documented JSON object format ('{"key":"value"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| --params 'formId=<formId>' | |
| --params '{"formId": "<formId>"}' |
|
|
||
| ```bash | ||
| gws people people get \ | ||
| --params 'resourceName=people/me&personFields=names,emailAddresses,phoneNumbers' |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a URL query string format (key1=value1&key2=value2), which is inconsistent with the documented JSON object format ('{"key1":"value1", "key2":"value2"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| --params 'resourceName=people/me&personFields=names,emailAddresses,phoneNumbers' | |
| --params '{"resourceName": "people/me", "personFields": "names,emailAddresses,phoneNumbers"}' |
| ### Get a presentation | ||
|
|
||
| ```bash | ||
| gws slides presentations get --params 'presentationId=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms' |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a key=value string, which is inconsistent with the documented JSON object format ('{"key":"value"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| gws slides presentations get --params 'presentationId=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms' | |
| gws slides presentations get --params '{"presentationId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms"}' |
|
|
||
| ```bash | ||
| gws slides presentations batchUpdate \ | ||
| --params 'presentationId=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms' \ |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a key=value string, which is inconsistent with the documented JSON object format ('{"key":"value"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| --params 'presentationId=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms' \ | |
| --params '{"presentationId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms"}' \ |
|
|
||
| > **Verification:** After a successful `batchUpdate`, confirm the changes took effect by fetching the presentation: | ||
| > ```bash | ||
| > gws slides presentations get --params 'presentationId=PRESENTATION_ID' |
There was a problem hiding this comment.
The format for the --params flag appears to be incorrect. This example uses a key=value string, which is inconsistent with the documented JSON object format ('{"key":"value"}') used in other skill examples. This will likely cause the command to fail. Please use the JSON format for consistency and correctness.
| > gws slides presentations get --params 'presentationId=PRESENTATION_ID' | |
| > gws slides presentations get --params '{"presentationId": "PRESENTATION_ID"}' |
| ```bash | ||
| #!/usr/bin/env bash | ||
| # sheet_data.tsv: tab-separated output from the sheets read command (one row per line) | ||
| while IFS=$'\t' read -r summary start duration attendees; do | ||
| # Skip rows missing required fields | ||
| if [[ -z "$summary" || -z "$start" ]]; then | ||
| echo "SKIPPED row: summary='$summary' start='$start'" | ||
| continue | ||
| fi | ||
|
|
||
| gws calendar +insert \ | ||
| --summary "$summary" \ | ||
| --start "$start" \ | ||
| --duration "$duration" \ | ||
| --attendees "$attendees" | ||
|
|
||
| echo "CREATED: $summary @ $start" | ||
| done < sheet_data.tsv | ||
| ``` |
There was a problem hiding this comment.
This shell script example appears to be broken. The gws sheets +read command in step 1 will produce JSON by default, but the while loop is attempting to read tab-separated values (IFS=$'\t'). Additionally, the script reads from a file sheet_data.tsv that is never created.
To fix this, the read command should specify --format csv and redirect its output to a file. The loop should then be updated to use a comma as a delimiter (IFS=',') and read from the created CSV file.
#!/usr/bin/env bash
# First, save the CSV output to a file
gws sheets +read --spreadsheet-id SHEET_ID --range 'Events!A2:D' --format csv > sheet_data.csv
# sheet_data.csv: comma-separated output from the sheets read command
while IFS=',' read -r summary start duration attendees; do
# Skip rows missing required fields
if [[ -z "$summary" || -z "$start" ]]; then
echo "SKIPPED row: summary='$summary' start='$start'"
continue
fi
gws calendar +insert \
--summary "$summary" \
--start "$start" \
--duration "$duration" \
--attendees "$attendees"
echo "CREATED: $summary @ $start"
done < sheet_data.csv|
skill files are autogenerated. needs to be fixed upstream. |
Hullo Google Friends... 👋
I ran all your skills through
tessl skill reviewat work and found some targeted improvements across all 88 skills. These are the top ten most improved:Here's the before/after for all of them:
Full list of improved skills
Changes made
The improvements fall into a few consistent categories across all 88 skills:
Honest disclosure — I work at @tesslio where we build tooling around skills like these. Not a pitch - just saw room for improvement and wanted to contribute.
If you want to run reviews, evals and optimizations yourself, just
npm install @tessl/clithen runtessl skill review path/to/your/SKILL.md, and click here to find out more.Thanks in advance 🙏
Checklist:
AGENTS.mdguidelines (no generatedgoogle-*crates).cargo fmt --allto format the code perfectly.cargo clippy -- -D warningsand resolved all warnings.pnpx changeset) to document my changes.