@easysociable/cli 0.1.1 → 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 (116) hide show
  1. package/README.md +29 -18
  2. package/content-engine/fixtures/golden-run-en/draft.md +13 -0
  3. package/content-engine/fixtures/golden-run-en/idea.md +26 -0
  4. package/content-engine/fixtures/golden-run-en/pack-tiktok.json +11 -0
  5. package/content-engine/scripts/contracts.mjs +183 -0
  6. package/content-engine/scripts/export-contracts.mjs +76 -0
  7. package/content-engine/scripts/fixture.test.mjs +24 -0
  8. package/content-engine/scripts/starter.mjs +55 -0
  9. package/content-engine/scripts/validate-export.mjs +42 -0
  10. package/content-engine/scripts/validate-pack.mjs +48 -0
  11. package/content-engine/scripts/validate-run.mjs +100 -0
  12. package/content-engine/scripts/validate.test.mjs +101 -0
  13. package/content-engine/scripts/workbench.mjs +135 -0
  14. package/content-engine/starter/CLAUDE.md +756 -0
  15. package/content-engine/starter/accounts/README.md +9 -0
  16. package/content-engine/starter/accounts/_index.md +31 -0
  17. package/content-engine/starter/accounts/overrides/README.md +3 -0
  18. package/content-engine/starter/discovery/README.md +18 -0
  19. package/content-engine/starter/discovery/_index.md +27 -0
  20. package/content-engine/starter/discovery/_template.md +41 -0
  21. package/content-engine/starter/engine.json +19 -0
  22. package/content-engine/starter/exports/README.md +28 -0
  23. package/content-engine/starter/inbox/README.md +9 -0
  24. package/content-engine/starter/inbox/_index.md +24 -0
  25. package/content-engine/starter/inbox/entries/README.md +3 -0
  26. package/content-engine/starter/platforms/README.md +19 -0
  27. package/content-engine/starter/platforms/ig.md +69 -0
  28. package/content-engine/starter/platforms/instagram.md +5 -0
  29. package/content-engine/starter/platforms/linkedin.md +72 -0
  30. package/content-engine/starter/platforms/threads.md +69 -0
  31. package/content-engine/starter/platforms/tiktok.md +71 -0
  32. package/content-engine/starter/platforms/x.md +78 -0
  33. package/content-engine/starter/platforms/xiaohongshu.md +19 -0
  34. package/content-engine/starter/profiles/_index.md +13 -0
  35. package/content-engine/starter/profiles/default/README.md +11 -0
  36. package/content-engine/starter/profiles/default/audience.md +38 -0
  37. package/content-engine/starter/profiles/default/pillars.md +33 -0
  38. package/content-engine/starter/profiles/default/voice.md +24 -0
  39. package/content-engine/starter/published/_index.md +20 -0
  40. package/content-engine/starter/raw/README.md +4 -0
  41. package/content-engine/starter/raw/_index.md +12 -0
  42. package/content-engine/starter/runs/README.md +22 -0
  43. package/content-engine/starter/runs/_index.md +41 -0
  44. package/content-engine/starter/runs/_template/brief.md +66 -0
  45. package/content-engine/starter/runs/_template/draft.md +11 -0
  46. package/content-engine/starter/runs/_template/editor.md +18 -0
  47. package/content-engine/starter/runs/_template/feedback.md +15 -0
  48. package/content-engine/starter/runs/_template/idea.md +27 -0
  49. package/content-engine/starter/runs/_template/pack.md +47 -0
  50. package/content-engine/starter/runs/_template/packet.md +25 -0
  51. package/content-engine/starter/runs/_template/rubric.md +19 -0
  52. package/content-engine/starter/swipe/_index.md +27 -0
  53. package/content-engine/starter/swipe/_template.md +34 -0
  54. package/content-engine/starter/topics/README.md +25 -0
  55. package/content-engine/starter/topics/WATCHLIST.md +65 -0
  56. package/content-engine/starter/topics/_index.md +44 -0
  57. package/content-engine/starter/topics/_template-item.md +90 -0
  58. package/content-engine/starter/topics/items/README.md +4 -0
  59. package/content-engine/starter/topics/scoring.md +201 -0
  60. package/content-engine/starter/topics/watchlists/README.md +10 -0
  61. package/content-engine/starter/topics/watchlists/_shared.md +14 -0
  62. package/content-engine/starter/topics/watchlists/default.md +6 -0
  63. package/content-engine/starter/wiki/README.md +13 -0
  64. package/content-engine/starter/wiki/atoms/_index.md +23 -0
  65. package/content-engine/starter/wiki/atoms/_template.md +31 -0
  66. package/content-engine/starter/wiki/claims/_index.md +26 -0
  67. package/content-engine/starter/wiki/claims/_template.md +38 -0
  68. package/content-engine/starter/workbench/README.md +17 -0
  69. package/content-engine/workbench/build.py +1074 -0
  70. package/content-engine/workbench/serve.py +53 -0
  71. package/content-engine/workbench/template.html +2119 -0
  72. package/dist/easysociable.js +804 -2903
  73. package/dist/easysociable.js.map +1 -1
  74. package/package.json +19 -13
  75. package/skills/ONBOARDING.md +20 -14
  76. package/skills/easysociable-content/SKILL.md +38 -102
  77. package/skills/easysociable-slideshow/SKILL.md +24 -16
  78. package/skills/easysociable-slideshow/references/VAULT.md +13 -11
  79. package/skills/easysociable-template/SKILL.md +26 -24
  80. package/skills/easysociable-template/references/CATALOG_METADATA.md +2 -2
  81. package/skills/easysociable-template/references/DESIGN_V2_1.md +53 -2
  82. package/skills/easysociable-template/references/GATEWAY.md +7 -2
  83. package/skills/easysociable-template/references/PLATFORM_SPECS.md +11 -3
  84. package/skills/easysociable-template/references/THEME_TOKENS.md +1 -1
  85. package/skills/easysociable-template/references/fixtures/image-reference.design-plan.json +74 -0
  86. package/skills/easysociable-template/references/fixtures/image-reference.visual-qa.json +28 -0
  87. package/skills/easysociable-template/scripts/generate-theme-from-hex.mjs +0 -0
  88. package/skills/easysociable-template/scripts/validate-design-v2.mjs +97 -0
  89. package/skills/easysociable-template/workflows/ASSET_PLAN.md +2 -1
  90. package/skills/easysociable-template/workflows/AUTHORING_FROM_BRIEF.md +4 -4
  91. package/skills/easysociable-template/workflows/AUTHORING_FROM_IMAGE.md +66 -16
  92. package/skills/easysociable-template/workflows/AUTHORING_STUDIO.md +28 -15
  93. package/skills/easysociable-template/workflows/DESIGN_BRIEF.md +4 -3
  94. package/skills/easysociable-template/workflows/MULTI_PLATFORM_FAMILY.md +81 -0
  95. package/skills/easysociable-template/workflows/PUBLISH_FROM_DRAFT.md +1 -1
  96. package/skills/easysociable-template/workflows/VISUAL_QA.md +10 -0
  97. package/skills/easysociable-content/platforms/claude.md +0 -5
  98. package/skills/easysociable-content/platforms/codex.md +0 -5
  99. package/skills/easysociable-content/platforms/hermes.md +0 -5
  100. package/skills/easysociable-content/platforms/openclaw.md +0 -5
  101. package/skills/easysociable-content/references/CLI.md +0 -27
  102. package/skills/easysociable-content/references/MCP.md +0 -20
  103. package/skills/easysociable-content/references/PAGE_PACK.md +0 -6
  104. package/skills/easysociable-content/references/TROUBLESHOOTING.md +0 -11
  105. package/skills/easysociable-content/references/VAULT.md +0 -20
  106. package/skills/easysociable-content/scripts/setup.mjs +0 -156
  107. package/skills/easysociable-content/scripts/setup.test.mjs +0 -71
  108. package/skills/easysociable-content/scripts/starter.mjs +0 -53
  109. package/skills/easysociable-content/workflows/ANALYSIS_AND_COVERAGE.md +0 -8
  110. package/skills/easysociable-content/workflows/CONTENT_EXPORT.md +0 -19
  111. package/skills/easysociable-content/workflows/DEVICE_TASKS.md +0 -5
  112. package/skills/easysociable-content/workflows/EXPERIMENTS.md +0 -6
  113. package/skills/easysociable-content/workflows/MCP_FIRST.md +0 -10
  114. package/skills/easysociable-content/workflows/PUBLICATION.md +0 -5
  115. package/skills/easysociable-content/workflows/TOPIC_DRAFT.md +0 -5
  116. package/skills/easysociable-content/workflows/WORKING_DRAFT.md +0 -10
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@easysociable/cli",
3
- "version": "0.1.1",
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,26 +33,32 @@
33
33
  "bin",
34
34
  "dist",
35
35
  "skills",
36
+ "content-engine",
36
37
  "LICENSE",
37
38
  "README.md"
38
39
  ],
40
+ "scripts": {
41
+ "typecheck": "tsc --noEmit",
42
+ "test": "vitest run",
43
+ "build": "tsup",
44
+ "prepack": "node scripts/prepack.mjs && pnpm build",
45
+ "pack:check": "npm pack --dry-run"
46
+ },
39
47
  "publishConfig": {
40
48
  "access": "public",
41
49
  "registry": "https://registry.npmjs.org/"
42
50
  },
51
+ "dependencies": {
52
+ "commander": "^11.1.0"
53
+ },
43
54
  "devDependencies": {
55
+ "@easysociable/mcp-server": "workspace:*",
56
+ "@easysociable/template-gateway-client": "workspace:*",
57
+ "@easysociable/tsconfig": "workspace:*",
58
+ "@easysociable/vitest-config": "workspace:*",
44
59
  "@types/node": "^22.14.0",
45
- "commander": "^11.1.0",
46
60
  "tsup": "^8.0.2",
47
61
  "typescript": "^5.8.3",
48
- "vitest": "^1.3.1",
49
- "@easysociable/tsconfig": "0.0.0",
50
- "@easysociable/vitest-config": "0.0.0"
51
- },
52
- "scripts": {
53
- "typecheck": "tsc --noEmit",
54
- "test": "vitest run",
55
- "build": "tsup",
56
- "pack:check": "npm pack --dry-run"
62
+ "vitest": "^1.3.1"
57
63
  }
58
- }
64
+ }
@@ -1,33 +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). Skipping Content does **not** block single-page or Slideshow renders.
35
+ 4. **Ask the Agent to create graphics** — account creation is deferred until a hosted operation requires authentication.
31
36
 
32
37
  ## Lazy auth (Agent script)
33
38
 
@@ -52,10 +57,11 @@ idempotency key when applicable.
52
57
  ## What works without auth
53
58
 
54
59
  - `easysociable install` / `update`
60
+ - `easysociable engine init` / `serve` / `build` / `validate`
55
61
  - Reading installed Skill instructions
56
62
  - Public template catalog in the browser (`/templates`)
57
63
 
58
64
  ## What requires auth
59
65
 
60
- - Profiles, Themes, images, drafts, Slideshow Runs
66
+ - Brands, Themes, images, drafts, Slideshow Runs
61
67
  - Hosted preview sessions and final PNG renders (`hosted_render_page` allowance)
@@ -1,115 +1,51 @@
1
1
  ---
2
2
  name: easysociable-content
3
3
  description: >
4
- Set up and operate a local Obsidian-based Content Engine for EasySociable.
5
- Obsidian is required. During setup, ask the user to choose 中文 or English;
6
- that locale names the engine folders and starter notes. This Skill records
7
- Runs, Packs and exports for the Template and Slideshow Skills. It does not
8
- provide a hosted content backend, Content API, SQLite runtime, content MCP
9
- server or 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.
10
8
  ---
11
9
 
12
- # EasySociable Content Skill
13
-
14
- This Skill owns the user's local knowledge base. It is intentionally filesystem-
15
- first: the Agent writes Markdown and JSON under the user's existing Obsidian
16
- Vault, while hosted Template and Slideshow operations are performed later by
17
- the unified `easysociable` CLI/MCP.
18
-
19
- ## Non-negotiable rules
20
-
21
- 1. Obsidian must already be installed. If it is missing, stop and give the
22
- official installation guidance; do not create a partial vault.
23
- 2. Ask the user to choose **中文 (`zh`)** or **English (`en`)** before the first
24
- preview. Do not default the locale silently.
25
- 3. Ask the user to choose an existing Vault. Never create a new Vault silently.
26
- 4. Create or validate only the locale root: `Content Engine/` (`en`) or
27
- `内容引擎/` (`zh`). Never create both in one Vault.
28
- 5. Existing Content Engine files are read-only during setup. Report differences
29
- and ask before any migration; never auto-repair or overwrite user content.
30
- 6. Do not start a Local API, open SQLite, call Content MCP, or call private
31
- Directus/R2/Stripe endpoints.
32
- 7. Every intent/run is saved under the locale runs folder (`runs/<slug>/` or
33
- `成稿/<slug>/`). Every platform gets a Pack. Binary outputs belong only
34
- under the locale exports folder.
35
- 8. The host Agent owns copy and semantic decisions. Template and Slideshow Skills
36
- own template selection, hosted preview and final rendering.
37
- 9. V1 final output is PNG only. Never create ZIP, JPEG, WebP, PDF or video output.
38
- 10. `content-pack.v1` JSON field names, `role` values and slot keys stay English
39
- even when the vault language is 中文. Folder names and Markdown notes follow
40
- the chosen locale.
41
-
42
- ## Setup workflow
43
-
44
- 1. Detect Obsidian.app.
45
- 2. Ask: 内容引擎用中文还是 English? Map the answer to `--locale zh` or `--locale en`.
46
- 3. Ask for an existing Vault path.
47
- 4. Preview with `scripts/setup.mjs --vault <path> --locale zh|en --preview --json`.
48
- 5. Create the sanitized Starter and generalized `CLAUDE.md` only after confirmation,
49
- using `--apply`.
50
- 6. Open the Vault in Obsidian.
51
- 7. Return the Vault path, locale, engine folder name, and the next workflow.
52
-
53
- The deterministic setup helper is `scripts/setup.mjs`. Use `--preview` before
54
- `--apply`; it never overwrites an existing file and refuses to create anything
55
- when Obsidian is not installed. It is a helper for the host Agent, not a
56
- separate product CLI.
57
-
58
- After setup, read `locale.json` in the engine root (or detect `内容引擎/` vs
59
- `Content Engine/`) and keep using that tree. Do not switch language later.
60
-
61
- The Starter contains empty indexes, templates and operating rules only. It must
62
- not contain the owner's personal examples, previous Runs or generated media.
63
-
64
- ## Run and Pack workflow
65
-
66
- For each piece of content, create a local Run with:
67
-
68
- - a stable slug and title;
69
- - platform and language;
70
- - semantic outline and page roles;
71
- - generated copy and selected media references;
72
- - the chosen Profile/Theme identifiers when known;
73
- - links to the corresponding platform Pack and export Manifest.
74
-
75
- Write user-facing notes in the vault locale. The Pack is the handoff to
76
- `easysociable-slideshow`. It contains public page roles and slot values, never
77
- private AST, Binding Maps, RenderPlans or a hosted ContentDocument:
78
-
79
- ```json
80
- {
81
- "schemaVersion": "content-pack.v1",
82
- "platform": "tiktok",
83
- "title": "A short story",
84
- "pages": [
85
- { "role": "hook", "slots": { "text_0": "Hook", "text_1": "Support" } },
86
- { "role": "value", "slots": { "text_0": "One idea" } }
87
- ]
88
- }
10
+ # EasySociable Content (pointer)
11
+
12
+ This skill is an entry card only. **Do not invent a parallel workflow.**
13
+
14
+ ## Create the engine
15
+
16
+ ```bash
17
+ easysociable engine init --root <parent-or-engine> --yes
18
+ easysociable engine serve --engine <parent>/Content Engine --no-open
89
19
  ```
90
20
 
91
- ## Handoff
21
+ On a dedicated agent computer (e.g. Grok Bot), prefer `--root /workspace`.
22
+
23
+ Existing files are never overwritten. `python3` is required for the workbench.
24
+
25
+ ## Operate
92
26
 
93
- For a single image, hand the selected published Page Template and slot values to
94
- the Template workflow. For a slideshow:
27
+ Read and follow `Content Engine/CLAUDE.md` (and `engine.json`, `platforms/<platform>.md`).
95
28
 
96
- 1. write the Pack to the Run folder;
97
- 2. ask the Slideshow Skill to create/update a temporary Run;
98
- 3. let the Agent review the returned Studio URL;
99
- 4. after confirmation, let the Agent call `easysociable slideshows render`;
100
- 5. let the Agent call `easysociable renders export` to atomically write PNGs and
101
- `manifest.json` under the Run's exports directory.
29
+ Rebuild the observatory after markdown writes:
102
30
 
103
- Preview is not a final local export and does not consume hosted Render Page
104
- allowance. The final render does.
31
+ ```bash
32
+ easysociable engine build --engine <Content Engine>
33
+ ```
34
+
35
+ ## Render handoff
36
+
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 |
105
42
 
106
- Network research is optional. If the host does not expose a search tool, keep
107
- the source URL in the local note and continue with user-provided evidence; do
108
- not install an MCP server automatically and do not block vault setup.
43
+ Validate a run before slideshow create:
44
+
45
+ ```bash
46
+ easysociable engine validate --run <run-dir> --require-pack
47
+ ```
109
48
 
110
- ## Required references
49
+ ## Out of scope
111
50
 
112
- - `references/PAGE_PACK.md`
113
- - `references/VAULT.md`
114
- - `workflows/CONTENT_EXPORT.md`
115
- - `workflows/MCP_FIRST.md` (for the unified CLI/MCP handoff only)
51
+ No social posting, Content MCP, Local API, or SQLite content library.
@@ -1,11 +1,12 @@
1
1
  ---
2
2
  name: easysociable-slideshow
3
3
  description: >
4
- Create and review temporary multi-page Slideshow Runs for EasySociable from a
5
- local Obsidian Content Pack. Use the unified `easysociable` CLI or MCP, open
6
- Studio for preview, and perform final PNG rendering only after confirmation.
7
- There is no Slideshow Template product, UGC publishing, social posting or
8
- separate Slideshow CLI/MCP in V1.
4
+ Create, list, update and review durable multi-page Slideshow Runs for
5
+ EasySociable from a local Obsidian Content Pack. Use the unified
6
+ `easysociable` CLI or MCP, open Studio for preview, and perform final PNG
7
+ rendering only after confirmation. Runs remain in the owner dashboard until
8
+ archive/trash. There is no Slideshow Template product, UGC publishing,
9
+ social posting or separate Slideshow CLI/MCP in V1.
9
10
  ---
10
11
 
11
12
  # EasySociable Slideshow Skill
@@ -27,8 +28,8 @@ It is not a reusable Carousel/Deck Template and it is not a public post.
27
28
  in Studio.
28
29
  6. Studio is preview-only. It has no final download, publish, unpublish, UGC,
29
30
  SEO/GEO or social-posting action.
30
- 7. Agent revisions update the same unexpired Run. Studio activity extends the
31
- seven-day TTL. Expired Runs are not recoverable through the public API.
31
+ 7. Before creating a new Run for an existing content intent, list/find prior Runs
32
+ by `contentSlug` and update the same Run when possible.
32
33
  8. Preview is free but rate/concurrency limited. Final rendering is PNG-only,
33
34
  uses one atomic reservation for all pages and charges only when every page
34
35
  succeeds.
@@ -38,15 +39,21 @@ It is not a reusable Carousel/Deck Template and it is not a public post.
38
39
  1. Validate the Pack and platform/page count.
39
40
  2. Resolve or create the user's Profile/Theme through the unified CLI/MCP.
40
41
  3. Select a compatible published Page Template for every page.
41
- 4. Call:
42
+ 4. List existing Runs when the Pack has a stable content slug:
43
+
44
+ ```bash
45
+ easysociable slideshows list --content-slug my-post --json
46
+ ```
47
+
48
+ 5. Create or update:
42
49
 
43
50
  ```bash
44
51
  easysociable slideshows create --file ./pack.json --json
45
52
  ```
46
53
 
47
- 5. Open the returned `studioUrl` and inspect every page.
48
- 6. Save Studio edits and wait for the saved revision.
49
- 7. After explicit confirmation, call:
54
+ 6. Open the returned `studioUrl` and inspect every page.
55
+ 7. Save Studio edits and wait for the saved revision.
56
+ 8. After explicit confirmation, call:
50
57
 
51
58
  ```bash
52
59
  easysociable slideshows render --id run_xxx --idempotency-key run_xxx-final-1 --json
@@ -60,7 +67,7 @@ It is not a reusable Carousel/Deck Template and it is not a public post.
60
67
 
61
68
  8. Verify checksums and the reconstruction `manifest.json` in the Obsidian
62
69
  Run export. The export is the local final deliverable; cloud artifacts expire
63
- after 24 hours.
70
+ after 24 hours while the Run remains listed for the owner.
64
71
 
65
72
  ## Failure handling
66
73
 
@@ -68,10 +75,11 @@ It is not a reusable Carousel/Deck Template and it is not a public post.
68
75
  error to the Agent; do not substitute another template.
69
76
  - If any final page fails, there is no partial final set and no page charge.
70
77
  - Retry the same final request with the same idempotency key to reuse the Job.
71
- - If the Run is expired, create a new Run from the Pack.
78
+ - If a Run was trashed, create a new Run from the Pack.
72
79
 
73
80
  ## Handoff boundary
74
81
 
75
- The Content Skill owns semantic copy and Pack creation. The Template Skill owns
76
- single-page authoring and fill-slots. This Skill only composes explicit page
77
- 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.
@@ -1,18 +1,20 @@
1
1
  # Obsidian export
2
2
 
3
- The local Obsidian Run folder is the final delivery mirror:
3
+ Final PNGs are written at the **engine root exports directory**:
4
4
 
5
5
  ```text
6
- Content Engine/ or 内容引擎/
7
- └── runs/<slug>/ or 成稿/<slug>/
8
- └── exports/<slug>/<platform>/ or 导出/<slug>/<platform>/
9
- ├── 01.png
10
- ├── 02.png
11
- └── manifest.json
6
+ Content Engine/exports/<slug>/<platform>/ (en)
7
+ 内容引擎/导出/<slug>/<platform>/ (zh)
8
+ ├── 01.png
9
+ ├── 02.png
10
+ └── manifest.json
12
11
  ```
13
12
 
14
- Read `locale.json` in the engine root (`en` or `zh`) and use that tree. Pack JSON keys stay English.
13
+ Semantic work and Packs stay under `runs/<slug>/` or `成稿/<slug>/`. Do not
14
+ write PNGs inside the run folder.
15
15
 
16
- The CLI verifies checksums and atomically replaces this directory only after a
17
- complete atomic Hosted Render succeeds. No ZIP is created. The cloud artifact
18
- may expire after 24 hours; the local PNGs remain the user's files.
16
+ Read `locale.json` in the engine root. Pack JSON keys stay English.
17
+
18
+ The CLI verifies checksums and atomically replaces the export directory only
19
+ after a complete atomic Hosted Render succeeds. No ZIP is created. Cloud
20
+ artifacts may expire after 24 hours; local PNGs remain the user's files.
@@ -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.