docs(linkedin-studio): M0-14 — D3 path-convention + voice-readers prototype

This commit is contained in:
Kjell Tore Guttormsen 2026-06-18 12:38:17 +02:00
commit c0abb82d9c
21 changed files with 138 additions and 38 deletions

View file

@ -24,7 +24,7 @@ You are a LinkedIn carousel content specialist. Create high-engagement carousel
## Step 0: Load Context
- Read `~/.claude/linkedin-studio.local.md` for posting state and expertise areas
- Read `assets/voice-samples/authentic-voice-samples.md` for voice profile
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` for voice profile
- Check recent posts to avoid topic repetition
## Step 1: Choose Template

View file

@ -24,7 +24,7 @@ The first post doesn't need to be perfect. It needs to EXIST. Every day without
## Step 0: Load Context
Read `~/.claude/linkedin-studio.local.md` for current state.
Read `assets/voice-samples/authentic-voice-samples.md` for voice profile (if it exists).
Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` for voice profile (if it exists).
Check: If `first_post_date` is already set, this user has posted before. Suggest `/linkedin:post` or `/linkedin:quick` instead, and explain this command is for true first-timers.
@ -44,7 +44,7 @@ Total: ~10 minutes. Let's go.
## Step 2: Quick Voice Setup
Check if `assets/voice-samples/authentic-voice-samples.md` has substantive content (more than just the template headers).
Check if `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` has substantive content (more than just the template headers).
**If voice profile exists:** Say "I already have your voice profile. Let's use it." Skip to Step 3.

View file

@ -25,7 +25,7 @@ worked plan: who to engage, what to say, and exactly when — persisted to state
## Step 0: Load Context
- Read `~/.claude/linkedin-studio.local.md` for posting state (streak, weekly progress, recent posts, follower phase).
- Read `assets/voice-samples/authentic-voice-samples.md` so every draft comment is in the user's voice.
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` so every draft comment is in the user's voice.
- Note the user's growth phase (follower count) — it sets daily comment volume and target split.
## Step 1: Identify the Post
@ -113,6 +113,6 @@ delayed spike) with the post-feedback monitor — invoke it via `Task` with
## Reference Files
- `assets/voice-samples/authentic-voice-samples.md` — voice matching for the draft comments
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` — voice matching for the draft comments
- `references/engagement-frameworks.md` — hook types, CEA, engagement hierarchy
- `references/algorithm-signals-reference.md` — first-hour weighting, signal order, timing data

View file

@ -170,8 +170,8 @@ the edition left off before doing anything.
Step 2. Do not confuse `<serie>/STATE.md` (this edition's production state)
with the plugin's own `STATE.md` / `docs/BUILD-HANDOVER.local.md` (which govern
building the plugin itself).
4. **Read the voice profile**`assets/voice-samples/authentic-voice-samples.md`
and anything else under `assets/voice-samples/`. Long-form must match the
4. **Read the voice profile**`${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md`
and anything else under `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/`. Long-form must match the
author's voice; this is the reference for every drafting and review phase.
5. **Resolve the active personas (per-artifact).** Personas are configured **per
edition**, not from one fixed global file. Resolve the set for
@ -541,7 +541,7 @@ Typically ~2030 % of the edition's final length.
**Procedure:**
1. **Re-read the voice profile** (`assets/voice-samples/`) before writing a
1. **Re-read the voice profile** (`${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/`) before writing a
single sentence — this is the existing LTL rule and it is not optional for
long-form. Voice match starts at the spine, not at expansion.
@ -635,7 +635,7 @@ turning-points the spine already named.
**Procedure:**
1. **Re-read the voice profile** (`assets/voice-samples/`) before expanding —
1. **Re-read the voice profile** (`${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/`) before expanding —
the voice was set at the spine; do not lose it in expansion.
2. **Expand section by section, against the spine.** Each section's paragraph
@ -724,7 +724,7 @@ linkedin-studio:voice-scrubber`, from THIS command layer in the
foreground (principle 4). Pass it the draft path AND the paths to the **approved
Norwegian editions** as the gold standard (e.g. earlier parts' locked
`linkedin/NN/POST.html` or their approved `NN-utkast.md`). **Do NOT** point it at
`assets/voice-samples/authentic-voice-samples.md` — that corpus is English
`${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` — that corpus is English
short-form and forbids the em-dash; using it as the gold standard would degrade
the Norwegian chronicle voice. The scrubber runs two passes: Pass 1 strips
AI-tells (objective — «la meg være ærlig», reflex rule-of-three, em-dash-spam,
@ -1587,7 +1587,7 @@ the honest decision surface; it sells nothing.
- `${CLAUDE_PLUGIN_ROOT}/commands/headless-review.md` — the Step 6.5 cold review package as a standalone command (run in a fresh session for maximum isolation)
- `${CLAUDE_PLUGIN_ROOT}/commands/pivot.md` — re-opens the pipeline after a late pivot so Steps 56.5 re-run on the changed version before lock
- `${CLAUDE_PLUGIN_ROOT}/commands/react.md` — multi-source synthesis discipline (reused in Step 2)
- `${CLAUDE_PLUGIN_ROOT}/assets/voice-samples/authentic-voice-samples.md` — voice matching
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` — voice matching
- `${CLAUDE_PLUGIN_ROOT}/references/longform-quality-rules.md` — canonical long-form rules (Steps 2.5, 3a, 3b, 49 all reference)
- `${CLAUDE_PLUGIN_ROOT}/render/build-linkedin.mjs` — POST.html delivery; reads `linkedin/NN/cover.png` + credit/caption (Step 8)
- `${CLAUDE_PLUGIN_ROOT}/render/build-html.mjs` — annotatable review renderer (Step 7)

View file

@ -140,7 +140,7 @@ Use AskUserQuestion:
4. "Paste a paragraph you've written that sounds like YOU (email, doc, anything)"
5. "Any words or phrases you'd NEVER use?"
Save the responses to `assets/voice-samples/authentic-voice-samples.md`. **If the
Save the responses to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md`. **If the
file is the shipped placeholder** (it contains `<!-- VOICE_PLACEHOLDER -->`),
**REPLACE it entirely** with the profile built from the answers — the
`<!-- VOICE_PLACEHOLDER -->` sentinel must NOT remain, or the voice score stays at
@ -196,7 +196,7 @@ Then ask: "Give me a sentence or two about what you have in mind." If expertise
### 3.2 — Write the post (3-line formula)
Draft the post using the voice profile from Phase 2 (or the existing `assets/voice-samples/` profile):
Draft the post using the voice profile from Phase 2 (or the existing `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/` profile):
- **Line 1 — Hook (110-140 chars):** specific to their experience, no generic opening
- **Line 2 — Context (1-3 sentences):** the what and why, kept tight
- **Line 3 — Insight + question:** their takeaway, ending on a genuine question that invites comments

View file

@ -26,7 +26,7 @@ You are a LinkedIn content pipeline orchestrator. Guide the user through the com
Load persistent state and personalization:
- Read `~/.claude/linkedin-studio.local.md` for posting state
- Read `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-studio/SKILL.md` for profile and preferences
- Check `assets/voice-samples/` for voice matching
- Check `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/` for voice matching
- Read `assets/templates/my-post-templates.md` for proven post templates — use these in Step 2 (Draft)
- Read `assets/frameworks/framework-template.md` if the topic involves a framework or methodology
@ -81,7 +81,7 @@ Run the draft through optimization checks:
- [ ] Authentic voice (not AI-sounding)
**Voice check:**
Compare against `assets/voice-samples/` to ensure natural tone.
Compare against `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/` to ensure natural tone.
Present optimized version with before/after comparison.
@ -207,5 +207,5 @@ Replace placeholders with actual post data. Set `next_planned_topic` manually if
- `${CLAUDE_PLUGIN_ROOT}/references/linkedin-formats.md`
- `${CLAUDE_PLUGIN_ROOT}/references/scheduling-strategy.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/checklists/quality-scorecard.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/voice-samples/`
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/`
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`

View file

@ -36,7 +36,7 @@ Check weekly progress:
- If `posts_this_week == weekly_goal - 1`, note: "This is your last post to hit this week's goal."
Check for existing assets:
- `assets/voice-samples/` - Match the user's natural voice
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/` - Match the user's natural voice
- `assets/examples/high-engagement-posts.md` - Study past successful posts and replicable patterns
- `assets/frameworks/framework-template.md` - Reference user's documented frameworks for framework posts
- `assets/templates/my-post-templates.md` - User's proven post templates with success rates. **Prefer these over generic structures.**

View file

@ -25,7 +25,7 @@ You are a LinkedIn content creator specializing in turning external content into
First, load persistent state and personalization:
- Read `~/.claude/linkedin-studio.local.md` for posting state (streak, weekly progress, recent topics)
- Read `assets/voice-samples/authentic-voice-samples.md` for voice profile
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` for voice profile
- Check recent posts to avoid topic repetition within 7 days
## Step 1: Get URL(s)
@ -264,7 +264,7 @@ Same as Step 8 — run `state-updater.mjs` with actual post data.
## Reference Files
- `assets/voice-samples/authentic-voice-samples.md` — Voice matching
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` — Voice matching
- `references/thought-leadership-angles.md` — 8 universal angles
- `references/engagement-frameworks.md` — Hooks, structure, CTAs
- `assets/checklists/quality-scorecard.md` — Pre-publish check

View file

@ -26,7 +26,7 @@ Read these 8 asset files and detect placeholder patterns to calculate the curren
| Category | Weight | File/Directory | Placeholder Detection |
|----------|--------|----------------|----------------------|
| Voice samples | 25 | `assets/voice-samples/authentic-voice-samples.md` | Placeholder if it contains the `<!-- VOICE_PLACEHOLDER -->` sentinel (or has <50 lines) |
| Voice samples | 25 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` | Placeholder if it contains the `<!-- VOICE_PLACEHOLDER -->` sentinel (or has <50 lines) |
| User profile | 20 | `config/user-profile.local.md` | Check if file exists; count `[Your ` placeholders |
| Case studies | 15 | `assets/case-studies/*.md` | Count non-template `.md` files (exclude `case-study-template.md`) |
| Frameworks | 10 | `assets/frameworks/*.md` | Count non-template `.md` files (exclude `framework-template.md`) |
@ -81,7 +81,7 @@ Based on their answer, run the corresponding sub-workflow below.
## Step 3a: Voice Samples Workflow
**Goal:** Populate `assets/voice-samples/authentic-voice-samples.md` with real voice data.
**Goal:** Populate `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` with real voice data.
**Delegate the analysis + profile construction to the `voice-trainer` agent** — invoke it via `Task` with `subagent_type: linkedin-studio:voice-trainer` (foreground, from this command layer). The agent performs the pattern detection and extraction (steps 23 below) and returns the structured voice profile; this command owns collecting the samples (step 1) and writing the profile back to disk (steps 46).
@ -98,7 +98,7 @@ Based on their answer, run the corresponding sub-workflow below.
- Words/phrases they avoid
- How they handle technical depth
- How they conclude (CTA style, takeaway style)
4. Read the existing `assets/voice-samples/authentic-voice-samples.md`
4. Read the existing `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md`
5. **If the file is the shipped placeholder** (it contains `<!-- VOICE_PLACEHOLDER -->`):
**REPLACE it entirely** with the profile built from the user's samples. The
placeholder's `<!-- VOICE_PLACEHOLDER -->` sentinel must NOT survive — if it

View file

@ -39,7 +39,7 @@ Load video-specific references:
- Read `references/linkedin-formats.md` (Video Content Deep Dive section) for algorithm data and technical specs
Check for existing assets:
- `assets/voice-samples/` — Match the user's natural voice (REQUIRED before scripting)
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/` — Match the user's natural voice (REQUIRED before scripting)
- `assets/examples/high-engagement-posts.md` — Study successful patterns
## Step 1: Choose Video Type
@ -87,7 +87,7 @@ Delegate script generation to the `video-scripter` agent — invoke it via `Task
- Visual cues (`[CAM:]`, `[SCREEN:]`, `[SLIDE:]`, `[TEXT:]`)
- Energy cues (`[ENERGY: up]`, `[PAUSE: 1s]`)
- Transition markers (`[CUT]`, `[TRANSITION:]`)
4. Match voice against `assets/voice-samples/`
4. Match voice against `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/`
5. Generate captions, thumbnail suggestion, post caption, and first comment
## Step 5: Quality Check