Merge Google Slides workflow into Slide Factory
This commit is contained in:
parent
ec8ba8dff8
commit
a010792eef
6 changed files with 344 additions and 9 deletions
20
README.md
20
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.
|
||||
|
||||
|
|
|
|||
118
apps/web/public/google-slides-workflow.html
Normal file
118
apps/web/public/google-slides-workflow.html
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Google Slides Workflow - Slide Factory</title>
|
||||
<style>
|
||||
:root {
|
||||
color: #172033;
|
||||
background: #f4f6fa;
|
||||
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #172033;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 4px;
|
||||
color: #f05a28;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 18px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 28px 0 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
p,
|
||||
li {
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow-x: auto;
|
||||
padding: 14px;
|
||||
border: 1px solid #d8dee9;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.back {
|
||||
display: inline-flex;
|
||||
margin-bottom: 18px;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<a class="back" href="/">Back to Slide Factory</a>
|
||||
<p class="eyebrow">Merged prior work</p>
|
||||
<h1>Google Slides Workflow</h1>
|
||||
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2>Brand-Safe Flow</h2>
|
||||
<ol>
|
||||
<li>Copy the template deck.</li>
|
||||
<li>Generate a template inventory.</li>
|
||||
<li>Choose slides by native container pattern.</li>
|
||||
<li>Fill existing text containers by object ID.</li>
|
||||
<li>Delete unused template slides.</li>
|
||||
<li>Render thumbnails and a contact sheet for visual QA.</li>
|
||||
</ol>
|
||||
|
||||
<h2>Contract</h2>
|
||||
<p>
|
||||
The current PPTX-oriented DeckSpec should be adapted into the
|
||||
container-oriented Google Slides schema before mutating a copied
|
||||
template.
|
||||
</p>
|
||||
<pre>schemas/google-slides-deck-spec.schema.json</pre>
|
||||
|
||||
<h2>Local Prior Art</h2>
|
||||
<pre>/Users/tars/AgentPlane/projects/google-slides
|
||||
/Users/tars/.codex/skills/google-slides/scripts/</pre>
|
||||
|
||||
<h2>Handoff Evidence</h2>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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() {
|
|||
<p className="eyebrow">Slide Factory</p>
|
||||
<h1>Source to deck</h1>
|
||||
</div>
|
||||
<button className="primary-action" onClick={createDeck} disabled={busy}>
|
||||
{busy ? <Loader2 className="spin" size={18} /> : <WandSparkles size={18} />}
|
||||
{busy ? "Building" : "Build deck"}
|
||||
</button>
|
||||
<div className="topbar-actions">
|
||||
<a className="secondary-action" href="/google-slides-workflow.html">
|
||||
<ExternalLink size={16} />
|
||||
Google Slides workflow
|
||||
</a>
|
||||
<button className="primary-action" onClick={createDeck} disabled={busy}>
|
||||
{busy ? <Loader2 className="spin" size={18} /> : <WandSparkles size={18} />}
|
||||
{busy ? "Building" : "Build deck"}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="main-grid">
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
81
docs/google-slides-workflow.md
Normal file
81
docs/google-slides-workflow.md
Normal file
|
|
@ -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.
|
||||
100
schemas/google-slides-deck-spec.schema.json
Normal file
100
schemas/google-slides-deck-spec.schema.json
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue