diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index 704d4bb2..7896c124 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -40,6 +40,30 @@ }, "category": "Productivity" }, + { + "name": "google-docs", + "source": { + "source": "local", + "path": "./plugins/google-docs" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Productivity" + }, + { + "name": "google-sheets", + "source": { + "source": "local", + "path": "./plugins/google-sheets" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Productivity" + }, { "name": "slack", "source": { @@ -2828,6 +2852,30 @@ "authentication": "ON_INSTALL" } }, + { + "name": "google-slides", + "source": { + "source": "local", + "path": "./plugins/google-slides" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Productivity" + }, + { + "name": "google-drive-old", + "source": { + "source": "local", + "path": "./plugins/google-drive-old" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Productivity" + }, { "name": "hubspot-legacy", "source": { diff --git a/plugins/google-docs/.app.json b/plugins/google-docs/.app.json new file mode 100644 index 00000000..92885b0e --- /dev/null +++ b/plugins/google-docs/.app.json @@ -0,0 +1,7 @@ +{ + "apps": { + "google-docs": { + "id": "connector_4964e3b22e3e427e9b4ae1acf2c1fa34" + } + } +} diff --git a/plugins/google-docs/.codex-plugin/plugin.json b/plugins/google-docs/.codex-plugin/plugin.json new file mode 100644 index 00000000..9bc14d44 --- /dev/null +++ b/plugins/google-docs/.codex-plugin/plugin.json @@ -0,0 +1,41 @@ +{ + "name": "google-docs", + "version": "0.1.0", + "description": "Work with Google Docs using the configured Google Docs app connector.", + "author": { + "name": "OpenAI", + "email": "support@openai.com", + "url": "https://openai.com/" + }, + "homepage": "https://workspace.google.com/products/docs/", + "repository": "https://github.com/openai/plugins", + "license": "MIT", + "keywords": [ + "google-docs", + "documents", + "google" + ], + "skills": "./skills/", + "apps": "./.app.json", + "interface": { + "displayName": "Google Docs", + "shortDescription": "Work with Google Docs", + "longDescription": "Use Google Docs to summarize documents, draft edits, and organize written work through the connected Google Docs app.", + "developerName": "OpenAI", + "category": "Productivity", + "capabilities": [ + "Interactive", + "Write" + ], + "websiteURL": "https://workspace.google.com/products/docs/", + "privacyPolicyURL": "https://policies.google.com/privacy", + "termsOfServiceURL": "https://policies.google.com/terms", + "defaultPrompt": [ + "Summarize document, draft revisions, or organize written" + ], + "brandColor": "#1A73E8", + "composerIcon": "./assets/google-docs-small.svg", + "logo": "./assets/google-docs.png", + "screenshots": [] + } +} diff --git a/plugins/google-docs/assets/google-docs-small.svg b/plugins/google-docs/assets/google-docs-small.svg new file mode 100644 index 00000000..76e52bb4 --- /dev/null +++ b/plugins/google-docs/assets/google-docs-small.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/plugins/google-docs/assets/google-docs.png b/plugins/google-docs/assets/google-docs.png new file mode 100644 index 00000000..578f383f Binary files /dev/null and b/plugins/google-docs/assets/google-docs.png differ diff --git a/plugins/google-docs/skills/google-docs/SKILL.md b/plugins/google-docs/skills/google-docs/SKILL.md new file mode 100644 index 00000000..f627be7f --- /dev/null +++ b/plugins/google-docs/skills/google-docs/SKILL.md @@ -0,0 +1,51 @@ +--- +name: google-docs +description: Summarize and revise connected Google Docs. Use when the user asks to inspect a doc, review structure, convert notes into prose, plan section-level revisions, or apply edits while preserving heading hierarchy. +--- + +# Google Docs + +## Overview + +Use this skill to turn document content into clear summaries, revision plans, and structured edits. Read the document first, preserve its organization, and distinguish between summarizing, rewriting, and directly editing content. + +## Preferred Deliverables + +- Document briefs that summarize purpose, structure, and missing or weak sections. +- Revision plans that show which headings or sections will change and why. +- Rewritten passages that preserve the surrounding structure and audience. + +## Workflow + +1. Read the document structure before writing. Capture the title, major headings, important sections, and any existing style or organization that should be preserved. +2. Decide whether the request is a summary, a targeted edit, or a broader rewrite. If the scope is unclear, summarize the current state before proposing changes. +3. For larger edits, present a revision plan before applying changes. Make the intended section-level updates easy to review. +4. Preserve the document's structure while drafting. Keep headings, section order, and existing intent unless the user asks for a reorganization. +5. If the user asks for a revision but not direct editing, default to a proposed rewrite or section-by-section plan. +6. Only apply major rewrites or destructive edits when the user has clearly requested them. + +## Write Safety + +- Preserve exact section names, links, dates, and structured content from the source document unless the user asks to change them. +- Treat long-form rewrites, deletions, and restructuring as explicit actions that should be clearly scoped. +- If a request could be satisfied with either comments, a revision plan, or direct edits, state which path you are taking. +- If the document has multiple sections with similar themes, identify the exact target section before editing. + +## Output Conventions + +- Reference headings or section names when summarizing or planning changes. +- Use concise revision plans for multi-section edits before presenting rewritten content. +- When presenting rewrites, label the affected section so the user can compare old and new structure easily. +- Keep rewritten text aligned with the existing audience and purpose unless the user asks to change tone or format. +- When summarizing, lead with the main purpose of the document and then list the most important sections or unresolved gaps. + +## Example Requests + +- "Summarize this project brief and tell me what is still missing before review." +- "Rewrite the executive summary so it is clearer and more concise." +- "Turn these bullet notes into polished prose in the existing document style." +- "Plan the edits needed to make the onboarding doc accurate for the new launch process." + +## Light Fallback + +If document content is missing, say that Google Docs access may be unavailable or pointed at the wrong document and ask the user to reconnect or clarify which document should be used. diff --git a/plugins/google-docs/skills/google-docs/agents/openai.yaml b/plugins/google-docs/skills/google-docs/agents/openai.yaml new file mode 100644 index 00000000..95b437ef --- /dev/null +++ b/plugins/google-docs/skills/google-docs/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Google Docs" + short_description: "Summarize docs and plan revisions" + icon_small: "./assets/google-docs-small.svg" + icon_large: "./assets/google-docs.png" + brand_color: "#1A73E8" + default_prompt: "Use $google-docs to summarize a document, outline revisions, or rewrite a section." diff --git a/plugins/google-docs/skills/google-docs/assets/google-docs-small.svg b/plugins/google-docs/skills/google-docs/assets/google-docs-small.svg new file mode 100644 index 00000000..ca9a8a12 --- /dev/null +++ b/plugins/google-docs/skills/google-docs/assets/google-docs-small.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/google-docs/skills/google-docs/assets/google-docs.svg b/plugins/google-docs/skills/google-docs/assets/google-docs.svg new file mode 100644 index 00000000..dbfb29b6 --- /dev/null +++ b/plugins/google-docs/skills/google-docs/assets/google-docs.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/plugins/google-drive-old/.app.json b/plugins/google-drive-old/.app.json new file mode 100644 index 00000000..46fc28a8 --- /dev/null +++ b/plugins/google-drive-old/.app.json @@ -0,0 +1,7 @@ +{ + "apps": { + "google-drive-old": { + "id": "connector_5f3c8c41a1e54ad7a76272c89e2554fa" + } + } +} diff --git a/plugins/google-drive-old/.codex-plugin/plugin.json b/plugins/google-drive-old/.codex-plugin/plugin.json new file mode 100644 index 00000000..b0c16a8b --- /dev/null +++ b/plugins/google-drive-old/.codex-plugin/plugin.json @@ -0,0 +1,28 @@ +{ + "name": "google-drive-old", + "description": "Search and reference files from your Drive.", + "author": { + "name": "OpenAI", + "url": "https://www.google.com/" + }, + "homepage": "https://www.google.com/", + "repository": "https://github.com/openai/plugins", + "license": "MIT", + "keywords": [], + "apps": "./.app.json", + "interface": { + "displayName": "Google Drive old", + "shortDescription": "Search and reference files from your Drive.", + "developerName": "OpenAI", + "category": "Productivity", + "capabilities": [], + "websiteURL": "https://www.google.com/", + "privacyPolicyURL": "https://policies.google.com/privacy", + "defaultPrompt": [ + "Find a Drive doc and summarize the key points" + ], + "composerIcon": "./assets/app-icon.png", + "logo": "./assets/app-icon.png", + "screenshots": [] + } +} diff --git a/plugins/google-drive-old/assets/app-icon.png b/plugins/google-drive-old/assets/app-icon.png new file mode 100644 index 00000000..99c56f66 Binary files /dev/null and b/plugins/google-drive-old/assets/app-icon.png differ diff --git a/plugins/google-sheets/.app.json b/plugins/google-sheets/.app.json new file mode 100644 index 00000000..68f525ed --- /dev/null +++ b/plugins/google-sheets/.app.json @@ -0,0 +1,7 @@ +{ + "apps": { + "google-sheets": { + "id": "connector_9d7cfa34e6654a5f98d3387af34b2e1c" + } + } +} diff --git a/plugins/google-sheets/.codex-plugin/plugin.json b/plugins/google-sheets/.codex-plugin/plugin.json new file mode 100644 index 00000000..06e91f9a --- /dev/null +++ b/plugins/google-sheets/.codex-plugin/plugin.json @@ -0,0 +1,41 @@ +{ + "name": "google-sheets", + "version": "0.1.0", + "description": "Work with Google Sheets using the configured Google Sheets app connector.", + "author": { + "name": "OpenAI", + "email": "support@openai.com", + "url": "https://openai.com/" + }, + "homepage": "https://workspace.google.com/products/sheets/", + "repository": "https://github.com/openai/plugins", + "license": "MIT", + "keywords": [ + "google-sheets", + "spreadsheets", + "google" + ], + "skills": "./skills/", + "apps": "./.app.json", + "interface": { + "displayName": "Google Sheets", + "shortDescription": "Analyze Google Sheets", + "longDescription": "Use Google Sheets to inspect spreadsheet data, draft formulas, and organize tabular work through the connected Google Sheets app.", + "developerName": "OpenAI", + "category": "Productivity", + "capabilities": [ + "Interactive", + "Write" + ], + "websiteURL": "https://workspace.google.com/products/sheets/", + "privacyPolicyURL": "https://policies.google.com/privacy", + "termsOfServiceURL": "https://policies.google.com/terms", + "defaultPrompt": [ + "Analyze spreadsheet data, suggest formulas, or update" + ], + "brandColor": "#0F9D58", + "composerIcon": "./assets/google-sheets-small.svg", + "logo": "./assets/google-sheets.png", + "screenshots": [] + } +} diff --git a/plugins/google-sheets/assets/google-sheets-small.svg b/plugins/google-sheets/assets/google-sheets-small.svg new file mode 100644 index 00000000..0e34eb18 --- /dev/null +++ b/plugins/google-sheets/assets/google-sheets-small.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/plugins/google-sheets/assets/google-sheets.png b/plugins/google-sheets/assets/google-sheets.png new file mode 100644 index 00000000..e0f4fd08 Binary files /dev/null and b/plugins/google-sheets/assets/google-sheets.png differ diff --git a/plugins/google-sheets/skills/google-sheets-chart-builder/SKILL.md b/plugins/google-sheets/skills/google-sheets-chart-builder/SKILL.md new file mode 100644 index 00000000..96129950 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets-chart-builder/SKILL.md @@ -0,0 +1,28 @@ +--- +name: google-sheets-chart-builder +description: Design, create, and revise Google Sheets charts with better chart-spec recall and editing discipline. Use when the user wants to add a chart to a sheet, choose the right chart type for existing data, repair a broken chart, update a chart's data series, or reposition or resize a chart after creating it. +--- + +# Google Sheets Chart Builder + +Use this skill when the chart itself is the task. + +Read `./references/chart-recipes.md` before the first chart write. The point is to refresh chart request shapes and a few non-obvious API constraints before building or editing. + +## Workflow + +1. Ground the chart in the live sheet first: exact source tab, domain column, series columns, headers, and whether the data is contiguous. +2. Choose the simplest chart type that matches the table shape and user intent. +3. Draft one chart spec first, using a clean anchor position that will not collide with existing content. +4. If the chart needs revision, update the chart spec deliberately rather than trying to patch a tiny nested fragment from memory. +5. Treat chart content changes and chart position changes as separate operations. + +## Output Conventions + +- Name the source sheet and the exact domain and series ranges. +- State the chosen chart type and why it fits the data. +- For edits, state whether you are changing the chart spec, the chart position, or both. + +## References + +- For chart-type heuristics, request-shape reminders, and official Google Sheets docs links, read `./references/chart-recipes.md`. diff --git a/plugins/google-sheets/skills/google-sheets-chart-builder/agents/openai.yaml b/plugins/google-sheets/skills/google-sheets-chart-builder/agents/openai.yaml new file mode 100644 index 00000000..f0e352ef --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets-chart-builder/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Google Sheets Chart Builder" + short_description: "Build and revise charts with better spec recall" + default_prompt: "Use $google-sheets-chart-builder to create or repair a Google Sheets chart, choose a sensible chart type, and use the right chart request shapes." diff --git a/plugins/google-sheets/skills/google-sheets-chart-builder/references/chart-recipes.md b/plugins/google-sheets/skills/google-sheets-chart-builder/references/chart-recipes.md new file mode 100644 index 00000000..0606cc20 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets-chart-builder/references/chart-recipes.md @@ -0,0 +1,425 @@ +# Chart Recipes + +Use this file as a chart-spec refresher, not a full charting manual. + +## High-Value API Reminders + +- Official chart samples: https://developers.google.com/workspace/sheets/api/samples/charts +- Official chart spec reference: https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/charts +- Official request reference: https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/request + +- Create charts with `addChart`. +- Edit chart content with `updateChartSpec`. +- Move or resize charts with `updateEmbeddedObjectPosition`. +- Delete charts with `deleteEmbeddedObject`. +- Google documents that `updateChartSpec` replaces the chart `spec`; it is not a tiny partial edit surface. +- Google also notes that the API does not expose full control over every chart setting, and some unsupported settings can reset to defaults when edited through the API. + +## Chart Choice Heuristics + +- Use a column or bar chart for discrete category comparisons. +- Use a line chart for trends over an ordered domain, especially time. +- Use a pie chart only for a small number of parts-of-whole values. +- Start with a basic chart unless the user explicitly wants a more specialized chart family. + +## Styling Defaults + +- Always set a meaningful title, and add a subtitle only when it clarifies units, timeframe, or source. +- Prefer one accent color plus muted supporting series instead of the default rainbow palette. +- Use `legendPosition` intentionally. If the series names are obvious or there is only one series, prefer a cleaner layout over a large legend. +- Use data labels only when the chart is sparse enough that labels improve readability instead of adding clutter. +- Avoid 3D styling by default, even when the chart type supports it. +- Give the chart enough size and whitespace to breathe. Clean placement and reasonable dimensions do a lot of the styling work. +- For line charts, use smoothing and point styling only when they improve readability rather than decoration. +- Keep axis titles concise and use them when the metric or unit is not obvious from context. + +## Styling Syntax Reminders + +These are the main styling knobs worth remembering: + +- Chart-level text and defaults live on `ChartSpec`, including `title`, `subtitle`, `titleTextFormat`, `subtitleTextFormat`, `fontName`, `backgroundColorStyle`, and `maximized`. +- Basic chart styling lives mostly on `BasicChartSpec`, including `legendPosition`, `axis[].title`, `lineSmoothing`, and `threeDimensional`. +- Series-level styling lives on `BasicChartSeries`, including `dataLabel`, `colorStyle`, and `pointStyle`. +- Prefer `colorStyle` over deprecated `color` fields when both exist. +- Pie charts have their own styling surface, especially `legendPosition`, `threeDimensional`, and `pieHole`. + +Example chart-level styling: + +```json +{ + "title": "Weekly Active Users", + "subtitle": "Last 12 weeks", + "fontName": "Google Sans", + "titleTextFormat": { + "fontSize": 18, + "bold": true + }, + "subtitleTextFormat": { + "fontSize": 11, + "foregroundColorStyle": { + "rgbColor": { + "red": 0.4, + "green": 0.4, + "blue": 0.4 + } + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } +} +``` + +Example basic-chart styling: + +```json +{ + "basicChart": { + "legendPosition": "BOTTOM_LEGEND", + "lineSmoothing": true, + "axis": [ + { + "position": "BOTTOM_AXIS", + "title": "Week" + }, + { + "position": "LEFT_AXIS", + "title": "WAU" + } + ], + "series": [ + { + "colorStyle": { + "rgbColor": { + "red": 0.1, + "green": 0.45, + "blue": 0.9 + } + }, + "dataLabel": { + "type": "DATA" + }, + "pointStyle": { + "shape": "CIRCLE", + "size": 5 + } + } + ] + } +} +``` + +## Source Range Reminders + +- Google documents that chart data comes from a `ChartSourceRange`, whose `sources` are `GridRange` objects. +- For a chart domain or series, exactly one dimension must have length 1. +- If using multiple non-adjacent ranges, Google requires them to stay aligned across domain and series. +- Google documents that if `headerCount` is not set, Sheets may guess the number of header rows. +- Existing chart IDs can be retrieved via `spreadsheets.get` with `fields=sheets(charts)`. + +## Minimal Column Chart Shape + +Use this when you have one category column and one or more numeric series. + +```json +[ + { + "addChart": { + "chart": { + "spec": { + "title": "Monthly Sales", + "basicChart": { + "chartType": "COLUMN", + "legendPosition": "BOTTOM_LEGEND", + "axis": [ + { + "position": "BOTTOM_AXIS", + "title": "Model" + }, + { + "position": "LEFT_AXIS", + "title": "Sales" + } + ], + "domains": [ + { + "domain": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 7, + "startColumnIndex": 0, + "endColumnIndex": 1 + } + ] + } + } + } + ], + "series": [ + { + "series": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 7, + "startColumnIndex": 1, + "endColumnIndex": 2 + } + ] + } + }, + "targetAxis": "LEFT_AXIS" + } + ], + "headerCount": 1 + } + }, + "position": { + "overlayPosition": { + "anchorCell": { + "sheetId": 123456789, + "rowIndex": 0, + "columnIndex": 6 + }, + "offsetXPixels": 0, + "offsetYPixels": 0, + "widthPixels": 720, + "heightPixels": 440 + } + } + } + } + } +] +``` + +## Minimal Line Chart Shape + +Use this for trends over dates or other ordered domains. + +```json +[ + { + "addChart": { + "chart": { + "spec": { + "title": "Weekly Active Users", + "basicChart": { + "chartType": "LINE", + "legendPosition": "BOTTOM_LEGEND", + "domains": [ + { + "domain": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 13, + "startColumnIndex": 0, + "endColumnIndex": 1 + } + ] + } + } + } + ], + "series": [ + { + "series": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 13, + "startColumnIndex": 1, + "endColumnIndex": 2 + } + ] + } + }, + "targetAxis": "LEFT_AXIS" + } + ], + "headerCount": 1 + } + }, + "position": { + "overlayPosition": { + "anchorCell": { + "sheetId": 123456789, + "rowIndex": 0, + "columnIndex": 5 + } + } + } + } + } + } +] +``` + +## Minimal Pie Chart Shape + +Use this only for a small categorical breakdown. + +```json +[ + { + "addChart": { + "chart": { + "spec": { + "title": "Channel Mix", + "pieChart": { + "legendPosition": "RIGHT_LEGEND", + "domain": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 6, + "startColumnIndex": 0, + "endColumnIndex": 1 + } + ] + } + }, + "series": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 6, + "startColumnIndex": 1, + "endColumnIndex": 2 + } + ] + } + }, + "threeDimensional": false + } + }, + "position": { + "overlayPosition": { + "anchorCell": { + "sheetId": 123456789, + "rowIndex": 0, + "columnIndex": 4 + } + } + } + } + } + } +] +``` + +## Update Chart Content + +Use `updateChartSpec` when the chart type, data ranges, title, legend, or axis config should change. + +```json +[ + { + "updateChartSpec": { + "chartId": 9001, + "spec": { + "title": "Weekly Active Users", + "basicChart": { + "chartType": "LINE", + "legendPosition": "BOTTOM_LEGEND", + "domains": [ + { + "domain": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 13, + "startColumnIndex": 0, + "endColumnIndex": 1 + } + ] + } + } + } + ], + "series": [ + { + "series": { + "sourceRange": { + "sources": [ + { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 13, + "startColumnIndex": 1, + "endColumnIndex": 2 + } + ] + } + }, + "targetAxis": "LEFT_AXIS" + } + ], + "headerCount": 1 + } + } + } + } +] +``` + +## Move Or Resize A Chart + +Use `updateEmbeddedObjectPosition` separately from chart-spec edits. + +```json +[ + { + "updateEmbeddedObjectPosition": { + "objectId": 9001, + "newPosition": { + "overlayPosition": { + "anchorCell": { + "rowIndex": 4, + "columnIndex": 6 + }, + "offsetXPixels": 40, + "widthPixels": 840, + "heightPixels": 520 + } + }, + "fields": "anchorCell(rowIndex,columnIndex),offsetXPixels,widthPixels,heightPixels" + } + } +] +``` + +## Common Failure Modes + +- Picking a chart type before inspecting the table shape +- Wiring the wrong domain column or mismatching domain and series lengths +- Forgetting `headerCount` and then getting surprising inferred labels +- Treating `updateChartSpec` like a tiny patch instead of a full spec replacement +- Mixing chart-spec rewrites and layout moves into one confusing edit step + +## Official References + +- Chart samples: https://developers.google.com/workspace/sheets/api/samples/charts +- Charts reference: https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/charts +- Requests reference: https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/request +- Batch update guide: https://developers.google.com/workspace/sheets/api/guides/batchupdate diff --git a/plugins/google-sheets/skills/google-sheets-formula-builder/SKILL.md b/plugins/google-sheets/skills/google-sheets-formula-builder/SKILL.md new file mode 100644 index 00000000..bf0d0432 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets-formula-builder/SKILL.md @@ -0,0 +1,33 @@ +--- +name: google-sheets-formula-builder +description: Design, repair, and roll out Google Sheets formulas with better syntax recall and validation discipline. Use when the user wants to add a formula column, fix a broken formula, choose between a row formula and a spill formula, build a lookup or filter formula, or turn repeated logic into a reusable named function. +--- + +# Google Sheets Formula Builder + +Use this skill when the formula itself is the task. + +Read `./references/formula-patterns.md` before drafting the first formula. The point is not to relearn Sheets from scratch. It is to refresh exact syntax and a few high-value function constraints before writing. + +## Workflow + +1. Ground the formula in the live sheet first: exact input columns, target output cell or column, and a few representative rows. +2. Choose the formula shape deliberately: + - row formula when the logic is local to one row and should copy down + - spill formula when one formula should populate a whole output range + - lookup formula when the task is key-to-value retrieval + - filter/query formula when the task is to derive a subset or summary table + - named function only when the same logic is conceptually reusable +3. Draft the formula in one helper cell or a scratch location first. +4. Test on a small representative slice, including likely edge cases. +5. Iterate until the sample output is correct, then roll the formula out to the intended target range. + +## Output Conventions + +- Name the exact target cell or output column. +- Return the final formula exactly as it should be entered. +- If rollout matters, say whether the formula should be filled down, spilled from one anchor cell, or turned into a named function. + +## References + +- For syntax reminders, formula-shape heuristics, and official Google Sheets docs links, read `./references/formula-patterns.md`. diff --git a/plugins/google-sheets/skills/google-sheets-formula-builder/agents/openai.yaml b/plugins/google-sheets/skills/google-sheets-formula-builder/agents/openai.yaml new file mode 100644 index 00000000..2fd28291 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets-formula-builder/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Google Sheets Formula Builder" + short_description: "Design and validate formulas before rolling them out" + default_prompt: "Use $google-sheets-formula-builder to design or repair a Google Sheets formula, validate it on a few representative rows, and then roll it out cleanly." diff --git a/plugins/google-sheets/skills/google-sheets-formula-builder/references/formula-patterns.md b/plugins/google-sheets/skills/google-sheets-formula-builder/references/formula-patterns.md new file mode 100644 index 00000000..93c960e6 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets-formula-builder/references/formula-patterns.md @@ -0,0 +1,102 @@ +# Formula Patterns + +Use this file as a syntax refresher, not a full formulas manual. + +## Formula Shape Heuristics + +- Use a row formula when the logic is evaluated row-by-row and should be copied down. +- Use a spill formula when one anchor cell should populate the whole output region. +- Prefer `XLOOKUP` for straightforward exact lookups when available. +- If using `VLOOKUP`, explicitly pass `FALSE` for exact match behavior. +- Use `FILTER` when the output should be the original rows or columns that satisfy conditions. +- Use a named function when the same formula pattern should be reused semantically, not just copied. +- Use `MAP` with `LAMBDA` when you need per-item transformation logic that would be awkward as a plain spill formula. + +## High-Value Syntax Reminders + +### ARRAYFORMULA + +- Official doc: https://support.google.com/docs/answer/3093275?hl=en +- Google notes that many array formulas automatically expand into neighboring cells, so explicit `ARRAYFORMULA` is not always required. +- Good when one anchor formula should fill an output column. + +Example: + +```gs +=ARRAYFORMULA(IF(A2:A="", "", IF(E2:E>=90, "On track", "At risk"))) +``` + +### FILTER + +- Official doc: https://support.google.com/docs/answer/3093197?hl=en +- Conditions must match the length of the filtered range. +- Google notes that you cannot mix row conditions and column conditions in the same `FILTER`. +- If no values satisfy the conditions, Google returns `#N/A`. + +Example: + +```gs +=FILTER(A2:D, D2:D="Open", A2:A<>"") +``` + +### XLOOKUP + +- Official doc: https://support.google.com/docs/answer/12405947?hl=en +- `lookup_range` must be a single row or column. +- `result_range` should have the same row or column size as the lookup range. +- Use `missing_value` when you want a cleaner fallback than raw `#N/A`. + +Example: + +```gs +=XLOOKUP(A2, Lookup!A:A, Lookup!D:D, "") +``` + +### VLOOKUP + +- Official doc: https://support.google.com/docs/answer/3093318?hl=en +- Google strongly recommends using `FALSE` for `is_sorted` for more predictable exact-match behavior. +- The search key must be in the first column of the lookup range. +- If you need a friendlier fallback, wrap with `IFNA` or `IFERROR`. + +Example: + +```gs +=IFNA(VLOOKUP(A2, Lookup!A:D, 4, FALSE), "") +``` + +### MAP + +- Official doc: https://support.google.com/docs/answer/12568985?hl=en +- The `LAMBDA` must accept exactly as many names as the number of input arrays. +- Each mapped value must resolve to a single value, not another array. +- Useful for per-item transformations that are more expressive than a plain copied formula. + +Example: + +```gs +=MAP(A2:A, LAMBDA(item, JOIN("-", SPLIT(item, ",")))) +``` + +### Named Functions + +- Official doc: https://support.google.com/docs/answer/12504534?hl=en +- Named functions are appropriate when the formula pattern should be reused conceptually across a sheet or across files. +- Google requires placeholder names rather than A1-style references for function arguments. + +## Practical Rollout Pattern + +1. Draft in one helper cell or scratch column. +2. Test on representative rows, including blanks, missing lookups, and unusual values. +3. Decide whether the final rollout should be copy-down, spill-from-anchor, or named-function-based. +4. Only then replace the target formula region. + +## Official References + +- Google Sheets function list: https://support.google.com/docs/table/25273?hl=en +- ARRAYFORMULA: https://support.google.com/docs/answer/3093275?hl=en +- FILTER: https://support.google.com/docs/answer/3093197?hl=en +- XLOOKUP: https://support.google.com/docs/answer/12405947?hl=en +- VLOOKUP: https://support.google.com/docs/answer/3093318?hl=en +- MAP: https://support.google.com/docs/answer/12568985?hl=en +- Named functions: https://support.google.com/docs/answer/12504534?hl=en diff --git a/plugins/google-sheets/skills/google-sheets/SKILL.md b/plugins/google-sheets/skills/google-sheets/SKILL.md new file mode 100644 index 00000000..ed053ed4 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets/SKILL.md @@ -0,0 +1,26 @@ +--- +name: google-sheets +description: Analyze and edit connected Google Sheets with range precision. Use when the user wants to find a spreadsheet, inspect tabs or ranges, search rows, plan formulas, clean or restructure tables, write concise summaries, or make explicit cell-range updates. +--- + +# Google Sheets + +Use this skill to keep spreadsheet work grounded in the exact spreadsheet, sheet, range, headers, and formulas that matter. + +## Workflow + +1. If the spreadsheet or tab is not already grounded, identify it first and read metadata before deeper reads or writes. +2. Prefer narrow reads and row search over dumping large tabs into context. +3. Ground the task in exact sheet, range, header, and formula context before proposing changes. +4. Before the first write-heavy `batch_update`, read `./references/batch-update-recipes.md` for request-shape recall. +5. Cluster logically related edits into one `batch_update` so the batch is coherent and atomic. Avoid both mega-batches and one-request micro-batches. +6. If the user asks to clean, normalize, or restructure data, summarize the intended table shape before writing. + +## Output Conventions + +- Always reference the spreadsheet, sheet name, and range when describing findings or planned edits. +- For `batch_update` work, use a compact table or list with the request type, target range or sheet, proposed change, and reason. + +## References + +- For raw Sheets write shapes and example `batch_update` bodies, read `./references/batch-update-recipes.md`. diff --git a/plugins/google-sheets/skills/google-sheets/agents/openai.yaml b/plugins/google-sheets/skills/google-sheets/agents/openai.yaml new file mode 100644 index 00000000..4aefb684 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Google Sheets" + short_description: "Find sheets, inspect ranges, and plan batch updates" + icon_small: "./assets/google-sheets-small.svg" + icon_large: "./assets/google-sheets.png" + brand_color: "#0F9D58" + default_prompt: "Use $google-sheets to find the right spreadsheet, inspect a range, search rows, or plan an exact batch_update." diff --git a/plugins/google-sheets/skills/google-sheets/assets/google-sheets-small.svg b/plugins/google-sheets/skills/google-sheets/assets/google-sheets-small.svg new file mode 100644 index 00000000..50da7315 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets/assets/google-sheets-small.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/plugins/google-sheets/skills/google-sheets/assets/google-sheets.svg b/plugins/google-sheets/skills/google-sheets/assets/google-sheets.svg new file mode 100644 index 00000000..73dc0bed --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets/assets/google-sheets.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/plugins/google-sheets/skills/google-sheets/references/batch-update-recipes.md b/plugins/google-sheets/skills/google-sheets/references/batch-update-recipes.md new file mode 100644 index 00000000..48d13132 --- /dev/null +++ b/plugins/google-sheets/skills/google-sheets/references/batch-update-recipes.md @@ -0,0 +1,291 @@ +# Batch Update Recipes + +Use these patterns as copy-and-fill templates. The goal is request-shape recall, not a second copy of the Sheets docs. + +## Rules + +- Each request object must set exactly one request type key. +- Use exact Google field names and structured objects instead of stringified JSON. +- Prefer `sheetId` from `get_spreadsheet_metadata` when building `GridRange`, `GridCoordinate`, or `DimensionRange`. +- For `GridRange`, row and column indexes are zero-based, start-inclusive, and end-exclusive. +- For update-style requests, set a precise `fields` mask. Do not include the root object name in the mask. +- Keep batches logically clustered. Group edits that should succeed or fail together, but do not mix unrelated table rewrites, formatting passes, and structure changes into one mega-batch. + +## Coordinate Templates + +Use these shapes repeatedly: + +```json +{ + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 10, + "startColumnIndex": 0, + "endColumnIndex": 4 +} +``` + +`GridRange` for rectangular regions. + +```json +{ + "sheetId": 123456789, + "rowIndex": 0, + "columnIndex": 0 +} +``` + +`GridCoordinate` for a single starting cell. + +```json +{ + "sheetId": 123456789, + "dimension": "ROWS", + "startIndex": 1, + "endIndex": 4 +} +``` + +`DimensionRange` for whole rows or columns. + +## High-Signal Request Families + +Reach for these first: + +- Content and formulas: `updateCells`, `appendCells`, `repeatCell`, `copyPaste`, `autoFill` +- Row and column layout: `insertDimension`, `deleteDimension`, `moveDimension`, `updateDimensionProperties`, `autoResizeDimensions` +- Table operations: `sortRange`, `setBasicFilter`, `clearBasicFilter`, `deleteDuplicates`, `trimWhitespace` +- Validation and protection: `setDataValidation`, `addProtectedRange`, `updateProtectedRange`, `deleteProtectedRange` +- Sheet structure: `addSheet`, `deleteSheet`, `duplicateSheet`, `updateSheetProperties` + +For the full request catalog, use the official reference linked below. + +## Write A Fixed Block Of Values Or Formulas + +Use `updateCells` for a known rectangle. This is the most common raw write recipe. + +```json +[ + { + "updateCells": { + "range": { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 2, + "startColumnIndex": 0, + "endColumnIndex": 2 + }, + "rows": [ + { + "values": [ + { "userEnteredValue": { "stringValue": "Owner" } }, + { "userEnteredValue": { "stringValue": "Status" } } + ] + }, + { + "values": [ + { "userEnteredValue": { "stringValue": "Alex" } }, + { "userEnteredValue": { "formulaValue": "=IF(B1=\"\",\"Missing\",\"Ready\")" } } + ] + } + ], + "fields": "userEnteredValue" + } + } +] +``` + +## Format A Header Row And Freeze It + +Use `repeatCell` for shared formatting across a range, then `updateSheetProperties` for sheet-level behavior. + +```json +[ + { + "repeatCell": { + "range": { + "sheetId": 123456789, + "startRowIndex": 0, + "endRowIndex": 1 + }, + "cell": { + "userEnteredFormat": { + "backgroundColorStyle": { + "rgbColor": { + "red": 0.12, + "green": 0.47, + "blue": 0.71 + } + }, + "textFormat": { + "bold": true, + "foregroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + }, + "fields": "userEnteredFormat(backgroundColorStyle,textFormat)" + } + }, + { + "updateSheetProperties": { + "properties": { + "sheetId": 123456789, + "gridProperties": { + "frozenRowCount": 1 + } + }, + "fields": "gridProperties.frozenRowCount" + } + } +] +``` + +## Append New Rows + +Use `appendCells` when the user wants to add new rows after the existing data. + +```json +[ + { + "appendCells": { + "sheetId": 123456789, + "rows": [ + { + "values": [ + { "userEnteredValue": { "stringValue": "2026-03-13" } }, + { "userEnteredValue": { "numberValue": 42 } }, + { "userEnteredValue": { "stringValue": "complete" } } + ] + } + ], + "fields": "userEnteredValue" + } + } +] +``` + +## Resize Or Delete Rows Or Columns + +Use `updateDimensionProperties` for size changes and `deleteDimension` for destructive row or column removal. + +```json +[ + { + "updateDimensionProperties": { + "range": { + "sheetId": 123456789, + "dimension": "COLUMNS", + "startIndex": 0, + "endIndex": 3 + }, + "properties": { + "pixelSize": 180 + }, + "fields": "pixelSize" + } + }, + { + "deleteDimension": { + "range": { + "sheetId": 123456789, + "dimension": "ROWS", + "startIndex": 10, + "endIndex": 12 + } + } + } +] +``` + +## Sort A Table And Turn On A Basic Filter + +Use this for spreadsheet workflows that should behave like a table view instead of manual row shuffling. + +```json +[ + { + "sortRange": { + "range": { + "sheetId": 123456789, + "startRowIndex": 1, + "startColumnIndex": 0, + "endColumnIndex": 5 + }, + "sortSpecs": [ + { + "dimensionIndex": 2, + "sortOrder": "ASCENDING" + } + ] + } + }, + { + "setBasicFilter": { + "filter": { + "range": { + "sheetId": 123456789, + "startRowIndex": 0, + "startColumnIndex": 0, + "endColumnIndex": 5 + } + } + } + } +] +``` + +## Add Dropdown Validation + +Use `setDataValidation` for restricted inputs, including status dropdowns. + +```json +[ + { + "setDataValidation": { + "range": { + "sheetId": 123456789, + "startRowIndex": 1, + "endRowIndex": 200, + "startColumnIndex": 3, + "endColumnIndex": 4 + }, + "rule": { + "condition": { + "type": "ONE_OF_LIST", + "values": [ + { "userEnteredValue": "todo" }, + { "userEnteredValue": "in_progress" }, + { "userEnteredValue": "done" } + ] + }, + "strict": true, + "showCustomUi": true + } + } + } +] +``` + +## Common Failure Modes + +- Confusing `spreadsheets.batchUpdate` with `spreadsheets.values.batchUpdate` +- Stringifying the `requests` array instead of sending structured objects +- Using A1 notation where the request expects `GridRange` or `DimensionRange` +- Forgetting that indexes are zero-based and end-exclusive +- Omitting `fields` on update-style requests +- Mixing too many unrelated operations into one batch + +## Official References + +- Request catalog: https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/request +- Sheets API samples index: https://developers.google.com/workspace/sheets/api/samples +- Basic writing samples: https://developers.google.com/workspace/sheets/api/samples/writing +- Basic formatting samples: https://developers.google.com/workspace/sheets/api/samples/formatting +- Row and column samples: https://developers.google.com/workspace/sheets/api/samples/rowcolumn +- Sheet operations samples: https://developers.google.com/workspace/sheets/api/samples/sheet diff --git a/plugins/google-slides/.app.json b/plugins/google-slides/.app.json new file mode 100644 index 00000000..349847f4 --- /dev/null +++ b/plugins/google-slides/.app.json @@ -0,0 +1,7 @@ +{ + "apps": { + "google-slides": { + "id": "connector_6f1ec045b8fa4ced8738e32c7f74514b" + } + } +} diff --git a/plugins/google-slides/.codex-plugin/plugin.json b/plugins/google-slides/.codex-plugin/plugin.json new file mode 100644 index 00000000..c8e313bb --- /dev/null +++ b/plugins/google-slides/.codex-plugin/plugin.json @@ -0,0 +1,45 @@ +{ + "name": "google-slides", + "version": "0.1.0", + "description": "Work with Google Slides decks and import presentation files using the configured Google Slides app connector.", + "author": { + "name": "OpenAI", + "email": "support@openai.com", + "url": "https://openai.com/" + }, + "homepage": "https://workspace.google.com/products/slides/", + "repository": "https://github.com/openai/plugins", + "license": "MIT", + "keywords": [ + "google-slides", + "pptx", + "presentation-import", + "presentations", + "template-migration", + "visual-iteration", + "productivity" + ], + "skills": "./skills/", + "apps": "./.app.json", + "interface": { + "displayName": "Google Slides", + "shortDescription": "Inspect and edit Google Slides decks", + "longDescription": "Use Google Slides to import presentation files, inspect deck structure, polish slide layouts, repair repeated template issues, and migrate deck content onto a company template through the connected Google Slides app.", + "developerName": "OpenAI", + "category": "Productivity", + "capabilities": [ + "Interactive", + "Write" + ], + "websiteURL": "https://workspace.google.com/products/slides/", + "privacyPolicyURL": "https://policies.google.com/privacy", + "termsOfServiceURL": "https://policies.google.com/terms", + "defaultPrompt": [ + "Inspect a deck and clean up slide layouts" + ], + "brandColor": "#F9AB00", + "composerIcon": "./assets/app-icon.png", + "logo": "./assets/app-icon.png", + "screenshots": [] + } +} diff --git a/plugins/google-slides/assets/app-icon.png b/plugins/google-slides/assets/app-icon.png new file mode 100644 index 00000000..ef4ef4e6 Binary files /dev/null and b/plugins/google-slides/assets/app-icon.png differ diff --git a/plugins/google-slides/skills/google-slides-import-presentation/SKILL.md b/plugins/google-slides/skills/google-slides-import-presentation/SKILL.md new file mode 100644 index 00000000..57bedd0d --- /dev/null +++ b/plugins/google-slides/skills/google-slides-import-presentation/SKILL.md @@ -0,0 +1,66 @@ +--- +name: google-slides-import-presentation +description: Import a local `.ppt`, `.pptx`, or `.odp` file into Google Slides, verify the resulting native deck, and hand it off to the right follow-on workflow. Use when the user wants to convert a presentation file into a native Google Slides deck before follow-on work. +--- + +# Google Slides Import Presentation + +## Overview + +Use this skill when the source material is a presentation file rather than an existing Google Slides deck. The goal is to create a native Google Slides copy first, then continue work on the imported deck. + +## Required Tooling + +Confirm the runtime exposes: +- `import_presentation` +- `get_presentation` or `get_presentation_text` +- `get_slide_thumbnail` when visual verification matters + +If `import_presentation` is unavailable, stop and say the file cannot be converted into native Google Slides from Codex. + +## Workflow + +1. Confirm the input file. +- Accept `.ppt`, `.pptx`, or `.odp`. +- Use the uploaded file path directly when available. + +2. Import the presentation. +- Use `import_presentation` to create a new native Google Slides deck. +- If the user gives a destination title, use it. Otherwise keep the imported title. + +3. Read the imported deck. +- Capture the resulting presentation ID or URL, slide count, and major slide titles. +- Treat the imported deck as the new source of truth for follow-on work. + +4. Verify enough to hand it off safely. +- Compare the imported slide count to the source file when that information is available. +- Use thumbnails for spot checks when layout fidelity matters or the user plans formatting cleanup next. + +5. Hand off to the right next skill. +- Use [google-slides](../google-slides/SKILL.md) for general summaries or edits. +- Use [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md) for post-import slide formatting cleanup. +- Use [google-slides-template-migration](../google-slides-template-migration/SKILL.md) when the imported deck should move onto a branded template. + +## Rules + +- Treat import as conversion into a new native Google Slides deck, not in-place editing of the original file. +- Preserve source slide order and content by default. +- Do not promise perfect fidelity for animations, transitions, SmartArt, or other Office-specific features. +- If import introduces layout drift, fix it in the native Google Slides deck rather than editing the source file. +- When the user says "edit this PPTX," import first and then operate on the resulting Google Slides deck. + +## Output + +- Return the resulting deck title and link or ID when the runtime exposes it. +- Call out any obvious import drift or unsupported formatting that needs follow-up. +- If no further edit was requested, stop after confirming that the native deck is ready. + +## Example Requests + +- "Import this PPTX into Google Slides so I can edit it." +- "Convert this deck to native Google Slides and then summarize the first five slides." +- "Bring this ODP into Google Slides and clean up any layout drift." + +## Light Fallback + +If the file is missing, unreadable, or the runtime cannot import it, say that presentation import may be unavailable or the provided file may be invalid, then ask for a valid local file or a connected Google Slides deck instead. diff --git a/plugins/google-slides/skills/google-slides-import-presentation/agents/openai.yaml b/plugins/google-slides/skills/google-slides-import-presentation/agents/openai.yaml new file mode 100644 index 00000000..317fd046 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-import-presentation/agents/openai.yaml @@ -0,0 +1,5 @@ +interface: + display_name: "Google Slides Import" + short_description: "Convert PPTX or ODP into Google Slides" + brand_color: "#F9AB00" + default_prompt: "Use $google-slides-import-presentation to import a local PPTX into native Google Slides and verify the resulting deck." diff --git a/plugins/google-slides/skills/google-slides-template-migration/SKILL.md b/plugins/google-slides/skills/google-slides-template-migration/SKILL.md new file mode 100644 index 00000000..00606b92 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-migration/SKILL.md @@ -0,0 +1,121 @@ +--- +name: google-slides-template-migration +description: Migrate a Google Slides deck onto a target template. Use when the user wants to preserve source content while rebuilding slides from a branded template structure instead of making incremental in-place edits. +--- + +# Google Slides Template Migration + +Use this skill when the user has: +- a source deck whose content should be kept +- a target template deck whose visual system should be adopted + +This is not the same as cleanup or template surgery. +- For local polish, prefer [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md). +- For fixing a broken repeated pattern inside one deck, prefer [google-slides-template-surgery](../google-slides-template-surgery/SKILL.md). +- Use this skill when the right answer is to rebuild slides from the template, not keep nudging the old layout. +- When the content comes from notes, a changelog, or another generated source, outline what each slide should say before choosing a template slide. + +## Required Tooling + +Confirm the runtime exposes: +- `get_presentation` or `get_presentation_text` +- `get_slide` +- `get_slide_thumbnail` +- `batch_update` + +If the user is starting from a local `.pptx`, also confirm `import_presentation`. + +## Core Workflow + +1. Identify the two decks. +- Source deck: the content to preserve. +- Template deck: the company deck or branded presentation whose layout language should be reused. + +2. Plan the target slide story before editing. +- Build or confirm an outline of what each migrated slide should communicate. +- For each slide, write down its narrative job, must-keep content, likely density, and whether it needs an image, chart, grid, or mostly text. +- If a source slide is trying to do two jobs at once, such as summary plus evidence, split it in the outline before choosing a template pattern. + +3. Read both decks before editing. +- Build a slide inventory for the source deck. +- Build a pattern inventory for the template deck. +- Use thumbnails, not just JSON, to understand the template’s real visual system. + +4. Map source slides to template archetypes. +- Classify source slides into a small set of types such as title, section divider, agenda, metrics, 2-column content, image-heavy, quote, or appendix. +- Match by narrative job and density first, then by visual similarity. +- Find the closest matching template slide for each type. +- Read `./references/slide-archetype-mapping.md` when deciding the mapping. + +5. Duplicate from the template, not from the source. +- Prefer duplicating the closest matching template slide and then adapting it. +- Do not try to “convert” the old slide in place when a clean template pattern already exists. + +6. Port content into the duplicated template slide. +- Replace title and body text. +- Move charts, images, and supporting copy into the template structure. +- Preserve the message and evidence, but let the template control spacing, hierarchy, and visual rhythm. +- Fill the template with intention. Do not leave a slide or major text box looking half-empty unless the template clearly calls for airy whitespace. + +7. Verify every migrated slide with thumbnails. +- Re-check the migrated slide after each content port. +- If content does not fit the template cleanly, split it into multiple slides instead of overcrowding the layout. + +8. Finish with a deck-wide consistency pass. +- Normalize title treatment, image sizing, section-divider behavior, and spacing rhythm across the migrated deck. + +## Migration Rules + +- Decide what each slide needs to say before deciding what template slide to use. +- The template is the source of truth for layout, margins, hierarchy, and decorative style. +- The source deck is the source of truth for content. +- Preserve content by default; do not silently drop claims, bullets, data, or charts just to make the slide fit. +- Choose the template slide that matches the slide's narrative job and content density, not the one that merely looks close at first glance. +- When a source slide is denser than the template pattern allows, split the content across multiple template-based slides. +- Avoid excessive whitespace inside major text or content regions. If a box or slide feels underfilled, choose a better template archetype, combine related content, or rewrite the outline rather than leaving a weak composition. +- If no template archetype fits cleanly, split the source content or flag the slide for human design judgment instead of forcing a bad fit. +- Keep the migration deterministic. One source slide should map to one explicit template archetype or a deliberate split. + +## Preferred Strategy + +Use this order: + +1. Migrate a small representative set first. +- Start by validating the outline and archetype choices, not by bulk-copying content. +- Title slide +- One section divider +- One dense content slide +- One image or chart slide + +2. Verify that the template mapping is working. +- If those look good, continue with the rest of the deck. +- If not, adjust the archetype mapping before bulk migration. + +3. Roll out by slide family. +- Migrate all section dividers together. +- Then title/content slides. +- Then charts/images. +- Then appendix or oddballs. + +## What To Avoid + +- Do not restyle the old deck slide by slide with ad hoc geometry edits if the template already has a clean pattern. +- Do not paste fresh content into an arbitrary template slide before deciding the slide's job and density. +- Do not force all source slides into one template layout. +- Do not keep decorative source shapes unless they are required content. +- Do not accept a migrated slide that is on-brand but less legible than the source. + +## Verification Standard + +A migration pass is only done when: +- the migrated slide is visibly consistent with the company template +- the source content still exists and is readable +- no clipping, overlap, or awkward density was introduced +- the main content areas feel intentionally filled rather than sparse by accident +- sibling slides of the same type look like they belong in the same deck + +## References + +Read these before migrating beyond the first few slides: +- `./references/migration-playbook.md` +- `./references/slide-archetype-mapping.md` diff --git a/plugins/google-slides/skills/google-slides-template-migration/agents/openai.yaml b/plugins/google-slides/skills/google-slides-template-migration/agents/openai.yaml new file mode 100644 index 00000000..ebf71fa5 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-migration/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Google Slides Template Migration" + short_description: "Port a deck onto a company template with slide-type mapping" + default_prompt: "Use $google-slides-template-migration to migrate this source Google Slides deck onto the company template deck. Read both decks, map each source slide to a template archetype, duplicate from the template, port the content over, verify with thumbnails, and split slides when the source content is too dense for the template." diff --git a/plugins/google-slides/skills/google-slides-template-migration/references/migration-playbook.md b/plugins/google-slides/skills/google-slides-template-migration/references/migration-playbook.md new file mode 100644 index 00000000..89b6bf52 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-migration/references/migration-playbook.md @@ -0,0 +1,100 @@ +# Migration Playbook + +Use this reference after the skill triggers and you are ready to migrate slides. + +## Migration Sequence + +1. Read the source deck and template deck. +2. Draft or confirm an outline for what each target slide should communicate. +3. Inventory source slide types. +4. Inventory template slide patterns. +5. Map each outline item to the best template archetype. +6. Pick a representative subset and migrate those first. +7. Validate the mapping with thumbnails. +8. Roll out to the remaining slides by family. +9. Do one deck-wide consistency pass at the end. + +## Outline Before Layout + +Before you duplicate any template slide, define the target slide in words: +- what the slide is trying to do +- what content must survive +- what content can become secondary or move to another slide +- whether it needs a chart, image, grid, KPI, or mostly text +- whether the content density is light, medium, or dense +- whether the chosen layout will feel intentionally filled rather than leaving large accidental empty areas + +If a generated summary, changelog, or raw notes produce a messy slide brief, fix that in the outline first. Do not expect the template choice to solve an unclear slide concept. + +## Pick The Template Archetype Before Populating + +For each slide, answer these questions in order: +- Is this a title, section divider, summary, dense content, KPI, chart, image, or appendix slide? +- How much content should fit without crowding? +- Which template slide already does that job well? + +Only after that should you duplicate the template slide and populate it. + +When populating: +- avoid leaving major text boxes or card regions mostly empty unless that whitespace is an intentional part of the template +- if the slide looks too empty, reconsider the archetype, combine related content, or tighten the outline before doing geometry tweaks + +Common failure mode: +- taking a large blob of content +- dropping it into the visually nicest template slide +- trying to resize and nudge everything until it fits + +That usually produces an on-brand but ugly slide. The fix is to choose the right template pattern first or split the content across multiple slides. + +## Representative Subset + +Do not bulk-migrate immediately. Start with: +- title slide +- one section divider +- one dense content slide +- one visual slide with an image or chart + +This is the fastest way to discover whether the template actually supports the source content density. + +Validate two things in this subset: +- the content outline is correct +- the archetype mapping is correct + +If either is wrong, fix that before scaling up. + +## When To Split A Source Slide + +Split a source slide into multiple migrated slides when: +- the template pattern cannot fit the content without crowding +- the source mixes two different narrative jobs, like summary plus deep evidence +- the slide only works in the source because it ignores the template’s spacing and hierarchy + +When splitting: +- keep the template style constant +- preserve the original order of ideas +- use the same title family or section logic so the split feels intentional + +## Handling Images And Charts + +- Prefer the template’s image and chart frames over the source geometry. +- Resize or crop source visuals to fit the template framing rather than stretching the template to fit the source. +- If a chart is too detailed for the template frame, either use a denser template archetype or split the chart onto its own slide. + +## Handling Oddball Slides + +Not every source slide will match a template exactly. + +For oddballs: +- pick the closest archetype and adapt carefully +- or duplicate the nearest good migrated slide instead of a raw template slide +- if neither works, say the slide needs human design judgment rather than over-automating a bad fit + +## Deck-Wide Consistency Check + +At the end, verify: +- title positions are consistent +- section dividers feel related +- recurring image treatments match +- chart slides use the same alignment logic +- margins and text density feel stable across the deck +- large text or content regions do not have accidental excessive whitespace diff --git a/plugins/google-slides/skills/google-slides-template-migration/references/slide-archetype-mapping.md b/plugins/google-slides/skills/google-slides-template-migration/references/slide-archetype-mapping.md new file mode 100644 index 00000000..370ba23d --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-migration/references/slide-archetype-mapping.md @@ -0,0 +1,91 @@ +# Slide Archetype Mapping + +Use this file when mapping source slides onto the template deck. + +## Common Source Archetypes + +### Title + +Typical content: +- presentation title +- subtitle +- presenter/date/company + +Template target: +- title slide + +### Section Divider + +Typical content: +- section name +- short transition phrase + +Template target: +- section divider or chapter opener + +### Agenda + +Typical content: +- short list of sections or goals + +Template target: +- agenda or overview slide +- if none exists, use a clean bulleted content slide + +### Dense Content + +Typical content: +- title plus 3-7 bullets +- supporting sub-bullets or short annotations + +Template target: +- standard body-content slide +- 2-column text slide if the density is too high for one column + +### Metrics Or Dashboard + +Typical content: +- headline metric +- charts +- KPI callouts + +Template target: +- metrics or dashboard slide +- if the template has no such slide, use the most structured data-forward archetype + +### Image-Heavy + +Typical content: +- hero image +- caption +- one or two supporting text blocks + +Template target: +- image-forward or split-layout slide + +### Quote Or Testimonial + +Typical content: +- large quote +- attribution + +Template target: +- quote slide +- otherwise a minimal text-forward slide + +### Appendix + +Typical content: +- backup tables +- dense charts +- supporting notes + +Template target: +- appendix or detailed-content slide + +## Mapping Rules + +- Match by narrative job first, not by superficial similarity. +- A source slide with three cramped charts should not be forced into a clean hero-image template. +- If two template slides both fit, choose the one that preserves legibility with the least structural churn. +- If no template archetype fits cleanly, split the source slide or flag it as a human-review case. diff --git a/plugins/google-slides/skills/google-slides-template-surgery/SKILL.md b/plugins/google-slides/skills/google-slides-template-surgery/SKILL.md new file mode 100644 index 00000000..a95d153f --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-surgery/SKILL.md @@ -0,0 +1,88 @@ +--- +name: google-slides-template-surgery +description: Perform structural rework in connected Google Slides decks. Use when local visual cleanup is not enough and repeated layout defects require batch_update structure edits plus strict verification. +--- + +# Google Slides Template Surgery + +Use this skill for structural Google Slides cleanup. This is the escalation path after normal visual iteration fails to converge. + +Start with local slide fixes first. Escalate to template surgery only when one of these is true: +- the same spacing or overlap problem repeats across multiple slides +- the slide structure is fundamentally bad and local nudges keep re-breaking the layout +- the user explicitly asks to rework the template, placeholders, or repeated layout pattern +- the deck needs a consistent structural reset, not just cosmetic polish + +For simple cleanup, prefer [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md). + +## Required Tooling + +Confirm the runtime exposes: +- `get_presentation` or `get_presentation_text` +- `get_slide` +- `get_slide_thumbnail` +- `batch_update` + +If any of those are missing, stop and explain that the deck cannot be safely restructured from Codex. + +## Workflow + +1. Read the deck before changing it. +- Inventory slide types, repeated layouts, title patterns, image-heavy slides, and broken outliers. +- Fetch the target slide structure with `get_slide` before writing. +- Use live object IDs only. Never guess them. + +2. Decide whether to patch or rebuild. +- Patch in place when the slide has the right elements but the geometry is bad. +- Duplicate or recreate structure when the slide is too broken for safe incremental edits. +- Prefer one layout pattern at a time instead of broad deck-wide surgery in a single batch. + +3. Plan the operation as a small structural batch. +- Keep each batch narrow and intentional. +- Do not mix unrelated edits just because they touch the same slide. +- Copy request shapes from `./references/batch-update-recipes.md` instead of inventing them from memory. + +4. Verify on representative slides. +- After each structural batch, re-fetch thumbnails for the edited slide and 1-2 sibling slides that use the same pattern. +- Do not assume a successful write means the layout is improved. + +5. Roll forward carefully. +- Once a structural pattern works, apply it to the next matching slides. +- Reuse the same margin logic, title placement, and content rhythm across sibling slides. + +## Structural Rules + +- Prefer duplicating a clean slide pattern over endlessly mutating a broken one. +- Prefer deleting or replacing redundant elements over stacking new ones on top of old ones. +- Preserve user content by default. Structural cleanup is not permission to rewrite the narrative. +- Keep batches reversible. If the slide gets worse after a pass, correct the structure before adding more edits. +- If repeated edits are failing, stop and explain what constraint is blocking clean automation. + +## Common Surgery Cases + +Use this skill for: +- rebuilding crowded title/content slides with a cleaner text-and-image split +- replacing a bad placeholder stack with a simpler repeated pattern +- deleting duplicate or stale decorative shapes that keep causing overlap +- normalizing title position, body width, and image frame placement across a section +- duplicating a strong “golden” slide structure and adapting it for sibling slides + +Do not use this skill for: +- one-off typo fixes +- simple repositioning on a single slide +- content generation from scratch +- freeform redesign when the user only asked for cleanup + +## Verification Standard + +A structural pass is only done when: +- the target slide no longer has clipping or overlaps +- the new structure looks stable in the thumbnail, not just valid in raw JSON +- sibling slides using the same pattern still look coherent +- no stale elements remain hidden behind the new layout + +## References + +Read these before the first write: +- `./references/template-surgery-playbook.md` +- `./references/batch-update-recipes.md` diff --git a/plugins/google-slides/skills/google-slides-template-surgery/agents/openai.yaml b/plugins/google-slides/skills/google-slides-template-surgery/agents/openai.yaml new file mode 100644 index 00000000..d1a2256e --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-surgery/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Google Slides Template Surgery" + short_description: "Restructure repeated slide layouts with safer batch-update patterns" + default_prompt: "Use $google-slides-template-surgery to repair the template structure of this connected Google Slides deck. Start with one representative slide, use the skill's batch_update recipes instead of inventing raw request shapes, verify with thumbnails, then roll the pattern out to sibling slides if it works." diff --git a/plugins/google-slides/skills/google-slides-template-surgery/references/batch-update-recipes.md b/plugins/google-slides/skills/google-slides-template-surgery/references/batch-update-recipes.md new file mode 100644 index 00000000..c6132522 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-surgery/references/batch-update-recipes.md @@ -0,0 +1,166 @@ +# Batch Update Recipes + +Use these patterns as copy-and-fill templates. Do not invent raw `batch_update` objects from scratch when one of these fits. + +## Rules + +- Each request object must set exactly one request type key. +- Use live `objectId` values from `get_slide`. +- Keep batches small. +- Re-fetch a thumbnail after every batch. +- Prefer exact field masks. Do not use guessed field names. + +## Duplicate a strong slide + +```json +[ + { + "duplicateObject": { + "objectId": "slide-strong-1" + } + } +] +``` + +Use this when one sibling slide already has the right structure and you want to clone that pattern. + +## Delete a stale element + +```json +[ + { + "deleteObject": { + "objectId": "shape-stale-1" + } + } +] +``` + +Use this before adding new structure if the old element is clearly redundant or overlapping. + +## Replace repeated placeholder text everywhere + +```json +[ + { + "replaceAllText": { + "containsText": { + "text": "{{TITLE}}", + "matchCase": true + }, + "replaceText": "Q2 Business Review" + } + } +] +``` + +Use this for deterministic placeholder replacement. Do not use it when only one specific object should change. + +## Clear and rewrite a single text box + +```json +[ + { + "deleteText": { + "objectId": "shape-body-1", + "textRange": { + "type": "ALL" + } + } + }, + { + "insertText": { + "objectId": "shape-body-1", + "insertionIndex": 0, + "text": "Updated body copy" + } + } +] +``` + +Use this when a specific text box should be preserved structurally but its content must reset. + +## Move or scale an existing element + +```json +[ + { + "updatePageElementTransform": { + "objectId": "shape-hero-1", + "applyMode": "ABSOLUTE", + "transform": { + "scaleX": 1, + "scaleY": 1, + "translateX": 720000, + "translateY": 1080000, + "unit": "EMU", + "shearX": 0, + "shearY": 0 + } + } + } +] +``` + +Use this for geometry adjustments when the object already exists and only its position or scale is wrong. + +## Create a new rectangle placeholder + +```json +[ + { + "createShape": { + "objectId": "shape-new-placeholder-1", + "shapeType": "TEXT_BOX", + "elementProperties": { + "pageObjectId": "slide-1", + "size": { + "width": { + "magnitude": 4000000, + "unit": "EMU" + }, + "height": { + "magnitude": 900000, + "unit": "EMU" + } + }, + "transform": { + "scaleX": 1, + "scaleY": 1, + "translateX": 900000, + "translateY": 700000, + "unit": "EMU", + "shearX": 0, + "shearY": 0 + } + } + } + } +] +``` + +Use this when rebuilding a content zone is simpler than repairing a broken element. + +## Insert text into a newly created text box + +```json +[ + { + "insertText": { + "objectId": "shape-new-placeholder-1", + "insertionIndex": 0, + "text": "Section overview" + } + } +] +``` + +Use this immediately after `createShape` for text boxes. + +## Common Failure Modes + +- Wrong request key count: one object containing both `insertText` and `deleteObject` +- Guessed IDs instead of IDs from `get_slide` +- Stringified JSON instead of structured objects +- Giant batches mixing duplication, deletion, movement, and copy changes all at once +- Verifying only the API response and not the next thumbnail diff --git a/plugins/google-slides/skills/google-slides-template-surgery/references/template-surgery-playbook.md b/plugins/google-slides/skills/google-slides-template-surgery/references/template-surgery-playbook.md new file mode 100644 index 00000000..376f5e2d --- /dev/null +++ b/plugins/google-slides/skills/google-slides-template-surgery/references/template-surgery-playbook.md @@ -0,0 +1,81 @@ +# Template Surgery Playbook + +Use this file when the main skill has already triggered and you need the operational details. + +## When To Escalate + +Escalate from normal visual iteration to template surgery when: +- a slide needs more than 2-4 visual passes and still looks structurally wrong +- the same layout defect appears across a family of slides +- the problem is caused by placeholder design, not local position drift +- fixing one element keeps creating new collisions elsewhere + +## Safe Operating Order + +1. Choose one representative slide. +2. Fetch the live slide structure. +3. Choose a narrow structural move: +- duplicate the clean slide +- delete stale elements +- replace one placeholder pattern +- rework one title/body/image arrangement +4. Apply a small batch. +5. Re-fetch the thumbnail. +6. Check one sibling slide with the same pattern. +7. Only then continue to the rest of the section. + +## Preferred Structural Strategies + +### Strategy 1: Duplicate the cleanest sibling + +Use when one slide in the section already has the right composition. + +Why: +- lower risk than creating a new layout from scratch +- easier to preserve consistency across a section + +Then: +- duplicate the clean slide +- replace or reset only the objects that should differ +- verify the duplicated slide thumbnail immediately + +### Strategy 2: Remove stale structure first + +Use when the slide has multiple overlapping legacy shapes, text boxes, or images. + +Why: +- many bad iterations happen because the model keeps adding instead of clearing + +Then: +- identify redundant objects from `get_slide` +- delete only clearly stale or duplicate elements +- verify the slide before adding new structure + +### Strategy 3: Rebuild one content zone + +Use when only one region is broken, such as title band, body column, or image area. + +Why: +- safer than rebuilding the whole slide + +Then: +- keep untouched regions intact +- rebuild only the broken zone +- verify that the rebuilt zone does not collide with preserved content + +## Deck-Wide Rollout + +After a representative slide works: +- apply the same structure to 2-3 more slides in the same family +- verify each one with thumbnails +- stop if content density makes the pattern stop fitting + +Do not force one template across slides that clearly need different density or visual hierarchy. + +## Stop Conditions + +Stop and report instead of continuing when: +- you cannot identify stable object IDs for the target elements +- every pass makes the slide less legible +- the remaining choices are aesthetic and subjective rather than structural +- the requested change would require a broad redesign rather than safe cleanup diff --git a/plugins/google-slides/skills/google-slides-visual-iteration/SKILL.md b/plugins/google-slides/skills/google-slides-visual-iteration/SKILL.md new file mode 100644 index 00000000..a7c9c3e0 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-visual-iteration/SKILL.md @@ -0,0 +1,198 @@ +--- +name: google-slides-visual-iteration +description: Iteratively inspect and polish existing connected Google Slides presentations in Codex using slide thumbnails plus raw Slides edits. Use when a user asks to fix a slide visually, clean up formatting, improve slide quality, make a deck look better, fix alignment, spacing, overlap, overflow, crowding, awkward whitespace, or deck-wide visual consistency in an existing Google Slides deck or shared Slides link, especially when the work should follow a thumbnail -> diagnose -> batch_update -> re-thumbnail verification loop. +--- + +# Google Slides Visual Iteration + +Use this skill for existing or newly imported Google Slides decks when the user wants visual cleanup, not just content edits. + +Prefer the connected Google Slides workflow over generic slide-generation skills when the task is about improving a real Slides deck. +Treat this as the focused formatting workflow: work one slide at a time, and complete the thumbnail -> diagnose -> batch_update -> re-thumbnail loop before moving to the next slide. +Prefer this skill over [google-slides](../google-slides/SKILL.md) when the request is primarily about visual polish on an existing deck rather than content generation or general deck inspection. + +## Use When + +- The user wants to improve how an existing Google Slides deck looks, not just change its copy. +- The request includes phrases like "fix this slide," "make this deck look better," "clean up formatting," "fix overflow," "fix spacing," "fix alignment," or "visual iteration." +- The user shares a connected Google Slides deck or link and wants edits applied directly to that deck. + +## Required Tooling + +Confirm the runtime exposes the Google Slides actions you need before editing: +- `get_presentation` or `get_presentation_text` +- `get_slide` +- `get_slide_thumbnail` +- `batch_update` + +If the user wants to bring in a local `.pptx`, also confirm `import_presentation`. + +If a dedicated visual-iteration tool exists in the runtime, use it. Otherwise, emulate the loop with `get_slide_thumbnail` plus direct Google Slides edits. + +## Default Approach + +1. Clarify scope. +- Determine whether the user wants one slide fixed or the whole presentation. +- If multiple slides need cleanup, still process formatting slide by slide unless a single repeated structural fix is clearly safer. +- Preserve content by default. Do not rewrite copy unless the user asks or layout cannot be fixed any other way. + +2. Read structure before editing. +- Use `get_presentation` or `get_presentation_text` to identify slide order, titles, and object IDs. +- Use `get_slide` on the target slide before the first write so you have the current element structure and IDs. +- Before each additional write pass on that same slide, call `get_slide` again so the next `batch_update` uses fresh geometry and current element state rather than stale structure from the prior pass. + +3. Start with a thumbnail. +- Call `get_slide_thumbnail` first. +- Fetch the thumbnail for the current slide only. Do not prefetch thumbnails for the rest of the deck before starting the current slide's edit loop. +- Use `LARGE` when spacing, overlap, cropping, or dense layouts are the concern. +- Treat the thumbnail as the source of truth for visual quality. Raw JSON alone is not enough. +- When the tool returns inline image content in `content`, including image bytes, base64 image data, or an image-bearing data wrapper, treat that as analyzable visual input for this workflow and inspect it directly. +- If the thumbnail payload includes image bytes, a data URL, or base64 image content, ingest it directly as if the user had uploaded a screenshot of the slide. +- If `get_slide_thumbnail` succeeds, treat that as the visual verification path for this workflow even if the transcript view looks metadata-shaped. Do not abandon the thumbnail loop just because the runtime shows a thumbnail artifact, URL, or metadata wrapper instead of inline pixels in the message body. +- The response may also include `contentUrl` metadata, but if inline image data is present, inspect that directly instead of downloading the URL or switching to another image-analysis path. +- Do not switch to deck export, PDF rendering, or other fallback rendering paths when the thumbnail tool already succeeded. Only use a fallback path if the thumbnail action itself failed or is unavailable. + +4. Diagnose concrete visual problems. +- Before editing a slide, list the specific visible issues back to the user for that slide. +- Do not keep the diagnosis implicit. The user should be able to see what you think is wrong before the first `batch_update` pass. +- Limit the issue list to the 2-4 most important issues on that slide for the current pass. +- Look for text too close to edges or neighboring elements. +- Look for text overflow, clipping, or density that makes the slide feel compressed. +- Look for overlapping text boxes, shapes, charts, and images. +- Look for misaligned images, cards, icons, and text blocks. +- Look for grouped boxes, cards, or sections whose header text, body starts, icons, or internal padding do not sit on the same visual plane. +- Look for inconsistent emphasis such as one label or bullet line being bolded differently from its siblings without intent. +- Look for uneven alignment, broken grid structure, inconsistent spacing, off-center titles, awkward margins, and clipped elements. +- Look for image distortion, poor crops, weak hierarchy, and slides that feel heavier on one side without intent. +- Look for visual regressions introduced by the previous pass before adding more polish. +- Prioritize legibility and collisions first, then alignment/spacing, then aesthetic polish. + +5. Make one coherent edit pass. +- Use `batch_update` to fix the current issue cluster for that slide, not just a tiny nudge that leaves the main problems untouched. +- Be aggressive enough to materially improve the slide in each pass. Do not make timid edits that technically move elements but leave the slide still looking broken. +- Batch related fixes together when they affect the same slide structure, such as overflow plus alignment plus inconsistent spacing in one column or card set. +- Prefer moving, resizing, reflowing, redistributing, or re-aligning existing elements over rewriting the slide. +- If multiple boxes or sections are part of a visible group, align their headers, icons, top text baselines, and body starting positions unless the stagger is clearly intentional. +- Do not default to shrinking font size, tightening line spacing, or squishing elements closer together just to make the slide fit. +- If content still does not fit cleanly after a reasonable structural pass, split the content across slides or escalate to [google-slides-template-surgery](../google-slides-template-surgery/SKILL.md) instead of repeatedly compressing the layout. +- Keep each pass narrow enough that the effect is understandable, but strong enough to visibly improve the slide. +- When a fresh revision token is available from the runtime, include `write_control`; otherwise omit it and keep batches small. + +6. Verify immediately. +- Call `get_slide_thumbnail` again after every batch update. +- State which issues are now fixed, which issues remain, and whether the pass introduced any new regressions. +- Confirm the targeted issue cluster is actually fixed before moving on. +- If a fix introduced a new collision, imbalance, or cramped layout, correct that next instead of blindly continuing. +- After each verification thumbnail, do a fresh read of the current slide before the next write pass if more edits are needed. + +7. Iterate a few times, then stop. +- Run at least 2 full visual loops per slide in this skill. +- Do not stop after a single pass just because the first verification looks acceptable. +- The second loop must start with a fresh thumbnail review and refreshed slide structure so you can catch residual spacing, alignment, padding, and balance issues that were easy to miss in the first pass. +- After the second verified loop, continue to a third or fourth loop only if the slide still has meaningful issues. +- Only stop after the second loop if that fresh review finds nothing materially worth changing. +- Stop when further edits are becoming subjective or are not improving the slide. +- Escalate to [google-slides-template-surgery](../google-slides-template-surgery/SKILL.md) when a slide still has structural layout problems after 2-4 verified passes, or when the same issue repeats across multiple slides. + +## Slide-Level Heuristics + +Apply these in order: + +1. Legibility +- No clipped text. +- No elements touching or nearly touching unless intentionally grouped. +- Keep comfortable padding between text and container edges. +- Text inside a box, card, or shape should not sit uncomfortably close to that container's border. If the padding looks cramped in the thumbnail, treat it as a defect and fix it. + +2. Structure +- Align related elements to a shared left edge, center line, or grid. +- Normalize spacing between repeated items. +- Remove accidental overlaps before style refinements. +- When a container or shape is too small for its text, prefer resizing the container or redistributing the layout over tolerating cramped text padding. +- When multiple cards or panels are presented as siblings, keep their header text, icon blocks, and first body lines aligned on consistent horizontal and vertical planes. + +3. Balance +- Avoid slides that are top-heavy or left-heavy unless it is a deliberate composition. +- Resize or reposition oversized images/shapes that dominate the slide without helping the message. + +4. Consistency +- Keep repeated bullets, labels, captions, and card headings consistent in weight, alignment, and spacing unless the difference is intentional. +- If a row or family of elements should look parallel, treat one-off bolding, indentation, or sizing differences as defects to fix. +- If three or more boxes read as a set, treat mismatched header heights, top padding, or body-start positions as alignment defects even when the text itself is different lengths. + +5. Restraint +- Do not churn the whole slide if one local fix is enough. +- Do not invent new decorative elements unless the user explicitly wants a redesign. +- Do not treat compression as polish. A slide that only fits because everything was squeezed tighter is still broken. +- Do not stop after a cosmetic near-fix. If the text is still cramped against a border, still visually crowded, or still obviously misaligned, keep editing. + +## Deck-Wide Mode + +If the user asks to improve the whole presentation: + +Core rule: +- A whole-deck cleanup request still uses one-slide-at-a-time iteration. It does not mean "scan the whole deck first and then start editing." + +1. Read the presentation first and make a slide inventory. +- Note the title slide, section dividers, dense slides, image-heavy slides, and obvious outliers. +- Keep that inventory lightweight. Do not present one giant deck-wide issue dump before editing. + +2. Prioritize the slide order. +- If the user asked for the whole deck, start with slide 1 in the requested scope, finish slide 1, then move to slide 2, then slide 3, and continue in order until the last slide in scope. +- Do not skip ahead to later slides just because they look worse unless the user explicitly asked you to prioritize certain slides. +- Within each slide, address overlap, clipping, unreadable density, and broken crops before moving on to spacing, alignment, title placement, image treatment, and consistency. + +3. Finish each slide before moving on. +- For each target slide, run the full thumbnail -> diagnose -> batch_update -> re-thumbnail loop. +- Work strictly sequentially: finish the current slide before starting issue diagnosis for the next slide. +- Do not fetch thumbnails for later slides while the current slide is still in progress unless the user explicitly asked for a separate audit. +- Start each slide with an explicit list of the 2-4 key issues on that slide only. +- Fix that slide before moving to the next one. Do not diagnose the whole rest of the deck in detail while the current slide is still unresolved. +- End each pass with a fixed-vs-remaining issue summary for that slide only. +- Do at least 2 verified loops on that slide before advancing to the next one. +- Do not say a slide needs no second pass until you have actually completed the second fresh review loop on that slide. +- Between loops, re-read the current slide structure so follow-up writes use fresh state rather than stale element geometry. +- If the same formatting defect keeps recurring because of shared structure, escalate to [google-slides-template-surgery](../google-slides-template-surgery/SKILL.md) instead of hand-patching every slide forever. + +4. Keep a global style memory. +- Reuse the same margin logic, title placement, image sizing style, and spacing rhythm across similar slides. +- If one slide establishes a strong layout pattern, align sibling slides to it unless the content demands a different structure. + +5. Report what changed. +- Summarize which slides were updated, what categories of issues were fixed, and any slides that still need human taste decisions. + +## Output Conventions + +- Before the first edit pass on a slide, show a short issue list for that slide so the user can see what will be fixed. +- In deck-wide mode, narrate progress in strict slide order, for example `slide 1`, then `slide 2`, then `slide 3`, until the last slide in scope. +- Keep deck-wide work slide-scoped in the narration: talk about the current slide's issues, fixes, and remaining defects before moving on to another slide. +- After each pass, separate `fixed`, `remaining`, and `new regressions` clearly instead of giving a vague progress note. +- Do not announce `none that require a second pass` after pass 1. Complete the second slide-local loop first, then decide whether the slide is done. +- Keep the issue list concrete and visual, for example `text overflow in right card`, `image misaligned with left column`, or `middle bullet line is bolded inconsistently`. +- Do not open with a broad deck-wide cluster like `slides 3, 4, 7, 8, and 10 all have...` unless the user asked for an audit instead of an iteration workflow. +- Do not narrate a future-slide plan like `I am fetching the rest of the deck now` before finishing the current slide. + +## Editing Guidance For Raw Slides Requests + +The Slides connector exposes raw `batch_update` requests. That means: +- Always inspect the current slide before editing. +- Keep the tool loop local to the current slide: one slide thumbnail in, one slide edit pass, one verification thumbnail out. +- Use object IDs from the live slide state, not guessed IDs. +- Prefer reversible, geometric edits first: transform, size, alignment, deletion only when clearly safe. +- If a text box is too dense, try resizing, redistributing, or reflowing the slide before shortening the text. +- If the only apparent fix is to compress all the content tighter, stop and reconsider the layout pattern instead of blindly applying that edit. + +## Failure Policy + +- If the thumbnail action is unavailable, say that visual verification is blocked and fall back to structural cleanup only if the user still wants that. +- If the thumbnail action succeeded, do not claim that visual verification is blocked just because the response was wrapped as metadata or a separate artifact in the runtime transcript. +- If the runtime lacks the Slides edit action, stop and say the deck can be diagnosed but not corrected from Codex. +- If repeated passes do not improve the slide, stop and explain what remains subjective or structurally constrained. + +## Example Prompts + +- `Use $google-slides-visual-iteration to fix the alignment and overlap issues on slide 4 of this Google Slides deck.` +- `Use $google-slides-visual-iteration to clean up this entire deck and make the slide layouts feel consistent.` +- `Import this PPTX into Google Slides, then use $google-slides-visual-iteration to polish each slide with thumbnail-based verification.` +- `Use $google-slides-visual-iteration to make this existing Google Slides deck look better and fix the formatting issues.` +- `Use $google-slides-visual-iteration to clean up spacing, overflow, and alignment in this shared Google Slides link.` diff --git a/plugins/google-slides/skills/google-slides-visual-iteration/agents/openai.yaml b/plugins/google-slides/skills/google-slides-visual-iteration/agents/openai.yaml new file mode 100644 index 00000000..6f4633c2 --- /dev/null +++ b/plugins/google-slides/skills/google-slides-visual-iteration/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Google Slides Visual Iteration" + short_description: "Fix Google Slides formatting and visual polish" + default_prompt: "Use $google-slides-visual-iteration to clean up an existing Google Slides deck by starting with slide 1, listing the 2-4 key issues for that slide, fixing it, re-checking it, then doing a second fresh slide-local loop before moving to slide 2 and continuing in order." diff --git a/plugins/google-slides/skills/google-slides/SKILL.md b/plugins/google-slides/skills/google-slides/SKILL.md new file mode 100644 index 00000000..21c2ecdf --- /dev/null +++ b/plugins/google-slides/skills/google-slides/SKILL.md @@ -0,0 +1,109 @@ +--- +name: google-slides +description: Inspect, create, import, summarize, and update Google Slides presentations through connected Google Slides data. Use when the user wants to find a deck, read slide structure, summarize a presentation or specific slide, understand charts, graphs, or other slide visuals by combining slide text with thumbnail-based image understanding, create a new presentation, import a `.ppt`, `.pptx`, or `.odp`, or make general content edits in Google Slides. For visual polish on an existing deck, such as formatting cleanup, alignment fixes, overflow cleanup, or slide-by-slide deck cleanup, prefer `google-slides-visual-iteration`. +--- + +# Google Slides + +## Overview + +Use this skill as the default entrypoint for Google Slides work. Stay here for deck search, summaries, general content edits, imports, and new presentation creation. If the user primarily wants to make an existing deck look better by fixing formatting, overflow, spacing, alignment, or visual polish, prefer [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md). +Use this base skill when the request spans multiple Google Slides workflows or when no more focused Google Slides skill is a better fit. +For slide-reading and summary tasks, combine structural deck reads with slide thumbnails when the slide contains charts, graphs, diagrams, screenshots, or other content that cannot be understood from text alone. + +## Specialized Skills + +- For importing a local presentation file into native Google Slides first, prefer [google-slides-import-presentation](../google-slides-import-presentation/SKILL.md). +- For visual cleanup of an existing deck, prefer [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md). +- For repairing broken repeated layout structure inside a deck, prefer [google-slides-template-surgery](../google-slides-template-surgery/SKILL.md). +- For moving content onto a company or team template deck, prefer [google-slides-template-migration](../google-slides-template-migration/SKILL.md). + +## Required Tooling + +Confirm the runtime exposes the relevant Google Slides actions before editing: +- `search_presentations` when the user does not provide a target deck +- `get_presentation` or `get_presentation_text` +- `get_slide` +- `batch_update` +- `create_presentation` for new decks +- `import_presentation` when starting from a local `.ppt`, `.pptx`, or `.odp` +- `get_slide_thumbnail` when visual verification matters + +## Workflow + +1. Identify the target presentation. +- If the user names a deck but does not provide a URL, search for it first. +- If the user provides a local presentation file, tell the user you are importing it into native Google Slides first, then use [google-slides-import-presentation](../google-slides-import-presentation/SKILL.md). + +2. Read before writing. +- Use `get_presentation` or `get_presentation_text` to capture slide order, titles, and overall structure. +- Use `get_slide` before any slide-level write so object IDs and layout context come from the live deck. +- For slide summaries or inspection, do not rely on text extraction alone when a slide contains charts, graphs, screenshots, diagrams, or image-heavy content. +- Use `get_slide_thumbnail` alongside text/structure reads when visual evidence matters so the summary reflects both what the slide says and what the slide shows. +- If the thumbnail response includes inline image content, base64 image data, or an image-bearing data wrapper, ingest that directly as slide image input. The response may also include `contentUrl` metadata, but if inline image data is present, inspect that directly instead of downloading the URL or relying only on metadata. +- Treat the slide page size as a hard boundary for every shape, text box, image, and color band you create. + +3. Apply default creation polish when making a new presentation. +- Do not ask the user to specify visual styling unless the request depends on a specific brand, template, or aesthetic. +- First create the base version of each slide with the right structure, content, and layout. Then do a second polish pass before moving on. +- Make the slides feel pretty and visually appealing by default, not merely correct. +- Make new decks look intentionally designed by default rather than leaving them as raw black text on white slides. +- Keep the styling lightweight but visibly designed: use a restrained color palette, clear title/body hierarchy, comfortable spacing, and simple visual accents that improve scanability. +- Do not default to a plain white background with only colored title text. Use background color, tinted sections, colored bands, or colored cards so most slides have visible color surfaces, not just colored text. +- Add graphics, icons, diagrams, or simple visual motifs when they help explain the point or make the slide feel designed, but do not add decorative elements that overwhelm the content. +- In the polish pass, improve color, spacing, hierarchy, alignment, and slide-level composition without changing the meaning of the content. +- Keep all content inside a safe content frame inset from the slide edges, including a visible bottom margin. If you use a full-bleed header band, footer band, or background block, size it exactly to the slide bounds rather than past them. +- Keep slide titles to one line at most. If a title would wrap, shorten it or split the content across slides instead of using a multi-line title. +- When content is naturally a list of points, render it as an actual bullet list instead of stacked prose lines or repeated paragraph blocks. +- When using bullets, put each bullet on its own line. Do not combine multiple bullets into one paragraph or line, and do not fake bullets with plain paragraphs when true list formatting is available. +- If body text, cards, or labels would run wide or tall, shorten them, reduce density, or split the content across slides instead of letting any element exceed the slide frame. +- Use color to create structure such as title emphasis, section separators, callout boxes, light background shapes, or full-slide background treatment, but do not overdecorate the deck. +- Preserve user control over substantive design choices. Apply a clean default look, but do not invent a heavy brand system or overly specific theme unless the user asks. + +4. Route only when the job is narrower than general Slides work. +- Stay in this skill for deck summaries, slide-by-slide reviews, new presentation creation, small content edits, and isolated formatting fixes on specific slides. +- Use [google-slides-import-presentation](../google-slides-import-presentation/SKILL.md) when the source is a local presentation file. +- Use [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md) when the user asks to fix a slide visually, clean up formatting, make a deck look better, or correct spacing, overlap, alignment, cropping, density, overflow, or other layout cleanup where the slide image matters. +- Use [google-slides-template-surgery](../google-slides-template-surgery/SKILL.md) when the repeated layout structure is broken. +- Use [google-slides-template-migration](../google-slides-template-migration/SKILL.md) when content should move onto a company or team template deck. + +5. Keep writes grounded. +- Restate the target slide numbers, titles, or object IDs before making changes. +- Prefer small `batch_update` requests over large speculative batches. +- Send `batch_update` requests as structured request objects in the expected tool shape, not as JSON strings or stringified arrays. +- If the task depends on how the slide looks, fetch a thumbnail before editing and verify again after the write. +- If the task is to summarize, interpret, or sanity-check a visual slide, fetch a thumbnail and use it as evidence for charts, graphs, screenshots, diagrams, and other non-textual content rather than summarizing only the extracted text. +- When fixing slide formatting, use a tight loop: take a thumbnail, identify visible spacing/alignment/cropping/regression issues, send a focused `batch_update`, then take another thumbnail to verify the result. +- Run 2-4 verified formatting passes when needed. Stop earlier once the slide is clearly clean, and switch to [google-slides-visual-iteration](../google-slides-visual-iteration/SKILL.md) if the job turns into slide-by-slide formatting across a larger set of slides. +- After creating a new slide or applying layout-heavy changes, immediately verify that no text, shape, image, or color band extends beyond the slide boundary. If the editor would require horizontal or vertical scrolling to see the whole slide, or if the lowest text sits in the bottom safety margin, treat that as a failure and fix it before moving on. +- When supplying `objectId` values in `batch_update`, use valid Google Slides IDs that are 5-50 characters long and start with an alphanumeric character or `_`. Prefer descriptive IDs like `slide02`, `slide02_title`, or `slide02_body`; do not use very short IDs like `s2` or `i0`. +- If you need to create a slide and edit its placeholders in the same `batch_update`, create the slide with valid placeholder ID mappings first, then reference those placeholder IDs in later requests in the same batch. + +## Write Safety + +- Preserve slide order, titles, body text, charts, notes, and supporting evidence unless the user asks for a change. +- Use live object IDs from the current deck state. Never guess IDs or request shapes. +- Before deleting slides, rewriting multiple slides, or changing the layout pattern across a section, state exactly which slides will change and what kind of change you are about to make. +- Do not promise pixel-perfect fidelity when importing Office formats into Google Slides. +- When creating a new deck, default to readable structure plus visible color treatment, not a bare text dump. +- Never leave text boxes, shapes, or header bands hanging outside the slide frame unless they are intentional full-bleed elements sized exactly to the slide edges. + +## Output + +- Reference slide numbers and titles when summarizing or planning edits. +- For slide summaries that involve charts, graphs, or other visuals, distinguish clearly between what comes from extracted text and what comes from thumbnail-based visual understanding. +- Distinguish clearly between a proposed plan and changes that were actually applied. +- Say which presentation and slides were read or changed. +- Call out any remaining issues that need a narrower workflow or human design judgment. + +## Example Requests + +- "Find the Q2 board deck and summarize the storyline slide by slide." +- "Read slide 8 and summarize both the chart and the surrounding text." +- "Create a new Google Slides presentation from this outline." +- "Import this PPTX into Google Slides and then clean up the layout." +- "Update slide 6 so the title and chart description match the latest numbers." + +## Light Fallback + +If the presentation is missing or the Google Slides connector does not return deck data, say that Google Slides access may be unavailable, the wrong deck may be in scope, or the file may need to be imported first. diff --git a/plugins/google-slides/skills/google-slides/agents/openai.yaml b/plugins/google-slides/skills/google-slides/agents/openai.yaml new file mode 100644 index 00000000..2c85b155 --- /dev/null +++ b/plugins/google-slides/skills/google-slides/agents/openai.yaml @@ -0,0 +1,5 @@ +interface: + display_name: "Google Slides" + short_description: "Inspect decks and handle Slides content edits" + brand_color: "#F9AB00" + default_prompt: "Use $google-slides to inspect a deck, summarize a slide with both text and chart/image understanding, import a PPTX, create a presentation, or make a precise content edit in Google Slides."