@easysociable/cli 0.1.17 → 0.1.19
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/README.md +2 -1
- package/dist/easysociable.js +11408 -9432
- package/dist/easysociable.js.map +1 -1
- package/package.json +20 -17
- package/skills/ONBOARDING.md +2 -3
- package/skills/easysociable-slideshow/SKILL.md +254 -152
- package/skills/easysociable-slideshow/references/CONTENT_PACK.md +12 -15
- package/skills/easysociable-slideshow/references/PLATFORM_CAPS.md +1 -1
- package/skills/easysociable-slideshow/references/REFERENCES.md +97 -0
- package/skills/easysociable-slideshow/scripts/check-pages.mjs +136 -0
- package/skills/easysociable-slideshow/workflows/CREATE_RUN.md +12 -43
- package/skills/easysociable-slideshow/workflows/MCP_FIRST.md +1 -3
- package/skills/easysociable-slideshow/workflows/OUT_OF_SCOPE.md +1 -1
- package/skills/easysociable-template/SKILL.md +14 -14
- package/skills/easysociable-template/references/CATALOG_METADATA.md +2 -2
- package/skills/easysociable-template/references/GATEWAY.md +1 -3
- package/skills/easysociable-template/references/PLATFORM_SPECS.md +7 -9
- package/skills/easysociable-template/scripts/generate-theme-from-hex.mjs +0 -0
- package/skills/easysociable-template/workflows/AUTHORING_FROM_BRIEF.md +4 -4
- package/skills/easysociable-template/workflows/AUTHORING_FROM_IMAGE.md +1 -1
- package/skills/easysociable-template/workflows/AUTHORING_STUDIO.md +4 -4
- package/skills/easysociable-template/workflows/BIND_FORMULA_LOOK.md +39 -0
- package/skills/easysociable-template/workflows/DESIGN_BRIEF.md +2 -3
- package/skills/easysociable-tweet-image/SKILL.md +57 -0
- package/skills/easysociable-template/workflows/MULTI_PLATFORM_FAMILY.md +0 -81
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easysociable/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "Agent-first CLI for EasySociable: Content Engine, Template, Slideshow, and MCP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
"homepage": "https://easysociable.com",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/murphywuwu/
|
|
12
|
-
"directory": "apps/cli"
|
|
11
|
+
"url": "git+https://github.com/murphywuwu/easysociable-mcp.git"
|
|
13
12
|
},
|
|
14
13
|
"bugs": {
|
|
15
|
-
"url": "https://github.com/murphywuwu/
|
|
14
|
+
"url": "https://github.com/murphywuwu/easysociable-mcp/issues"
|
|
16
15
|
},
|
|
17
16
|
"keywords": [
|
|
18
17
|
"easysociable",
|
|
@@ -51,27 +50,31 @@
|
|
|
51
50
|
"LICENSE",
|
|
52
51
|
"README.md"
|
|
53
52
|
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"build": "tsup",
|
|
57
|
+
"prepack": "node scripts/prepack.mjs && pnpm build",
|
|
58
|
+
"pack:check": "npm pack --dry-run"
|
|
59
|
+
},
|
|
54
60
|
"publishConfig": {
|
|
55
61
|
"access": "public",
|
|
56
62
|
"registry": "https://registry.npmjs.org/"
|
|
57
63
|
},
|
|
58
64
|
"dependencies": {
|
|
59
|
-
"
|
|
65
|
+
"@resvg/resvg-wasm": "^2.6.2",
|
|
66
|
+
"commander": "^11.1.0",
|
|
67
|
+
"satori": "^0.36.0"
|
|
60
68
|
},
|
|
61
69
|
"devDependencies": {
|
|
70
|
+
"@easysociable/mcp-server": "workspace:*",
|
|
71
|
+
"@easysociable/template-gateway-client": "workspace:*",
|
|
72
|
+
"@easysociable/tsconfig": "workspace:*",
|
|
73
|
+
"@easysociable/tweet-card": "workspace:*",
|
|
74
|
+
"@easysociable/vitest-config": "workspace:*",
|
|
62
75
|
"@types/node": "^22.14.0",
|
|
63
76
|
"tsup": "^8.0.2",
|
|
64
77
|
"typescript": "^5.8.3",
|
|
65
|
-
"vitest": "^1.3.1"
|
|
66
|
-
"@easysociable/mcp-server": "0.0.0",
|
|
67
|
-
"@easysociable/tsconfig": "0.0.0",
|
|
68
|
-
"@easysociable/template-gateway-client": "0.0.0",
|
|
69
|
-
"@easysociable/vitest-config": "0.0.0"
|
|
70
|
-
},
|
|
71
|
-
"scripts": {
|
|
72
|
-
"typecheck": "tsc --noEmit",
|
|
73
|
-
"test": "vitest run",
|
|
74
|
-
"build": "tsup",
|
|
75
|
-
"pack:check": "npm pack --dry-run"
|
|
78
|
+
"vitest": "^1.3.1"
|
|
76
79
|
}
|
|
77
|
-
}
|
|
80
|
+
}
|
package/skills/ONBOARDING.md
CHANGED
|
@@ -19,14 +19,13 @@ V1 expects an Agent (Grok Bot, Codex, Claude Code, …) to drive setup. The webs
|
|
|
19
19
|
|
|
20
20
|
Default skills:
|
|
21
21
|
|
|
22
|
-
- `easysociable-slideshow` — turns a
|
|
23
|
-
- `easysociable-template` — creates page templates
|
|
22
|
+
- `easysociable-slideshow` — turns a topic into carousel pages you edit and download in Studio
|
|
24
23
|
|
|
25
24
|
Optional Content Engine skill (install via CLI only — not in the public
|
|
26
25
|
content-engine git repo; operations still follow that engine’s `CLAUDE.md`):
|
|
27
26
|
|
|
28
27
|
```bash
|
|
29
|
-
easysociable install --skills content,
|
|
28
|
+
easysociable install --skills content,slideshow --yes
|
|
30
29
|
```
|
|
31
30
|
|
|
32
31
|
Get a Content Engine core (preferred):
|
|
@@ -1,178 +1,280 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: easysociable-slideshow
|
|
3
3
|
description: >
|
|
4
|
-
|
|
5
|
-
EasySociable
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
unified `easysociable` CLI or MCP, open Studio to preview and edit, then
|
|
11
|
-
ask the user to click Download for a PNG ZIP. CLI/MCP must not call
|
|
12
|
-
render/export or create_render_job for final pixels. Runs remain in the
|
|
13
|
-
owner dashboard until archive or hard delete.
|
|
4
|
+
Turn a topic into an editable, ready-to-post carousel (Slideshow Run) in
|
|
5
|
+
EasySociable Studio. Research facts, pick a proven hook and structure
|
|
6
|
+
(Formula), lay pages out from reference designs (the user's, a Formula's,
|
|
7
|
+
or the catalog's, shuffled), render-check every page locally, then create the Run and hand the user a Studio link.
|
|
8
|
+
Ask the user only for what only they know (their Brand, once; their own
|
|
9
|
+
images/screenshots). Final pixels come only from Studio Download.
|
|
14
10
|
---
|
|
15
11
|
|
|
16
12
|
# EasySociable Slideshow Skill
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
so
|
|
21
|
-
|
|
22
|
-
Page order is the argument of **this pack**, not a catalog recipe.
|
|
14
|
+
The user gives a topic. You return a Studio link to a carousel that is good
|
|
15
|
+
enough to post, where every word is still editable. The output is editable,
|
|
16
|
+
so **a wrong guess is cheap and a question is expensive**: decide platform,
|
|
17
|
+
page count, arc, style and copy yourself; the user fixes details in Studio.
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
Ask only for what only the user knows:
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
calls go through Gateway; never call Directus, R2, Stripe or private services.
|
|
29
|
-
3. Choose a Brand (or Profile/Theme) and an explicit Layout Family for every
|
|
30
|
-
page, sent as `layoutFamilyId` in the pack (Gateway resolves it to the
|
|
31
|
-
family's template on the Run's native canvas; `pageTemplateId` is still
|
|
32
|
-
accepted). The server never silently chooses or replaces a layout.
|
|
33
|
-
Order of precedence: (a) a Formula **Look** (see Formula handoff),
|
|
34
|
-
(b) families already chosen on the Content Engine pack (**Template
|
|
35
|
-
Selection** after **Page Contracts**), (c) a shortlist from
|
|
36
|
-
`easysociable slideshows recommend --file contracts.json --seed <slug>`
|
|
37
|
-
(MCP `recommend_slideshow_templates`) — pick one `familyId` per page with a reason.
|
|
38
|
-
The recommender filters platform + native canvas + slotSummary + cover rule,
|
|
39
|
-
demotes Layout Families used in the owner's recent Runs, and keeps one
|
|
40
|
-
unused family per page. `role` / `supportedRoles` are weak retrieval tags,
|
|
41
|
-
not sequence position. Never browse with bare `templates list` (first 20
|
|
42
|
-
ids only); use `--platform <p> --all` if you must see the full catalog.
|
|
43
|
-
Do not copy a previous pack's Template Selection as the default.
|
|
44
|
-
4. **Cover / hook placement (hard):** a template is cover/hook class when
|
|
45
|
-
`supportedRoles` includes `cover` or `hook`. `pages[0]` must use one.
|
|
46
|
-
Cover/hook class templates must not appear on any later page. Later pages
|
|
47
|
-
use metric / quote / compare / value / steps / cta / etc. Do not put a
|
|
48
|
-
Point or metric-only template on page 1 to “open with a number” — pick a
|
|
49
|
-
cover or hook template whose slots fit the opening copy.
|
|
50
|
-
5. A Run has up to 8 pages on Free and 20 on paid, one native platform
|
|
51
|
-
(`tiktok`, `instagram`, `linkedin` or `threads`; it sets the page cap and
|
|
52
|
-
the canvas edited first) and one Brand across pages. Studio renders the
|
|
53
|
-
same Run for every platform its Layout Families support.
|
|
54
|
-
6. Topology is fixed after creation: no add, copy, delete, reorder or template
|
|
55
|
-
switch. Page-instance slot/layout/type/style/decoration edits remain allowed
|
|
56
|
-
in Studio.
|
|
57
|
-
7. Final pixels leave the product only from **Studio Download** (browser PNG
|
|
58
|
-
ZIP). Do not call `slideshows render`, `slideshows export`, `renders create`
|
|
59
|
-
or MCP `render_slideshow_run` / `create_render_job`. Those return
|
|
60
|
-
`HEADLESS_RENDER_DISABLED`.
|
|
61
|
-
8. Before creating a new Run, list/find prior Runs by `contentSlug`. **Update**
|
|
62
|
-
the same Run only when page count, Layout Families, and intended sequence
|
|
63
|
-
still match. A different arc or family set is a **new Run** — never PATCH
|
|
64
|
-
new copy into a locked Cover-Point-Steps-Recap-CTA skeleton.
|
|
65
|
-
8b. **Knowledge hard gate (every create, not only the first Run):** before
|
|
66
|
-
`create_run` / `slideshows create`, read Identity (Role / What I build /
|
|
67
|
-
Point of view — no `(fill)`, non-empty) and `boundaries.md` (Not covering
|
|
68
|
-
and Never claim non-empty), or run
|
|
69
|
-
`easysociable engine validate --run <run-dir> --require-knowledge`.
|
|
70
|
-
If `needs/` exists, `needs/_index.md` ≥ 3 `N-` rows; if `needs/` is absent, skip that count. Fail → hand back to
|
|
71
|
-
**easysociable-content** / refuse create; list missing files. Do not add
|
|
72
|
-
Gateway or MCP params. User must say **强制继续** / **force continue**
|
|
73
|
-
to call Gateway. **Exempt:** Formula handoff Runs (prompt names
|
|
74
|
-
`Formula: F-…`) — the Formula supplies the arc and the user supplies the
|
|
75
|
-
topic, so a first-time user with no Content Engine is not blocked.
|
|
76
|
-
8c. **Identity chain (ADR-0036, hard):** before create, the CLI must be
|
|
77
|
-
logged in with the **user's Dashboard Workspace API key** (same account
|
|
78
|
-
that will open Studio). Refuse fixture `workspace_local` / local
|
|
79
|
-
`test-key` unless the user explicitly asked for a local fixture
|
|
80
|
-
(`--allow-local-fixture`). Order: `easysociable auth login` (opens the
|
|
81
|
-
browser; the user approves once and the key is stored — use
|
|
82
|
-
`--api-key <key>` only when headless) → create Run → open
|
|
83
|
-
`studioUrl` while logged in as that user. If Studio shows “belongs to
|
|
84
|
-
another account”, recreate with the current key — do not invent
|
|
85
|
-
cross-workspace access.
|
|
86
|
-
9. Preview is free. Free Download is 3 successful ZIPs per month and one
|
|
87
|
-
platform. Paid Download is unmetered.
|
|
88
|
-
10. **Forbidden default:** do not assemble Cover → Point → Steps → Recap → CTA
|
|
89
|
-
because those are P0 family names. Name the arc first
|
|
90
|
-
(`references/ARC.md`). Page count follows the argument, not the catalog.
|
|
91
|
-
Rule 4 still applies: page 1 is cover/hook class, not “whatever family
|
|
92
|
-
is named Cover”.
|
|
21
|
+
- their Brand (IP name, handle, avatar) — once, ever;
|
|
22
|
+
- their own material (screenshots, photos) when a page needs it.
|
|
93
23
|
|
|
94
24
|
## Workflow
|
|
95
25
|
|
|
96
|
-
|
|
97
|
-
2. Validate Page Contracts / pack when present:
|
|
98
|
-
`python3 scripts/validate-pack.py runs/<slug>/pack.md` (in the Content Engine).
|
|
99
|
-
Refuse create if contracts are empty or contain `templateId`.
|
|
100
|
-
3. Resolve or create the user's Brand through the unified CLI/MCP.
|
|
101
|
-
4. Use the Formula Look's families, else pack **Template Selection**. Otherwise run
|
|
102
|
-
`easysociable slideshows recommend --file contracts.json --seed <slug> --json`
|
|
103
|
-
and choose a `familyId` from each page's `candidates`; never place a cover/hook class
|
|
104
|
-
family after page 1. Report `gaps` (pages with < 2 role-matching
|
|
105
|
-
templates) to the user as authoring backlog. Record Layout Family evidence
|
|
106
|
-
as `hypothesis` unless published comparable results support `tested` /
|
|
107
|
-
`supported` — a template having been used before is not evidence.
|
|
108
|
-
5. List existing Runs when the Pack has a stable content slug:
|
|
26
|
+
### 0. Login (once per session)
|
|
109
27
|
|
|
110
|
-
|
|
111
|
-
easysociable slideshows list --content-slug my-post --json
|
|
112
|
-
```
|
|
28
|
+
`easysociable auth status --json`.
|
|
113
29
|
|
|
114
|
-
|
|
115
|
-
|
|
30
|
+
- `authenticated: false` → stop; ask the user to run `easysociable auth login`
|
|
31
|
+
(one browser approval covers CLI and Studio). Draft nothing while logged out.
|
|
32
|
+
- `authenticated: true` → say once: "This Run will be created as
|
|
33
|
+
`<account.email>` — open Studio with the same account."
|
|
116
34
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
35
|
+
### 1. Brand (ask once, ever)
|
|
36
|
+
|
|
37
|
+
`easysociable brands list --json`.
|
|
38
|
+
|
|
39
|
+
- A Brand exists → use it (the most recently updated if several), silently.
|
|
40
|
+
- None → ask in **one** message, everything skippable:
|
|
41
|
+
"What name and @handle should appear on your carousels? (Optional: an
|
|
42
|
+
avatar/logo image path.) Reply 'skip' to post without a signature."
|
|
43
|
+
Create it with `easysociable brands create --file brand.json`
|
|
44
|
+
(`{ "name", "handle", "colors", "logoAssetId" }`) using the default palette
|
|
45
|
+
that matches the deck's style (`references/REFERENCES.md`). An avatar: upload
|
|
46
|
+
it first (step 5's `images upload`) and pass the returned `asset.id` as
|
|
47
|
+
`logoAssetId`; `brands get` then returns its `logoUrl`.
|
|
48
|
+
Skipped → no Brand: header shows the topic, the CTA has no handle, and that
|
|
49
|
+
palette goes in `theme.json` (without a Brand or theme Studio falls back to
|
|
50
|
+
its dark default).
|
|
51
|
+
|
|
52
|
+
### 2. Facts
|
|
53
|
+
|
|
54
|
+
Research the topic from primary sources (official announcement, docs,
|
|
55
|
+
reputable press). Keep a source URL for every fact. Drop claims you can only
|
|
56
|
+
find in secondary blogs. Never invent numbers, dates, quotes or features.
|
|
57
|
+
|
|
58
|
+
When the user started from a Content Engine run, facts come from its knowledge
|
|
59
|
+
pages instead (see `easysociable-content`).
|
|
60
|
+
|
|
61
|
+
### 3. Hook and structure
|
|
62
|
+
|
|
63
|
+
Both catalogs are hosted cards distilled from real viral posts, with evidence
|
|
64
|
+
pooled across niches (a hook or structure works by its mechanism, not its
|
|
65
|
+
niche). Use a card when it fits; otherwise write your own. Never force one.
|
|
66
|
+
|
|
67
|
+
- Decide the content's **shape** from your facts: N tips → `tip-list`, a
|
|
68
|
+
procedure → `steps`, a transformation → `before-after`, errors →
|
|
69
|
+
`mistake-list`, a single piece of news or a claim → no list recipe.
|
|
70
|
+
- `easysociable hooks recommend --json` → one mold per hook type (list-tease,
|
|
71
|
+
contrast, number, identity, …), ranked by evidence.
|
|
72
|
+
- **Always** look for a structure first:
|
|
73
|
+
`easysociable formulas recommend [--recipe <recipe>] --platform <p> --fact-count <n> --json`
|
|
74
|
+
(`--recipe` when the shape is a list recipe; without it you see every
|
|
75
|
+
structure and judge fit yourself). Near-equal cards come back shuffled.
|
|
76
|
+
When the user asked for something different from last time, add
|
|
77
|
+
`--exclude <formulaId>` for the Formula that Run used.
|
|
78
|
+
- Use a card only if `stop` is false **and** it fits this content (a news
|
|
79
|
+
explainer is not an "N things" list). Prefer `published`; a `hypothesis`
|
|
80
|
+
card is thin evidence: use it only when it clearly fits.
|
|
81
|
+
- Hook: fill the mold's `format` with the topic (never copy its example).
|
|
82
|
+
Formula: its `swipe` is the page order and each `beat.fill` guides the copy.
|
|
83
|
+
- No fitting card → write the hook and arc yourself (`references/ARC.md`):
|
|
84
|
+
draft 3 hooks of different types, keep the most specific one the carousel
|
|
85
|
+
fully pays off.
|
|
86
|
+
- Platform: what the user said, else the one their Brand/history uses, else
|
|
87
|
+
Instagram 4:5. Page count follows the argument (usually 6–9), within
|
|
88
|
+
`references/PLATFORM_CAPS.md`.
|
|
89
|
+
- One idea per page, ≤ 45 words per page. Page 1 is the hook. Last page asks
|
|
90
|
+
for one action (comment, save or follow).
|
|
91
|
+
|
|
92
|
+
### 4. Look and pages
|
|
93
|
+
|
|
94
|
+
Structure (step 3) and look are chosen separately. The look comes from a
|
|
95
|
+
**reference**; the first rule that applies wins:
|
|
96
|
+
|
|
97
|
+
1. The user names a Run or says "same as last time / like this one" →
|
|
98
|
+
"Reuse a Run" below.
|
|
99
|
+
2. The user shares a post (screenshot or link) → study its grid, type scale,
|
|
100
|
+
background, density and decoration; take the closest catalog references as
|
|
101
|
+
structure and restyle them to match the post. Never copy its words or images.
|
|
102
|
+
3. A Formula with a Look → the Look's designs (Formula handoff below).
|
|
103
|
+
4. The user asks for a different look ("换个样子", "something else") → first
|
|
104
|
+
write 3–5 art directions that differ from each other and from this Brand's
|
|
105
|
+
previous Run (one line each: grid, type treatment, background, density,
|
|
106
|
+
decoration). Drop any the previous Run used, take the least conventional
|
|
107
|
+
one, and pick references whose `style` fits it.
|
|
108
|
+
5. Otherwise → the content decides: get candidates for the cover with
|
|
109
|
+
`easysociable templates references --role hook,cover [--no-image] --json`
|
|
110
|
+
(results are shuffled) and take the first that fits the content. Its
|
|
111
|
+
`style` is the deck's style; for each other page ask for that page's roles
|
|
112
|
+
with `--style <style>`. A number → `metric,proof`; a list item →
|
|
113
|
+
`point,value,steps`; a comparison → `compare`; a real product →
|
|
114
|
+
`screenshot`. No match in that style → any style, keeping the cover's chrome.
|
|
115
|
+
|
|
116
|
+
`--no-image` unless you have (or will leave a placeholder for) a real image.
|
|
117
|
+
Read each chosen design with `easysociable templates source --family <familyId> --json`
|
|
118
|
+
and adapt it as in `references/REFERENCES.md` ("Adapting a reference" and
|
|
119
|
+
"Avoid"). Put the result in the pack as a generated page:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{ "role": "hook", "slots": { "text_0": "…", "text_1": "…" },
|
|
123
|
+
"layout": { "studioJson": "<div id=\"Graphic\" data-type=\"post\" …>…</div>",
|
|
124
|
+
"canvas": { "width": 1080, "height": 1350 } } }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`slots` maps each `data-variable` to its plain text. Generated pages carry no
|
|
128
|
+
`layoutFamilyId` / `pageTemplateId`.
|
|
129
|
+
|
|
130
|
+
In the final message, add one line: "Want future carousels to look like this?
|
|
131
|
+
Say 'same as this'. Want another look? Say 'different look'."
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
is the only override (conversational — not a CLI flag). Formula handoff
|
|
123
|
-
Runs skip this knowledge check (rule 8b) but not the identity gate. Then:
|
|
133
|
+
### 5. Images
|
|
124
134
|
|
|
135
|
+
- Real products, apps, people, data → real screenshots or photos only. Never
|
|
136
|
+
an AI-generated picture of a real product UI.
|
|
137
|
+
- Concept / mood / background → generate one if this environment has an
|
|
138
|
+
image-generation tool; otherwise leave the page text-only.
|
|
139
|
+
- Images never contain text: all words stay in editable text layers.
|
|
140
|
+
- **Every page whose content needs a real image you don't have gets a
|
|
141
|
+
placeholder slot** (as many pages as need one), never a text-only layout. Size it into the composition (usually the
|
|
142
|
+
lower half of the page) and label it with exactly what belongs there, e.g.
|
|
143
|
+
"Add: Grok Bot app screenshot". The user selects it in Studio and clicks
|
|
144
|
+
the upload button to replace it. Markup and SVG in `references/REFERENCES.md`
|
|
145
|
+
("Image placeholder").
|
|
146
|
+
- An image you do have: upload it
|
|
147
|
+
(`easysociable images upload --file body.json` with
|
|
148
|
+
`{ "file": "data:image/png;base64,…", "filename": "x.png" }`) and use the
|
|
149
|
+
returned `asset.url` as `src`.
|
|
150
|
+
- List every placeholder in the final message ("page 2: app screenshot").
|
|
151
|
+
|
|
152
|
+
### 6. Check (hard gate)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
easysociable brands get --id <brandId> --json > brand.json
|
|
156
|
+
node <skill>/scripts/check-pages.mjs pack.json --out ./check --brand brand.json
|
|
157
|
+
# no Brand: --theme theme.json instead of --brand brand.json
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- Exit 1 → fix every ERROR (overflow, off-canvas, text overlap, contrast) and
|
|
161
|
+
re-run. Do not create the Run with errors.
|
|
162
|
+
- Warnings (small text, too many words, empty band) → fix unless deliberate.
|
|
163
|
+
- Open `check/grid.png` and review it as a designer: one clear focal point per
|
|
164
|
+
page, nothing cramped, no two adjacent pages alike, reads in 2 seconds.
|
|
165
|
+
At most two fix rounds.
|
|
166
|
+
- Exit 2 (no Chrome) → continue, and tell the user the visual check was skipped.
|
|
167
|
+
|
|
168
|
+
### 7. Create and hand off
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
easysociable slideshows create --file pack.json --brand-id <brandId> --json
|
|
172
|
+
# no Brand: --theme theme.json instead of --brand-id
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Reply once with: the `studioUrl`, the arc in one line, the sources, and each
|
|
176
|
+
image placeholder to replace (page + what to upload). Tell them to edit in
|
|
177
|
+
Studio and click **Download** for the PNG ZIP.
|
|
178
|
+
|
|
179
|
+
### 8. Revise (same Run, never a copy)
|
|
180
|
+
|
|
181
|
+
Feedback on an existing Run ("page 3 looks off", "shorter hook") edits that Run.
|
|
182
|
+
|
|
183
|
+
1. `easysociable slideshows get --id <runId> --json > revisions/<runId>-r<revision>.json`
|
|
184
|
+
— the saved Run is the source of truth (it holds the user's Studio edits);
|
|
185
|
+
never rebuild from your local pack.json. The file is also the backup.
|
|
186
|
+
2. Change only the pages the user named. Start from each page's saved `layout`
|
|
187
|
+
and `slots`, adapt as in step 4, and run step 6 on the changed pages.
|
|
188
|
+
3. Write `patch.json` and apply it:
|
|
189
|
+
```json
|
|
190
|
+
{ "baseRevision": <run.revision>,
|
|
191
|
+
"pages": [{ "pageIndex": 2, "layout": { "studioJson": "…", "canvas": { "width": 1080, "height": 1350 } }, "slots": { … } }] }
|
|
192
|
+
```
|
|
125
193
|
```bash
|
|
126
|
-
easysociable slideshows
|
|
194
|
+
easysociable slideshows update --id <runId> --file patch.json --json
|
|
127
195
|
```
|
|
196
|
+
`slots` replaces the page's slots, so send the full set for that page.
|
|
197
|
+
Unlisted pages stay untouched.
|
|
198
|
+
4. `RUN_REVISION_CONFLICT` → the user saved in Studio meanwhile: `get` again,
|
|
199
|
+
re-apply your change on top, retry once.
|
|
200
|
+
5. "Go back to the previous version" → take those pages' `layout` / `slots`
|
|
201
|
+
from the newest `revisions/<runId>-r*.json` before the change and send them
|
|
202
|
+
as a normal patch with the current `baseRevision`. The original generated
|
|
203
|
+
pages are in the Run's `packSnapshot`.
|
|
204
|
+
|
|
205
|
+
Same `studioUrl`; tell the user to reload Studio. A new Run only for a
|
|
206
|
+
different topic, or when the user asks for an alternative version to compare.
|
|
207
|
+
|
|
208
|
+
## Formula handoff (prompt names `Formula: F-…`)
|
|
209
|
+
|
|
210
|
+
`easysociable formulas get --id <id> --json`. Its `beats` are the pages (same
|
|
211
|
+
order and roles); `title_template` with `{X}` = the topic is the arc. Write copy
|
|
212
|
+
from each `beat.fill` and your facts; never copy the formula's example posts.
|
|
213
|
+
With `Look: L-…` (else the formula's first `looks` entry) the page source is
|
|
214
|
+
`look.slides["<n>"]` or `look.layouts[beat.role]` (a design's `familyId`):
|
|
215
|
+
read it with `templates source --family` and adapt it as in step 4. The Look
|
|
216
|
+
wins over rule 5 of step 4 but not over a Run or post the user named.
|
|
217
|
+
Then continue at step 5.
|
|
218
|
+
|
|
219
|
+
## Reuse a Run (prompt names a `run_…` for a new topic)
|
|
220
|
+
|
|
221
|
+
A new topic → a **new** Run; the source Run is never changed. Never ask which
|
|
222
|
+
mode; decide from the words and the content:
|
|
223
|
+
|
|
224
|
+
- **Template** — "using run_x as the template", "same as last time", "like
|
|
225
|
+
this one" (last time = the newest Run of this Brand, `slideshows list`).
|
|
226
|
+
Keep every page's look: only slot content changes.
|
|
227
|
+
- **Style** — "in the style / feel / vibe of run_x", or Template was asked but
|
|
228
|
+
the new content does not fit its page roles (a "N tips" Run for an "A vs B"
|
|
229
|
+
topic). Take its colours, type treatment, chrome and spacing; lay pages out
|
|
230
|
+
fresh in step 4.
|
|
231
|
+
|
|
232
|
+
Template steps:
|
|
233
|
+
|
|
234
|
+
1. `easysociable slideshows get --id <runId> --json`. Its pages' `role`,
|
|
235
|
+
`layout` and `slots` are the source (they include the user's Studio edits).
|
|
236
|
+
2. Write facts and the arc for the new topic (steps 2–3, no Formula search).
|
|
237
|
+
3. Pages by role: one-off roles (hook, cta) copy that page's `layout`
|
|
238
|
+
verbatim; repeated roles (point, step) reuse the source page of that role
|
|
239
|
+
**as many times as the new content needs** (4 tips → 4 pages, 6 → 6). Drop
|
|
240
|
+
roles the new content has none of.
|
|
241
|
+
4. Change only text inside `data-variable` elements and send matching
|
|
242
|
+
`slots`. Too long → rewrite shorter; never resize boxes or move elements.
|
|
243
|
+
Every source image becomes a placeholder for the new topic (step 5);
|
|
244
|
+
Brand avatar/logo stay.
|
|
245
|
+
5. Step 6 check, then create (step 7). In the reply, say in one line what
|
|
246
|
+
differs from the source ("6 tips, so 6 point pages instead of 4") and that
|
|
247
|
+
the user can say "back to 4 pages" or "different layout".
|
|
248
|
+
|
|
249
|
+
## Rules
|
|
128
250
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
4. **Look = copy the layout.** If the prompt names `Look: L-…` (else use the
|
|
145
|
-
formula's first entry in `looks`), set each page's `layoutFamilyId` to
|
|
146
|
-
`look.slides["<1-based slide number>"]` if present, else
|
|
147
|
-
`look.layouts[beat.role]`. Do not run `slideshows recommend` for those
|
|
148
|
-
pages and ignore the "demote recently used families" preference — the
|
|
149
|
-
user asked for this layout. Only roles missing from the Look fall back to
|
|
150
|
-
the recommender. Copy layout only: colours and fonts come from the user's
|
|
151
|
-
Brand. If a Look family has image slots, ask the user for images (or say
|
|
152
|
-
which slots are empty) instead of delivering blank image slots.
|
|
153
|
-
5. Turn beats into Page Contracts, then continue at Workflow step 3
|
|
154
|
-
(Brand → families → identity gate → create → Studio). The knowledge gate
|
|
155
|
-
(rule 8b) does not apply to Formula handoff Runs.
|
|
251
|
+
1. All hosted calls go through the `easysociable` CLI or the unified MCP
|
|
252
|
+
server (Gateway). Never call Directus, R2, Stripe or private services.
|
|
253
|
+
2. Final pixels leave only via Studio **Download**. Do not call
|
|
254
|
+
`slideshows render`, `slideshows export`, `renders create`, or MCP
|
|
255
|
+
`render_slideshow_run` / `create_render_job` (`HEADLESS_RENDER_DISABLED`).
|
|
256
|
+
3. Revisions edit the same Run page by page (step 8): layout, text and images
|
|
257
|
+
can all change. Page count and order are fixed for now (no add, delete,
|
|
258
|
+
reorder) — if the user needs that, say so; create a new Run only when they agree.
|
|
259
|
+
4. Every plan: up to 20 pages. Free: 3 Downloads per month and 1 Brand; Creator: unlimited, 3 Brands; Studio: unlimited, 25 Brands. `BRAND_LIMIT_REACHED` → tell the user their plan's limit and the suggested action; never create a Run without the Brand silently.
|
|
260
|
+
5. Identity: create with the user's own login, not `workspace_local` /
|
|
261
|
+
`test-key` (unless they asked for `--allow-local-fixture`). Studio says
|
|
262
|
+
"belongs to another account" → recreate with the current login.
|
|
263
|
+
6. Content Engine runs keep their knowledge gate:
|
|
264
|
+
`easysociable engine validate --run <run-dir> --require-knowledge`.
|
|
265
|
+
Topic-only requests (no Content Engine) use researched, sourced facts.
|
|
156
266
|
|
|
157
267
|
## Failure handling
|
|
158
268
|
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
error to the Agent; do not substitute another template.
|
|
166
|
-
- `LAYOUT_FAMILY_NOT_FOUND`: the family has no template for the Run's
|
|
167
|
-
platform. Tell the user and pick another platform or family; do not guess.
|
|
168
|
-
- If Download is exhausted (`USAGE_LIMIT_REACHED`) or past due, tell the user
|
|
169
|
-
to upgrade or update billing.
|
|
170
|
-
- If a Run was deleted, or Gateway returns `RUN_TOPOLOGY_LOCKED` because the
|
|
171
|
-
pack changed sequence/templates, create a new Run from the Pack.
|
|
269
|
+
- `CONTENT_PACK_INVALID` → fix the pack field it names; do not drop pages silently.
|
|
270
|
+
- `BRAND_NOT_FOUND` → the Brand belongs to another account; list Brands again.
|
|
271
|
+
- `USAGE_LIMIT_REACHED` / past due → tell the user to upgrade or update billing.
|
|
272
|
+
- `RUN_REVISION_CONFLICT` → `slideshows get`, re-apply on the latest revision, retry once.
|
|
273
|
+
- `RUN_TOPOLOGY_LOCKED` → you sent a full `pack` or a `pageTemplateId`; send
|
|
274
|
+
page `layout` / `slots` instead (step 8).
|
|
172
275
|
|
|
173
276
|
## Handoff boundary
|
|
174
277
|
|
|
175
|
-
The Content Engine owns
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
It does not own a product-level story recipe.
|
|
278
|
+
The Content Engine owns knowledge pages and Formula research. Reference
|
|
279
|
+
designs are authored internally (Template skill); this skill only reads them. This skill turns a topic into a Run
|
|
280
|
+
and opens Studio.
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# ContentPack v1
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`bindingMap`, AST, ContentDocument, or product `arc` / `pageSequence`.
|
|
3
|
+
A page is **generated**: `layout: { studioJson, canvas }` adapted from a
|
|
4
|
+
reference design (see `REFERENCES.md`). Catalog pages (`layoutFamilyId` /
|
|
5
|
+
`pageTemplateId`) are legacy; do not create new Runs with them. `role` is a weak tag from the closed enum, not a
|
|
6
|
+
sequence position. `slots` are public values only. Do not add a
|
|
7
|
+
`deck_template_id`, `bindingMap`, AST, ContentDocument, or product `arc` /
|
|
8
|
+
`pageSequence`.
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
It does not require Cover → Point → Steps → Recap → CTA.
|
|
10
|
+
Generated page:
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
```json
|
|
13
|
+
{ "role": "hook", "slots": { "text_0": "Meta's new AI doesn't chat." },
|
|
14
|
+
"layout": { "studioJson": "<div id=\"Graphic\" data-type=\"post\" …>…</div>",
|
|
15
|
+
"canvas": { "width": 1080, "height": 1350 } } }
|
|
16
|
+
```
|
|
16
17
|
|
|
17
18
|
## Example: cost → mechanism (TikTok)
|
|
18
19
|
|
|
@@ -47,10 +48,6 @@ Opening beat is cost; page 1 is still a hook-class template.
|
|
|
47
48
|
}
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
Pick families by **slotSummary + density** (or take them from a Formula Look),
|
|
51
|
-
not by matching the beat name to a family named Cover / Point / Steps / Recap /
|
|
52
|
-
CTA. Page 1 must still be cover/hook class.
|
|
53
|
-
|
|
54
51
|
The renderer accepts any supported page count within the platform cap. A newly
|
|
55
52
|
published Layout Family can be selected in a new Run without creating a
|
|
56
53
|
carousel asset.
|