@easysociable/cli 0.1.5 → 0.1.7
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/content-engine/scripts/starter.mjs +1 -0
- package/content-engine/starter/CLAUDE.md +105 -42
- package/content-engine/starter/engine.json +1 -0
- package/content-engine/starter/hits/README.md +5 -0
- package/content-engine/starter/hits/_index.md +30 -0
- package/content-engine/starter/hits/_template.md +46 -0
- package/content-engine/starter/hits/entries/README.md +3 -0
- package/content-engine/starter/products/_index.md +1 -0
- package/content-engine/starter/products/entries/P-002-content-engine.md +136 -0
- package/content-engine/starter/profiles/default/README.md +3 -0
- package/content-engine/starter/profiles/default/handles.md +8 -0
- package/content-engine/starter/profiles/default/keywords.md +31 -0
- package/content-engine/starter/runs/_template/brief.md +41 -31
- package/content-engine/starter/topics/_template-item.md +30 -27
- package/content-engine/starter/topics/scoring.md +5 -2
- package/content-engine/workbench/__pycache__/build.cpython-310.pyc +0 -0
- package/content-engine/workbench/build.py +177 -2
- package/content-engine/workbench/serve.py +0 -0
- package/content-engine/workbench/template.html +505 -16
- package/dist/easysociable.js +2 -1
- package/dist/easysociable.js.map +1 -1
- package/package.json +14 -13
- package/skills/easysociable-content/SKILL.md +18 -9
- package/skills/easysociable-content/workflows/NEEDS.md +20 -3
- package/skills/easysociable-template/scripts/generate-theme-from-hex.mjs +0 -0
|
@@ -42,6 +42,9 @@ This folder is the local **Content Engine** for EasySociable.
|
|
|
42
42
|
| `profiles/<id>/boundaries.md` | Creator must-avoid (Not covering / Never claim) |
|
|
43
43
|
| `profiles/<id>/expression.md` | Expression likes / dislikes |
|
|
44
44
|
| `profiles/<id>/lanes.md` | Publishing lanes; distinct from pillars |
|
|
45
|
+
| `profiles/<id>/keywords.md` | Search recipes; scan may stage `hits/` |
|
|
46
|
+
| `profiles/<id>/handles.md` | ≤8 ally/foil/competitor handles |
|
|
47
|
+
| `hits/_index.md` | Research triage (not Topics) |
|
|
45
48
|
| `accounts/_index.md` | handle → profile, platforms, voice, overrides |
|
|
46
49
|
| `accounts/overrides/<handle>.md` | Optional account deltas |
|
|
47
50
|
| `platforms/*.md` | Platform craft only |
|
|
@@ -72,6 +75,11 @@ This folder is the local **Content Engine** for EasySociable.
|
|
|
72
75
|
|-------------|--------|
|
|
73
76
|
| capture / 记一下 (+ link) | **§ Capture** only — **not** topics by default |
|
|
74
77
|
| 记需求 / 用户原话 / 评论导出 | **§ Needs** only |
|
|
78
|
+
| 加关键词 / 更新关键词库 | Edit `profiles/<id>/keywords.md` (**ask profile** if unset) |
|
|
79
|
+
| 从需求生成关键词 / 生成 listen\|search\|ask 词 | **§ Keywords · Generate** (chat → confirm → write) |
|
|
80
|
+
| 加/改 handles | Edit `profiles/<id>/handles.md`; keep **≤8** |
|
|
81
|
+
| 扫关键词 / 扫 K-xx / 看 @handle | **§ Keywords** scan (**listen** default) → **§ Hits** |
|
|
82
|
+
| 路由 Hit / H-xx | **§ Hits** → Needs or Capture+library / discard |
|
|
75
83
|
| **扫需求选题** | **§ Topics** from `needs/` where `status=captured`; max 5 `produce` |
|
|
76
84
|
| 扫 inbox 选题 | **§ Topics** — from captures without topic yet (max 5) |
|
|
77
85
|
| 生成 topic (no source specified) | **§ Topics** — offer captured needs or ask which explicit input to use |
|
|
@@ -234,8 +242,6 @@ relationships before drafting.
|
|
|
234
242
|
|
|
235
243
|
### Topic generation modes
|
|
236
244
|
|
|
237
|
-
Use the smallest honest mode:
|
|
238
|
-
|
|
239
245
|
| mode | Required inputs |
|
|
240
246
|
|------|-----------------|
|
|
241
247
|
| `demand` | Needs + Profile |
|
|
@@ -245,8 +251,7 @@ Use the smallest honest mode:
|
|
|
245
251
|
| `offer_education` | Product + Profile + mechanism |
|
|
246
252
|
| `profile_thesis` | Profile + Pillar |
|
|
247
253
|
|
|
248
|
-
|
|
249
|
-
audience demand and never raises a Topic to `ready` by itself.
|
|
254
|
+
**Mode pick (hard):** Before any `produce` Topic write (扫需求选题 / 做成选题 / 生成 topic / 把 N-|C- 做成选题), **ask the user to choose `generation_mode`**. Recommend `demand` when the input is Need-led; do **not** silently assume. Enforce that mode’s required inputs. Product or Recommendation presence never proves audience demand and never raises a Topic to `ready` by itself.
|
|
250
255
|
|
|
251
256
|
---
|
|
252
257
|
|
|
@@ -271,6 +276,7 @@ audience demand and never raises a Topic to `ready` by itself.
|
|
|
271
276
|
- `ready` requires **opp_score ≥ 7.5 and audience ≥ 6**
|
|
272
277
|
- `src_likes` / `src_replies` / `src_bookmarks` (+ views if known) + `engagement_at` on **index** when source is external
|
|
273
278
|
- Do **not** fold `src_*` into opp_score; among **ready** only, prefer replies/bookmarks over views
|
|
279
|
+
- **Language (hard):** Readable judgment + `one_liner` + Decision Card body = profile public language from `voice.md` **Language** (else pillars “Primary public language”, else `engine.json` locale). Verbatim Needs/Capture quotes stay untranslated. Operator chat may add a short gloss in another language; the Topic file and `ready` card body do not. Wrong-language prose → fix before `ready`.
|
|
274
280
|
|
|
275
281
|
### Signal paths
|
|
276
282
|
|
|
@@ -290,44 +296,54 @@ audience demand and never raises a Topic to `ready` by itself.
|
|
|
290
296
|
1. If needs exist with `status=captured`, offer **扫需求选题**.
|
|
291
297
|
2. Otherwise ask which explicit input to use.
|
|
292
298
|
|
|
299
|
+
0. Resolve profile **Language** (`voice.md` → pillars → `engine.json` locale).
|
|
293
300
|
1. Hard filters (`scoring.md`); else skip.
|
|
294
|
-
2. **Scout gate** — set `purpose` + `scout_label`; if `discard`, do not create T-.
|
|
295
|
-
3.
|
|
296
|
-
|
|
301
|
+
2. **Scout gate** — set `purpose` + `scout_label`; if `discard`, do not create T-. Needs-sourced default `scout_label=demand` (ally/foil/craft_only still allowed when honest).
|
|
302
|
+
3. **Mode pick** — if proceeding toward `produce`, **ask** `generation_mode` (six modes). Recommend `demand` for Need-led input; wait for user choice. Do not write a `produce` T- before the choice. Validate required ids for that mode.
|
|
303
|
+
4. If `produce` (or user forces score):
|
|
304
|
+
a. Write the **decision card** first (`topics/_template-item.md` upper half), in profile Language: Verdict, Why this status, Who it’s for, Core judgment, Next step, then What problem / What they believe / What cut / Why now / What should change / Based on / Gaps / Suggested form. Keep the summary short; no enum lists, heat, or weighted arithmetic in the readable layer. Set frontmatter `generation_mode` to the chosen mode.
|
|
297
305
|
b. Score all 5 opportunity dims (0–10) → `opp_score`. Put **numbers only** in `## Score`. Do not repeat the card as table notes.
|
|
298
306
|
c. Fill `## Trace` (ids, src heat) and `## Constraints` (writer must-nots). Write `topics/items/T-….md`.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
307
|
+
5. If `library`: optional light item with `status: library`, or capture offer only. Source needs stay `captured` (or `retired` if the user discards).
|
|
308
|
+
6. Add row on `topics/_index.md` (`item` + `src_*` when external). `one_liner` = the card’s core-judgment sentence, same language.
|
|
309
|
+
7. If this T- was `produce` from `N-` ids: update each `needs/_index.md` row + entry to `status=promoted` and `topic_ids` containing this T-. Skip if no T- was written (`discard`).
|
|
310
|
+
8. Output the **Decision Card** in chat — same shape and language as the file’s readable layer, not a score walkthrough. Optional operator gloss in another language is chat-only.
|
|
303
311
|
|
|
304
|
-
**Important:**
|
|
312
|
+
**Important:** “What do they believe now?” must name the false belief. If you cannot, conflict cannot score above 5. Brief inherits the readable judgment layer, not the Score table.
|
|
305
313
|
|
|
306
|
-
###
|
|
314
|
+
### Decision Card
|
|
307
315
|
|
|
308
316
|
Paste the decision summary and readable judgment sections. Do not walk five scores in the main body.
|
|
309
317
|
|
|
310
318
|
```text
|
|
311
|
-
📋
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
319
|
+
📋 Decision card T-YYYYMMDD-XX
|
|
320
|
+
【Verdict】 ready | backlog | parked
|
|
321
|
+
【Why this status】 …
|
|
322
|
+
【Who it’s for】 …
|
|
323
|
+
【Core judgment】 …
|
|
324
|
+
【Next step】 open a run / fill needs / fill evidence / re-angle / kill
|
|
325
|
+
【What problem】 …
|
|
326
|
+
【What they believe】 believe X → actually Y
|
|
327
|
+
【What cut】 …
|
|
328
|
+
【Why now】 …
|
|
329
|
+
【After reading】 before … → after …
|
|
330
|
+
【Based on】 …
|
|
331
|
+
【Gaps】 …
|
|
332
|
+
【Suggested form】 …
|
|
325
333
|
```
|
|
326
334
|
|
|
327
335
|
### Topic → run
|
|
328
336
|
|
|
329
337
|
On `用 T-xxx 开一单`: **ask platform(s)** if unset (multi-select OK). Create **one run per platform**, same `topic_id`, prefill selection per platform, mark topic `promoted` + list run ids on `topics/_index` `run` column.
|
|
330
338
|
|
|
339
|
+
### Do not (Topics)
|
|
340
|
+
|
|
341
|
+
- Create a Topic from a Hit, a scan, or from heat alone
|
|
342
|
+
- Silently pick `generation_mode` (always ask before `produce`)
|
|
343
|
+
- Skip Scout gate or opportunity scoring on `produce` topics
|
|
344
|
+
- Skip the decision card readable layer on `produce`
|
|
345
|
+
- Put `N-` in `capture_id` (needs go in `need_ids` only)
|
|
346
|
+
|
|
331
347
|
---
|
|
332
348
|
|
|
333
349
|
## § Swipe / atom library
|
|
@@ -367,9 +383,46 @@ Hard gate vs first-session (`profile: partial`) vs complete seven dimensions (`p
|
|
|
367
383
|
|
|
368
384
|
---
|
|
369
385
|
|
|
386
|
+
## § Keywords & handles
|
|
387
|
+
|
|
388
|
+
`keywords.md` is **three-track**: `listen` (social → Hits), `search` (SEO), `ask` (GEO questions).
|
|
389
|
+
`handles.md` ≤8 ally/foil/competitor.
|
|
390
|
+
|
|
391
|
+
**Generate:** from Needs/audience/pillars → chat candidates (max 10) → user confirm → append row with `track` + `seed_from`.
|
|
392
|
+
**Scan「扫关键词」:** `track=listen` + `active` only (unless user names other ids). Stage **§ Hits**; never Topic; never invent heat/quotes.
|
|
393
|
+
**search/ask:** not default social scan. Volume/kd optional on search only.
|
|
394
|
+
|
|
395
|
+
## § Hits (research triage)
|
|
396
|
+
|
|
397
|
+
**Role:** Sort research hits → **need** | **library** (swipe/atom via Capture+ingest) | **discard**. Not a Topic queue.
|
|
398
|
+
|
|
399
|
+
| Path | Role |
|
|
400
|
+
|------|------|
|
|
401
|
+
| `hits/_index.md` | Registry |
|
|
402
|
+
| `hits/_template.md` | Entry shape |
|
|
403
|
+
| `hits/entries/H-*.md` | Per-hit files |
|
|
404
|
+
|
|
405
|
+
Id `H-YYYYMMDD-XX`. Status: `triage` → `routed_need` | `routed_library` | `discarded`.
|
|
406
|
+
|
|
407
|
+
```text
|
|
408
|
+
🔎 Hit H-…
|
|
409
|
+
【Keyword】 K-xx
|
|
410
|
+
【Source】 @handle · url
|
|
411
|
+
【Kind】 author_post | comment | thread
|
|
412
|
+
【Signal】 demand_language | structure | foil | mixed | noise
|
|
413
|
+
【Heat】 likes … · replies … · bookmarks … · views … @ date
|
|
414
|
+
【Excerpt】 verbatim
|
|
415
|
+
【Suggest】 need | library | discard
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
On scan: `keyword_id` + `src_*` when known. Route need → **§ Needs**. Route library → **§ Capture** + library offer. Never Hit → Topic.
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
370
422
|
## § Needs (audience quotes)
|
|
371
423
|
|
|
372
424
|
Triggers: 记需求 / 用户原话 / 评论导出 / capture audience quotes / user needs.
|
|
425
|
+
Hits → Needs **only after route confirm** (**§ Hits**).
|
|
373
426
|
扫需求选题 → **§ Topics** (this section only writes `N-` records).
|
|
374
427
|
|
|
375
428
|
Follow `easysociable-content/workflows/NEEDS.md` when this engine's copy of the workflow is the newer one; this section wins if both exist.
|
|
@@ -439,10 +492,11 @@ User wants a tracked job: "开一单", "open a run", "按完整流程", or a mul
|
|
|
439
492
|
### Platform gate (required before folder create)
|
|
440
493
|
|
|
441
494
|
1. User already named platform(s) → use them.
|
|
442
|
-
2. Else **ask
|
|
443
|
-
3.
|
|
444
|
-
4. **
|
|
445
|
-
5.
|
|
495
|
+
2. Else **stop and ask a required multi-select platform question**. Offer the account’s `platforms` from `accounts/_index` plus any supported platforms the user may name: `x`, `linkedin`, `instagram`, `tiktok`, `threads`, `xiaohongshu`. The user must be able to select one or more.
|
|
496
|
+
3. Do not create a folder, row, brief, or draft before the platform selection is answered.
|
|
497
|
+
4. **Do not** silently default to `x` when opening a run (default `x` still applies to other flows, e.g. watchlist filter).
|
|
498
|
+
5. **N platforms selected → N runs** (same topic/goal/pillar; independent platform craft, brief, draft, editor, rubric, and ship state).
|
|
499
|
+
6. Slug: include the platform when N>1 or always OK — e.g. `2026-08-26-angle-x`, `…-linkedin`.
|
|
446
500
|
|
|
447
501
|
### Load platform craft (required — every run, every draft stage)
|
|
448
502
|
|
|
@@ -548,7 +602,21 @@ Sharpen these for the specific platform/angle — do not re-derive from scratch.
|
|
|
548
602
|
|
|
549
603
|
**Step 3 — Fill brief.md**
|
|
550
604
|
|
|
551
|
-
|
|
605
|
+
The brief has two layers. The **reading surface** (top) is what a human reviews in 30 seconds. The **appendix** (bottom) is machine handoff data.
|
|
606
|
+
|
|
607
|
+
Reading surface — fill in this order:
|
|
608
|
+
|
|
609
|
+
1. **Thesis** — one sentence a stranger can understand.
|
|
610
|
+
2. **For whom → what changes** — reader, their false belief, the after state.
|
|
611
|
+
3. **Evidence** — named sources, type, quality, and what we cannot prove.
|
|
612
|
+
4. **Platform and expression** — platform, form, hook, structure outline.
|
|
613
|
+
5. **Boundaries** — must include / must avoid.
|
|
614
|
+
|
|
615
|
+
Appendix — fill after the reading surface:
|
|
616
|
+
|
|
617
|
+
6. **Inherited from Topic** — context, audience, conflict, insight, outcome, evidence (sharpened, not copied).
|
|
618
|
+
7. **Selection** — swipe, atoms, claim ids.
|
|
619
|
+
8. **Quality gate** — 6 × 1–5 scores.
|
|
552
620
|
|
|
553
621
|
**Step 4 — Brief quality gate (self-scoring)**
|
|
554
622
|
|
|
@@ -624,21 +692,16 @@ Score `rubric.md` (6 × 0–2, max 12).
|
|
|
624
692
|
【State】 open → next: brief
|
|
625
693
|
```
|
|
626
694
|
|
|
627
|
-
**Brief card** (after quality gate passes)
|
|
695
|
+
**Brief card** (after quality gate passes — mirrors brief.md reading surface)
|
|
628
696
|
|
|
629
697
|
```text
|
|
630
698
|
📋 Brief RUN-…
|
|
631
|
-
【Inherited from T-…】
|
|
632
|
-
Context: …
|
|
633
|
-
Conflict: current belief → reality
|
|
634
|
-
Insight: …
|
|
635
|
-
|
|
636
699
|
【Thesis】 one sentence
|
|
637
|
-
【
|
|
638
|
-
【
|
|
639
|
-
【
|
|
700
|
+
【For whom】 reader · false belief → after state
|
|
701
|
+
【Evidence】 sources · type · quality · what we cannot prove
|
|
702
|
+
【Platform】 platform · form · hook · structure outline
|
|
703
|
+
【Boundaries】 must include · must avoid
|
|
640
704
|
【Gate】 Thesis … · Evi … · Angle … · Struct … · Outcome … · Tension … = …/30 ✓
|
|
641
|
-
【Selection】 swipe … · atoms … · claim …
|
|
642
705
|
Reply 简报 OK / 改 …
|
|
643
706
|
```
|
|
644
707
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Hits index (research triage)
|
|
2
|
+
|
|
3
|
+
**Role:** Staging board for research hits. Route to Needs or Library — **not** a Topic queue.
|
|
4
|
+
|
|
5
|
+
Newest on top. Scan may write rows here (include source-post heat). Routing out still needs explicit confirm.
|
|
6
|
+
|
|
7
|
+
| id | date | profile | platform | keyword_id | source | hit_kind | signal | status | excerpt | src_likes | src_replies | src_bookmarks | src_views | engagement_at | file |
|
|
8
|
+
|----|------|---------|----------|------------|--------|----------|--------|--------|---------|-----------|-------------|---------------|-----------|---------------|------|
|
|
9
|
+
|
|
10
|
+
## Status
|
|
11
|
+
|
|
12
|
+
| status | Meaning |
|
|
13
|
+
|--------|---------|
|
|
14
|
+
| `triage` | Waiting for route |
|
|
15
|
+
| `routed_need` | Written to `needs/` |
|
|
16
|
+
| `routed_library` | Capture + library ingest path |
|
|
17
|
+
| `discarded` | Rejected |
|
|
18
|
+
|
|
19
|
+
## Columns
|
|
20
|
+
|
|
21
|
+
| Column | Meaning |
|
|
22
|
+
|--------|---------|
|
|
23
|
+
| `keyword_id` | Primary recipe `K-xx` |
|
|
24
|
+
| `src_*` | Source-post heat snapshot (not our results) |
|
|
25
|
+
|
|
26
|
+
## Agent rules
|
|
27
|
+
|
|
28
|
+
- Exits: **need** \| **library** \| **discard**. Hits are not Topic inputs.
|
|
29
|
+
- On scan: write `keyword_id` + engagement snapshot when known. Do not invent metrics.
|
|
30
|
+
- Author hooks ≠ Needs. Zero starter rows — do not invent hits.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: H-YYYYMMDD-XX
|
|
3
|
+
date: YYYY-MM-DD
|
|
4
|
+
profile: default
|
|
5
|
+
platform: x
|
|
6
|
+
status: triage
|
|
7
|
+
hit_kind: author_post | comment | thread
|
|
8
|
+
signal: demand_language | structure | foil | mixed | noise
|
|
9
|
+
source_keyword:
|
|
10
|
+
keyword_id: K-XX
|
|
11
|
+
source_handle:
|
|
12
|
+
source_url:
|
|
13
|
+
src_likes:
|
|
14
|
+
src_replies:
|
|
15
|
+
src_bookmarks:
|
|
16
|
+
src_views:
|
|
17
|
+
engagement_at:
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# H-YYYYMMDD-XX
|
|
21
|
+
|
|
22
|
+
## Excerpt
|
|
23
|
+
|
|
24
|
+
> verbatim excerpt — do not rewrite
|
|
25
|
+
|
|
26
|
+
## Context
|
|
27
|
+
|
|
28
|
+
Where this came from and why it was kept for triage.
|
|
29
|
+
|
|
30
|
+
## Engagement snapshot
|
|
31
|
+
|
|
32
|
+
- likes:
|
|
33
|
+
- replies:
|
|
34
|
+
- bookmarks:
|
|
35
|
+
- views:
|
|
36
|
+
- snapshot_at:
|
|
37
|
+
|
|
38
|
+
## Suggested route
|
|
39
|
+
|
|
40
|
+
need | library | discard | undecided
|
|
41
|
+
|
|
42
|
+
## Route log
|
|
43
|
+
|
|
44
|
+
| date | action | result_ids |
|
|
45
|
+
|------|--------|------------|
|
|
46
|
+
| | | |
|
|
@@ -5,6 +5,7 @@ file.
|
|
|
5
5
|
|
|
6
6
|
| id | name | status | audience | price | effective_from | file |
|
|
7
7
|
|----|------|--------|----------|-------|----------------|------|
|
|
8
|
+
| P-002 | Content Engine | active | AI-native creators and small content teams building repeatable content workflows | free local install; hosted features not included | 2026-09-16 | products/entries/P-002-content-engine.md |
|
|
8
9
|
| P-001 | EasySociable | active | creators and teams producing branded multi-page social visuals | see entry | 2026-09-04 | products/entries/P-001-easysociable.md |
|
|
9
10
|
|
|
10
11
|
## Status values
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: P-002
|
|
3
|
+
name: Content Engine
|
|
4
|
+
status: active
|
|
5
|
+
effective_from: 2026-09-16
|
|
6
|
+
source_of_truth:
|
|
7
|
+
- apps/cli/README.md
|
|
8
|
+
- apps/cli/package.json
|
|
9
|
+
- apps/cli/content-engine/starter/CLAUDE.md
|
|
10
|
+
- apps/cli/content-engine/starter/engine.json
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Content Engine
|
|
14
|
+
|
|
15
|
+
## Product promise
|
|
16
|
+
|
|
17
|
+
Give AI-native creators and small content teams a local, repeatable workflow
|
|
18
|
+
from audience signals to topics, briefs, drafts, review, feedback, and
|
|
19
|
+
publishable content.
|
|
20
|
+
|
|
21
|
+
## What it is
|
|
22
|
+
|
|
23
|
+
Content Engine is a local-first content system installed and operated through
|
|
24
|
+
the `easysociable` command-line tool. It provides a structured local vault,
|
|
25
|
+
profile and audience context, needs, topics, product facts, drafts, runs,
|
|
26
|
+
feedback, and a workbench for inspecting the engine.
|
|
27
|
+
|
|
28
|
+
It does not require Obsidian. The engine can be initialized and served from a
|
|
29
|
+
workspace directory.
|
|
30
|
+
|
|
31
|
+
## Best for
|
|
32
|
+
|
|
33
|
+
- AI-native creators building a repeatable publishing workflow.
|
|
34
|
+
- Agency-of-one operators and small content teams managing recurring content
|
|
35
|
+
decisions and review.
|
|
36
|
+
- Users who want local files and Agent-assisted workflows instead of a
|
|
37
|
+
browser-only content writing assistant.
|
|
38
|
+
|
|
39
|
+
## Not for
|
|
40
|
+
|
|
41
|
+
- Users looking for guaranteed reach, engagement, conversions, or virality.
|
|
42
|
+
- Users who want an AI model to invent their audience, point of view, proof,
|
|
43
|
+
or customer results.
|
|
44
|
+
- Users who want a hosted LLM or automatic social-account publishing.
|
|
45
|
+
- Users who only want one prompt or one generated post without a repeatable
|
|
46
|
+
workflow.
|
|
47
|
+
|
|
48
|
+
## Problem
|
|
49
|
+
|
|
50
|
+
AI makes drafting easier, but a blank prompt does not preserve the audience,
|
|
51
|
+
point of view, editorial judgment, review standards, or feedback from the last
|
|
52
|
+
piece. Content Engine turns those decisions into explicit local objects that
|
|
53
|
+
an Agent can use again.
|
|
54
|
+
|
|
55
|
+
## Mechanism
|
|
56
|
+
|
|
57
|
+
- Local profile, audience, voice, boundaries, and pillar files provide durable
|
|
58
|
+
context.
|
|
59
|
+
- Needs and source material become evaluated Topics rather than immediate
|
|
60
|
+
drafts.
|
|
61
|
+
- Brief, draft, editor, rubric, run, and feedback stages make review and
|
|
62
|
+
publishing decisions explicit.
|
|
63
|
+
- Product and recommendation libraries keep owned-offer facts separate from
|
|
64
|
+
audience demand and third-party research.
|
|
65
|
+
- The CLI can initialize, validate, build, serve, and detect local engines.
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
The CLI and local Content Engine are free to install:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
curl -fsSL https://easysociable.com/install.sh | bash
|
|
73
|
+
easysociable install --skills content,template,slideshow --yes
|
|
74
|
+
easysociable engine init --root /workspace --yes
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The installer requires Node.js 20 or newer. The Content Engine workbench also
|
|
78
|
+
requires `python3`. The default CLI skill set currently includes Template and
|
|
79
|
+
Slideshow; the `content` skill is enabled explicitly above.
|
|
80
|
+
|
|
81
|
+
## Pricing and entitlements
|
|
82
|
+
|
|
83
|
+
Content Engine and its CLI installation path are free to install. This entry
|
|
84
|
+
does not claim paid hosted features, managed storage, or a hosted LLM.
|
|
85
|
+
|
|
86
|
+
## Proof
|
|
87
|
+
|
|
88
|
+
No customer proof, adoption metrics, or performance improvements are recorded.
|
|
89
|
+
|
|
90
|
+
## Boundaries
|
|
91
|
+
|
|
92
|
+
- Content Engine owns local content knowledge, editorial workflow, and
|
|
93
|
+
production tracking.
|
|
94
|
+
- EasySociable is a separate visual production layer for branded templates,
|
|
95
|
+
slideshow runs, Studio review, and PNG download.
|
|
96
|
+
- The Agent remains responsible for reasoning, content judgment, and supplied
|
|
97
|
+
evidence.
|
|
98
|
+
- The system does not guarantee that generated content is correct, useful, or
|
|
99
|
+
successful.
|
|
100
|
+
|
|
101
|
+
## Claims
|
|
102
|
+
|
|
103
|
+
### Safe to say
|
|
104
|
+
|
|
105
|
+
- Install the CLI from the public installer or npm package.
|
|
106
|
+
- Initialize a local Content Engine with `easysociable engine init`.
|
|
107
|
+
- Use local files to preserve profile, audience, needs, topics, briefs, and
|
|
108
|
+
feedback.
|
|
109
|
+
- Validate and serve the engine through CLI commands.
|
|
110
|
+
|
|
111
|
+
### Say carefully
|
|
112
|
+
|
|
113
|
+
- “One-command install” refers to installing the CLI; enabling the Content
|
|
114
|
+
skill and initializing the engine are additional CLI commands.
|
|
115
|
+
- “Free” refers to the local Content Engine and CLI installation path, not to
|
|
116
|
+
hosted EasySociable plans or hosted usage.
|
|
117
|
+
- “Gets better” means decisions and feedback persist for the next run; it does
|
|
118
|
+
not mean the Agent learns autonomously from every review.
|
|
119
|
+
|
|
120
|
+
### Do not say
|
|
121
|
+
|
|
122
|
+
- “AI writes and publishes everything automatically.”
|
|
123
|
+
- “The Content Engine guarantees better performance.”
|
|
124
|
+
- “Obsidian is required.”
|
|
125
|
+
- “The hosted EasySociable app is the Content Engine.”
|
|
126
|
+
|
|
127
|
+
## CTA
|
|
128
|
+
|
|
129
|
+
- `educate`: explain why content needs durable decisions before generation.
|
|
130
|
+
- `invite`: install the CLI and initialize a local engine.
|
|
131
|
+
- `mention`: show how a Topic, Brief, or review gate survives into the next
|
|
132
|
+
run.
|
|
133
|
+
|
|
134
|
+
## Version notes
|
|
135
|
+
|
|
136
|
+
- 2026-09-16: Added as the local-first Content Engine product.
|
|
@@ -10,5 +10,8 @@ Replace this starter profile before the first serious draft.
|
|
|
10
10
|
| `stories.md` | Story inventory (cite or none) |
|
|
11
11
|
| `boundaries.md` | Creator must-avoid (Not covering / Never claim) |
|
|
12
12
|
| `expression.md` | Expression likes / dislikes |
|
|
13
|
+
| `lanes.md` | Publishing lanes |
|
|
14
|
+
| `keywords.md` | Three-track: listen→Hits, search=SEO, ask=GEO |
|
|
15
|
+
| `handles.md` | ≤8 ally/foil/competitor handles |
|
|
13
16
|
|
|
14
17
|
Accounts: see `accounts/_index.md`.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Handles — profile `default`
|
|
2
|
+
|
|
3
|
+
**Role:** Small ally / foil / competitor list (≤8). Not a topic radar. Demand language → `./keywords.md`.
|
|
4
|
+
|
|
5
|
+
| # | platform | handle | niche_tag | why_on_list | weight | status |
|
|
6
|
+
|---|----------|--------|-----------|-------------|--------|--------|
|
|
7
|
+
|
|
8
|
+
Zero starter rows. Add only with a concrete ally/foil/competitor reason.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Keywords — profile `default`
|
|
2
|
+
|
|
3
|
+
**Role:** Three-track recipes — **listen** (social), **search** (SEO), **ask** (GEO). Not topics.
|
|
4
|
+
|
|
5
|
+
| track | Means | Default use |
|
|
6
|
+
|-------|--------|-------------|
|
|
7
|
+
| `listen` | Social search strings | 「扫关键词」→ Hits |
|
|
8
|
+
| `search` | Google/SEO phrases | Content map; volume optional; not default social scan |
|
|
9
|
+
| `ask` | 15–25 word AI-engine questions | GEO coverage; not social scan |
|
|
10
|
+
|
|
11
|
+
**Scan rule:** 「扫关键词」→ `track=listen` + `active` only → Hits. Never scan → Topic.
|
|
12
|
+
|
|
13
|
+
| id | track | query | platform | intent | layer | pillar | why | weight | status | seed_from | pair_id | volume | kd | serp_intent | volume_source | volume_at | ask_engines | last_scanned |
|
|
14
|
+
|----|-------|-------|----------|--------|-------|--------|-----|--------|--------|-----------|---------|--------|----|-------------|---------------|-----------|-------------|--------------|
|
|
15
|
+
| K-01 | listen | (fill audience pain phrase) | x | pain | L1 | P1 | (why) | 1.0 | paused | manual | | | | | | | | |
|
|
16
|
+
|
|
17
|
+
Replace fill rows after interview / first needs. Prefer 8–12 active **listen** seeds before routine scans.
|
|
18
|
+
|
|
19
|
+
## Column notes
|
|
20
|
+
|
|
21
|
+
| Column | Meaning |
|
|
22
|
+
|--------|---------|
|
|
23
|
+
| `track` | `listen` \| `search` \| `ask` |
|
|
24
|
+
| `seed_from` | `need:N-…` / `hit:H-…` / `audience` / `pillar:P…` / `manual` |
|
|
25
|
+
| `volume` / `kd` | search annotations; empty OK |
|
|
26
|
+
|
|
27
|
+
## Agent rules
|
|
28
|
+
|
|
29
|
+
- Default scan: listen + active only; max 5
|
|
30
|
+
- Propose new rows in chat; write after confirm
|
|
31
|
+
- Do not invent Need quotes from keywords
|
|
@@ -6,52 +6,62 @@ gate_pass: false
|
|
|
6
6
|
|
|
7
7
|
# Brief
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Thesis
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- **audience:**
|
|
13
|
-
- **conflict:**
|
|
14
|
-
- **insight:**
|
|
11
|
+
One sentence a stranger can understand without any product context.
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
(fill)
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
## For whom → what changes
|
|
16
|
+
|
|
17
|
+
**Reader:** (who specifically has this problem)
|
|
18
|
+
|
|
19
|
+
**They currently believe:** (the false belief or stuck assumption)
|
|
20
|
+
|
|
21
|
+
**After reading:** (what they should believe, do, or stop doing)
|
|
23
22
|
|
|
24
23
|
## Evidence
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
**What we have:** (named sources — Need ids, product facts, mechanisms, cases)
|
|
26
|
+
|
|
27
|
+
**Evidence type:** data | example | case | mechanism | expert | observation
|
|
28
|
+
|
|
29
|
+
**Quality:** weak | moderate | strong
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
**What we cannot prove:** (be honest — no invented outcomes)
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
- **format:**
|
|
34
|
-
- **hook:**
|
|
35
|
-
- **structure:**
|
|
33
|
+
## Platform and expression
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
- **Platform:** x | linkedin | ig | tiktok
|
|
36
|
+
- **Form:** short post | thread | carousel | …
|
|
37
|
+
- **Hook:** (first line or opening move)
|
|
38
|
+
- **Structure:** (the argument flow in one line, e.g. hook → false belief → mechanism → action)
|
|
39
|
+
|
|
40
|
+
## Boundaries
|
|
41
|
+
|
|
42
|
+
- **Must include:** (non-negotiable claims or framing)
|
|
43
|
+
- **Must avoid:** (hard bans for this draft; merge `profiles/<id>/boundaries.md` + voice Do not say)
|
|
44
|
+
|
|
45
|
+
---
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
- **action:**
|
|
41
|
-
- **emotion:**
|
|
47
|
+
## Appendix (machine / handoff — not the reading surface)
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
### Inherited from Topic
|
|
44
50
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
51
|
+
- context:
|
|
52
|
+
- audience:
|
|
53
|
+
- conflict:
|
|
54
|
+
- insight:
|
|
55
|
+
- outcome:
|
|
56
|
+
- evidence:
|
|
47
57
|
|
|
48
|
-
|
|
58
|
+
### Selection
|
|
49
59
|
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
60
|
+
- swipe: id | none — why
|
|
61
|
+
- atoms: hook:… | cta:… | none — why
|
|
62
|
+
- claim: id | none — why
|
|
53
63
|
|
|
54
|
-
|
|
64
|
+
### Quality gate
|
|
55
65
|
|
|
56
66
|
| # | Gate | Score 1–5 | Note |
|
|
57
67
|
|---|------|-----------|------|
|