@easysociable/cli 0.1.2 → 0.1.3

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.
Files changed (120) hide show
  1. package/README.md +29 -21
  2. package/dist/easysociable.js +481 -52
  3. package/dist/easysociable.js.map +1 -1
  4. package/package.json +3 -2
  5. package/skills/ONBOARDING.md +20 -16
  6. package/skills/easysociable-content/SKILL.md +29 -104
  7. package/skills/easysociable-slideshow/SKILL.md +4 -3
  8. package/skills/easysociable-template/SKILL.md +26 -24
  9. package/skills/easysociable-template/references/CATALOG_METADATA.md +2 -2
  10. package/skills/easysociable-template/references/DESIGN_V2_1.md +53 -2
  11. package/skills/easysociable-template/references/GATEWAY.md +7 -2
  12. package/skills/easysociable-template/references/PLATFORM_SPECS.md +11 -3
  13. package/skills/easysociable-template/references/THEME_TOKENS.md +1 -1
  14. package/skills/easysociable-template/references/fixtures/image-reference.design-plan.json +74 -0
  15. package/skills/easysociable-template/references/fixtures/image-reference.visual-qa.json +28 -0
  16. package/skills/easysociable-template/scripts/validate-design-v2.mjs +97 -0
  17. package/skills/easysociable-template/workflows/ASSET_PLAN.md +2 -1
  18. package/skills/easysociable-template/workflows/AUTHORING_FROM_BRIEF.md +4 -4
  19. package/skills/easysociable-template/workflows/AUTHORING_FROM_IMAGE.md +66 -16
  20. package/skills/easysociable-template/workflows/AUTHORING_STUDIO.md +28 -15
  21. package/skills/easysociable-template/workflows/DESIGN_BRIEF.md +4 -3
  22. package/skills/easysociable-template/workflows/MULTI_PLATFORM_FAMILY.md +81 -0
  23. package/skills/easysociable-template/workflows/PUBLISH_FROM_DRAFT.md +1 -1
  24. package/skills/easysociable-template/workflows/VISUAL_QA.md +10 -0
  25. package/skills/easysociable-content/INSTALL.md +0 -60
  26. package/skills/easysociable-content/platforms/claude.md +0 -4
  27. package/skills/easysociable-content/platforms/codex.md +0 -4
  28. package/skills/easysociable-content/platforms/hermes.md +0 -4
  29. package/skills/easysociable-content/platforms/openclaw.md +0 -4
  30. package/skills/easysociable-content/references/CLI.md +0 -40
  31. package/skills/easysociable-content/references/CONTRACT_SYNC.md +0 -42
  32. package/skills/easysociable-content/references/MCP.md +0 -15
  33. package/skills/easysociable-content/references/PAGE_PACK.md +0 -129
  34. package/skills/easysociable-content/references/PLATFORM_GUIDE.md +0 -36
  35. package/skills/easysociable-content/references/RUN_LAYOUT.md +0 -73
  36. package/skills/easysociable-content/references/TROUBLESHOOTING.md +0 -13
  37. package/skills/easysociable-content/references/VAULT.md +0 -40
  38. package/skills/easysociable-content/references/VOICE.md +0 -16
  39. package/skills/easysociable-content/scripts/package-skill.mjs +0 -49
  40. package/skills/easysociable-content/scripts/setup.mjs +0 -200
  41. package/skills/easysociable-content/scripts/setup.test.mjs +0 -82
  42. package/skills/easysociable-content/workflows/ANALYSIS_AND_COVERAGE.md +0 -17
  43. package/skills/easysociable-content/workflows/CONTENT_EXPORT.md +0 -24
  44. package/skills/easysociable-content/workflows/GETTING_STARTED.md +0 -40
  45. package/skills/easysociable-content/workflows/MCP_FIRST.md +0 -5
  46. package/skills/easysociable-content/workflows/OUT_OF_SCOPE.md +0 -18
  47. package/skills/easysociable-content/workflows/PACK_AUTHORING.md +0 -42
  48. package/skills/easysociable-content/workflows/SWIPE_CAPTURE.md +0 -18
  49. package/skills/easysociable-content/workflows/TOPIC_DRAFT.md +0 -29
  50. package/skills/easysociable-content/workflows/WORKING_DRAFT.md +0 -19
  51. /package/{skills/easysociable-content → content-engine}/fixtures/golden-run-en/draft.md +0 -0
  52. /package/{skills/easysociable-content → content-engine}/fixtures/golden-run-en/idea.md +0 -0
  53. /package/{skills/easysociable-content → content-engine}/fixtures/golden-run-en/pack-tiktok.json +0 -0
  54. /package/{skills/easysociable-content → content-engine}/scripts/contracts.mjs +0 -0
  55. /package/{skills/easysociable-content → content-engine}/scripts/export-contracts.mjs +0 -0
  56. /package/{skills/easysociable-content → content-engine}/scripts/fixture.test.mjs +0 -0
  57. /package/{skills/easysociable-content → content-engine}/scripts/starter.mjs +0 -0
  58. /package/{skills/easysociable-content → content-engine}/scripts/validate-export.mjs +0 -0
  59. /package/{skills/easysociable-content → content-engine}/scripts/validate-pack.mjs +0 -0
  60. /package/{skills/easysociable-content → content-engine}/scripts/validate-run.mjs +0 -0
  61. /package/{skills/easysociable-content → content-engine}/scripts/validate.test.mjs +0 -0
  62. /package/{skills/easysociable-content → content-engine}/scripts/workbench.mjs +0 -0
  63. /package/{skills/easysociable-content → content-engine}/starter/CLAUDE.md +0 -0
  64. /package/{skills/easysociable-content → content-engine}/starter/accounts/README.md +0 -0
  65. /package/{skills/easysociable-content → content-engine}/starter/accounts/_index.md +0 -0
  66. /package/{skills/easysociable-content → content-engine}/starter/accounts/overrides/README.md +0 -0
  67. /package/{skills/easysociable-content → content-engine}/starter/discovery/README.md +0 -0
  68. /package/{skills/easysociable-content → content-engine}/starter/discovery/_index.md +0 -0
  69. /package/{skills/easysociable-content → content-engine}/starter/discovery/_template.md +0 -0
  70. /package/{skills/easysociable-content → content-engine}/starter/engine.json +0 -0
  71. /package/{skills/easysociable-content → content-engine}/starter/exports/README.md +0 -0
  72. /package/{skills/easysociable-content → content-engine}/starter/inbox/README.md +0 -0
  73. /package/{skills/easysociable-content → content-engine}/starter/inbox/_index.md +0 -0
  74. /package/{skills/easysociable-content → content-engine}/starter/inbox/entries/README.md +0 -0
  75. /package/{skills/easysociable-content → content-engine}/starter/platforms/README.md +0 -0
  76. /package/{skills/easysociable-content → content-engine}/starter/platforms/ig.md +0 -0
  77. /package/{skills/easysociable-content → content-engine}/starter/platforms/instagram.md +0 -0
  78. /package/{skills/easysociable-content → content-engine}/starter/platforms/linkedin.md +0 -0
  79. /package/{skills/easysociable-content → content-engine}/starter/platforms/threads.md +0 -0
  80. /package/{skills/easysociable-content → content-engine}/starter/platforms/tiktok.md +0 -0
  81. /package/{skills/easysociable-content → content-engine}/starter/platforms/x.md +0 -0
  82. /package/{skills/easysociable-content → content-engine}/starter/platforms/xiaohongshu.md +0 -0
  83. /package/{skills/easysociable-content → content-engine}/starter/profiles/_index.md +0 -0
  84. /package/{skills/easysociable-content → content-engine}/starter/profiles/default/README.md +0 -0
  85. /package/{skills/easysociable-content → content-engine}/starter/profiles/default/audience.md +0 -0
  86. /package/{skills/easysociable-content → content-engine}/starter/profiles/default/pillars.md +0 -0
  87. /package/{skills/easysociable-content → content-engine}/starter/profiles/default/voice.md +0 -0
  88. /package/{skills/easysociable-content → content-engine}/starter/published/_index.md +0 -0
  89. /package/{skills/easysociable-content → content-engine}/starter/raw/README.md +0 -0
  90. /package/{skills/easysociable-content → content-engine}/starter/raw/_index.md +0 -0
  91. /package/{skills/easysociable-content → content-engine}/starter/runs/README.md +0 -0
  92. /package/{skills/easysociable-content → content-engine}/starter/runs/_index.md +0 -0
  93. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/brief.md +0 -0
  94. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/draft.md +0 -0
  95. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/editor.md +0 -0
  96. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/feedback.md +0 -0
  97. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/idea.md +0 -0
  98. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/pack.md +0 -0
  99. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/packet.md +0 -0
  100. /package/{skills/easysociable-content → content-engine}/starter/runs/_template/rubric.md +0 -0
  101. /package/{skills/easysociable-content → content-engine}/starter/swipe/_index.md +0 -0
  102. /package/{skills/easysociable-content → content-engine}/starter/swipe/_template.md +0 -0
  103. /package/{skills/easysociable-content → content-engine}/starter/topics/README.md +0 -0
  104. /package/{skills/easysociable-content → content-engine}/starter/topics/WATCHLIST.md +0 -0
  105. /package/{skills/easysociable-content → content-engine}/starter/topics/_index.md +0 -0
  106. /package/{skills/easysociable-content → content-engine}/starter/topics/_template-item.md +0 -0
  107. /package/{skills/easysociable-content → content-engine}/starter/topics/items/README.md +0 -0
  108. /package/{skills/easysociable-content → content-engine}/starter/topics/scoring.md +0 -0
  109. /package/{skills/easysociable-content → content-engine}/starter/topics/watchlists/README.md +0 -0
  110. /package/{skills/easysociable-content → content-engine}/starter/topics/watchlists/_shared.md +0 -0
  111. /package/{skills/easysociable-content → content-engine}/starter/topics/watchlists/default.md +0 -0
  112. /package/{skills/easysociable-content → content-engine}/starter/wiki/README.md +0 -0
  113. /package/{skills/easysociable-content → content-engine}/starter/wiki/atoms/_index.md +0 -0
  114. /package/{skills/easysociable-content → content-engine}/starter/wiki/atoms/_template.md +0 -0
  115. /package/{skills/easysociable-content → content-engine}/starter/wiki/claims/_index.md +0 -0
  116. /package/{skills/easysociable-content → content-engine}/starter/wiki/claims/_template.md +0 -0
  117. /package/{skills/easysociable-content → content-engine}/starter/workbench/README.md +0 -0
  118. /package/{skills/easysociable-content → content-engine}/workbench/build.py +0 -0
  119. /package/{skills/easysociable-content → content-engine}/workbench/serve.py +0 -0
  120. /package/{skills/easysociable-content → content-engine}/workbench/template.html +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@easysociable/cli",
3
- "version": "0.1.2",
4
- "description": "Agent-first CLI and MCP host for EasySociable Template and Slideshow V1",
3
+ "version": "0.1.3",
4
+ "description": "Agent-first CLI for EasySociable: Content Engine, Template, Slideshow, and MCP",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "EasySociable",
@@ -33,6 +33,7 @@
33
33
  "bin",
34
34
  "dist",
35
35
  "skills",
36
+ "content-engine",
36
37
  "LICENSE",
37
38
  "README.md"
38
39
  ],
@@ -1,35 +1,38 @@
1
1
  # EasySociable agent-first onboarding
2
2
 
3
- V1 expects Codex or Claude Code to drive setup. The website is not the primary
4
- workspace.
3
+ V1 expects an Agent (Grok Bot, Codex, Claude Code, …) to drive setup. The website is not the primary workspace.
5
4
 
6
- ## User steps (3)
5
+ ## User steps
7
6
 
8
7
  1. **Install CLI**
9
8
 
10
9
  ```bash
11
10
  curl -fsSL https://easysociable.com/install.sh | bash
11
+ # or: npm i -g @easysociable/cli
12
12
  ```
13
13
 
14
- 2. **Install hosted Skills + MCP** (Template + Slideshow by default)
14
+ 2. **Create the Content Engine** (markdown + workbench)
15
15
 
16
16
  ```bash
17
- easysociable install --yes
17
+ easysociable engine init --root /workspace --yes
18
+ easysociable engine serve --engine /workspace/Content Engine --no-open
18
19
  ```
19
20
 
20
- 3. **Ask the Agent to create graphics** — account creation is deferred until a
21
- hosted operation requires authentication.
21
+ On a laptop, use any parent path instead of `/workspace`.
22
22
 
23
- Optional later:
23
+ 3. **Install hosted Skills + MCP** (Template + Slideshow by default; for Codex / Claude Code)
24
24
 
25
- ```bash
26
- easysociable install --skills content --yes
27
- ```
25
+ ```bash
26
+ easysociable install --yes
27
+ ```
28
+
29
+ Optional pointer skill (discovery only — operations live in `Content Engine/CLAUDE.md`):
30
+
31
+ ```bash
32
+ easysociable install --skills content --yes
33
+ ```
28
34
 
29
- Then run the `easysociable-content` setup workflow (Obsidian Vault + Content
30
- Engine). For a private copy to another machine, see
31
- `skills/easysociable-content/INSTALL.md`. Skipping Content does **not** block
32
- single-page or Slideshow renders.
35
+ 4. **Ask the Agent to create graphics** — account creation is deferred until a hosted operation requires authentication.
33
36
 
34
37
  ## Lazy auth (Agent script)
35
38
 
@@ -54,10 +57,11 @@ idempotency key when applicable.
54
57
  ## What works without auth
55
58
 
56
59
  - `easysociable install` / `update`
60
+ - `easysociable engine init` / `serve` / `build` / `validate`
57
61
  - Reading installed Skill instructions
58
62
  - Public template catalog in the browser (`/templates`)
59
63
 
60
64
  ## What requires auth
61
65
 
62
- - Profiles, Themes, images, drafts, Slideshow Runs
66
+ - Brands, Themes, images, drafts, Slideshow Runs
63
67
  - Hosted preview sessions and final PNG renders (`hosted_render_page` allowance)
@@ -1,126 +1,51 @@
1
1
  ---
2
2
  name: easysociable-content
3
3
  description: >
4
- Set up and operate a local Content Engine for EasySociable. English folder
5
- tree only (Content Engine/). One platform = one Run. The Agent writes
6
- markdown; workbench is the observatory UI. Hosted Template/Slideshow work
7
- uses the unified easysociable CLI/MCP. No Obsidian requirement, no content
8
- MCP, no content CLI.
4
+ Operate the EasySociable Content Engine (capture, discovery, topics, runs).
5
+ If no engine exists, run `easysociable engine init`. Then follow
6
+ Content Engine/CLAUDE.md. Render handoff: easysociable-template (1 page) or
7
+ easysociable-slideshow (2+). Never publish or post.
9
8
  ---
10
9
 
11
- # EasySociable Content Skill
12
-
13
- This Skill owns the user's local knowledge base. The Agent writes Markdown
14
- under `Content Engine/`. After writes, rebuild the workbench. Hosted Template
15
- and Slideshow operations stay with the unified `easysociable` CLI/MCP.
16
-
17
- **Operating manual lives in the engine:** `Content Engine/CLAUDE.md`. Follow it
18
- for capture, discovery, topics, 开一单, ingest, ship, and catalog evidence. This
19
- file is setup, routing, and hosted handoff only.
20
-
21
- ## Non-negotiable rules
22
-
23
- 1. English tree only: `Content Engine/`. Do not ask language.
24
- 2. Obsidian is **not** required. Do not detect, install, or open it.
25
- 3. Ask for a parent directory (or an existing `Content Engine/` path). Never create the engine silently in a random folder.
26
- 4. Existing engine files are read-only during setup. Never overwrite user content, especially `workbench/template.html`.
27
- 5. One platform = one Run (one folder). Same Topic, native rewrite for another network → **N runs**, shared `topic_id`.
28
- 6. On **开一单**: **ask platform(s)** if unset. Multi-select → N runs. Do **not** silent-default to `x`.
29
- 7. Before brief / draft / editor / pack: **read** `platforms/<platform>.md` (`instagram` → `ig.md`).
30
- 8. Write selection into `idea.md` (`swipe_id` / `atoms` / `claim_id`). Chat cards are not citations.
31
- 9. Pack JSON (`content-pack.v1`) only at **handoff to render**. Until then the run uses `pack.md` (slideshow platforms after SHIP).
32
- 10. Final PNGs live under `exports/<run-slug>/`, never inside the run folder. V1 output is PNG only.
33
- 11. Do not start a Local API, open SQLite, call a Content MCP, or call private Directus/R2/Stripe endpoints.
34
- 12. Do not create a hosted Brand Profile during setup.
35
-
36
- ## When this skill runs
37
-
38
- 1. Resolve the engine (`--root` parent, or existing `Content Engine/`).
39
- 2. If missing files: `node scripts/setup.mjs --root <path> --apply --json` (never overwrites).
40
- 3. Ensure `workbench/` exists (copy skill `workbench/` files **only if missing**).
41
- 4. `python3` is required. If missing, stop and tell the user.
42
- 5. Run `python3 workbench/build.py`.
43
- 6. If port **8765** is free: start `workbench/serve.py`. If it is already listening, reuse it — do not start a second server.
44
- 7. Open `http://127.0.0.1:8765/workbench/`.
45
- 8. After Agent writes markdown: run `build.py` again (leave serve running).
10
+ # EasySociable Content (pointer)
46
11
 
47
- ```bash
48
- node scripts/setup.mjs --root <parent-or-engine> --preview --json
49
- node scripts/setup.mjs --root <parent-or-engine> --apply --json
50
- node scripts/workbench.mjs start --engine "<path>/Content Engine" --json
51
- node scripts/workbench.mjs build --engine "<path>/Content Engine" --json
52
- ```
12
+ This skill is an entry card only. **Do not invent a parallel workflow.**
13
+
14
+ ## Create the engine
53
15
 
54
- `--no-open` skips the browser / server start.
55
-
56
- ## Intent routing
57
-
58
- Defer the body of each flow to engine `CLAUDE.md`. Use these skill workflows only for setup and hosted handoff.
59
-
60
- | User intent | Action |
61
- |---|---|
62
- | First install / missing engine | Setup above → `workflows/GETTING_STARTED.md` |
63
- | capture / 记一下 | Engine `CLAUDE.md` § Capture |
64
- | Watchlist add | Engine `CLAUDE.md` § Topics (watchlist files) |
65
- | 扫 watchlist / 发现内容 | Engine `CLAUDE.md` § Discovery — Source Digest only; no Topics |
66
- | 选题 / score topics | Engine `CLAUDE.md` § Topics — explicit input; Scout→opportunity 5-dim; ready=opp≥7.5 and aud≥6; cap=5 produce |
67
- | 开一单 / open a run | Engine `CLAUDE.md` § Open a run — **ask platforms**; N platforms → N folders |
68
- | 收成 swipe/atom/claim | Engine `CLAUDE.md` § Library ingest |
69
- | Ship + URL + result | Engine `CLAUDE.md` § Published index + Catalog evidence |
70
- | 出图 / pack + render | Engine `CLAUDE.md` § PagePack, then handoff below |
71
- | Platform craft | `Content Engine/platforms/<platform>.md` + `references/PLATFORM_GUIDE.md` |
72
- | Single-page image | Hand off → **easysociable-template** |
73
- | Multi-page slideshow | Hand off → **easysociable-slideshow** (Pack JSON at this step) |
74
- | Export PNGs | `workflows/CONTENT_EXPORT.md` |
75
- | Hosted CLI/MCP | `workflows/MCP_FIRST.md` |
76
- | Out of scope | `workflows/OUT_OF_SCOPE.md` |
77
-
78
- ### Single-page vs slideshow
79
-
80
- ```text
81
- 1 page → easysociable-template
82
- 2+ pages + slideshow platform → easysociable-slideshow
83
- x / xiaohongshu → easysociable-template only
16
+ ```bash
17
+ easysociable engine init --root <parent-or-engine> --yes
18
+ easysociable engine serve --engine <parent>/Content Engine --no-open
84
19
  ```
85
20
 
86
- Slideshow platforms: `tiktok`, `instagram`/`ig`, `linkedin`, `threads`.
21
+ On a dedicated agent computer (e.g. Grok Bot), prefer `--root /workspace`.
87
22
 
88
- ## Run model
23
+ Existing files are never overwritten. `python3` is required for the workbench.
89
24
 
90
- ```text
91
- ask platform(s) → N folders
92
- runs/<YYYY-MM-DD-slug[-platform]>/idea.md ← one platform, selection ids
93
- brief.md → packet.md → draft.md → editor.md → rubric.md
94
- pack.md (after SHIP, image decks only)
95
- pack-<platform>.json ← only at Slideshow/Template handoff
96
- ```
25
+ ## Operate
97
26
 
98
- Copy `runs/_template/` for each platform. Update `runs/_index.md` (one row per run).
27
+ Read and follow `Content Engine/CLAUDE.md` (and `engine.json`, `platforms/<platform>.md`).
99
28
 
100
- Validate before slideshow handoff:
29
+ Rebuild the observatory after markdown writes:
101
30
 
102
31
  ```bash
103
- node scripts/validate-run.mjs --run <run-dir> --json
104
- node scripts/validate-run.mjs --run <run-dir> --require-pack --json
32
+ easysociable engine build --engine <Content Engine>
105
33
  ```
106
34
 
107
- ## Handoff
35
+ ## Render handoff
108
36
 
109
- **Slideshow (multi-page):**
37
+ | Intent | Hand off |
38
+ |--------|----------|
39
+ | 1 page image | **easysociable-template** |
40
+ | 2+ pages on tiktok / instagram / linkedin / threads | **easysociable-slideshow** |
41
+ | x / xiaohongshu images | **easysociable-template** only |
110
42
 
111
- 1. Rubric SHIP on this run. Write `pack.md` (slots only).
112
- 2. Hand off to `easysociable-slideshow`. It selects a Page Template per page and writes `pack-<platform>.json`.
113
- 3. User confirms Studio preview.
114
- 4. Final render + export to `{engine}/exports/<run-slug>/`.
43
+ Validate a run before slideshow create:
115
44
 
116
- **Template (single-page):**
117
-
118
- 1. Hand off slot values to `easysociable-template` `FILL_AND_RENDER`.
119
-
120
- Preview does not consume Render Page allowance. Final render does.
45
+ ```bash
46
+ easysociable engine validate --run <run-dir> --require-pack
47
+ ```
121
48
 
122
- ## Reference loading
49
+ ## Out of scope
123
50
 
124
- Always read engine `CLAUDE.md`, `engine.json`, `references/RUN_LAYOUT.md` and
125
- `references/PLATFORM_GUIDE.md`. Load `GETTING_STARTED` on first install,
126
- `PACK_AUTHORING` / `CONTENT_EXPORT` / `MCP_FIRST` only at render handoff.
51
+ No social posting, Content MCP, Local API, or SQLite content library.
@@ -79,6 +79,7 @@ It is not a reusable Carousel/Deck Template and it is not a public post.
79
79
 
80
80
  ## Handoff boundary
81
81
 
82
- The Content Skill owns semantic copy and Pack creation. The Template Skill owns
83
- single-page authoring and fill-slots. This Skill only composes explicit page
84
- instances and coordinates preview/final render.
82
+ The Content Engine (`CLAUDE.md` + `easysociable engine …`) owns semantic copy
83
+ and Pack creation. The Template Skill owns single-page authoring and fill-slots.
84
+ This Skill only composes explicit page instances and coordinates preview/final
85
+ render.
@@ -3,18 +3,17 @@ name: easysociable-template
3
3
  description: >
4
4
  Create single-page social image templates for EasySociable via the unified
5
5
  Template MCP or `easysociable` CLI, and fill published template slots to Hosted Render
6
- (get_template → slots → create_render_job). Use when the user wants to author a
7
- page template from a reference image or text brief, write a shared visual design
8
- philosophy, explore 2–3 professional layout concepts as spatial expressions of that
9
- philosophy, plan or generate visual assets, co-create/reuse a Theme with brand-hex
10
- palette generation, choose a Surface (flat / Gateway gradient catalog / host
11
- Unsplash·Pexels·Pinterest photo), pull icons via Template Gateway
12
- search_icons/get_icon (internal Icon Catalog), run
13
- screenshot-based visual QA, attach catalog metadata (platforms including
14
- x/linkedin/threads, pageRoles, archetypes, density, slotSummary), open Authoring
15
- Studio, publish a single-page template, or render a published template by filling
16
- public slots. Do not use for multi-slide slideshow composition, ContentDocument as
17
- render input, local content library, or carousel packs.
6
+ (get_template → slots → create_render_job). Default create path is a Layout Family:
7
+ one master canvas plus derived multi-platform variants (e.g. XHS 3:4, IG/Threads 4:5,
8
+ TikTok 9:16, LinkedIn 1:1) with hand-tuned layouts per preset. Use when the user wants
9
+ to author a page template from a reference image or text brief (including “做多平台
10
+ 模板”), write a shared visual design philosophy, explore 2–3 professional layout
11
+ concepts, plan or generate visual assets, co-create Theme/preview tokens with brand-hex
12
+ palette generation, choose a Surface, pull icons via Template Gateway
13
+ search_icons/get_icon, run screenshot-based visual QA, attach catalog metadata, open
14
+ Authoring Studio, publish, or render by filling public slots. Do not use for multi-slide
15
+ slideshow composition, ContentDocument as render input, local content library, or
16
+ carousel packs.
18
17
  ---
19
18
 
20
19
  # EasySociable Template Skill
@@ -25,10 +24,10 @@ server. Do not install or invoke `easysociable-template`, `easysociable-slidesho
25
24
 
26
25
  **This skill owns two single-page paths:**
27
26
 
28
- 1. **Author** templates (Studio + Publish).
27
+ 1. **Author** templates as a **Layout Family** (master + multi-platform variants) → Studio + Publish (`workflows/MULTI_PLATFORM_FAMILY.md`).
29
28
  2. **Fill slots → Hosted Render** for a published PageTemplate (`workflows/FILL_AND_RENDER.md`).
30
29
 
31
- It is a template factory **and** the Agent surface for single-page fill-slots out图 (ADR-0021). It is **not** a multi-slide slideshow compositor.
30
+ It is a template factory **and** the Agent surface for single-page fill-slots rendering (ADR-0021). It is **not** a multi-slide slideshow compositor. Single-page ≠ single-platform.
32
31
 
33
32
  Every published page must carry **P0 catalog metadata** so Agents can filter and fill templates (`references/CATALOG_METADATA.md`).
34
33
 
@@ -45,18 +44,19 @@ Out of scope (hand off):
45
44
  2. Submit only public Gateway DTOs. Never invent or request private Safe AST / Binding Map / RenderPlan.
46
45
  3. Do not start Local Runtime, read content library SQLite, or call Content MCP/CLI for Template work.
47
46
  4. Catalog and create targets are **single-page** only. Never treat site Carousel packs as Agent templates.
48
- 5. After `create` / `createDraft`, the primary authoring path is `authoringStudioUrl` (`/authoring/{draftId}`). Always send the handoff message in `AUTHORING_STUDIO.md` (edit → **Save** → tell Agent to publish). Do not require a Hosted Preview Job for interactive authoring.
47
+ 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.
49
48
  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`.
50
- 7. **Do not Publish without complete P0 selection metadata** (`CATALOG_METADATA.md`). Gateway enforces this.
51
- 8. Theme: reuse `themeId` **or** co-create full `ThemeTokens`. Colors/fonts belong in Theme; page nodes use semantic `--es-*` tokens where possible.
49
+ 7. **Do not Publish without complete P0 selection metadata** (`CATALOG_METADATA.md`). Gateway enforces this. Each family variant carries its own `platforms` / `canvasPreset` / `canvas`.
50
+ 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.
52
51
  9. Layout model is **absolute positioning** on a **flat canvas tree** (see prior authoring rules / `AUTHORING_SOURCE.md`).
53
52
  10. **Runtime layout CSS:** put exact geometry in JSX inline `style={{...}}`. Never depend on Tailwind arbitrary-value classes for geometry.
54
53
  11. Run `scripts/validate-authoring-source.mjs` before every create/update.
55
54
  12. `supportedRoles` uses closed **pageRoles**; `platforms` is a multi-select array.
56
55
  13. Canvas sizes must follow `references/PLATFORM_SPECS.md`.
57
56
  14. **Text-only V2.1 authoring:** `DESIGN_BRIEF` → Philosophy → Concepts → assets/surface → author → Visual QA.
58
- 15. **Visual QA** before Studio handoff when authoring.
59
- 16. Prefer **reusable/brand assets**, Gateway gradient recipes, and catalog icons for deterministic visuals. Geometric chrome (hairlines, rails, discs) may use plain CSS shapes — **not** as a substitute for named icons.
57
+ 15. **Visual QA** before Studio handoff when authoring. For `image_reference`, QA **must** side-by-side compare Studio canvas to the reference (`VISUAL_QA.md` § Reference compare).
58
+ 16. Prefer **reusable/brand assets**, Gateway gradient recipes, and catalog icons for deterministic visuals. Geometric chrome (hairlines, rails, discs) may use plain CSS shapes — **not** as a substitute for named icons **or** for pictorial regions on a reference-image rebuild.
59
+ 16b. **Reference image → template (hard):** follow `workflows/AUTHORING_FROM_IMAGE.md` as SoT. **Read the reference with a vision tool**, write `referenceSpec` + `referenceImageInventory` into `design-plan.json`, and place pictorial regions as **`image` slots** (empty frames matching the boxes). `validate-design-v2.mjs` rejects `image_reference` plans missing those fields or using `css_svg` stand-ins for inventoried pictures. Do not mood-board a different layout.
60
60
  17. Preserve `draftId`, `templateId`, `themeId`, `jobId`, `authoringStudioUrl`, and `previewUrl` across steps.
61
61
  18. **Theme / Surface confirmation gates** unchanged for authoring (see `PALETTE_REVIEW`, `SURFACE_REVIEW`).
62
62
  19. **Fill-slots render (primary consumption path):** `get_template` → fill `slots[]` → `create_render_job({ templateId, slots, output })` → poll Job/Manifest. Image slots always use an account-owned `imageId` from the existing Gateway → R2 + Directus `Image` flow. Never pass a third-party URL, local path, transient `renderAssetId`, ContentDocument or `contentDocumentHash`. See `workflows/FILL_AND_RENDER.md`.
@@ -79,11 +79,12 @@ easysociable auth status --json
79
79
 
80
80
  | User intent | Workflow |
81
81
  |---|---|
82
- | Text description → template | `DESIGN_BRIEF.md` → … → `AUTHORING_STUDIO.md` |
83
- | Reference image → template | `AUTHORING_FROM_IMAGE.md` → … → `AUTHORING_STUDIO.md` |
82
+ | Text description → template (incl. multi-platform) | `DESIGN_BRIEF.md` → … → `AUTHORING_STUDIO.md` → **`MULTI_PLATFORM_FAMILY.md`** (derive + hand-tune) |
83
+ | Reference image → template | `AUTHORING_FROM_IMAGE.md` → … → `AUTHORING_STUDIO.md` → **`MULTI_PLATFORM_FAMILY.md`** + reference-compare QA on master |
84
+ | “只要某一个平台” | Same authoring path; skip derive / only named presets in `MULTI_PLATFORM_FAMILY.md` |
84
85
  | Need gradient / photo surface / icons only | `SURFACE_REVIEW.md` |
85
86
  | **Add / change an icon** (arrow, chevron, check, …) | **MUST** `SURFACE_REVIEW.md` § Icons — search → confirm → get_icon. **Do not** hand-draw SVG paths. |
86
- | Already have authoring payload / continue Studio | `workflows/AUTHORING_STUDIO.md` |
87
+ | Already have authoring payload / continue Studio | `workflows/AUTHORING_STUDIO.md` (+ family derive if variants still missing) |
87
88
  | User says publish / 发布该模板 (after Save) | `workflows/PUBLISH_FROM_DRAFT.md` |
88
89
  | Browse published single-page templates | `list` / `get_template` + public metadata |
89
90
  | **Fill a published template → PNG/JPEG** | `workflows/FILL_AND_RENDER.md` |
@@ -91,13 +92,14 @@ easysociable auth status --json
91
92
 
92
93
  ## Core model
93
94
 
95
+ - `workflows/MULTI_PLATFORM_FAMILY.md` — **default** multi-platform create (Family + derive + hand-tune)
94
96
  - `references/PLATFORM_SPECS.md`
95
97
  - `references/CATALOG_METADATA.md`
96
98
  - `references/SLOTS.md` — public slot contract for fill-slots render
97
99
  - `references/AUTHORING_SOURCE.md`
98
- - `references/THEME_TOKENS.md`
100
+ - `references/THEME_TOKENS.md` — Family `preview_tokens` (no TemplateTheme)
99
101
  - `references/EXTERNAL_RESOURCES.md`
100
- - `references/GATEWAY.md` — CLI / MCP including `render` / `create_render_job`
102
+ - `references/GATEWAY.md` — CLI / MCP including families derive + `render`
101
103
  - `workflows/FILL_AND_RENDER.md` — get_template → slots → Hosted Render
102
104
  - Authoring V2.1 workflows + validators as before
103
105
 
@@ -134,11 +134,11 @@ Derived from the slot table in `SLOTS.md`.
134
134
  | `notFor` | string[1..3] | Honest exclusions |
135
135
  | `selectionHints` | string | Short Agent-only hint |
136
136
  | `visualStyle` | enum | Look affinity |
137
- | `defaultThemeId` | string? | Soft preview theme |
138
- | `compatibleThemeIds` | string[]? | Optional |
139
137
  | `locale` | `zh-CN` \| `en` \| `bilingual` | |
140
138
  | `exampleFilledPreviewUrl` | url? | Filled sample beats empty shell |
141
139
 
140
+ Do **not** put Theme FKs (`defaultThemeId`, `compatibleThemeIds`) on published selection metadata (ADR-0033). Runtime look comes from Brand `themeSnapshot`.
141
+
142
142
  ---
143
143
 
144
144
  ## P2 — optional
@@ -122,7 +122,8 @@ Rules:
122
122
 
123
123
  - `text_brief` requires 2–3 concepts; `image_reference` permits one.
124
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.
125
+ - `image_reference` requires the same `philosophy` fields (short reverse-engineer from the reference).
126
+ - **`image_reference` also requires `referenceSpec` + `referenceImageInventory`** (see below). `validate-design-v2.mjs` enforces these.
126
127
  - Optional philosophy fields: `subtleReference`, `templateConstraints` (recommended).
127
128
  - Concepts must have unique IDs and all listed art-direction fields.
128
129
  - Every concept requires `philosophyExpression` (how this layout expresses the shared philosophy in space).
@@ -136,6 +137,48 @@ Rules:
136
137
  - 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
138
  - 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
139
  - 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).
140
+
141
+ ### `referenceSpec` + `referenceImageInventory` (`image_reference` only)
142
+
143
+ Required when `sourceKind` is `image_reference`. Rebuild to this measured spec; do not mood-board a different layout.
144
+
145
+ ```json
146
+ {
147
+ "referenceSpec": {
148
+ "stackOrder": ["title", "soft-card", "soft-card-2", "tip", "cta"],
149
+ "margins": "~48px outer",
150
+ "gaps": "~24px between cards",
151
+ "radii": "cards 16px; figure wells 12px",
152
+ "typeScale": "title ~42/bold; body ~22; tip ~18"
153
+ },
154
+ "referenceImageInventory": [
155
+ {
156
+ "label": "Left soft-card person illustration",
157
+ "slotKey": "image_0",
158
+ "imageRole": "hero",
159
+ "boxApprox": "left mid ~280×320"
160
+ }
161
+ ],
162
+ "assetPlan": [
163
+ {
164
+ "role": "hero",
165
+ "source": "user_upload",
166
+ "required": true,
167
+ "slotKey": "image_0",
168
+ "description": "Left soft-card person illustration — empty image-slot frame",
169
+ "treatment": "Match reference box; placeholder until account imageId fill"
170
+ }
171
+ ]
172
+ }
173
+ ```
174
+
175
+ Rules:
176
+
177
+ - `referenceSpec.stackOrder`: non-empty string array (region labels top→bottom or primary reading order).
178
+ - `referenceSpec.margins` / `gaps` / `radii` / `typeScale`: non-empty strings (measured or tightly estimated).
179
+ - `referenceImageInventory`: array required (empty only when the reference has **no** pictorial regions). Each item: `label`, `slotKey` (`image_N`), `imageRole` (`hero|screenshot|avatar|product`), `boxApprox`.
180
+ - Every inventory `slotKey` must appear on an `assetPlan` entry with the same `slotKey` and source in `user_upload|brand_kit|external_photo|generated` — never `css_svg` stand-ins for pictures.
181
+ - Procedure for filling these fields: `workflows/AUTHORING_FROM_IMAGE.md`.
139
182
  ## Companion `design-philosophy.md`
140
183
 
141
184
  Human-readable twin of `design-plan.json` → `philosophy`. Recommended structure:
@@ -246,7 +289,14 @@ Rules:
246
289
  "schemaVersion": "visual_qa_v2_1",
247
290
  "draftId": "draft_123",
248
291
  "iteration": 1,
292
+ "sourceKind": "image_reference",
249
293
  "screenshotEvidence": "/absolute/path/to/studio-render.png",
294
+ "referenceCompare": {
295
+ "performed": true,
296
+ "geometryMatch": true,
297
+ "imageSlotsMatchInventory": true,
298
+ "notes": "Card stack and image_0/image_1 frames match referenceSpec"
299
+ },
250
300
  "hardFailures": [],
251
301
  "scores": {
252
302
  "hierarchy": 18,
@@ -272,7 +322,8 @@ Score maxima total 100. `pass` requires:
272
322
  - no `hardFailures`
273
323
  - each score within its maximum
274
324
  - declared `total` equal to the calculated sum and at least 80
325
+ - when `sourceKind` is `image_reference`: `referenceCompare` with `performed`, `geometryMatch`, and `imageSlotsMatchInventory` all `true`
275
326
 
276
327
  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
328
 
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.
329
+ 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. Set `sourceKind` on `visual-qa.json` to match the design plan when authoring from a reference.
@@ -8,15 +8,20 @@ easysociable auth status --json
8
8
  easysociable templates list --json
9
9
  easysociable templates get --id <id> --json
10
10
  easysociable templates create-draft --file ./draft.json --json
11
- easysociable templates update --id <id> --file ./patch.json --json
11
+ 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
+ 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
14
17
  easysociable icons search --query "arrow" --json
15
- easysociable icons get --icon-id <id> --idempotency-key <key> --json
18
+ easysociable icons get --id <id> --idempotency-key <key> --json
16
19
  easysociable renders create --template-id <id> --slots ./slots.json --format png --idempotency-key render_1 --json
17
20
  easysociable renders wait --id <id> --json
18
21
  ```
19
22
 
23
+ Multi-platform create flow (derive + hand-tune): `workflows/MULTI_PLATFORM_FAMILY.md`.
24
+
20
25
  All requests go through Gateway. The client receives public summaries, slot
21
26
  contracts, stable Image references and render Manifests only. It never receives
22
27
  AST, Binding Maps, private RenderPlans or provider credentials.
@@ -120,12 +120,20 @@ 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)
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.
130
+
123
131
  ## Selection rules for Agents
124
132
 
125
- 1. If user names one platform → set `platforms: [that]` and use that platform’s **Recommended** row.
126
- 2. If user names several → intersection of workable presets; if empty, ask them to pick a primary platform or accept letterboxing.
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`).
127
135
  3. Never mix presets across slides of one deck without an explicit user choice (IG/Threads/TikTok crop to first slide).
128
- 4. Put platform + preset into P0 `selectionMetadata` before Publish.
136
+ 4. Each family variant’s P0 `selectionMetadata` must list only platforms that match that page’s `canvasPreset`.
129
137
  5. Specs above are **practical authoring targets** (2026 guides + Meta help for IG). Re-verify if a platform announces breaking crop changes.
130
138
 
131
139
  ## Sources (research snapshot)
@@ -15,7 +15,7 @@ Theme is the **skin** (color / font / surface). The page template is the **struc
15
15
 
16
16
  ## Gateway payload (`theme_schema_v1`)
17
17
 
18
- Gateway persists `themeTokens` in `TemplateTheme.tokens`. When `palette` is present, `theme_schema_version` is `theme_schema_v2`. The `colors` object includes six semantic roles: `canvas`, `text`, `accent`, `muted`, `primary`, `border`.
18
+ Authoring persists Studio preview tokens on **`TemplateLayoutFamily.preview_tokens`** (not a TemplateTheme row). Fill/render uses Brand `themeSnapshot` first, then family preview tokens, then a service default (ADR-0033). When `palette` is present, treat tokens as `theme_schema_v2`. The `colors` object includes six semantic roles: `canvas`, `text`, `accent`, `muted`, `primary`, `border`.
19
19
 
20
20
  ```ts
21
21
  {
@@ -0,0 +1,74 @@
1
+ {
2
+ "schemaVersion": "design_plan_v2_1",
3
+ "sourceKind": "image_reference",
4
+ "intent": {
5
+ "jobToBeDone": "Rebuild soft-card landing convert poster from reference",
6
+ "primaryPlatform": "instagram",
7
+ "canvas": { "width": 1080, "height": 1350 }
8
+ },
9
+ "philosophy": {
10
+ "movementName": "Soft Ledger",
11
+ "space": "Stacked rounded cards with generous outer margin",
12
+ "color": "Warm cream canvas, dark ink, soft peach accents",
13
+ "rhythm": "Even card gaps; one tip band; bottom CTA",
14
+ "composition": "Title → dual soft cards with figures → tip → CTA",
15
+ "typographyAccent": "Bold title; quieter body in cards",
16
+ "craftBar": "Match reference geometry; image slots for figures; no CSS fake people"
17
+ },
18
+ "concepts": [
19
+ {
20
+ "id": "soft-ledger-rebuild",
21
+ "name": "Soft ledger rebuild",
22
+ "rationale": "Reference already fixes composition",
23
+ "philosophyExpression": "Same stack and figure wells as referenceSpec",
24
+ "visualMotif": "soft rounded cards",
25
+ "layout": "title, two cards, tip, cta",
26
+ "hierarchy": "title > card copy > tip > cta",
27
+ "typography": "bold title, medium body",
28
+ "colorStrategy": "cream + ink from reference",
29
+ "assetStrategy": "two image slots for person illustrations",
30
+ "risks": ["figure crops"]
31
+ }
32
+ ],
33
+ "selectedConceptId": "soft-ledger-rebuild",
34
+ "selectionReason": "Single reconstruction of the supplied reference",
35
+ "referenceSpec": {
36
+ "stackOrder": ["title", "soft-card-1", "soft-card-2", "tip", "cta"],
37
+ "margins": "~48px outer",
38
+ "gaps": "~24px between cards",
39
+ "radii": "cards 16px; figure wells 12px",
40
+ "typeScale": "title ~42/bold; body ~22; tip ~18"
41
+ },
42
+ "referenceImageInventory": [
43
+ {
44
+ "label": "Left soft-card person illustration",
45
+ "slotKey": "image_0",
46
+ "imageRole": "hero",
47
+ "boxApprox": "left mid ~280×320"
48
+ },
49
+ {
50
+ "label": "Right soft-card person illustration",
51
+ "slotKey": "image_1",
52
+ "imageRole": "hero",
53
+ "boxApprox": "right mid ~280×320"
54
+ }
55
+ ],
56
+ "assetPlan": [
57
+ {
58
+ "role": "hero",
59
+ "source": "user_upload",
60
+ "required": true,
61
+ "slotKey": "image_0",
62
+ "description": "Left soft-card person illustration — empty image-slot frame",
63
+ "treatment": "Match reference box; placeholder until account imageId fill"
64
+ },
65
+ {
66
+ "role": "hero",
67
+ "source": "user_upload",
68
+ "required": true,
69
+ "slotKey": "image_1",
70
+ "description": "Right soft-card person illustration — empty image-slot frame",
71
+ "treatment": "Match reference box; placeholder until account imageId fill"
72
+ }
73
+ ]
74
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "schemaVersion": "visual_qa_v2_1",
3
+ "draftId": "draft_fixture_ref",
4
+ "iteration": 0,
5
+ "sourceKind": "image_reference",
6
+ "screenshotEvidence": "/tmp/studio-render-fixture.png",
7
+ "referenceCompare": {
8
+ "performed": true,
9
+ "geometryMatch": true,
10
+ "imageSlotsMatchInventory": true,
11
+ "notes": "Fixture — stack and image_0/image_1 frames match referenceSpec"
12
+ },
13
+ "hardFailures": [],
14
+ "scores": {
15
+ "hierarchy": 18,
16
+ "composition": 14,
17
+ "spacingAlignment": 14,
18
+ "typography": 14,
19
+ "colorContrast": 9,
20
+ "assetRelevance": 9,
21
+ "contentResilience": 8,
22
+ "editability": 5
23
+ },
24
+ "total": 91,
25
+ "verdict": "pass",
26
+ "issues": [],
27
+ "changesMade": []
28
+ }