diff --git a/README.md b/README.md index cb749bd..aa133aa 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,20 @@ source content This is deliberately local-first. It proves the core source-to-deck loop before production hosting, auth, persistence, or full LLM orchestration. +## Google Slides Workflow + +The older AgentPlane Google Slides project has been merged into this repo as +workflow guidance and a future renderer contract: + +```text +docs/google-slides-workflow.md +schemas/google-slides-deck-spec.schema.json +``` + +Use that path for branded Google Slides generation: copy the template first, +inventory native containers, fill existing object IDs, delete unused slides, and +render thumbnails/contact sheets for visual QA. + ## Quick Start On MBS ```bash @@ -165,9 +179,8 @@ docs/ /Users/tars/AgentPlane/projects/google-slides ``` -For branded Google Slides, use brand-safe mode: copy the template, inventory -native containers, fill existing object IDs, delete unused slides, and render -thumbnails/contact sheets for visual QA. +For branded Google Slides, use brand-safe mode as documented in +`docs/google-slides-workflow.md`. ## Suggested Next Session @@ -190,4 +203,3 @@ Recommended v0.2 priorities: 5. Add PPTX visual QA: render thumbnails or PDF previews and catch overflow. 6. Add style-pack save/load workflow and template import. 7. Add Google Slides renderer using the existing template-container workflow. - diff --git a/apps/web/public/google-slides-workflow.html b/apps/web/public/google-slides-workflow.html new file mode 100644 index 0000000..7f84107 --- /dev/null +++ b/apps/web/public/google-slides-workflow.html @@ -0,0 +1,118 @@ + + + + + + Google Slides Workflow - Slide Factory + + + +
+ Back to Slide Factory +

Merged prior work

+

Google Slides Workflow

+ +

+ Slide Factory now supersedes the older AgentPlane Google Slides project + as the active slide-generation product. The reusable Google Slides work + remains the brand-safe renderer pattern for future native Slides output. +

+ +

Brand-Safe Flow

+
    +
  1. Copy the template deck.
  2. +
  3. Generate a template inventory.
  4. +
  5. Choose slides by native container pattern.
  6. +
  7. Fill existing text containers by object ID.
  8. +
  9. Delete unused template slides.
  10. +
  11. Render thumbnails and a contact sheet for visual QA.
  12. +
+ +

Contract

+

+ The current PPTX-oriented DeckSpec should be adapted into the + container-oriented Google Slides schema before mutating a copied + template. +

+
schemas/google-slides-deck-spec.schema.json
+ +

Local Prior Art

+
/Users/tars/AgentPlane/projects/google-slides
+/Users/tars/.codex/skills/google-slides/scripts/
+ +

Handoff Evidence

+

+ Native Slides output should return the deck title, presentation ID, edit + URL, source template, target folder, contact sheet path, brand-safe + status, and any overflow or weak-template-match risks. +

+
+ + diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx index 0c9685a..382bbf8 100644 --- a/apps/web/src/main.tsx +++ b/apps/web/src/main.tsx @@ -1,6 +1,6 @@ import React, { DragEvent, useMemo, useRef, useState } from "react"; import { createRoot } from "react-dom/client"; -import { Download, FileText, Image as ImageIcon, Loader2, Paperclip, Upload, WandSparkles, X } from "lucide-react"; +import { Download, ExternalLink, FileText, Image as ImageIcon, Loader2, Paperclip, Upload, WandSparkles, X } from "lucide-react"; import "./styles.css"; type DeckResult = { @@ -116,10 +116,16 @@ function App() {

Slide Factory

Source to deck

- +
+ + + Google Slides workflow + + +
diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css index af5938d..154ef16 100644 --- a/apps/web/src/styles.css +++ b/apps/web/src/styles.css @@ -40,6 +40,14 @@ button { margin-bottom: 18px; } +.topbar-actions { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; + gap: 10px; +} + .eyebrow { margin: 0 0 4px; color: #f05a28; @@ -82,6 +90,7 @@ h1 { color: #172033; background: #fff; border: 1px solid #d8dee9; + text-decoration: none; } .icon-action { @@ -243,6 +252,15 @@ textarea { padding: 16px; } + .topbar { + align-items: flex-start; + flex-direction: column; + } + + .topbar-actions { + justify-content: flex-start; + } + .main-grid { grid-template-columns: 1fr; } diff --git a/docs/google-slides-workflow.md b/docs/google-slides-workflow.md new file mode 100644 index 0000000..075d4f4 --- /dev/null +++ b/docs/google-slides-workflow.md @@ -0,0 +1,81 @@ +# Google Slides Workflow + +Slide Factory supersedes the older AgentPlane Google Slides project as the +active slide-generation product. The older project remains useful as a +brand-safe Google Slides renderer pattern and is now folded into this repo as +implementation guidance. + +## Source + +Prior project: + +```text +/Users/tars/AgentPlane/projects/google-slides +``` + +Key reusable assets: + +- Template inventory workflow. +- Container/object-id mapping. +- Brand-safe deck mutation rules. +- Contact sheet visual QA. +- Container-oriented deck spec schema. + +## Operating Rule + +Treat Google Slides templates as design systems. A Slide Factory Google Slides +renderer should copy a template first, inspect its native containers, then fill +existing text containers by object ID. It should create new page elements only +when the user explicitly permits that or when no usable container exists. + +## Brand-Safe Flow + +1. Copy the template deck. +2. Generate a template inventory. +3. Choose slides by container pattern. +4. Delete existing text and insert generated text into existing containers. +5. Delete unused template slides. +6. Render thumbnails and a contact sheet. +7. Patch copy density before changing layout geometry. + +## Local Skill Scripts + +The current implementation helpers still live in the local Codex skill until +they are ported into Slide Factory packages: + +```text +/Users/tars/.codex/skills/google-slides/scripts/ +``` + +Primary scripts: + +- `slides_template_inventory.py` +- `slides_contact_sheet.py` +- `slides_structured_deck.py` +- `slides_container_map.py` + +## Contract Bridge + +Slide Factory's current `DeckSpec` is PPTX-oriented. Google Slides export should +use an adapter step that maps the internal `DeckSpec` into the container-based +Google Slides schema at: + +```text +schemas/google-slides-deck-spec.schema.json +``` + +Do not mutate live/private Google Drive files directly from the planner. The +renderer should work from a copied template deck and return the edit URL, +presentation ID, source template, target folder, and contact sheet evidence. + +## Handoff Evidence + +At handoff, include: + +- Deck title. +- Presentation ID and edit URL. +- Source template and folder. +- Auth account used. +- Contact sheet path. +- Whether brand-safe mode was used. +- Slides with overflow risk or weak template matches. diff --git a/schemas/google-slides-deck-spec.schema.json b/schemas/google-slides-deck-spec.schema.json new file mode 100644 index 0000000..37a10a1 --- /dev/null +++ b/schemas/google-slides-deck-spec.schema.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://agentplane.local/projects/slide-factory/google-slides-deck-spec.schema.json", + "title": "Slide Factory Google Slides Deck Spec", + "type": "object", + "required": ["title", "slides"], + "additionalProperties": false, + "properties": { + "title": { + "type": "string", + "minLength": 1 + }, + "template_id": { + "type": "string", + "minLength": 1 + }, + "folder_id": { + "type": "string", + "minLength": 1 + }, + "brand_safe": { + "type": "boolean", + "default": true + }, + "slides": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/slide" + } + } + }, + "$defs": { + "slide": { + "type": "object", + "required": ["containers"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "cover_or_close", + "section_divider", + "title_body", + "two_column", + "three_column", + "image_plus_text", + "toc_or_timeline", + "table", + "single_statement", + "visual_or_blank" + ] + }, + "template_slide": { + "oneOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "string", + "minLength": 1 + } + ] + }, + "title": { + "type": "string" + }, + "containers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/container" + } + }, + "speaker_notes": { + "type": "string" + } + } + }, + "container": { + "type": "object", + "required": ["text"], + "additionalProperties": false, + "properties": { + "role": { + "type": "string", + "examples": ["title", "subtitle", "body", "column", "callout", "label"] + }, + "text": { + "type": "string" + }, + "bullets": { + "type": "boolean", + "default": false + } + } + } + } +}