@easysociable/cli 0.1.18 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easysociable/cli",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Agent-first CLI for EasySociable: Content Engine, Template, Slideshow, and MCP",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -8,11 +8,10 @@
8
8
  "homepage": "https://easysociable.com",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/murphywuwu/8MRR-Project.git",
12
- "directory": "apps/cli"
11
+ "url": "git+https://github.com/murphywuwu/easysociable-mcp.git"
13
12
  },
14
13
  "bugs": {
15
- "url": "https://github.com/murphywuwu/8MRR-Project/issues"
14
+ "url": "https://github.com/murphywuwu/easysociable-mcp/issues"
16
15
  },
17
16
  "keywords": [
18
17
  "easysociable",
@@ -19,14 +19,13 @@ V1 expects an Agent (Grok Bot, Codex, Claude Code, …) to drive setup. The webs
19
19
 
20
20
  Default skills:
21
21
 
22
- - `easysociable-slideshow` — turns a draft into slideshow pages you preview and download in the dashboard
23
- - `easysociable-template` — creates page templates
22
+ - `easysociable-slideshow` — turns a topic into carousel pages you edit and download in Studio
24
23
 
25
24
  Optional Content Engine skill (install via CLI only — not in the public
26
25
  content-engine git repo; operations still follow that engine’s `CLAUDE.md`):
27
26
 
28
27
  ```bash
29
- easysociable install --skills content,template,slideshow --yes
28
+ easysociable install --skills content,slideshow --yes
30
29
  ```
31
30
 
32
31
  Get a Content Engine core (preferred):
@@ -3,8 +3,8 @@ name: easysociable-slideshow
3
3
  description: >
4
4
  Turn a topic into an editable, ready-to-post carousel (Slideshow Run) in
5
5
  EasySociable Studio. Research facts, pick a proven hook and structure
6
- (Formula), adapt pages from one Deck Style's catalog layouts, render-check
7
- every page locally, then create the Run and hand the user a Studio link.
6
+ (Formula), lay pages out from reference designs (the user's, a Formula's,
7
+ or the catalog's, shuffled), render-check every page locally, then create the Run and hand the user a Studio link.
8
8
  Ask the user only for what only they know (their Brand, once; their own
9
9
  images/screenshots). Final pixels come only from Studio Download.
10
10
  ---
@@ -40,12 +40,14 @@ Ask only for what only the user knows:
40
40
  - None → ask in **one** message, everything skippable:
41
41
  "What name and @handle should appear on your carousels? (Optional: an
42
42
  avatar/logo image path.) Reply 'skip' to post without a signature."
43
- Create it with `easysociable brands create --file brand.json` using the
44
- palette of the chosen Deck Style (`references/DECK_STYLES.md`).
45
- Skipped → no Brand: header shows the topic, the CTA has no handle, and the
46
- Deck Style palette goes in `theme.json` as
47
- `{ "color": { "canvas", "text", "textMuted", "accent", "primary" } }`
48
- (without a Brand or theme Studio falls back to its dark default).
43
+ Create it with `easysociable brands create --file brand.json`
44
+ (`{ "name", "handle", "colors", "logoAssetId" }`) using the default palette
45
+ that matches the deck's style (`references/REFERENCES.md`). An avatar: upload
46
+ it first (step 5's `images upload`) and pass the returned `asset.id` as
47
+ `logoAssetId`; `brands get` then returns its `logoUrl`.
48
+ Skipped → no Brand: header shows the topic, the CTA has no handle, and that
49
+ palette goes in `theme.json` (without a Brand or theme Studio falls back to
50
+ its dark default).
49
51
 
50
52
  ### 2. Facts
51
53
 
@@ -67,8 +69,12 @@ niche). Use a card when it fits; otherwise write your own. Never force one.
67
69
  `mistake-list`, a single piece of news or a claim → no list recipe.
68
70
  - `easysociable hooks recommend --json` → one mold per hook type (list-tease,
69
71
  contrast, number, identity, …), ranked by evidence.
70
- - `easysociable formulas recommend --recipe <recipe> --platform <p> --fact-count <n> --json`
71
- when the shape is a recipe.
72
+ - **Always** look for a structure first:
73
+ `easysociable formulas recommend [--recipe <recipe>] --platform <p> --fact-count <n> --json`
74
+ (`--recipe` when the shape is a list recipe; without it you see every
75
+ structure and judge fit yourself). Near-equal cards come back shuffled.
76
+ When the user asked for something different from last time, add
77
+ `--exclude <formulaId>` for the Formula that Run used.
72
78
  - Use a card only if `stop` is false **and** it fits this content (a news
73
79
  explainer is not an "N things" list). Prefer `published`; a `hypothesis`
74
80
  card is thin evidence: use it only when it clearly fits.
@@ -83,19 +89,38 @@ niche). Use a card when it fits; otherwise write your own. Never force one.
83
89
  - One idea per page, ≤ 45 words per page. Page 1 is the hook. Last page asks
84
90
  for one action (comment, save or follow).
85
91
 
86
- ### 4. Style and pages
87
-
88
- Pick one Deck Style (`references/DECK_STYLES.md`): the Brand's style if it has
89
- one, else by content. Styles that need images only when you have the images.
90
-
91
- For each page, take the family that fits its purpose and adapt its source:
92
-
93
- ```bash
94
- easysociable templates source --family <familyId> --platform <platform> --json
95
- ```
96
-
97
- Follow "Adapting a family" in `DECK_STYLES.md`. Put the result in the pack as a
98
- generated page:
92
+ ### 4. Look and pages
93
+
94
+ Structure (step 3) and look are chosen separately. The look comes from a
95
+ **reference**; the first rule that applies wins:
96
+
97
+ 1. The user names a Run or says "same as last time / like this one" →
98
+ "Reuse a Run" below.
99
+ 2. The user shares a post (screenshot or link) → study its grid, type scale,
100
+ background, density and decoration; take the closest catalog references as
101
+ structure and restyle them to match the post. Never copy its words or images.
102
+ 3. A Formula with a Look → the Look's designs (Formula handoff below).
103
+ 4. The user asks for a different look ("换个样子", "something else") → first
104
+ write 3–5 art directions that differ from each other and from this Brand's
105
+ previous Run (one line each: grid, type treatment, background, density,
106
+ decoration). Drop any the previous Run used, take the least conventional
107
+ one, and pick references whose `style` fits it.
108
+ 5. Otherwise → the content decides: get candidates for the cover with
109
+ `easysociable templates references --role hook,cover --json`
110
+ (results are shuffled) and take the first that fits the content. Its
111
+ `style` is the deck's style; for each other page ask for that page's roles
112
+ with `--style <style>`. A number → `metric,proof`; a list item →
113
+ `point,value,steps`; a comparison → `compare`; a real product →
114
+ `screenshot`. No match in that style → any style, keeping the cover's chrome.
115
+
116
+ Don't filter out references that need an image just because you have none:
117
+ most covers in the library have an image area. Use one and fill that area
118
+ without a photo (references/REFERENCES.md, "A reference's image area"). Keep a
119
+ placeholder only where the content needs a real screenshot or photo (step 5).
120
+ `--no-image` is for when you specifically want designs drawn with type alone.
121
+ Read each chosen design with `easysociable templates source --family <familyId> --json`
122
+ and adapt it as in `references/REFERENCES.md` ("Adapting a reference" and
123
+ "Avoid"). Put the result in the pack as a generated page:
99
124
 
100
125
  ```json
101
126
  { "role": "hook", "slots": { "text_0": "…", "text_1": "…" },
@@ -104,8 +129,10 @@ generated page:
104
129
  ```
105
130
 
106
131
  `slots` maps each `data-variable` to its plain text. Generated pages carry no
107
- `layoutFamilyId` / `pageTemplateId`. A Formula with a Look uses the Look's
108
- families as the sources instead of a Deck Style.
132
+ `layoutFamilyId` / `pageTemplateId`.
133
+
134
+ In the final message, add one line: "Want future carousels to look like this?
135
+ Say 'same as this'. Want another look? Say 'different look'."
109
136
 
110
137
  ### 5. Images
111
138
 
@@ -118,7 +145,7 @@ families as the sources instead of a Deck Style.
118
145
  placeholder slot** (as many pages as need one), never a text-only layout. Size it into the composition (usually the
119
146
  lower half of the page) and label it with exactly what belongs there, e.g.
120
147
  "Add: Grok Bot app screenshot". The user selects it in Studio and clicks
121
- the upload button to replace it. Markup and SVG in `DECK_STYLES.md`
148
+ the upload button to replace it. Markup and SVG in `references/REFERENCES.md`
122
149
  ("Image placeholder").
123
150
  - An image you do have: upload it
124
151
  (`easysociable images upload --file body.json` with
@@ -188,8 +215,40 @@ different topic, or when the user asks for an alternative version to compare.
188
215
  order and roles); `title_template` with `{X}` = the topic is the arc. Write copy
189
216
  from each `beat.fill` and your facts; never copy the formula's example posts.
190
217
  With `Look: L-…` (else the formula's first `looks` entry) the page source is
191
- `look.slides["<n>"]` or `look.layouts[beat.role]`: adapt that family exactly as
192
- in step 4. Then continue at step 5.
218
+ `look.slides["<n>"]` or `look.layouts[beat.role]` (a design's `familyId`):
219
+ read it with `templates source --family` and adapt it as in step 4. The Look
220
+ wins over rule 5 of step 4 but not over a Run or post the user named.
221
+ Then continue at step 5.
222
+
223
+ ## Reuse a Run (prompt names a `run_…` for a new topic)
224
+
225
+ A new topic → a **new** Run; the source Run is never changed. Never ask which
226
+ mode; decide from the words and the content:
227
+
228
+ - **Template** — "using run_x as the template", "same as last time", "like
229
+ this one" (last time = the newest Run of this Brand, `slideshows list`).
230
+ Keep every page's look: only slot content changes.
231
+ - **Style** — "in the style / feel / vibe of run_x", or Template was asked but
232
+ the new content does not fit its page roles (a "N tips" Run for an "A vs B"
233
+ topic). Take its colours, type treatment, chrome and spacing; lay pages out
234
+ fresh in step 4.
235
+
236
+ Template steps:
237
+
238
+ 1. `easysociable slideshows get --id <runId> --json`. Its pages' `role`,
239
+ `layout` and `slots` are the source (they include the user's Studio edits).
240
+ 2. Write facts and the arc for the new topic (steps 2–3, no Formula search).
241
+ 3. Pages by role: one-off roles (hook, cta) copy that page's `layout`
242
+ verbatim; repeated roles (point, step) reuse the source page of that role
243
+ **as many times as the new content needs** (4 tips → 4 pages, 6 → 6). Drop
244
+ roles the new content has none of.
245
+ 4. Change only text inside `data-variable` elements and send matching
246
+ `slots`. Too long → rewrite shorter; never resize boxes or move elements.
247
+ Every source image becomes a placeholder for the new topic (step 5);
248
+ Brand avatar/logo stay.
249
+ 5. Step 6 check, then create (step 7). In the reply, say in one line what
250
+ differs from the source ("6 tips, so 6 point pages instead of 4") and that
251
+ the user can say "back to 4 pages" or "different layout".
193
252
 
194
253
  ## Rules
195
254
 
@@ -201,7 +260,7 @@ in step 4. Then continue at step 5.
201
260
  3. Revisions edit the same Run page by page (step 8): layout, text and images
202
261
  can all change. Page count and order are fixed for now (no add, delete,
203
262
  reorder) — if the user needs that, say so; create a new Run only when they agree.
204
- 4. Free: up to 8 pages and 3 Downloads per month; paid: 20 pages, unmetered.
263
+ 4. Every plan: up to 20 pages. Free: 3 Downloads per month and 1 Brand; Creator: unlimited, 3 Brands; Studio: unlimited, 25 Brands. `BRAND_LIMIT_REACHED` → tell the user their plan's limit and the suggested action; never create a Run without the Brand silently.
205
264
  5. Identity: create with the user's own login, not `workspace_local` /
206
265
  `test-key` (unless they asked for `--allow-local-fixture`). Studio says
207
266
  "belongs to another account" → recreate with the current login.
@@ -220,6 +279,6 @@ in step 4. Then continue at step 5.
220
279
 
221
280
  ## Handoff boundary
222
281
 
223
- The Content Engine owns knowledge pages and Formula research. The Template
224
- skill owns authoring new catalog layouts. This skill turns a topic into a Run
282
+ The Content Engine owns knowledge pages and Formula research. Reference
283
+ designs are authored internally (Template skill); this skill only reads them. This skill turns a topic into a Run
225
284
  and opens Studio.
@@ -1,9 +1,8 @@
1
1
  # ContentPack v1
2
2
 
3
- A page is either **generated** (`layout: { studioJson, canvas }` adapted from a
4
- Deck Style family — the default, see `DECK_STYLES.md`) or a **catalog page**
5
- (`layoutFamilyId` / `pageTemplateId`, used as-is; only for Formula Looks the
6
- user asked to copy exactly). `role` is a weak tag from the closed enum, not a
3
+ A page is **generated**: `layout: { studioJson, canvas }` adapted from a
4
+ reference design (see `REFERENCES.md`). Catalog pages (`layoutFamilyId` /
5
+ `pageTemplateId`) are legacy; do not create new Runs with them. `role` is a weak tag from the closed enum, not a
7
6
  sequence position. `slots` are public values only. Do not add a
8
7
  `deck_template_id`, `bindingMap`, AST, ContentDocument, or product `arc` /
9
8
  `pageSequence`.
@@ -0,0 +1,104 @@
1
+ # Reference designs
2
+
3
+ A reference is a published catalog design (one canvas: the source post's) made
4
+ from a real post. Pages are **adapted from references**: you keep a reference's
5
+ composition, type scale, spacing and chrome, and replace content, colours
6
+ (Brand) and canvas size. You never copy one verbatim and never draw a page with
7
+ no reference at all.
8
+
9
+ Find references for a page role, shuffled, as short summaries:
10
+
11
+ ```bash
12
+ easysociable templates references --role hook,cover [--style <style>] [--exclude <familyIds>] [--no-image] --json
13
+ easysociable templates source --family <familyId> --json # the design's Studio source
14
+ ```
15
+
16
+ Roles overlap in the catalog, so pass related ones together: `hook,cover` ·
17
+ `point,value,steps,checklist` · `metric,proof,evidence` · `compare` ·
18
+ `screenshot` (needs an image) · `recap` · `cta,follow`. Styles: `minimal`,
19
+ `editorial`, `swiss`, `dark`, `bold_promo`.
20
+
21
+ ## Adapting a reference (the rules that make it look designed)
22
+
23
+ 1. Start from the reference's source. Keep its chrome (header, pill, page
24
+ number, rule, footer) only if the deck keeps it on every page; keep its
25
+ margins (`left` of the first column), type scale and fonts.
26
+ 2. Fit the Run's canvas: a reference made for another canvas (3:4, 9:16, 4:5)
27
+ keeps its left margin and type scale; re-space vertically, never squash text.
28
+ 3. Change text, then fix each text box: explicit `<br />` line breaks, and
29
+ `height` = lines × lineHeight + ~12% of fontSize for descenders.
30
+ 4. Remove what you do not need; add only elements copied from another reference
31
+ with the same `style` (rule rows, a stat row).
32
+ 4a. **A reference's image area** when you have no image and the content does
33
+ not need a real one: keep the area's box and fill it from the content with a
34
+ large number or keyword, a short quote with an oversized quote mark, an
35
+ accent-colour block carrying one word, or one icon from
36
+ `easysociable icons search` on a tinted block. Never a grey placeholder or an
37
+ empty box on the cover. If nothing fits, delete the area and give the
38
+ headline its space.
39
+ 5. Brand chrome: the header label is the Brand name (or the topic when there is
40
+ no Brand); the CTA names the Brand handle. Never leave a reference's original
41
+ name or handle (e.g. "Will.AI.m") on a page. **Bind them** so a Brand change
42
+ updates every page: the element holding only the Brand name gets
43
+ `data-brand="name"`, only the handle `data-brand="handle"`, and an avatar /
44
+ logo `<img>` gets `data-brand="avatar"` with the Brand's `logoUrl` as `src`.
45
+ Without a Brand, leave them unbound (the topic is not the Brand).
46
+ 6. Accent colour only on large text (≥ 36px, or ≥ 28px bold) and blocks. Small
47
+ labels use the text or muted colour.
48
+ 7. Semantic `data-type` values (`title`, `subtitle`, `kicker`, `metric`,
49
+ `caption`) get Brand colours forced by Studio. Text on an accent or image
50
+ block uses `label`, `body` or `statement` with an explicit colour.
51
+ 8. One deck = one `style`. No reference twice in a Run unless the page purpose
52
+ repeats (several numbered points), and no two adjacent pages with the same
53
+ composition.
54
+
55
+ ## Avoid (what makes every Run look the same)
56
+
57
+ - The same cover composition as this Brand's previous Run, unless the user
58
+ asked for "same as last time".
59
+ - Header label + pill + page number + "SWIPE →" on every page by habit: chrome
60
+ comes from the chosen reference, or there is none.
61
+ - An accent-coloured second half of the headline on more than two pages.
62
+ - A deck that is only left-aligned text stacks: at least one page's focal point
63
+ is not a headline (a big number, an image, a quote, a comparison).
64
+ - A generic "Save this / Follow for more" CTA when the content suggests a
65
+ specific action (comment a word, try the prompt, read the source).
66
+
67
+ ## Default palettes (no Brand)
68
+
69
+ Use one in `theme.json` as `{ "color": { "canvas", "text", "textMuted", "accent", "primary" } }`
70
+ (`primary` = `accent`), matched to the deck's style:
71
+
72
+ | Style | canvas / text / textMuted / accent |
73
+ |---|---|
74
+ | `editorial` | `#F4EEE7` / `#121A2B` / `#4A4F5C` / `#D4450F` |
75
+ | `minimal`, `swiss` | `#FFFFFF` / `#15191E` / `#384352` / `#445164` |
76
+ | `dark` | `#06080C` / `#FFFFFF` / `#C7CBD3` / `#4C9BFF` |
77
+ | `bold_promo` | `#F9F9F9` / `#0A0A0A` / `#555555` / `#0066DD` |
78
+
79
+ ## Image placeholder
80
+
81
+ A replaceable image slot for a real screenshot or photo the user will add.
82
+ Studio shows an upload button when it is selected.
83
+
84
+ ```jsx
85
+ <img data-type="image" data-variable="image_0" data-image-mode="slot_default"
86
+ alt="Add: <what goes here>" src="data:image/svg+xml;base64,<SVG>"
87
+ style={{ position: 'absolute', left: 88, top: 760, width: 904, height: 388, objectFit: 'cover', borderRadius: 24 }} />
88
+ ```
89
+
90
+ `<SVG>` is base64 of a grey box with an image icon and the label, sized to the slot:
91
+
92
+ ```xml
93
+ <svg xmlns='http://www.w3.org/2000/svg' width='904' height='388' viewBox='0 0 904 388'>
94
+ <rect width='904' height='388' fill='#DDD6CC'/>
95
+ <g transform='translate(416,124)' fill='none' stroke='#8C8781' stroke-width='5' stroke-linejoin='round'>
96
+ <rect width='72' height='56' rx='8'/><path d='M6 50 L26 28 L40 42 L50 34 L66 50'/><circle cx='52' cy='16' r='6'/>
97
+ </g>
98
+ <text x='50%' y='230' text-anchor='middle' font-family='Inter, Arial, sans-serif' font-size='32' font-weight='600' fill='#6F6A64'>Add: Grok Bot app screenshot</text>
99
+ </svg>
100
+ ```
101
+
102
+ Put the same data URL in the page's `slots` under `image_N`. Number slots
103
+ `image_0`, `image_1`, … per page. Use the style's own colours for the box
104
+ (canvas-adjacent grey on light styles, `#1A1F27` on dark ones).
@@ -1,7 +1,7 @@
1
1
  # Create Run
2
2
 
3
3
  Follow the Workflow in `SKILL.md` (login → Brand → facts → hook/structure →
4
- Deck Style pages → images → `scripts/check-pages.mjs` → create).
4
+ look + pages from references → images → `scripts/check-pages.mjs` → create).
5
5
 
6
6
  Notes for updates:
7
7
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: easysociable-template
3
3
  description: >
4
- Create single-page social image templates for EasySociable via the unified
5
- Template MCP or `easysociable` CLI. Default create path is a Layout Family:
6
- one master canvas plus derived multi-platform variants (e.g. XHS 3:4, IG/Threads 4:5,
7
- TikTok 9:16, LinkedIn 1:1) with hand-tuned layouts per preset. Use when the user wants
8
- to author a page template from a reference image or text brief, write a shared visual
4
+ Internal tool (opt-in install): turn a real post's page (reference image) or a
5
+ text brief into a single-canvas reference design for the slideshow skill's
6
+ reference library, then bind it to a Formula Look. One canvas only (the
7
+ source post's size, e.g. TikTok 9:16); no multi-platform variants. Use when the
8
+ maintainer wants to author a reference from a reference image or text brief, write a shared visual
9
9
  design philosophy, explore layout concepts, co-create Theme/preview tokens, pull icons
10
10
  via search_icons/get_icon, open Authoring Studio, or publish. Do not use for
11
11
  fill-slots hosted PNG jobs (`create_render_job` is retired), multi-slide slideshow
@@ -21,7 +21,7 @@ server. Do not install or invoke `easysociable-template`, `easysociable-slidesho
21
21
 
22
22
  **This skill owns template authoring:**
23
23
 
24
- 1. **Author** templates as a **Layout Family** (master + multi-platform variants) → Studio + Publish (`workflows/MULTI_PLATFORM_FAMILY.md`).
24
+ 1. **Author** reference designs: **one canvas**, the source post's size → Studio + Publish, then bind to a Formula Look (`workflows/BIND_FORMULA_LOOK.md`). Other platforms are re-laid out by the slideshow agent at generation time, so never derive variants.
25
25
  2. Fill-slots Hosted Render (`create_render_job`) is **retired** as a paid delivery path. Customer PNG packs come from Slideshow Studio Download.
26
26
 
27
27
  It is a template factory. It is **not** a multi-slide slideshow compositor and it is **not** a PNG API.
@@ -41,9 +41,9 @@ Out of scope (hand off):
41
41
  2. Submit only public Gateway DTOs. Never invent or request private Safe AST / Binding Map / RenderPlan.
42
42
  3. Do not start Local Runtime, read content library SQLite, or call Content MCP/CLI for Template work.
43
43
  4. Catalog and create targets are **single-page** only. Never treat site Carousel packs as Agent templates.
44
- 5. After `create` / `createDraft`, the primary authoring path is `authoringStudioUrl` (`/authoring/{draftId}`). **Default:** run `workflows/MULTI_PLATFORM_FAMILY.md` (derive + hand-tune variants) before handoff unless the user asked for one platform only. Always send the handoff in `AUTHORING_STUDIO.md` (edit → **Save** → tell Agent to publish). Do not require a Hosted Preview Job for interactive authoring.
44
+ 5. After `create` / `createDraft`, the primary authoring path is `authoringStudioUrl` (`/authoring/{draftId}`). One canvas only (never `families derive`). Always send the handoff in `AUTHORING_STUDIO.md` (edit → **Save** → tell Agent to publish). Do not require a Hosted Preview Job for interactive authoring.
45
45
  6. Studio has **Save only** — no Publish button. Publish only after the user saves and **explicitly** asks to publish; then run `workflows/PUBLISH_FROM_DRAFT.md`.
46
- 7. **Do not Publish without complete P0 selection metadata** (`CATALOG_METADATA.md`). Gateway enforces this. Each family variant carries its own `platforms` / `canvasPreset` / `canvas`.
46
+ 7. **Do not Publish without complete P0 selection metadata** (`CATALOG_METADATA.md`). Gateway enforces this. What the slideshow agent filters on must be right: `supportedRoles`, `contentArchetypes`, `requiresImage`, `visualStyle`, `bestFor`.
47
47
  8. Theme/preview: co-create `ThemeTokens` on draft create (`theme.create`) → Family `preview_tokens` (ADR-0033). No authoring TemplateTheme row. Colors/fonts via semantic `--es-*` on page nodes.
48
48
  9. Layout model is **absolute positioning** on a **flat canvas tree** (see prior authoring rules / `AUTHORING_SOURCE.md`).
49
49
  10. **Runtime layout CSS:** put exact geometry in JSX inline `style={{...}}`. Never depend on Tailwind arbitrary-value classes for geometry.
@@ -76,12 +76,12 @@ easysociable auth status --json
76
76
 
77
77
  | User intent | Workflow |
78
78
  |---|---|
79
- | Text description → template (incl. multi-platform) | `DESIGN_BRIEF.md` → … → `AUTHORING_STUDIO.md` → **`MULTI_PLATFORM_FAMILY.md`** (derive + hand-tune) |
80
- | Reference image → template | `AUTHORING_FROM_IMAGE.md` → … → `AUTHORING_STUDIO.md` → **`MULTI_PLATFORM_FAMILY.md`** + reference-compare QA on master |
81
- | “只要某一个平台” | Same authoring path; skip derive / only named presets in `MULTI_PLATFORM_FAMILY.md` |
79
+ | Text description → reference | `DESIGN_BRIEF.md` → … → `AUTHORING_STUDIO.md` → publish |
80
+ | Reference image (a real post's page) → reference | `AUTHORING_FROM_IMAGE.md` → … → `AUTHORING_STUDIO.md` (reference-compare QA) → publish |
81
+ | A viral post → its Formula's Look | each page via `AUTHORING_FROM_IMAGE.md` → publish → **`BIND_FORMULA_LOOK.md`** |
82
82
  | Need gradient / photo surface / icons only | `SURFACE_REVIEW.md` |
83
83
  | **Add / change an icon** (arrow, chevron, check, …) | **MUST** `SURFACE_REVIEW.md` § Icons — search → confirm → get_icon. **Do not** hand-draw SVG paths. |
84
- | Already have authoring payload / continue Studio | `workflows/AUTHORING_STUDIO.md` (+ family derive if variants still missing) |
84
+ | Already have authoring payload / continue Studio | `workflows/AUTHORING_STUDIO.md` |
85
85
  | User says publish / 发布该模板 (after Save) | `workflows/PUBLISH_FROM_DRAFT.md` |
86
86
  | Browse published single-page templates | `list` / `get_template` + public metadata |
87
87
  | **Fill a published template → PNG/JPEG** | `workflows/FILL_AND_RENDER.md` |
@@ -89,14 +89,14 @@ easysociable auth status --json
89
89
 
90
90
  ## Core model
91
91
 
92
- - `workflows/MULTI_PLATFORM_FAMILY.md` — **default** multi-platform create (Family + derive + hand-tune)
92
+ - `workflows/BIND_FORMULA_LOOK.md` — published references → a Formula's Look (role → design)
93
93
  - `references/PLATFORM_SPECS.md`
94
94
  - `references/CATALOG_METADATA.md`
95
95
  - `references/SLOTS.md` — public slot contract for fill-slots render
96
96
  - `references/AUTHORING_SOURCE.md`
97
97
  - `references/THEME_TOKENS.md` — Family `preview_tokens` (no TemplateTheme)
98
98
  - `references/EXTERNAL_RESOURCES.md`
99
- - `references/GATEWAY.md` — CLI / MCP including families derive + `render`
99
+ - `references/GATEWAY.md` — CLI / MCP
100
100
  - `workflows/FILL_AND_RENDER.md` — get_template → slots → Hosted Render
101
101
  - Authoring V2.1 workflows + validators as before
102
102
 
@@ -12,15 +12,13 @@ easysociable templates update-draft --id <id> --file ./patch.json --json
12
12
  easysociable templates validate --id <id> --json
13
13
  easysociable templates publish --id <id> --json
14
14
  easysociable templates families get --id <familyId> --json
15
- easysociable templates families derive --id <familyId> --presets 4:5,9:16,1:1 --json
16
- easysociable templates families migrate-legacy --json
17
15
  easysociable icons search --query "arrow" --json
18
16
  easysociable icons get --id <id> --idempotency-key <key> --json
19
17
  easysociable renders create --template-id <id> --slots ./slots.json --format png --idempotency-key render_1 --json
20
18
  easysociable renders wait --id <id> --json
21
19
  ```
22
20
 
23
- Multi-platform create flow (derive + hand-tune): `workflows/MULTI_PLATFORM_FAMILY.md`.
21
+ One canvas per reference; binding to a Formula: `workflows/BIND_FORMULA_LOOK.md`.
24
22
 
25
23
  All requests go through Gateway. The client receives public summaries, slot
26
24
  contracts, stable Image references and render Manifests only. It never receives
@@ -120,20 +120,18 @@ No platform chrome assumptions. Still pick a concrete preset (`1:1`, `4:5`, `3:4
120
120
 
121
121
  ---
122
122
 
123
- ## Layout Family (multi-platform create)
123
+ ## One canvas per reference
124
124
 
125
- Creating a template **defaults** to a Layout Family with one master page + derived presets — see `workflows/MULTI_PLATFORM_FAMILY.md`.
126
-
127
- Same-preset platforms share one variant tree (**Instagram + Threads → `4:5`**). Do not invent a second 4:5 page for Threads.
128
-
129
- Typical vertical bucket when master is `3:4` (Xiaohongshu): also derive `4:5`, `9:16`, `1:1`. Absolute layout cannot share one AST across those presets — hand-tune each variant after derive.
125
+ A reference design has exactly one canvas: the source post's (a TikTok post → `9:16`).
126
+ Never derive other presets; the slideshow agent re-lays a reference out for the
127
+ Run's platform.
130
128
 
131
129
  ## Selection rules for Agents
132
130
 
133
- 1. If user names one platform only → set master `platforms: [that]` + that platform’s **Recommended** row; skip family derive unless they later ask for more.
134
- 2. If user names several **or** does not limit platforms → pick a master Recommended canvas, then derive the default vertical targets (`MULTI_PLATFORM_FAMILY.md`).
131
+ 1. Canvas = the source post's platform **Recommended** row (text brief with no post → TikTok 9:16).
132
+ 2. One canvas only; no `families derive`.
135
133
  3. Never mix presets across slides of one deck without an explicit user choice (IG/Threads/TikTok crop to first slide).
136
- 4. Each family variant’s P0 `selectionMetadata` must list only platforms that match that page’s `canvasPreset`.
134
+ 4. P0 `selectionMetadata` lists only platforms that match the page's `canvasPreset`.
137
135
  5. Specs above are **practical authoring targets** (2026 guides + Meta help for IG). Re-verify if a platform announces breaking crop changes.
138
136
 
139
137
  ## Sources (research snapshot)
@@ -4,12 +4,12 @@ Primary intake when the user describes a single-page template in words (no refer
4
4
 
5
5
  ## Goal
6
6
 
7
- One publishable **single-page** template **Family** (master canvas + multi-platform variants by default): Design Brief → Design Philosophy → 2–3 Concepts → Asset Plan → Theme lock → master layout → Authoring Studio → `MULTI_PLATFORM_FAMILY.md`.
7
+ One publishable **single-page, single-canvas** reference design: Design Brief → Design Philosophy → 2–3 Concepts → Asset Plan → Theme lock → layout → Authoring Studio → publish.
8
8
 
9
9
  ## Steps
10
10
 
11
- 1. Confirm this is **one page**, not a slideshow. If they want a multi-slide deck, stop and hand off (`OUT_OF_SCOPE.md`). Multi-platform variants of the same page are expected — that is not a slideshow.
12
- 2. Read `references/PLATFORM_SPECS.md`. Lock **master** platform + recommended canvas, and the default vertical derive targets unless the user limited platforms (`MULTI_PLATFORM_FAMILY.md`).
11
+ 1. Confirm this is **one page**, not a slideshow. If they want a multi-slide deck, stop and hand off (`OUT_OF_SCOPE.md`).
12
+ 2. Read `references/PLATFORM_SPECS.md`. Lock platform + recommended canvas (one canvas).
13
13
  3. **Mandatory — V2.1 design plan first** (no reference image):
14
14
  - Follow `workflows/DESIGN_BRIEF.md`
15
15
  - Follow `workflows/DESIGN_PHILOSOPHY.md`; lock shared `philosophy` (+ companion `design-philosophy.md`)
@@ -30,7 +30,7 @@ One publishable **single-page** template **Family** (master canvas + multi-platf
30
30
  - `authoringSource` per `references/AUTHORING_SOURCE.md` (flat tree + text-nesting exception)
31
31
  - Theme per `references/THEME_TOKENS.md` — use `themeTokens` from validated `theme-tokens.json` for `theme.create`
32
32
  5. Run `scripts/validate-authoring-source.mjs <authoring-source.json>` and fix every error.
33
- 6. Continue with `workflows/AUTHORING_STUDIO.md` (`source.kind = text_brief`) → **`MULTI_PLATFORM_FAMILY.md`** (derive + hand-tune + QA each variant) before handoff.
33
+ 6. Continue with `workflows/AUTHORING_STUDIO.md` (`source.kind = text_brief`) → Visual QA before handoff.
34
34
 
35
35
  ## Checklist pages
36
36
 
@@ -79,7 +79,7 @@ If unsure whether a region is “illustration” vs “icon”: prefer **image s
79
79
  9. Propose Theme reuse or `ThemeTokens` create from `theme-tokens.json` (`references/THEME_TOKENS.md`).
80
80
  10. Show the user: geometry summary, **image inventory → slot map**, selection metadata, Theme. Call out any region you could not match and why. Proceed when they accept.
81
81
  11. Run `scripts/validate-authoring-source.mjs <authoring-source.json>` and fix every error.
82
- 12. Continue with `workflows/AUTHORING_STUDIO.md` (`source.kind = image_reference`, brief = path or short note) → **`MULTI_PLATFORM_FAMILY.md`** (derive + hand-tune other presets). Run Visual QA **including reference compare on the master** before handoff; still QA each derived variant for fit/clipping.
82
+ 12. Continue with `workflows/AUTHORING_STUDIO.md` (`source.kind = image_reference`, brief = path or short note) Run Visual QA **including reference compare** before handoff. One canvas only; after publish, bind it with `BIND_FORMULA_LOOK.md` when it comes from a Formula's post.
83
83
 
84
84
  ## Limits (state upfront when relevant)
85
85
 
@@ -18,11 +18,11 @@ Complete intake first:
18
18
  ## Layout Family (multi-platform)
19
19
 
20
20
  New drafts create a **Layout Family** (`familyId`) plus a master canvas page.
21
- **Default create path:** after the master draft exists, follow `MULTI_PLATFORM_FAMILY.md` (derive + hand-tune variants) before handoff unless the user asked for one platform only.
21
+ One canvas per reference: never derive platform variants.
22
22
 
23
23
  - Authoring URL: `/authoring/{draftId}?platform=…`. Top bar **platform chips** switch variants (do not resize one AST).
24
24
  - Preview skin = Family `preview_tokens` from `theme.create`; fill/render uses Brand snapshot first (ADR-0033).
25
- - Legacy drafts without `familyId` auto-wrap on `getDraft` / `listDrafts`. Bulk: `easysociable templates families migrate-legacy --json`.
25
+ - Legacy drafts without `familyId` auto-wrap on `getDraft` / `listDrafts`.
26
26
 
27
27
  ## Flow
28
28
 
@@ -47,9 +47,9 @@ AST or Binding Maps.
47
47
 
48
48
  3. Read `data.id` / `data.templateId` / `data.familyId` / `data.authoringStudioUrl` (and `data.variants` when present).
49
49
 
50
- 4. **Multi-platform (default):** run `workflows/MULTI_PLATFORM_FAMILY.md` — derive target presets, hand-tune each variant, QA each canvas. Skip only when the user asked for a single platform.
50
+ 4. One canvas only: do not run `families derive`.
51
51
 
52
- 5. **Before handoff, run `workflows/VISUAL_QA.md`** on the master (and each variant from step 4). Open the actual Studio render; inspect screenshots, not only source. When a draft fails, fix authoring JSON, validate, update that page id, and re-render:
52
+ 5. **Before handoff, run `workflows/VISUAL_QA.md`** on the page. Open the actual Studio render; inspect screenshots, not only source. When a draft fails, fix authoring JSON, validate, update that page id, and re-render:
53
53
 
54
54
  ```bash
55
55
  node scripts/validate-authoring-source.mjs ./authoring-source.json
@@ -0,0 +1,39 @@
1
+ # Bind references to a Formula Look
2
+
3
+ A Formula is the structure distilled from a real viral post; its **Look** says
4
+ which reference design each slide uses. The slideshow skill reads it
5
+ (`look.slides["<n>"]`, else `look.layouts[<role>]`) whenever that Formula is used.
6
+
7
+ ## When
8
+
9
+ After publishing the references for a post's pages (one reference per distinct
10
+ page layout, via `AUTHORING_FROM_IMAGE.md`).
11
+
12
+ ## Steps
13
+
14
+ 1. `easysociable formulas get --id <F-…> --json` — note its `beats` (slide order
15
+ and roles) and existing `looks`.
16
+ 2. Map each beat to a published design's `familyId`
17
+ (`easysociable templates list --canvas 9:16 --json` shows `familyId`):
18
+ - `layouts`: one design per role (`hook`, `point`, `cta`, …);
19
+ - `slides`: only for a slide whose design differs from its role's default
20
+ (1-based slide number → `familyId`).
21
+ 3. Write the Look:
22
+
23
+ ```json
24
+ { "id": "L-<short-name>",
25
+ "ref": { "platform": "tiktok", "platform_post_id": "<the post's id>" },
26
+ "layouts": { "hook": "fam_…", "point": "fam_…", "cta": "fam_…" },
27
+ "slides": { "2": "fam_…" } }
28
+ ```
29
+
30
+ 4. There is no public write API for Formulas: hand the JSON to the maintainer
31
+ to append to that Formula's `looks` in the Directus admin (a new Look goes
32
+ last, so the Formula's default Look — the first — does not change unless
33
+ they choose to reorder).
34
+ 5. Check: `easysociable formulas get --id <F-…> --json` shows the Look, and
35
+ every `familyId` in it resolves with
36
+ `easysociable templates source --family <familyId> --json`.
37
+
38
+ Never bind an agent-authored design that was not made from a real post: the
39
+ reference library only holds proven designs.
@@ -16,7 +16,7 @@ Skip this workflow when `AUTHORING_FROM_IMAGE.md` applies and a reference image
16
16
 
17
17
  ### 1. Gather intent (batch questions; skip known answers)
18
18
 
19
- - **Master** platform + canvas from `references/PLATFORM_SPECS.md`, plus default multi-platform derive targets (`MULTI_PLATFORM_FAMILY.md`) unless the user wants one platform only
19
+ - Platform + canvas from `references/PLATFORM_SPECS.md` (one canvas: the source post's)
20
20
  - Page roles (1–2) + contentFamily / archetypes / density (`CATALOG_METADATA.md`)
21
21
  - Content job: what must the viewer understand in one glance?
22
22
  - Must-have slots: title / metric / image / CTA / fixed N checklist lines…
@@ -31,8 +31,7 @@ Use this structure (Chinese or English to match the user):
31
31
 
32
32
  ## 1. Job to be done
33
33
  - One-sentence purpose of this page
34
- - Master platform + canvas (preset + pixels) — cite PLATFORM_SPECS recommended row
35
- - Multi-platform targets (default vertical bucket unless user limited) — `MULTI_PLATFORM_FAMILY.md`
34
+ - Platform + canvas (preset + pixels) — cite PLATFORM_SPECS recommended row
36
35
 
37
36
  ## 2. Visual constraints
38
37
  - Desired/forbidden moods or brand rules