@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
@@ -0,0 +1,9 @@
1
+ # accounts/
2
+
3
+ | File | Role |
4
+ |------|------|
5
+ | `_index.md` | **Source of truth** for handle → profile, platforms, voice, overrides path |
6
+ | `overrides/<handle>.md` | **Optional** — only when account-only deltas exist; path listed in `_index.overrides` |
7
+
8
+ Do **not** keep a full `accounts/<handle>.md` for every account.
9
+ Pillars/audience bodies stay under `profiles/<id>/`.
@@ -0,0 +1,31 @@
1
+ # Accounts index
2
+
3
+ Each handle points at a **profile** + platforms.
4
+ Full pillars/audience/voice live under `profiles/<id>/` (unless voice overridden).
5
+
6
+ Replace the starter handle before the first run.
7
+
8
+ | handle | profile_id | voice | platforms | default_platform | overrides | status |
9
+ |--------|------------|-------|-----------|------------------|-----------|--------|
10
+ | your-handle | default | profile | x | x | | active |
11
+
12
+ ## Columns
13
+
14
+ | Column | Meaning |
15
+ |--------|---------|
16
+ | `handle` | Social account id |
17
+ | `profile_id` | Row in `profiles/_index.md` |
18
+ | `voice` | `profile` → `profiles/<profile_id>/voice.md`; or explicit path to another voice file |
19
+ | `platforms` | Platforms this account posts on |
20
+ | `default_platform` | Watchlist / catalog filter when unset — **not** used to silent-default 开一单 |
21
+ | `overrides` | Empty = none; else path e.g. `accounts/overrides/<handle>.md` |
22
+ | `status` | active / planned / retired |
23
+
24
+ ## Resolve path (Agent)
25
+
26
+ 1. Read this table for the handle (default: first **active** row)
27
+ 2. Load `profiles/<profile_id>/pillars.md` + `audience.md`
28
+ 3. Voice: if `profile` or empty → `profiles/<profile_id>/voice.md`; else load the path in the cell
29
+ 4. If `overrides` non-empty, read that file last
30
+ 5. Load `platforms/<platform>.md` for craft (**required** when drafting that platform; map in `platforms/README.md`)
31
+ 6. Filter swipe/atoms/claims by platform + profile (`*` = all)
@@ -0,0 +1,3 @@
1
+ # Account overrides
2
+
3
+ Optional per-handle deltas. Path must be listed in `accounts/_index.md` `overrides` column.
@@ -0,0 +1,18 @@
1
+ # Discovery
2
+
3
+ Discovery is the intermediate layer between watchlist signals and Topics.
4
+
5
+ ```text
6
+ watchlist → discovery → (explicit promote) → topic → brief
7
+ ```
8
+
9
+ It makes the source understandable before deciding whether the idea belongs to us.
10
+
11
+ - `Source Digest` is a short natural-language note: what happened, the author's argument, support, native language, and limits.
12
+ - `Source limits` records what the source does not establish.
13
+ - `Decision` stores only workflow status and next action.
14
+ - A source with high engagement can still remain `saved` or `rejected`.
15
+
16
+ Do not add our audience, product, thesis, ownership, or candidate Topics to a Discovery.
17
+ Do not use 5C as the default Discovery reading format.
18
+ Discovery does not generate publish-ready copy.
@@ -0,0 +1,27 @@
1
+ # Discovery index
2
+
3
+ One row = one analyzed external signal from a watchlist scan. Discovery is not a topic queue.
4
+
5
+ Newest on top.
6
+
7
+ | id | date | profile | platform | source_handle | source_url | source_claim | source_role | status | next_action | topic_ids | file |
8
+ |----|------|---------|----------|---------------|------------|--------------|-------------|--------|-------------|-----------|------|
9
+ | -- | ---- | ------- | -------- | ------------- | ---------- | ------------ | ----------- | ------ | ----------- | --------- | ---- |
10
+
11
+ ## Status values
12
+
13
+ | status | Meaning |
14
+ |--------|---------|
15
+ | `unread` | Signal captured; digest not read |
16
+ | `read` | Source Digest completed |
17
+ | `saved` | Useful reference; no Topic decision yet |
18
+ | `promoted` | User explicitly promoted it to Topic |
19
+ | `rejected` | Not relevant, provable, or ownable |
20
+
21
+ ## Rules
22
+
23
+ - Watchlist heat is source context, not our evidence.
24
+ - New Discovery records contain only Source Digest, source limits, and workflow state.
25
+ - Do not create a Topic during watchlist scanning; Topic creation requires explicit promotion.
26
+ - Do not store our audience, product, ownership, or candidate opportunities inside Discovery.
27
+ - 5C belongs to Topic evaluation and is never the default Discovery reading surface.
@@ -0,0 +1,41 @@
1
+ ---
2
+ id: D-YYYYMMDD-XX
3
+ date: YYYY-MM-DD
4
+ status: read
5
+ profile: default
6
+ platform: x
7
+ source_role: demand | ally | foil | mechanism
8
+ ---
9
+
10
+ # Discovery
11
+
12
+ One sentence describing the external signal in the source's terms. Do not turn it into our topic here.
13
+
14
+ ## Source
15
+
16
+ - **handle:**
17
+ - **url:**
18
+ - **captured_at:**
19
+ - **engagement snapshot:** likes / replies / bookmarks / views @ time
20
+ - **why on watchlist:**
21
+
22
+ ## Source Digest
23
+
24
+ ### In one sentence
25
+
26
+ ### What happened
27
+
28
+ ### What the author is arguing
29
+
30
+ ### How the author supports it
31
+
32
+ ### The author's own language
33
+
34
+ ### Source limits
35
+
36
+ What the source does not establish. Keep this short.
37
+
38
+ ## Decision
39
+
40
+ - **status:** unread | read | saved | promoted | rejected
41
+ - **next_action:** none | revisit | promote_to_topic
@@ -0,0 +1,19 @@
1
+ {
2
+ "schemaVersion": "content-engine.v1",
3
+ "locale": "en",
4
+ "root": "Content Engine",
5
+ "paths": {
6
+ "runs": "runs",
7
+ "exports": "exports",
8
+ "topics": "topics",
9
+ "swipe": "swipe",
10
+ "profiles": "profiles",
11
+ "inbox": "inbox",
12
+ "accounts": "accounts",
13
+ "raw": "raw",
14
+ "published": "published",
15
+ "wiki": "wiki",
16
+ "platforms": "platforms",
17
+ "workbench": "workbench"
18
+ }
19
+ }
@@ -0,0 +1,28 @@
1
+ # exports/
2
+
3
+ **Rendered image packs only** (slideshow skill / Gateway). Not drafts.
4
+
5
+ ## Layout
6
+
7
+ One run = one platform, so the slug already scopes the platform. Optional `<platform>/` subfolder still OK.
8
+
9
+ ```text
10
+ exports/
11
+ <run-folder-slug>/ # same name as runs/YYYY-MM-DD-slug[-platform]
12
+ 01.png
13
+ 02.png
14
+ …
15
+ manifest.json # optional: job_id, deck_hint, page_count
16
+ ```
17
+
18
+ Example: `exports/2026-08-26-angle-linkedin/01.png`
19
+
20
+ ## Pointers
21
+
22
+ - `runs/.../pack.md` → `export_path: exports/<slug>/`
23
+ - `runs/_index` column `export`: `no` \| `yes`
24
+ - **Do not** put binaries in `published/` — only URLs after ship
25
+
26
+ ## Until slideshow skill is wired
27
+
28
+ Folder may stay empty. Agent must not invent images; pack render status stays `not_requested` / `blocked`.
@@ -0,0 +1,9 @@
1
+ # inbox/
2
+
3
+ | Path | Role |
4
+ |------|------|
5
+ | `_index.md` | Capture registry (source of truth for list/status) |
6
+ | `entries/C-YYYYMMDD-XX.md` | Working notes for one capture |
7
+ | *(no capture.md)* | Deprecated stream file removed |
8
+
9
+ Authoritative originals → `../raw/`.
@@ -0,0 +1,24 @@
1
+ # Inbox index
2
+
3
+ Registry of captures. **Source of truth for capture lifecycle**.
4
+
5
+ Newest rows on top.
6
+
7
+ | id | date | type | one_liner | platforms | profile | entry | raw | library | status |
8
+ |----|------|------|-----------|-----------|---------|-------|-----|---------|--------|
9
+
10
+ ## Columns
11
+
12
+ | Column | Meaning |
13
+ |--------|---------|
14
+ | `entry` | Working notes file under `inbox/entries/` |
15
+ | `raw` | Authoritative source file if any; else empty |
16
+ | `library` | `none` or e.g. `swipe:S1` / `atom:A-…` / `claim:C-…` after user-approved ingest |
17
+ | `profile` | Which content profile this capture is for |
18
+ | `status` | `captured` \| `ingested` \| `archived` |
19
+
20
+ ## Agent rules
21
+
22
+ - Every capture: new row + new `entries/<id>.md`
23
+ - raw file only when URL / structure / media / user says important → also row in `raw/_index.md`
24
+ - Never silent-write swipe/atoms/claims; only update `library` after approval
@@ -0,0 +1,3 @@
1
+ # inbox/entries/
2
+
3
+ One file per capture (`C-YYYYMMDD-XX.md`). Registry: `../_index.md`.
@@ -0,0 +1,19 @@
1
+ # Platforms (craft only)
2
+
3
+ One file per network. **Required** whenever drafting that platform (especially § Open a run: brief → draft → editor → rubric → pack).
4
+
5
+ Loaded as `platforms/<platform>.md` after account → profile resolve. Map:
6
+
7
+ | Platform id | File |
8
+ |-------------|------|
9
+ | `x` | `x.md` |
10
+ | `linkedin` | `linkedin.md` |
11
+ | `ig` | `ig.md` |
12
+ | `instagram` | `ig.md` (canonical; `instagram.md` is redirect stub) |
13
+ | `tiktok` | `tiktok.md` |
14
+ | `threads` | `threads.md` |
15
+ | `xiaohongshu` / `xhs` | `xiaohongshu.md` |
16
+
17
+ **Not here:** ICP, pillars, voice → `profiles/`. Pixels → EasySociable `PLATFORM_SPECS`.
18
+ **Rule:** same Topic, different platforms → **N runs**, each **re-reads** its craft file (no paste-across).
19
+ **Missing file:** do not invent craft; stop and tell the user.
@@ -0,0 +1,69 @@
1
+ # Platform: Instagram
2
+
3
+ **Scope:** How to *write* for Instagram — caption, carousel norms, job-of-format.
4
+ **Not in this file:** Who you are, product story, pillars, voice, audience.
5
+ **Pixels / canvas:** EasySociable `PLATFORM_SPECS` — feed carousel default **4:5 @ 1080×1350** (or `1:1` if user wants max compatibility).
6
+
7
+ Agent: platform id in this vault is often `ig` (also accept `instagram` → this file).
8
+
9
+ ---
10
+
11
+ ## Defaults
12
+
13
+ - Language: English (unless user asks otherwise)
14
+ - Default unit for easysociable-builder: **feed carousel** (save/depth job) — **not** Reels unless the user explicitly asks for Reels
15
+ - Assume thumb stop on **cover slide**; caption supports the cover, does not replace it
16
+ - Pack: **yes** for carousel runs
17
+
18
+ ## Length & shape
19
+
20
+ | Form | Guidance |
21
+ |------|----------|
22
+ | Carousel | **7–9 slides** common; keep one aspect for all slides. One tip/step per slide. Big type; few words. |
23
+ | Caption | 1–3 short lines: hook + what they’ll get by swiping. Optional soft CTA (“Save for your next brand kit”). |
24
+ | Reels | Only if user asks. Different job: discovery/reach. Do not silently turn a carousel brief into a Reel script. |
25
+ | Single image | Rare for system topics; prefer carousel when teaching steps. |
26
+
27
+ ## Hooks (mechanics only)
28
+
29
+ Cover slide should:
30
+
31
+ - Stop the scroll with a **bold, specific promise or mistake**
32
+ - Signal “worth saving” (checklist, steps, before/after), not “watch me talk”
33
+
34
+ Caption line 1 mirrors the cover; no LinkedIn-length essay above the fold.
35
+
36
+ ## Craft rules
37
+
38
+ 1. **Visual first.** If the slides don’t work with sound off and skim-reading, rewrite.
39
+ 2. Optimize carousel for **saves** and return visits — reference content, not dunks.
40
+ 3. One idea per slide; max clarity over clever wordplay.
41
+ 4. Keep brand kit / template consistency visible (this is where EasySociable proof belongs).
42
+ 5. CTA: save / share to a teammate / soft follow — not comment-gate lead magnets.
43
+ 6. Hashtags: light or none; never a block of 30.
44
+ 7. Do not paste X thread text onto slides.
45
+
46
+ ## Anti-slop (Instagram)
47
+
48
+ Do **not** default to:
49
+
50
+ - Wall-of-text slides
51
+ - Engagement bait (“Comment SAVE”) as the whole strategy
52
+ - Faceless “viral in 60 seconds” energy as the brand voice
53
+ - Using Reels trends/audio as required for every post
54
+ - Treating IG as a dump of LinkedIn PDF screenshots with tiny type
55
+
56
+ ## Quality self-check
57
+
58
+ - [ ] Cover stops a visual scroll without reading the caption?
59
+ - [ ] Would someone save this to reuse next week?
60
+ - [ ] Words per slide low enough for mobile?
61
+ - [ ] Same aspect across the deck?
62
+ - [ ] Job clear: save/authority (carousel) vs reach (Reel) — and format matches?
63
+ - [ ] No invented metrics; EasySociable only if earned?
64
+
65
+ ## Out of scope here
66
+
67
+ - Reels editing / trending audio tactics
68
+ - Pixel export → EasySociable skills + `PLATFORM_SPECS`
69
+ - Other networks → sibling `platforms/*.md`
@@ -0,0 +1,5 @@
1
+ # Platform: Instagram (alias)
2
+
3
+ Vault platform id is often **`ig`**. Product/catalog enum may say **`instagram`**.
4
+
5
+ **→ Follow [`ig.md`](./ig.md) in full.** Do not maintain a second craft body here.
@@ -0,0 +1,72 @@
1
+ # Platform: LinkedIn
2
+
3
+ **Scope:** How to *write* for LinkedIn — length, rhythm, quality bars, document/carousel norms.
4
+ **Not in this file:** Who you are, product story, pillars, voice, audience.
5
+ Those live under `profiles/<id>/` (via account → profile resolve).
6
+ **Pixels / canvas:** EasySociable `PLATFORM_SPECS` (LinkedIn page templates; PDF document pages often `4:5` or `1:1`).
7
+
8
+ Agent: before drafting any LinkedIn post, read this file for craft.
9
+
10
+ ---
11
+
12
+ ## Defaults
13
+
14
+ - Language: English (unless user asks otherwise)
15
+ - Default unit: **document carousel (PDF pages) + short post text** — not a pure text hot take
16
+ - Assume professional feed skim: **cover slide + first line of caption** do most of the work
17
+ - Pack: **almost always yes** for easysociable-builder runs (visual production proof)
18
+
19
+ ## Length & shape
20
+
21
+ | Form | Guidance |
22
+ |------|----------|
23
+ | Caption | Hook in line 1 (above the fold). 3–8 short lines total. One clear promise. Put outbound links in the **first comment**, not the post body when possible. |
24
+ | Document carousel | **7–10 pages** sweet spot (acceptable band ~5–15). One idea per page. Headlines scannable alone. Body under ~30 words/page when present. |
25
+ | Aspect (pack) | Prefer **4:5 (1080×1350)** mobile-first, or **1:1 (1080×1080)** for safe desktop+mobile. Same size every page. |
26
+ | Text-only | Allowed as a light mid-week post; do not make it the default for system/framework topics. |
27
+
28
+ ## Hooks (mechanics only)
29
+
30
+ Cover slide **and** caption line 1 should each do one of:
31
+
32
+ - Name a **specific agency / operator pain** (revisions, brand feedback, blank prompt)
33
+ - Promise a **numbered framework** or checklist the reader can steal
34
+ - Lead with a **concrete claim or contrast** (not “My thoughts on AI”)
35
+
36
+ Avoid vague covers: “Leadership lessons”, “What I learned this week”.
37
+
38
+ ## Craft rules
39
+
40
+ 1. Write like a **saveable mini-deck**, not like an X dunk.
41
+ 2. One idea per slide; if it needs a paragraph, split across two slides.
42
+ 3. Prefer frameworks, steps, before/after production loops, cost-of-revision angles.
43
+ 4. Soft CTA on the last slide (invite / question / “save for your next client kickoff”) — not “Buy now”.
44
+ 5. EasySociable only as **visual production layer** proof after the framework lands.
45
+ 6. Tone: calm, specific, peer-to-peer operator — not hype, not meme war.
46
+ 7. Hashtags: 0–3 max, optional; never a wall.
47
+
48
+ ## Anti-slop (LinkedIn)
49
+
50
+ Do **not** default to:
51
+
52
+ - Inspiration-poster fluff with no procedure
53
+ - Hard sell on slide 1 or slide N
54
+ - Crypto flex / “I made $X in 30 days” unless user supplies a real number for that draft
55
+ - Pasting an X-style contrarian one-liner as the whole post
56
+ - External link in the post body as the main content
57
+ - Dense slides that require pinch-zoom
58
+
59
+ ## Quality self-check
60
+
61
+ - [ ] Cover works as a standalone headline in under 3 seconds?
62
+ - [ ] Would an agency lead save this for a teammate?
63
+ - [ ] Each page one idea; captions not essays?
64
+ - [ ] Soft CTA, not a pitch deck close?
65
+ - [ ] Matches pillars; no invented metrics/customers?
66
+ - [ ] Pack page count and aspect sensible for LI document post?
67
+
68
+ ## Out of scope here
69
+
70
+ - Exact render pipeline → run `pack.md` + EasySociable slideshow/template skills
71
+ - Profile ICP emphasis → `profiles/.../audience.md`
72
+ - Other networks → sibling `platforms/*.md`
@@ -0,0 +1,69 @@
1
+ # Platform: Threads
2
+
3
+ **Scope:** How to *write* for Meta Threads — length, tone, conversation norms.
4
+ **Not in this file:** Who you are, product story, pillars, voice, audience.
5
+ **Pixels / canvas:** Optional; if images, follow EasySociable `PLATFORM_SPECS` for **threads** (often shared with IG **4:5 @ 1080×1350**).
6
+
7
+ Agent: before drafting any Threads post, read this file for craft.
8
+
9
+ ---
10
+
11
+ ## Defaults
12
+
13
+ - Language: English (unless user asks otherwise)
14
+ - Default unit: **1 conversational short post** (≤500 characters available — use only what you need)
15
+ - Assume calmer, Instagram-adjacent feed: **invitation > combat**
16
+ - Pack: **optional**. Prefer text (+ one image) unless the user wants a mini carousel
17
+ - Role for easysociable-builder: **secondary** surface — warm process / questions; not the main agency acquisition channel (X / LinkedIn lead)
18
+
19
+ ## Length & shape
20
+
21
+ | Form | Guidance |
22
+ |------|----------|
23
+ | Single post | 1–5 short sentences. Room for one nuance line X might cut. End with a **real question** when you want replies. |
24
+ | Reply | Add substance or a precise follow-up. Same ban on empty praise as X. |
25
+ | Media | Images help; don’t rely on a 10-slide deck as the default Threads unit. |
26
+ | Cross-post from X | **Rewrite.** Do not paste X dunks unchanged. |
27
+
28
+ ## Hooks (mechanics only)
29
+
30
+ A strong open usually:
31
+
32
+ - Shares a **process observation** (“We stopped letting the agent pick templates silently…”)
33
+ - Offers a **small, stealable rule**
34
+ - Asks an **answerable** ICP question
35
+
36
+ Avoid opening with maximum contrarian heat meant for X ratio.
37
+
38
+ ## Craft rules
39
+
40
+ 1. Tone: warmer, more human, less debate-club than X.
41
+ 2. Optimize for **replies and positive conversation**, not quote-dunk chains.
42
+ 3. Good fits: behind-the-scenes, experiment notes, “what’s your bottleneck?”, light system tips.
43
+ 4. Bad fits as primary: hard category warfare, political newsjacking, long frameworks (send those to LinkedIn).
44
+ 5. EasySociable: mention lightly as visual production layer when relevant — no install sermon.
45
+ 6. One topic tag max if used; no hashtag walls.
46
+
47
+ ## Anti-slop (Threads)
48
+
49
+ Do **not** default to:
50
+
51
+ - Raw paste of an X banger
52
+ - Corporate LinkedIn voice
53
+ - Engagement bait with no point
54
+ - Fake vulnerability / engagement-pod energy
55
+ - Treating Threads as the only growth channel for AI-native agencies
56
+
57
+ ## Quality self-check
58
+
59
+ - [ ] Would this feel natural in a calm group chat, not a town-hall fight?
60
+ - [ ] If there’s a question, can a busy operator answer in one sentence?
61
+ - [ ] Rewritten for Threads — not an X clone?
62
+ - [ ] Media optional and not a tiny-type PDF dump?
63
+ - [ ] No invented metrics?
64
+
65
+ ## Out of scope here
66
+
67
+ - Meta ads / Instagram cross-post mechanics
68
+ - Full carousel systems → prefer `ig.md` / `linkedin.md` / `tiktok.md`
69
+ - Other networks → sibling `platforms/*.md`
@@ -0,0 +1,71 @@
1
+ # Platform: TikTok
2
+
3
+ **Scope:** How to *write* for TikTok — especially **Photo Mode / slideshow** craft.
4
+ **Not in this file:** Who you are, product story, pillars, voice, audience.
5
+ **Pixels / canvas:** EasySociable `PLATFORM_SPECS` — default **9:16 @ 1080×1920** for Photo Mode; keep text out of UI chrome safe zones.
6
+
7
+ Agent: before drafting any TikTok slideshow/post, read this file for craft.
8
+
9
+ ---
10
+
11
+ ## Defaults
12
+
13
+ - Language: English (unless user asks otherwise)
14
+ - Default unit for easysociable-builder: **photo slideshow (carousel)** competing in For You next to video
15
+ - Assume: if slide 1 fails, slides 2–N never exist
16
+ - Pack: **yes**; design for **completion / swipe-through**, not desktop reading
17
+
18
+ ## Length & shape
19
+
20
+ | Form | Guidance |
21
+ |------|----------|
22
+ | Slideshow | **6–10 slides** sweet spot (platform allows more; completion pressure rises). One line per slide when possible. |
23
+ | Slide 1 | Hook only — open loop, specific pain, or numbered promise. Not a course title. |
24
+ | Middle | One tip / mistake / step each. Max ~15 words/slide; hook slide often ≤10 words, huge type. |
25
+ | Last | Explicit save/share CTA is OK on TikTok (more direct than LinkedIn). |
26
+ | On-video / talking head | Only if user asks; not the default for EasySociable PNG runs. |
27
+
28
+ ## Hooks (mechanics only)
29
+
30
+ Slide 1 usually does one of:
31
+
32
+ - Specific cringe / cost (“You redesign the carousel every Wednesday”)
33
+ - Numbered open loop (“7 production leaks agencies ignore”)
34
+ - Sharp contrast / “stop doing X”
35
+
36
+ Avoid textbook titles: “Content Systems Explained”.
37
+
38
+ ## Craft rules
39
+
40
+ 1. Write for a **video-trained thumb**: bigger type, fewer words, higher contrast than IG if needed.
41
+ 2. Each slide must **earn the next swipe**; cut any slide that only restates.
42
+ 3. Prefer listicle / mistakes / stack / steps formats.
43
+ 4. Tone: spoken, direct, slightly punchy — not LinkedIn deck voice.
44
+ 5. Agency worldview is OK if compressed into swipeable bites; deep theory → X or LinkedIn instead.
45
+ 6. EasySociable as quick proof of visual production — not a feature tour.
46
+ 7. Same aspect every slide; default 9:16 unless user overrides.
47
+
48
+ ## Anti-slop (TikTok)
49
+
50
+ Do **not** default to:
51
+
52
+ - Soft corporate captions on slide 1
53
+ - Dense paragraphs or LI-style frameworks with 40 words/slide
54
+ - “Follow for part 2” without delivering value in-post
55
+ - Watermarked or letterboxed 4:5 content that looks like a wrong-platform export
56
+ - Comment-gate playbooks as the primary CTA for this brand
57
+
58
+ ## Quality self-check
59
+
60
+ - [ ] Slide 1 works as a For You interrupt?
61
+ - [ ] Would a stranger swipe to slide 3 without loving you already?
62
+ - [ ] Word count low; type large; chrome-safe?
63
+ - [ ] Completion-friendly length (not a 20-slide essay)?
64
+ - [ ] 9:16 (or user-agreed alt) consistent across pack?
65
+ - [ ] No invented metrics?
66
+
67
+ ## Out of scope here
68
+
69
+ - TikTok Shop / live / music licensing
70
+ - Native video editing
71
+ - Exact render → EasySociable slideshow skill + `PLATFORM_SPECS`
@@ -0,0 +1,78 @@
1
+ # Platform: X (Twitter)
2
+
3
+ **Scope:** How to *write* for X — length, rhythm, quality bars.
4
+ **Not in this file:** Who you are, product story, pillars, voice, audience.
5
+ Those live under `profiles/<id>/` (via account → profile resolve).
6
+ **Pixels / canvas:** Optional; if images, EasySociable `PLATFORM_SPECS` for **x** (often wide ~1200×675 or `1:1` for multi-image).
7
+
8
+ Agent: before drafting any X post, read this file for craft. For topics/tone/readers, use resolved profile files.
9
+
10
+ ---
11
+
12
+ ## Defaults
13
+
14
+ - Language: English (unless user asks otherwise)
15
+ - Default unit: **1 short post** (not a thread), unless user asks for a thread
16
+ - Assume timeline scroll: **first line** does most of the work
17
+ - Success for easysociable-builder: **qualified replies / DMs**, not raw impressions
18
+ - Pack: **optional**. Text-first; add carousel/images when showing the visual production layer
19
+
20
+ ## Length & shape
21
+
22
+ | Form | Guidance |
23
+ |------|----------|
24
+ | Single post | Prefer **1–3 short sentences** or tight line breaks. Rarely fill the full character limit. |
25
+ | Thread | Only if user asks. Tweet 1 = hook only; each next tweet = one idea; end without a summary paragraph that restates everything. |
26
+ | Reply | Add information or a precise question. Avoid “Great point!” / empty agreement. |
27
+ | Media | Optional. If used, text should still stand alone if the image fails. Carousel images = proof of system, not the default body. |
28
+
29
+ ## Hooks (mechanics only — not your brand story)
30
+
31
+ A strong first line usually does **one** of:
32
+
33
+ - Names a **concrete mistake** or false belief
34
+ - States a **sharp contrast** (X vs Y)
35
+ - Opens a **gap** the rest of the post closes
36
+ - Gives a **specific** observation (not “in today’s world…”)
37
+
38
+ Avoid first lines that only announce a topic list (“Here are 3 tips to…”).
39
+
40
+ ## Craft rules
41
+
42
+ 1. **One idea per post** (or per thread tweet).
43
+ 2. Prefer concrete nouns and verbs over abstract “value / leverage / unlock”.
44
+ 3. Cut filler and restatements. No closing that only summarizes what was already said.
45
+ 4. Line breaks are for rhythm, not for fake drama on every word.
46
+ 5. Questions: use when you want replies; make them answerable, not vague (“thoughts?”).
47
+ 6. Links: prefer zero or one; if needed, put after the point lands — not as the whole post.
48
+ 7. Optimize for **classifiable takes** and conversation — authority/signal, not soft lifestyle chatter (that’s closer to Threads).
49
+ 8. EasySociable only when earned; frame as **visual production layer**, never as full content OS.
50
+
51
+ ## Anti-slop (X)
52
+
53
+ Do **not** default to:
54
+
55
+ - “In a world where…” / “Here’s the thing:” / “Let’s dive in”
56
+ - “It’s not X, it’s Y” as empty cadence with no substance
57
+ - Engagement bait with no point (“Who’s still awake?” / “Like if you agree”)
58
+ - Wall of hashtags
59
+ - Corporate intern tone or fake guru certainty without a claim the user owns
60
+ - Comment-gate lead magnets (“Comment SLIDES”) as the primary CTA
61
+ - **RIP Canva** / “AI replaced your designer” as the main hook
62
+ - Empty praise replies when engaging others’ posts
63
+
64
+ ## Quality self-check (before showing draft to user)
65
+
66
+ - [ ] First line works without the rest?
67
+ - [ ] Would a stranger understand the claim in one read?
68
+ - [ ] Any sentence pure filler? Delete it.
69
+ - [ ] Does this match **pillars.md** (topic allowed), not only “sounds like a tweet”?
70
+ - [ ] Would the right ICP reply “we have this problem” / ask how — or only react with emoji?
71
+ - [ ] No invented metrics, customers, or results?
72
+ - [ ] If media: still makes sense as text-only?
73
+
74
+ ## Out of scope here
75
+
76
+ - Carousel / slideshow page structure → run `pack` + EasySociable skills; see also `linkedin.md` / `ig.md` / `tiktok.md` for visual-native networks
77
+ - Learned strategies → `wiki/claims/`; techniques → `wiki/atoms/`
78
+ - Multi-platform native rules → other `platforms/*.md` files (do **not** paste X copy into Threads/LI/IG/TT unchanged)
@@ -0,0 +1,19 @@
1
+ # Platform: Xiaohongshu (小红书)
2
+
3
+ **Scope:** How to *write* for Xiaohongshu notes.
4
+ **Not in this file:** Who you are, pillars, voice, audience.
5
+
6
+ ## Defaults
7
+
8
+ - Language: follow the account; many notes mix 中文 body + English product names
9
+ - Default unit: **single image note** in V1 (slideshow not a Content Pack route yet)
10
+ - Pack: **no** for V1 — hand off to **easysociable-template** fill-slots
11
+ - Canvas: often **3:4 @ 1080×1440** — see Template `PLATFORM_SPECS`
12
+
13
+ ## Craft
14
+
15
+ - Cover must stop the thumb; one idea per note
16
+ - Caption: concrete, saveable, not empty lifestyle filler
17
+ - Do not invent personal metrics or “爆款” proof
18
+
19
+ Missing more specific house rules → stop and ask; do not invent craft.
@@ -0,0 +1,13 @@
1
+ # Profiles index
2
+
3
+ Reusable **content profiles**: pillars + audience + voice.
4
+ Accounts point here; do not copy profile bodies into account files.
5
+
6
+ | id | path | voice | one_liner | accounts |
7
+ |----|------|-------|-----------|----------|
8
+ | default | profiles/default/ | `profiles/default/voice.md` | Replace this one-liner with the profile’s job | your-handle |
9
+
10
+ ## Voice column
11
+
12
+ - Empty or `profile` → load `profiles/<id>/voice.md`
13
+ - Explicit path → load that file instead
@@ -0,0 +1,11 @@
1
+ # Profile: default
2
+
3
+ Replace this starter profile before the first serious draft.
4
+
5
+ | File | Role |
6
+ |------|------|
7
+ | `pillars.md` | Topics this profile may cover |
8
+ | `audience.md` | Readers + per-platform emphasis |
9
+ | `voice.md` | Identity + tone |
10
+
11
+ Accounts: see `accounts/_index.md`.