@easysociable/cli 0.1.0
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/LICENSE +21 -0
- package/README.md +95 -0
- package/bin/easysociable.js +15 -0
- package/dist/easysociable.js +35464 -0
- package/dist/easysociable.js.map +1 -0
- package/package.json +58 -0
- package/skills/ONBOARDING.md +61 -0
- package/skills/easysociable-content/SKILL.md +115 -0
- package/skills/easysociable-content/platforms/claude.md +5 -0
- package/skills/easysociable-content/platforms/codex.md +5 -0
- package/skills/easysociable-content/platforms/hermes.md +5 -0
- package/skills/easysociable-content/platforms/openclaw.md +5 -0
- package/skills/easysociable-content/references/CLI.md +27 -0
- package/skills/easysociable-content/references/MCP.md +20 -0
- package/skills/easysociable-content/references/PAGE_PACK.md +6 -0
- package/skills/easysociable-content/references/TROUBLESHOOTING.md +11 -0
- package/skills/easysociable-content/references/VAULT.md +20 -0
- package/skills/easysociable-content/scripts/setup.mjs +156 -0
- package/skills/easysociable-content/scripts/setup.test.mjs +71 -0
- package/skills/easysociable-content/scripts/starter.mjs +53 -0
- package/skills/easysociable-content/workflows/ANALYSIS_AND_COVERAGE.md +8 -0
- package/skills/easysociable-content/workflows/CONTENT_EXPORT.md +19 -0
- package/skills/easysociable-content/workflows/DEVICE_TASKS.md +5 -0
- package/skills/easysociable-content/workflows/EXPERIMENTS.md +6 -0
- package/skills/easysociable-content/workflows/MCP_FIRST.md +10 -0
- package/skills/easysociable-content/workflows/PUBLICATION.md +5 -0
- package/skills/easysociable-content/workflows/TOPIC_DRAFT.md +5 -0
- package/skills/easysociable-content/workflows/WORKING_DRAFT.md +10 -0
- package/skills/easysociable-slideshow/SKILL.md +77 -0
- package/skills/easysociable-slideshow/references/CONTENT_PACK.md +25 -0
- package/skills/easysociable-slideshow/references/GATEWAY.md +16 -0
- package/skills/easysociable-slideshow/references/PLATFORM_CAPS.md +17 -0
- package/skills/easysociable-slideshow/references/VAULT.md +18 -0
- package/skills/easysociable-slideshow/workflows/CREATE_RUN.md +7 -0
- package/skills/easysociable-slideshow/workflows/MCP_FIRST.md +14 -0
- package/skills/easysociable-slideshow/workflows/OUT_OF_SCOPE.md +8 -0
- package/skills/easysociable-slideshow/workflows/PUBLISH_RUN.md +4 -0
- package/skills/easysociable-slideshow/workflows/RENDER_RUN.md +6 -0
- package/skills/easysociable-template/SKILL.md +106 -0
- package/skills/easysociable-template/references/AUTHORING_SOURCE.md +129 -0
- package/skills/easysociable-template/references/CATALOG_METADATA.md +221 -0
- package/skills/easysociable-template/references/DESIGN_INTELLIGENCE.md +69 -0
- package/skills/easysociable-template/references/DESIGN_V2_1.md +278 -0
- package/skills/easysociable-template/references/EXTERNAL_RESOURCES.md +52 -0
- package/skills/easysociable-template/references/GATEWAY.md +25 -0
- package/skills/easysociable-template/references/PLATFORM_SPECS.md +134 -0
- package/skills/easysociable-template/references/SLOTS.md +104 -0
- package/skills/easysociable-template/references/THEME_PRESETS.md +48 -0
- package/skills/easysociable-template/references/THEME_TOKENS.md +89 -0
- package/skills/easysociable-template/references/fixtures/surface-gradient.design-plan.json +74 -0
- package/skills/easysociable-template/references/theme-presets.json +95 -0
- package/skills/easysociable-template/scripts/generate-theme-from-hex.mjs +402 -0
- package/skills/easysociable-template/scripts/validate-authoring-source.mjs +228 -0
- package/skills/easysociable-template/scripts/validate-design-v2.mjs +318 -0
- package/skills/easysociable-template/workflows/ASSET_PLAN.md +34 -0
- package/skills/easysociable-template/workflows/AUTHORING_FROM_BRIEF.md +52 -0
- package/skills/easysociable-template/workflows/AUTHORING_FROM_IMAGE.md +52 -0
- package/skills/easysociable-template/workflows/AUTHORING_STUDIO.md +122 -0
- package/skills/easysociable-template/workflows/DESIGN_BRIEF.md +92 -0
- package/skills/easysociable-template/workflows/DESIGN_CONCEPTS.md +41 -0
- package/skills/easysociable-template/workflows/DESIGN_PHILOSOPHY.md +69 -0
- package/skills/easysociable-template/workflows/FILL_AND_RENDER.md +86 -0
- package/skills/easysociable-template/workflows/MCP_FIRST.md +9 -0
- package/skills/easysociable-template/workflows/OUT_OF_SCOPE.md +15 -0
- package/skills/easysociable-template/workflows/PALETTE_REVIEW.md +71 -0
- package/skills/easysociable-template/workflows/PUBLISH_FROM_DRAFT.md +60 -0
- package/skills/easysociable-template/workflows/SURFACE_REVIEW.md +178 -0
- package/skills/easysociable-template/workflows/THEME_FROM_BRAND.md +73 -0
- package/skills/easysociable-template/workflows/VISUAL_QA.md +55 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Catalog / selection metadata (single-page template)
|
|
2
|
+
|
|
3
|
+
Metadata that makes a published page template **discoverable and choosable** when Content Skill builds a slideshow.
|
|
4
|
+
Private AST/bindings stay server-side; this document is the **public selection contract** Agents must fill before Publish.
|
|
5
|
+
|
|
6
|
+
## Design choices (locked)
|
|
7
|
+
|
|
8
|
+
1. **One closed `pageRoles` set** (stored as `supportedRoles`) — narrative beat + layout kind in one enum. Do not maintain a second parallel taxonomy.
|
|
9
|
+
2. **`platforms` is a multi-select array**. Include `generic` when the page fits any platform at that aspect.
|
|
10
|
+
3. **P0 fields are required to Publish.** P1 should be filled when known; P2 optional.
|
|
11
|
+
|
|
12
|
+
Max **1–2** `supportedRoles` per page (primary + optional secondary).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Closed enums
|
|
17
|
+
|
|
18
|
+
### Platforms (`platforms: Platform[]`)
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
xiaohongshu | tiktok | instagram | threads | x | linkedin | wechat_cover | generic
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Multi-select. Use `x` for X/Twitter. See **exact recommended pixels** in `references/PLATFORM_SPECS.md` before choosing `canvasPreset`.
|
|
25
|
+
|
|
26
|
+
### Canvas preset (`canvasPreset`)
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
3:4 | 4:5 | 9:16 | 16:9 | 1:1 | 21:9 | custom
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Always also store exact `canvas: { width, height }`. Use `16:9` for X **1200×675** in-stream; use `custom` for non-standard boards like link cards **1200×628**. Prefer the platform **Recommended** row in `PLATFORM_SPECS.md`.
|
|
33
|
+
|
|
34
|
+
### Page roles (`supportedRoles` / pageRoles) — pick 1–2
|
|
35
|
+
|
|
36
|
+
| Role | When to use |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `cover` | Cover / first-frame poster |
|
|
39
|
+
| `hook` | Scroll-stop hook (often with cover) |
|
|
40
|
+
| `setup` | Setup / problem framing |
|
|
41
|
+
| `context` | Background / context |
|
|
42
|
+
| `value` | Single takeaway / value page |
|
|
43
|
+
| `point` | One sharp point (lighter than value) |
|
|
44
|
+
| `checklist` | Fixed N text lines (no list binding type) |
|
|
45
|
+
| `proof` | Proof / credibility |
|
|
46
|
+
| `evidence` | Evidence artifacts (data, case) |
|
|
47
|
+
| `compare` | Before/after or A/B compare |
|
|
48
|
+
| `screenshot` | App/web UI screenshot frame |
|
|
49
|
+
| `metric` | Big number / KPI / milestone |
|
|
50
|
+
| `quote` | Pull quote / testimonial |
|
|
51
|
+
| `steps` | Fixed-step howto |
|
|
52
|
+
| `cta` | Call to action |
|
|
53
|
+
| `follow` | Follow / profile CTA |
|
|
54
|
+
| `recap` | Summary / closing recap |
|
|
55
|
+
|
|
56
|
+
Legacy-compatible: `cover`, `setup`, `value`, `proof`, `cta` remain valid.
|
|
57
|
+
|
|
58
|
+
### Content family (`contentFamily`) — pick one
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
narrative | utility | social_proof | conversion
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Content archetypes (`contentArchetypes`) — pick ≥1 from closed set
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
product_review | tool_demo | tutorial | listicle
|
|
68
|
+
personal_story | opinion | news_explainer
|
|
69
|
+
lifestyle | travel | fitness | food_recipe
|
|
70
|
+
career | finance_lite | ai_update
|
|
71
|
+
launch | changelog | milestone_celebrate
|
|
72
|
+
ugc_repost | quote_card
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Density (`density`)
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
low | medium | high
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Align with `textDensityRange` when both are set (e.g. low → `[0, 0.34]`, medium → `[0.33, 0.67]`, high → `[0.66, 1]`).
|
|
82
|
+
|
|
83
|
+
### Visual style (`visualStyle`) — P1
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
swiss | editorial | bold_promo | minimal | dark
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Image roles (`imageRoles`) — when any image slot exists
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
hero | screenshot | avatar | product
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## P0 — required before Publish / must appear on Catalog summary
|
|
98
|
+
|
|
99
|
+
| Field | Type | Notes |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `name` | string | Human title |
|
|
102
|
+
| `shortDescription` | string | One sentence for chooser UI |
|
|
103
|
+
| `platforms` | `Platform[]` | Multi-select; use `generic` when truly cross-platform |
|
|
104
|
+
| `canvasPreset` | preset enum | Plus exact `canvas` pixels |
|
|
105
|
+
| `canvas` | `{ width, height }` | Exact board |
|
|
106
|
+
| `supportedRoles` | pageRole[1..2] | Closed set above |
|
|
107
|
+
| `contentFamily` | enum | Narrows before archetype |
|
|
108
|
+
| `contentArchetypes` | archetype[] | ≥1 from closed set |
|
|
109
|
+
| `density` | low/medium/high | |
|
|
110
|
+
| `textDensityRange` | `[number, number]` | Keep in sync with density |
|
|
111
|
+
| `requiresImage` | boolean | |
|
|
112
|
+
| `imageRoles` | imageRole[] | Required if `requiresImage` or any image slot |
|
|
113
|
+
| `mediaRequirements` | string[] | Normalized hints, e.g. `image`, `screenshot` |
|
|
114
|
+
| `slotSummary` | `{ text, number, image }` | Counts of slots by type |
|
|
115
|
+
| `fixedItemCount` | number? | Set for `checklist` / `steps` (absolute layout) |
|
|
116
|
+
| `previewImageUrl` | url? | Required when Gateway/Studio can supply; block Publish if product requires it |
|
|
117
|
+
| `tier` | `free` \| `paid` | From entitlement / owner; do not invent paid for free users |
|
|
118
|
+
|
|
119
|
+
### `slotSummary` example
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{ "text": 4, "number": 1, "image": 1 }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Derived from the slot table in `SLOTS.md`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## P1 — fill when known (strongly recommended)
|
|
130
|
+
|
|
131
|
+
| Field | Type | Notes |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| `bestFor` | string[2..4] | “适合…” bullets for users |
|
|
134
|
+
| `notFor` | string[1..3] | Honest exclusions |
|
|
135
|
+
| `selectionHints` | string | Short Agent-only hint |
|
|
136
|
+
| `visualStyle` | enum | Look affinity |
|
|
137
|
+
| `defaultThemeId` | string? | Soft preview theme |
|
|
138
|
+
| `compatibleThemeIds` | string[]? | Optional |
|
|
139
|
+
| `locale` | `zh-CN` \| `en` \| `bilingual` | |
|
|
140
|
+
| `exampleFilledPreviewUrl` | url? | Filled sample beats empty shell |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## P2 — optional
|
|
145
|
+
|
|
146
|
+
| Field | Notes |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `safeAreaProfile` | e.g. `xhs_default`, `ig_feed` |
|
|
149
|
+
| `featured` | Catalog boost |
|
|
150
|
+
| `colorDependency` | `theme_only` (preferred for new templates) \| `has_hardcoded_accents` |
|
|
151
|
+
| `tags` | Free-form search aides only — never replace closed enums |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Agent selection order (for Content → slideshow)
|
|
156
|
+
|
|
157
|
+
Content Skill exports a template-neutral `ContentDocument` (slide roles + fields only).
|
|
158
|
+
**Compose** (Template Skill / Desktop / render workflow) then selects pages:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
1. platforms ∩ aspect/canvasPreset
|
|
162
|
+
2. slide needs role ∈ supportedRoles
|
|
163
|
+
3. contentFamily / contentArchetypes match topic
|
|
164
|
+
4. requiresImage / imageRoles vs available assets
|
|
165
|
+
5. density + slotSummary (+ fixedItemCount) fit copy
|
|
166
|
+
6. Present 3–5 candidates: preview + name + shortDescription + bestFor
|
|
167
|
+
7. User confirms, or accept account/system default Look (Theme) separately
|
|
168
|
+
8. createRender with selected pageTemplateIds (never dump AST to the agent)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Example list call:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
easysociable templates list --platforms x --roles metric --density low --limit 5 --json
|
|
175
|
+
# MCP: list_templates({ platforms:['xiaohongshu'], roles:['metric'], density:'low', limit:5 })
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Catalog rules**
|
|
179
|
+
|
|
180
|
+
- Only **published** pages with complete P0 `selection_metadata` appear in `list`.
|
|
181
|
+
- Do **not** list every PageTemplate AST. Explain choices with this public metadata only.
|
|
182
|
+
- Content Skill must not call Directus / TemplatePage; keep ADR-0019 surface split.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Authoring checklist (before create / before Publish)
|
|
187
|
+
|
|
188
|
+
Agent must produce a `selection-metadata.json` (or equivalent fields on the draft) containing **all P0** keys. Confirm with the user when roles/platforms were inferred from a brief or reference image.
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"name": "XHS metric milestone 3:4",
|
|
193
|
+
"shortDescription": "大数字涨粉庆祝页,可选头像",
|
|
194
|
+
"platforms": ["xiaohongshu", "generic"],
|
|
195
|
+
"canvasPreset": "3:4",
|
|
196
|
+
"canvas": { "width": 1080, "height": 1440 },
|
|
197
|
+
"supportedRoles": ["metric", "cover"],
|
|
198
|
+
"contentFamily": "conversion",
|
|
199
|
+
"contentArchetypes": ["milestone_celebrate", "launch"],
|
|
200
|
+
"density": "low",
|
|
201
|
+
"textDensityRange": [0, 0.34],
|
|
202
|
+
"requiresImage": false,
|
|
203
|
+
"imageRoles": ["avatar"],
|
|
204
|
+
"mediaRequirements": [],
|
|
205
|
+
"slotSummary": { "text": 2, "number": 1, "image": 1 },
|
|
206
|
+
"fixedItemCount": null,
|
|
207
|
+
"visualStyle": "swiss",
|
|
208
|
+
"bestFor": ["涨粉节点", "数据庆祝封面"],
|
|
209
|
+
"notFor": ["长清单干货", "多步教程"],
|
|
210
|
+
"selectionHints": "Prefer when slide.role is metric or cover and a single KPI dominates.",
|
|
211
|
+
"locale": "zh-CN"
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Anti-patterns
|
|
216
|
+
|
|
217
|
+
- Tagging five roles on one page “just in case”
|
|
218
|
+
- Using only free-form `tags` instead of `supportedRoles` / archetypes
|
|
219
|
+
- Checklist without `fixedItemCount`
|
|
220
|
+
- `requiresImage: true` but `imageRoles` empty
|
|
221
|
+
- Platforms empty or inventing values outside the enum
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Design intelligence (lightweight)
|
|
2
|
+
|
|
3
|
+
Curated hints for philosophy, concept, and palette phases when the user has no brand hex. Not a replacement for `DESIGN_PHILOSOPHY.md` or `DESIGN_CONCEPTS.md` — use to seed `movementName`, `paletteCandidates`, and font pairing.
|
|
4
|
+
|
|
5
|
+
## Movement seeds (adapted from canvas-design; template-safe)
|
|
6
|
+
|
|
7
|
+
Use these as philosophy starters. Rewrite into `design-plan.json` `philosophy` fields; keep required slots readable.
|
|
8
|
+
|
|
9
|
+
| Seed movement | Space / composition | Rhythm / motif | Color mood | Font voice | Suggested hex |
|
|
10
|
+
|---------------|---------------------|----------------|------------|------------|---------------|
|
|
11
|
+
| Editorial Monument | One oversized focal; quiet gutters; thin attribution rail | Ledger rules, folio marks | Warm paper, dark ink, one accent | Editorial (serif display + Inter body) | `#0D9488` light |
|
|
12
|
+
| Terminal Pulse | Compact header; centered status metric; tabular footer | Prompt glyph, status dot, hairline grid | Near-black canvas, electric accent | Terminal (JetBrains Mono + Inter) | `#14B8A6` dark |
|
|
13
|
+
| Quiet Proof | Centered claim; generous negative space; small evidence row | Thin rules, soft dividers | Off-white, muted slate, restrained accent | Premium / editorial | `#475569` light |
|
|
14
|
+
| Warm Folio | Asymmetric author block; hero quote or metric; soft margin marks | Paper edge, soft rules | Cream-warm canvas, amber or deep ink | Premium | `#B45309` light |
|
|
15
|
+
| Signal Strip | Strong horizontal bands; one CTA or metric band dominates | Bars, ticks, progress marks | Neutral canvas, semantic green/blue sparingly | Modern SaaS (Inter/Inter) | `#2563EB` light |
|
|
16
|
+
| Creator Spark | Playful asymmetry; one bold gesture type; sparse stickers as siblings | Blobs/dots as CSS only | Light canvas, saturated accent | Playful | `#DB2777` light |
|
|
17
|
+
|
|
18
|
+
Map seed → `philosophy`:
|
|
19
|
+
|
|
20
|
+
- `movementName` ← seed name
|
|
21
|
+
- `space` / `composition` ← Space / composition column
|
|
22
|
+
- `rhythm` ← Rhythm / motif
|
|
23
|
+
- `color` ← Color mood (no final hex)
|
|
24
|
+
- `typographyAccent` ← Font voice + display/body ratio intent
|
|
25
|
+
- `craftBar` ← always include: one focal; no overlap; refine before adding decoration
|
|
26
|
+
|
|
27
|
+
## Archetype → style hints
|
|
28
|
+
|
|
29
|
+
| Archetype | Prefer movement seed | Layout bias | Palette mood |
|
|
30
|
+
|-----------|----------------------|-------------|--------------|
|
|
31
|
+
| Editorial / report | Editorial Monument | author rail, oversized metric | warm canvas, dark ink, one accent |
|
|
32
|
+
| Terminal / indie hacker | Terminal Pulse | compact header, centered metric | dark canvas, electric accent |
|
|
33
|
+
| Playful / creator | Creator Spark | asymmetric blocks | light canvas, saturated accent |
|
|
34
|
+
| Luxury / premium | Warm Folio / Quiet Proof | centered hero, small caps metadata | off-white canvas, gold or deep accent |
|
|
35
|
+
| Data / dashboard | Signal Strip | grid of metrics (still one primary focal) | neutral canvas, semantic green/red sparingly |
|
|
36
|
+
|
|
37
|
+
## Suggested brand hex (no user color)
|
|
38
|
+
|
|
39
|
+
Prefer curated presets in `references/THEME_PRESETS.md` / `theme-presets.json`, then generate with `--preset`. Fall back to mood hexes below only when presets do not fit.
|
|
40
|
+
|
|
41
|
+
| Mood | Light mode hex | Dark mode hex | Notes | Close preset |
|
|
42
|
+
|------|----------------|---------------|-------|--------------|
|
|
43
|
+
| Trust / finance | `#0D9488` | `#14B8A6` | teal — readable on white and near-black | `ocean-depths` |
|
|
44
|
+
| Energy / growth | `#16A34A` | `#22C55E` | green — watch muted contrast on light gray | `botanical-garden` |
|
|
45
|
+
| Tech / product | `#2563EB` | `#3B82F6` | blue — strong default for SaaS | `tech-innovation` |
|
|
46
|
+
| Bold / creator | `#DB2777` | `#EC4899` | pink — verify muted text on canvas | `desert-rose` (softer) |
|
|
47
|
+
| Premium | `#B45309` | `#D97706` | amber — pair with warm off-white canvas | `golden-hour` |
|
|
48
|
+
| Neutral authority | `#475569` | `#94A3B8` | slate — safe when accent must stay subtle | `modern-minimalist` |
|
|
49
|
+
|
|
50
|
+
## Font pairing (Gateway `themeTokens.fonts`)
|
|
51
|
+
|
|
52
|
+
| Voice | heading | body |
|
|
53
|
+
|-------|---------|------|
|
|
54
|
+
| Editorial | Georgia, serif stack | Inter |
|
|
55
|
+
| Terminal | JetBrains Mono | Inter |
|
|
56
|
+
| Modern SaaS | Inter | Inter |
|
|
57
|
+
| Playful | Fredoka | Nunito |
|
|
58
|
+
| Premium | Playfair Display | Source Sans 3 |
|
|
59
|
+
|
|
60
|
+
Use platform-safe stacks if custom fonts are not loaded — default to `Inter` for both when unsure. Do **not** vendor canvas-design’s `canvas-fonts` TTFs into this skill.
|
|
61
|
+
|
|
62
|
+
## Workflow tie-in
|
|
63
|
+
|
|
64
|
+
1. After Brief, run `DESIGN_PHILOSOPHY.md` and seed `movementName` from the table above when needed.
|
|
65
|
+
2. During `DESIGN_CONCEPTS.md`, attach `philosophyExpression` + named `paletteCandidates` (`name`, `brandHex`, `mode`, `bestFor`, optional `presetId`) per concept.
|
|
66
|
+
3. After selection, run `PALETTE_REVIEW.md`: showcase swatches → wait for explicit confirmation → lock winner.
|
|
67
|
+
4. Run `THEME_FROM_BRAND.md` (`--preset` or hex) to produce `theme-tokens.json`; do not `theme.create` until confirmed.
|
|
68
|
+
|
|
69
|
+
Do not treat this table as exhaustive — adjust hex when contrast fails.
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# V2.1 design and visual-QA contracts
|
|
2
|
+
|
|
3
|
+
Use these local artifacts to make art direction and screenshot review explicit. They are workflow artifacts, not Gateway DTOs.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- `design-philosophy.md`: human-readable visual philosophy (optional companion to the JSON field)
|
|
8
|
+
- `design-plan.json`: philosophy, art direction, concept selection, asset decisions, and theme preview
|
|
9
|
+
- `theme-tokens.json`: generated brand scale, semantic colors, and WCAG contrast report
|
|
10
|
+
- `visual-qa.json`: screenshot evidence, fixed scores, and pass/revise verdict
|
|
11
|
+
|
|
12
|
+
## `design-plan.json`
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"schemaVersion": "design_plan_v2_1",
|
|
17
|
+
"sourceKind": "text_brief",
|
|
18
|
+
"intent": {
|
|
19
|
+
"jobToBeDone": "Make monthly revenue understandable in one glance",
|
|
20
|
+
"primaryPlatform": "x",
|
|
21
|
+
"canvas": { "width": 1200, "height": 675 }
|
|
22
|
+
},
|
|
23
|
+
"philosophy": {
|
|
24
|
+
"movementName": "Editorial Ledger",
|
|
25
|
+
"space": "Generous top margin; one monumental metric zone; quiet side gutters",
|
|
26
|
+
"color": "Warm paper canvas, near-black ink, one teal accent; decoration stays ink-weight",
|
|
27
|
+
"rhythm": "Horizontal ledger rules and folio marks at a fixed cadence",
|
|
28
|
+
"composition": "Author rail top; oversized metric center-left; breakdown as a thin footer band",
|
|
29
|
+
"typographyAccent": "Display metric ~4x body; metadata in small caps or mono; no paragraph stacks",
|
|
30
|
+
"craftBar": "Museum-grade spacing; no overlap; one focal; refine before adding decoration",
|
|
31
|
+
"subtleReference": "Monthly close / ledger credibility without literal spreadsheet chrome",
|
|
32
|
+
"templateConstraints": "Required brief slots stay bindable; flat absolute siblings; Theme owns color; never flatten copy into a generated poster"
|
|
33
|
+
},
|
|
34
|
+
"concepts": [
|
|
35
|
+
{
|
|
36
|
+
"id": "editorial-ledger",
|
|
37
|
+
"name": "Editorial ledger",
|
|
38
|
+
"rationale": "Use report-like credibility and one oversized metric",
|
|
39
|
+
"philosophyExpression": "Monumental metric left of center; rules as quiet rhythm; author attribution as a thin top rail",
|
|
40
|
+
"visualMotif": "ledger rules and folio marks",
|
|
41
|
+
"layout": "author rail at top, metric center-left, breakdown footer",
|
|
42
|
+
"hierarchy": "revenue > period/title > author > breakdown",
|
|
43
|
+
"typography": "display metric at roughly 4x body scale",
|
|
44
|
+
"colorStrategy": "warm canvas, dark ink, one green accent",
|
|
45
|
+
"paletteCandidates": [
|
|
46
|
+
{
|
|
47
|
+
"name": "Ocean Depths",
|
|
48
|
+
"presetId": "ocean-depths",
|
|
49
|
+
"brandHex": "#1A6B6B",
|
|
50
|
+
"mode": "light",
|
|
51
|
+
"bestFor": "Finance, consulting, trust-building metric cards",
|
|
52
|
+
"label": "teal editorial"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"assetStrategy": "avatar plus CSS/SVG rules; no hero illustration",
|
|
56
|
+
"risks": ["long currency strings"]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "terminal-scorecard",
|
|
60
|
+
"name": "Terminal scorecard",
|
|
61
|
+
"rationale": "Give an indie-hacker technical voice",
|
|
62
|
+
"philosophyExpression": "Same ledger philosophy expressed as a compact prompt header and centered status metric",
|
|
63
|
+
"visualMotif": "terminal prompt and status light",
|
|
64
|
+
"layout": "compact author header, centered metric, tabular footer",
|
|
65
|
+
"hierarchy": "revenue > growth > author",
|
|
66
|
+
"typography": "large grotesk metric with monospace metadata",
|
|
67
|
+
"colorStrategy": "near-black canvas and one electric accent",
|
|
68
|
+
"paletteCandidates": [
|
|
69
|
+
{ "brandHex": "#0D9488", "mode": "dark", "label": "teal terminal" }
|
|
70
|
+
],
|
|
71
|
+
"assetStrategy": "avatar and CSS grid",
|
|
72
|
+
"risks": ["neon contrast can become harsh"]
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"selectedConceptId": "editorial-ledger",
|
|
76
|
+
"selectionReason": "Best matches a trustworthy monthly report",
|
|
77
|
+
"themePreview": {
|
|
78
|
+
"name": "Ocean Depths",
|
|
79
|
+
"presetId": "ocean-depths",
|
|
80
|
+
"brandHex": "#1A6B6B",
|
|
81
|
+
"activeMode": "light",
|
|
82
|
+
"contrastPass": true,
|
|
83
|
+
"bestFor": "Finance, consulting, trust-building metric cards",
|
|
84
|
+
"themeTokensPath": "theme-tokens.json",
|
|
85
|
+
"userConfirmed": true
|
|
86
|
+
},
|
|
87
|
+
"surfacePreview": {
|
|
88
|
+
"kind": "gradient",
|
|
89
|
+
"userConfirmed": true,
|
|
90
|
+
"recipeId": "grad_001_warm-flame",
|
|
91
|
+
"name": "Warm Flame",
|
|
92
|
+
"provider": "webgradients",
|
|
93
|
+
"textSafeZone": "light_end",
|
|
94
|
+
"contrastAnchor": "#FAD0C4",
|
|
95
|
+
"placement": "full_bleed"
|
|
96
|
+
},
|
|
97
|
+
"assetPlan": [
|
|
98
|
+
{
|
|
99
|
+
"role": "avatar",
|
|
100
|
+
"source": "user_upload",
|
|
101
|
+
"required": true,
|
|
102
|
+
"description": "X profile avatar",
|
|
103
|
+
"treatment": "circular crop; retain face focal point"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"role": "background",
|
|
107
|
+
"source": "gradient_catalog",
|
|
108
|
+
"required": false,
|
|
109
|
+
"description": "Warm Flame wash under metric"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"role": "decorative",
|
|
113
|
+
"source": "css_svg",
|
|
114
|
+
"required": false,
|
|
115
|
+
"description": "ledger rules and small folio marks"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Rules:
|
|
122
|
+
|
|
123
|
+
- `text_brief` requires 2–3 concepts; `image_reference` permits one.
|
|
124
|
+
- `text_brief` requires root `philosophy` with non-empty `movementName`, `space`, `color`, `rhythm`, `composition`, `typographyAccent`, and `craftBar`.
|
|
125
|
+
- `image_reference` should include a short reverse-engineered `philosophy` (same fields) so Visual QA has a craft bar.
|
|
126
|
+
- Optional philosophy fields: `subtleReference`, `templateConstraints` (recommended).
|
|
127
|
+
- Concepts must have unique IDs and all listed art-direction fields.
|
|
128
|
+
- Every concept requires `philosophyExpression` (how this layout expresses the shared philosophy in space).
|
|
129
|
+
- Concept `layout` / `hierarchy` / `typography` must be traceable to philosophy fields (documented rule; not NLP-checked).
|
|
130
|
+
- Concepts are spatial expressions of **one** shared philosophy — not unrelated slogans. Changing only colors is not a different concept.
|
|
131
|
+
- `selectedConceptId` must reference a concept.
|
|
132
|
+
- `selectionReason` is required.
|
|
133
|
+
- `assetPlan` may be empty when the concept intentionally uses typography only.
|
|
134
|
+
- Allowed asset roles: `background`, `hero`, `decorative`, `avatar`, `logo`, `icon`.
|
|
135
|
+
- Allowed sources: `user_upload`, `brand_kit`, `css_svg`, `gradient_catalog`, `asset_library`, `template_icon_catalog` (legacy alias `better_icons`), `external_photo`, `generated`, `none`.
|
|
136
|
+
- Optional per concept: `paletteCandidates` — array of `{ brandHex, mode, name?, presetId?, bestFor?, notFor?, label? }` where `mode` is `light` or `dark`. Prefer `name` + `bestFor` when presenting choices.
|
|
137
|
+
- Optional root: `themePreview` — `{ brandHex, activeMode, contrastPass, themeTokensPath, name?, presetId?, bestFor?, userConfirmed? }` after palette lock. Set `userConfirmed: true` only after explicit user choice (or waived).
|
|
138
|
+
- Optional root: `surfacePreview` — `{ kind: flat|gradient|image, userConfirmed, … }`. When `kind` is `gradient` or `image`, require `userConfirmed: true` before authoring those nodes; `gradient` needs `recipeId`; `image` needs `imageId` (or documented pending import) and `imageMode` (`fixed` default for surface background).
|
|
139
|
+
## Companion `design-philosophy.md`
|
|
140
|
+
|
|
141
|
+
Human-readable twin of `design-plan.json` → `philosophy`. Recommended structure:
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
144
|
+
# Design Philosophy — <movementName>
|
|
145
|
+
|
|
146
|
+
## Space
|
|
147
|
+
...
|
|
148
|
+
|
|
149
|
+
## Color
|
|
150
|
+
...
|
|
151
|
+
|
|
152
|
+
## Rhythm
|
|
153
|
+
...
|
|
154
|
+
|
|
155
|
+
## Composition
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
## Typography as accent
|
|
159
|
+
...
|
|
160
|
+
|
|
161
|
+
## Craft bar
|
|
162
|
+
...
|
|
163
|
+
|
|
164
|
+
## Template constraints
|
|
165
|
+
- Required brief slots stay bindable
|
|
166
|
+
- Flat absolute siblings only
|
|
167
|
+
- Theme owns color; never flatten copy into a generated poster
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## `theme-tokens.json`
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"schemaVersion": "theme_tokens_v2",
|
|
175
|
+
"brandHex": "#0D9488",
|
|
176
|
+
"scale": {
|
|
177
|
+
"50": "#F2FCFC",
|
|
178
|
+
"500": "#14E1D0",
|
|
179
|
+
"600": "#10BCAD",
|
|
180
|
+
"950": "#042F2B"
|
|
181
|
+
},
|
|
182
|
+
"semantic": {
|
|
183
|
+
"light": {
|
|
184
|
+
"canvas": "#FFFFFF",
|
|
185
|
+
"text": "#042F2B",
|
|
186
|
+
"accent": "#10BCAD",
|
|
187
|
+
"muted": "#10BCAD",
|
|
188
|
+
"primary": "#10BCAD",
|
|
189
|
+
"border": "#C6F5F1"
|
|
190
|
+
},
|
|
191
|
+
"dark": {
|
|
192
|
+
"canvas": "#042F2B",
|
|
193
|
+
"text": "#F2FCFC",
|
|
194
|
+
"accent": "#14E1D0",
|
|
195
|
+
"muted": "#51ECDF",
|
|
196
|
+
"primary": "#14E1D0",
|
|
197
|
+
"border": "#0B7F75"
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"activeMode": "light",
|
|
201
|
+
"themeTokens": {
|
|
202
|
+
"colors": {
|
|
203
|
+
"canvas": "#FFFFFF",
|
|
204
|
+
"text": "#042F2B",
|
|
205
|
+
"accent": "#10BCAD",
|
|
206
|
+
"muted": "#10BCAD",
|
|
207
|
+
"primary": "#10BCAD",
|
|
208
|
+
"border": "#C6F5F1"
|
|
209
|
+
},
|
|
210
|
+
"fonts": { "heading": "Inter", "body": "Inter" },
|
|
211
|
+
"surfaces": { "radius": "12px", "shadow": "0 8px 24px rgba(0,0,0,.12)" },
|
|
212
|
+
"palette": {}
|
|
213
|
+
},
|
|
214
|
+
"themeTokensLight": {},
|
|
215
|
+
"themeTokensDark": {},
|
|
216
|
+
"contrast": [
|
|
217
|
+
{
|
|
218
|
+
"pair": "text/canvas",
|
|
219
|
+
"mode": "light",
|
|
220
|
+
"foreground": "#042F2B",
|
|
221
|
+
"background": "#FFFFFF",
|
|
222
|
+
"ratio": 16.2,
|
|
223
|
+
"wcagAA": true,
|
|
224
|
+
"wcagAAA": true
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
"contrastPass": true
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Rules:
|
|
232
|
+
|
|
233
|
+
- `scale` must include shades `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`.
|
|
234
|
+
- `brandHex` must be `#` + 6 hex digits.
|
|
235
|
+
- `activeMode` is `light` or `dark`; `themeTokens` must match the active semantic palette.
|
|
236
|
+
- `themeTokens.colors` requires `canvas`, `text`, `accent`, `muted` (hex strings). Prefer also `primary` and `border` when co-creating v2.
|
|
237
|
+
- `themeTokens.fonts` requires `heading` and `body`.
|
|
238
|
+
- `themeTokens.surfaces` requires `radius` and `shadow`.
|
|
239
|
+
- `contrast` entries require `pair`, `mode`, `foreground`, `background`, `ratio`, `wcagAA`, `wcagAAA`.
|
|
240
|
+
- `contrastPass` must be `true` before authoring when co-creating a new theme.
|
|
241
|
+
|
|
242
|
+
## `visual-qa.json`
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"schemaVersion": "visual_qa_v2_1",
|
|
247
|
+
"draftId": "draft_123",
|
|
248
|
+
"iteration": 1,
|
|
249
|
+
"screenshotEvidence": "/absolute/path/to/studio-render.png",
|
|
250
|
+
"hardFailures": [],
|
|
251
|
+
"scores": {
|
|
252
|
+
"hierarchy": 18,
|
|
253
|
+
"composition": 13,
|
|
254
|
+
"spacingAlignment": 13,
|
|
255
|
+
"typography": 13,
|
|
256
|
+
"colorContrast": 9,
|
|
257
|
+
"assetRelevance": 8,
|
|
258
|
+
"contentResilience": 8,
|
|
259
|
+
"editability": 5
|
|
260
|
+
},
|
|
261
|
+
"total": 87,
|
|
262
|
+
"verdict": "pass",
|
|
263
|
+
"issues": [],
|
|
264
|
+
"changesMade": ["Increased metric size", "Reduced footer density"]
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Score maxima total 100. `pass` requires:
|
|
269
|
+
|
|
270
|
+
- inspectable `screenshotEvidence`
|
|
271
|
+
- `iteration` from 0 to 2
|
|
272
|
+
- no `hardFailures`
|
|
273
|
+
- each score within its maximum
|
|
274
|
+
- declared `total` equal to the calculated sum and at least 80
|
|
275
|
+
|
|
276
|
+
Use `verdict: "revise"` below threshold while iterating. Do not hand off a `revise` result as a reviewed template unless the user explicitly accepts it.
|
|
277
|
+
|
|
278
|
+
Craft Pass (behavior, not new score fields): when `iteration >= 1`, prefer tightening existing nodes over adding decoration; score against `philosophy.craftBar` and `philosophyExpression` of the selected concept.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# External resources & Surface routing
|
|
2
|
+
|
|
3
|
+
Template Skill **orchestrates** discovery; EasySociable **owns** materialization.
|
|
4
|
+
|
|
5
|
+
## Boundary
|
|
6
|
+
|
|
7
|
+
| Phase | Who | Tools |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Discover photos | Host Agent MCPs | Pinterest, Unsplash, Pexels |
|
|
10
|
+
| Discover icons | Template product | MCP/CLI `search_icons` / `get_icon` → Gateway Icon Catalog (ADR-0023) |
|
|
11
|
+
| Discover gradients | Template product | MCP/CLI `gradients list\|search\|get` → Gateway |
|
|
12
|
+
| Materialize | Template Gateway only | Image import (R2 + Directus `Image`), icon materialize (`TemplateIconAsset`), inline gradient CSS, Draft update, Preview, Publish |
|
|
13
|
+
|
|
14
|
+
Template MCP/CLI must **not** expose Unsplash/Pexels/Pinterest search tools. Icons are **not** discovered via Better Icons MCP — use the internal catalog only.
|
|
15
|
+
|
|
16
|
+
## Decision order
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
user_upload / brand_kit
|
|
20
|
+
→ Design Primitive / CSS-SVG
|
|
21
|
+
→ gradients (Gateway catalog)
|
|
22
|
+
→ search_icons / get_icon (Gateway Icon Catalog)
|
|
23
|
+
→ Pinterest / Unsplash / Pexels (host MCP)
|
|
24
|
+
→ generated topic image (last resort)
|
|
25
|
+
→ omit
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Degradation
|
|
29
|
+
|
|
30
|
+
| Missing | Agent behavior |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Unsplash/Pexels/Pinterest MCP | Say so; offer flat / gradient / user upload; continue without photo |
|
|
33
|
+
| Icon Catalog / Gateway auth | Return Gateway error (`ICON_*` / `TEMPLATE_API_KEY_REQUIRED`); offer CSS/SVG mark or omit icon — do **not** install or call Better Icons |
|
|
34
|
+
| Gradients API / auth | Fall back to `flat` or simple CSS two-stop only if user supplies hexes; do not scrape WebGradients at runtime |
|
|
35
|
+
| Draft image import unavailable | Keep confirmed photo out of Publish path; do not embed temp URLs; ask user to upload in Studio |
|
|
36
|
+
|
|
37
|
+
## Rights
|
|
38
|
+
|
|
39
|
+
- Record provider, source URL, creator, query, license/Attribution, rights state when importing images.
|
|
40
|
+
- Pinterest often starts `reference_only` / needs explicit publish-rights confirmation.
|
|
41
|
+
- Unsplash/Pexels follow provider license + Attribution rules.
|
|
42
|
+
- Gradients: record `provider` + `license` from catalog detail; inline CSS only.
|
|
43
|
+
- Icons: use `iconAssetId` + provenance from `get_icon`; Theme colors via `currentColor` / `--es-*` — never bake Theme hex into canonical SVG.
|
|
44
|
+
- Publish must reject unresolved rights (product gate); Skill must not pretend rights are cleared.
|
|
45
|
+
|
|
46
|
+
## Modes
|
|
47
|
+
|
|
48
|
+
- Surface background image → default **`fixed`**
|
|
49
|
+
- Slot image → ask **`fixed`** or **`slot_default`**
|
|
50
|
+
- Rights state is orthogonal to mode
|
|
51
|
+
|
|
52
|
+
See `workflows/SURFACE_REVIEW.md` for the confirmation loop.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Unified Gateway reference
|
|
2
|
+
|
|
3
|
+
The public executable is `easysociable`; the public MCP is the unified server.
|
|
4
|
+
Template operations use these command families:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
easysociable auth status --json
|
|
8
|
+
easysociable templates list --json
|
|
9
|
+
easysociable templates get --id <id> --json
|
|
10
|
+
easysociable templates create-draft --file ./draft.json --json
|
|
11
|
+
easysociable templates update --id <id> --file ./patch.json --json
|
|
12
|
+
easysociable templates validate --id <id> --json
|
|
13
|
+
easysociable templates publish --id <id> --json
|
|
14
|
+
easysociable icons search --query "arrow" --json
|
|
15
|
+
easysociable icons get --icon-id <id> --idempotency-key <key> --json
|
|
16
|
+
easysociable renders create --template-id <id> --slots ./slots.json --format png --idempotency-key render_1 --json
|
|
17
|
+
easysociable renders wait --id <id> --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
All requests go through Gateway. The client receives public summaries, slot
|
|
21
|
+
contracts, stable Image references and render Manifests only. It never receives
|
|
22
|
+
AST, Binding Maps, private RenderPlans or provider credentials.
|
|
23
|
+
|
|
24
|
+
External Pexels/Unsplash/Pinterest MCPs remain optional host capabilities for
|
|
25
|
+
discovery. They are not auto-installed and are not EasySociable API paths.
|