ktg-plugin-marketplace/plugins/linkedin-studio/CLAUDE.md
Kjell Tore Guttormsen 1fa2cc945e chore(linkedin-studio): release v4.0.0 — counts, three-doc, CHANGELOG (clears [skip-docs] debt)
Step 21 (remediation Wave 4 / S6, SOLO): finalize the audit-remediation as
v4.0.0. Version 3.1.0 -> 4.0.0 across all current-version declarations; counts
reconciled to the ls-derived source of truth (19 agents / 27 commands / 6 skills
/ 9 hooks / 25 reference docs / 16 newsletter phases — Step 20 confirmed NO
TRIM); three-doc sync (plugin README + plugin CLAUDE.md + root README) clears the
[skip-docs] debt accumulated across Wave 1-4; CHANGELOG v4.0.0 entry summarizing
Steps 1-20.

Scope additions beyond the plan's literal Files list, all version-sync or
[skip-docs]-debt in nature (flagged, not feature creep):
- ../../CLAUDE.md (root marketplace): linkedin-studio entry v3.1.0 -> v4.0.0
  (the version-sync invariant mandates updating every version reference; leaving
  it stale is a real inconsistency).
- scripts/test-runner.sh: added the version-consistency grep the file's own
  Step-1 comment promised ("added in Step 21") — plugin.json version must match
  the README badge, the CLAUDE.md header, and the CHANGELOG top entry — and
  folded the Wave 2 lint gap (plugin.json now covered by the stat-consistency
  scan). 66/0/0, exit 0.
- plugin README: added the missing /linkedin:firsthour command row (Step 16
  [skip-docs] debt) and the 25th reference doc (longform-quality-rules.md) to
  the knowledge-base table; fixed body counts ("All 26 commands" -> 27, "24
  reference documents" -> 25); badges + intro 26 -> 27 commands, 24 -> 25 refs.
- root README + marketplace.json: dropped the unpublishable model brand/date
  ("360Brew" / "January 2026") the algorithm-signal reconciliation already
  removed everywhere inside the plugin.

Surviving "3.1.0" strings are intentional history, not stale declarations: the
README version-history table row, the "vX added Y" attributions in
plugin.json/CLAUDE.md, and the headless-review reload caveat are all
changelog-genre. Every current-version declaration (plugin.json version, README
badge, CLAUDE.md header, root README marker, marketplace.json) reads 4.0.0.

The major bump reflects the remediation's scope plus the reinstall/reload the
newly-wired agents need to register, and consolidates — does not repeat — the
v3.0.0 identity break; it is not a fresh breaking API change (locked operator
decision).

Pre-existing and out of scope (flagged, untouched): a duplicate /linkedin:setup
row in the README command tables.

Verify: bash scripts/test-runner.sh exit 0 (66/0/0); plugin.json + marketplace.json
parse; counts consistent README == CLAUDE.md == root README; stale-count sweep
clean. NO push — /trekreview (S7) is the release gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 07:49:48 +02:00

112 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LinkedIn Studio Plugin (v4.0.0)
Full-spectrum LinkedIn content engine — short-form feed posts, carousels, video scripts, and long-form newsletter editions — with the 2026 relevance-ranking model baked in. **v4.0.0** is an **audit-remediation release (Voyage Phase 03)**: a critical self-review found overclaiming (tracking/analytics/review-independence the plugin couldn't deliver), dormant capability (11 agents never invoked by any command), and structural rot (a dead lint, a self-contradicting algorithm claim, an unpublishable model brand/date in user copy). The fix wires **all 11 orphaned agents** (no deletions → 19 agents), adds **`/linkedin:firsthour`** (→ 27 commands) + a short-form de-AI gate + a video quality gate, promotes `post-feedback-monitor` to Opus, makes the newsletter-distribution / profile-SEO / outreach surfaces honest, **reconciles the algorithm signals to one sourced statement** (no model name or date; `references/algorithm-signals-reference.md` is the single source of truth), fixes the analytics fresh-clone crash, closes the voice-profile leak (placeholder + sentinel + gitignore), and rebuilds the structure lint with version/count/stat-consistency guards. Breaking — reinstall/reload required for the newly-wired agents; consolidates the v3.0.0 identity break (slug, agent namespace, state-file path). v2.0.0 consolidated the surface (27 commands → 24, 16 agents → 14) while adding the long-form `/linkedin:newsletter` orchestrator + two longform-quality gate agents (`fact-checker`, `persona-reviewer`). v2.1.0 added two gates BEFORE prose (Step 2.5 skeleton + Step 3a spine prose) + a third `persona-reviewer` mode (`skjelett`). v2.2.0 hardened the longform gates with the lessons from the second production run (Seres-serien): blocking persona hard-fails, a post-cutoff fact-check mandate, a `voice-scrubber` agent, render+annotate operator gates, and STATE.md-reconciled edition state. v2.3.0 made **visual assets an explicit pipeline phase** — Step 7.5 (visual-assets) between annotation (Step 7) and lock (Step 8): cover (+ optional inline figures) or a carousel deck, generated (default `mcp-image`, external `cover-raw.png` accepted) and operator-gated BEFORE lock so `render/build-linkedin.mjs` picks up `cover.png` at lock without a post-lock re-render. **v2.4.0** makes an **editor's craft gate an explicit pipeline phase** — new **Step 5.5 (editorial-review)** between fact-check (Step 5) and the persona sweep (Step 6): a new **`editorial-reviewer` agent** (Opus) judges **craft** (prosa-håndverk + narrativ-arkitektur), not reader-response, returning ≤10 flags (BLOCK/REWORK/NICE) as direction, **operator-gated via `SendUserFile` BEFORE the persona sweep** so the personas measure resonance instead of stumbling on craft noise. Motivated by Del 4: every persona reported PASS, yet the editor found 8 fresh points on first reading, ~6/8 of them craft/architecture blind spots no agent measured. Mirrors the Maskinrommet writing-contract §C2. Pipeline 14 → 15 phases; agents 15 → 16; additive `editorialReview` state. Doc/orchestration-only for the wiring (the new agent + its fasit fixture + lint test are the only new files); commands unchanged (24). **v3.1.0 (Endring 9)** adds an **adversarial review package** run COLD on a frozen draft — new **Step 6.5 (headless-review)** between the persona sweep (Step 6) and lock, plus a standalone **`/linkedin:headless-review`** command (run in a fresh session for maximum isolation): three new headless archetypes — **`content-reviewer`** (argument integrity), **`language-reviewer`** (Norwegian language), **`fact-reviewer`** (cold re-verification incl. claims a late pivot bolted on) — plus `persona-reviewer` in resonance + conversion modes, all with NO drafting-session context (the independence layer the in-session gates structurally cannot be). v3.1.0 also adds **`/linkedin:pivot`** (re-opens cleared gates after a late change + a >20 %/>2-section pivot-detection gate at lock) and **per-artifact personas** (`articles.NN.personas` — one or more readers configurable per edition, resolved edition-state → series file → plugin library → interactive). Pipeline 15 → 16 phases; agents 16 → 19; commands 24 → 26; additive `personas` / `pivots` / `headlessReview` state. Motivated by Del 4: the in-session editor + persona sweep shared the drafting session's framing-bias, so the version that shipped was never independently re-reviewed.
## Architecture
- **State file:** `~/.claude/linkedin-studio.local.md` (YAML frontmatter, auto-initialized from `config/state-file.template.md`)
- **State updater:** `hooks/scripts/state-updater.mjs` — deterministic state mutations (post tracking, streak, content history pruning). Pure functions, tested, no AI involvement
- **Clipboard helper:** `hooks/scripts/clipboard-helper.mjs` — cross-platform clipboard integration (macOS `pbcopy`, Linux `xclip`/`xsel`, WSL `clip.exe`). All content commands auto-copy to clipboard
- **iCal generator:** `hooks/scripts/ical-generator.mjs` — RFC 5545 calendar file generation for batch scheduling. Standalone CLI + importable module
- **Post queue:** `assets/drafts/queue.json` (managed by `hooks/scripts/queue-manager.mjs`)
- **Analytics CLI:** `scripts/analytics/` (TypeScript, requires `tsx` and `npm install`)
- **Analytics data:** `assets/analytics/` (gitignored)
## Hooks
9 hooks across 7 events. All Node.js (.mjs). PreToolUse/PostToolUse hooks use parameterized `content-gatekeeper.mjs` with `isLinkedInContent()` check.
| Event | Purpose |
|-------|---------|
| `SessionStart` | Load state, REMEMBER.md, milestone tracker |
| `PreToolUse` (Write\|Edit) | Content quality gate, voice guardian, topic rotation gate |
| `Stop` | State update, pre-publish reminders, content history |
| `UserPromptSubmit` | LinkedIn context enrichment (three-tier matching) |
| `PostToolUse` (Write) | Post-creation automation (5x5x5, posting time) |
| `PreCompact` | Preserve LinkedIn context during compaction |
| `Notification` | Posting reminders (rate-limited 30min) |
**Session markers:** `/tmp/linkedin-hooks/session-active` (Stop hook gating, 12h staleness). **Shared modules:** `linkedin-content-filter.mjs`, `queue-manager.mjs`, `personalization-score.mjs`, `state-updater.mjs`, `clipboard-helper.mjs`.
**State updates:** Post tracking, streak management, and content history are handled deterministically by `state-updater.mjs` (called from Stop hook and commands). Content history entries older than 90 days are auto-pruned at session start.
**Hook editing:** Edit `hooks/hooks.template.json` + `hooks/prompts/*.md`, then run `python3 hooks/scripts/compile-hooks.py`. Do not edit `hooks.json` directly. Prompts are loaded at runtime by gatekeeper scripts; the compile step is only needed when adding `type: prompt` hooks.
## Commands (27)
All content commands (post, quick, react, pipeline, first-post, video, multiplatform, carousel, newsletter) auto-copy output to clipboard via `clipboard-helper.mjs`. Interactive steps are minimized — angle, format, and post type are inferred from context, with max 2 questions per post. **v2.0.0 net change:** 5 commands removed (`templates`, `publish`, `authority`, `collab`, `speaking` — absorbed into `quick`, `calendar`, `strategy`, `outreach` respectively) + 2 commands added (`newsletter`, `outreach`) = 27 → 24. **v3.1.0** adds 2 longform companions (`headless-review`, `pivot`) = 24 → 26. **Remediation Step 16** adds `firsthour` (wiring orphan agent #11 `engagement-coach`) = 26 → 27.
| Command | Purpose |
|---------|---------|
| `/linkedin` | Router — status line + command menu |
| `/linkedin:onboarding` | Multi-step onboarding wizard (profile → setup → first-post) |
| `/linkedin:first-post` | First-post accelerator (10 min) |
| `/linkedin:setup` | Guided personalization setup |
| `/linkedin:react` | URL-to-post pipeline |
| `/linkedin:post` | Full post creation (10-15 min) |
| `/linkedin:quick` | 5-minute quick post (3-line formula) + 8 post-type templates |
| `/linkedin:pipeline` | Full end-to-end content pipeline |
| `/linkedin:newsletter` | Long-form orchestrator: newsletter edition / essay / series article — multi-session 16-phase pipeline with **skeleton + spine-prose gates BEFORE prose (v2.1)**, **editorial-review craft gate BEFORE the persona sweep (Step 5.5, v2.4)**, fact-check + persona-sweep BEFORE lock, **headless adversarial review BEFORE lock (Step 6.5, v3.1)**, and **visual-assets gate BEFORE lock (Step 7.5, v2.3)** |
| `/linkedin:headless-review` | **(v3.1)** Cold adversarial review package — run the 3 headless archetypes (`content-reviewer`, `language-reviewer`, `fact-reviewer`) + `persona-reviewer` (resonance/conversion) on a FROZEN draft with no drafting-session context; consolidated, operator-gated report. Step 6.5's standalone surface (run in a fresh session for maximum isolation) |
| `/linkedin:pivot` | **(v3.1)** Re-open a long-form edition after a late substantive change so cleared gates (fact-check → editorial → persona → headless) re-run before lock; logs `pivots[]`, resets `currentPhase`, un-locks if needed (pivot heuristic: >20 % word-count change or >2 new sections) |
| `/linkedin:batch` | Create a full week of content |
| `/linkedin:calendar` | View/manage post scheduling queue + publish action (mark scheduled posts as published) |
| `/linkedin:firsthour` | Post-publish first-hour / reply-loop sprint — delegates to `engagement-coach` for a timestamped target list + draft comments + timeline, persists the plan to state (`recordFirstHourPlan`), hands off to `post-feedback-monitor` |
| `/linkedin:carousel` | Structured multi-slide carousel generator |
| `/linkedin:video` | Video script generator (30s-2min) |
| `/linkedin:multiplatform` | Adapt content for other platforms (short-form/cross-format; long-form → `/linkedin:newsletter`) |
| `/linkedin:analyze` | Content/performance analysis |
| `/linkedin:audit` | Periodic content strategy audit |
| `/linkedin:import` | Import CSV export → structured JSON (delegates analysis to `/linkedin:report`) |
| `/linkedin:report` | Generate weekly performance report |
| `/linkedin:ab-test` | Design and manage A/B content tests |
| `/linkedin:strategy` | Growth strategy + authority building (phase guidance, trajectory, signature content compounding) |
| `/linkedin:competitive` | Competitive analysis of niche |
| `/linkedin:monetize` | Monetization strategy and funnels (unlocks at ~1K followers) |
| `/linkedin:outreach` | Outreach orchestrator — collaborations + speaking opportunities (unlocks at ~1K followers) |
| `/linkedin:profile` | profile/topic-relevance optimization |
## Agents (19)
| Agent | Model | Color | Responsibility |
|-------|-------|-------|----------------|
| `content-optimizer` | Sonnet | Blue | Optimize existing posts |
| `strategy-advisor` | Sonnet | Green | Growth recommendations |
| `analytics-interpreter` | Sonnet | Yellow | Audience pattern analysis + weekly/monthly performance reports (interpret/report modes) |
| `engagement-coach` | Sonnet | Magenta | 5x5x5 + first-hour tactics + CEA commenting + target selection |
| `content-planner` | Sonnet | Cyan | Content audit + weekly/monthly plans |
| `network-builder` | Sonnet | Teal | Strategic networking + outreach |
| `content-repurposer` | Sonnet | Purple | Format conversion + evergreen refresh |
| `trend-spotter` | Sonnet | White | Trending topics + opportunity scores |
| `voice-trainer` | Sonnet | Pink | Voice profile building + drift detection |
| `differentiation-checker` | Sonnet | Gray | Originality scoring + commodity detection |
| `post-feedback-monitor` | Opus | Lime | Post-publish 48h monitoring |
| `video-scripter` | Sonnet | Violet | Video script creation with pacing |
| `fact-checker` | Opus | Brown | Factual-claim verification against primary sources, post-cutoff web-search mandate (longform) |
| `editorial-reviewer` | Opus | Orange | Editor's craft gate (v2.4, Step 5.5, before persona sweep): prosa-håndverk + narrativ-arkitektur, ≤10 flags BLOCK/REWORK/NICE as direction, operator-gated via `SendUserFile`; mirrors Maskinrommet §C2 (longform) |
| `persona-reviewer` | Opus | Olive | Reader-persona skeleton (v2.1, before prose) + resonance (before lock) + hook-conversion (after lock) gate, blocking hard-fail list (longform) |
| `voice-scrubber` | Opus | Red | De-AI scrub + Norwegian-chronicle voice-drift correction; gold standard = approved Norwegian editions, not the English post corpus (longform, v2.2) |
| `content-reviewer` | Opus | Maroon | **(v3.1, Step 6.5 — cold/headless)** Argument-integrity review on a frozen draft: C1 logical holes · C2 unsupported assumptions · C3 argument contradiction · C4 missing concretization · C5 unanswered objection. ≤8 flags BLOCK/REWORK/NICE as direction; refuses drafting-session framing as context pollution (longform) |
| `language-reviewer` | Opus | Navy | **(v3.1, Step 6.5 — cold/headless)** Norwegian-language review on a frozen draft: L1 verbatim repetition · L2 anglicisms · L3 stiff bureaucratic register · L4 language-level self-contradiction · L5 clang/rhythm. ≤10 flags BLOCK/REWORK/NICE; deliberate cold re-take of editorial's prose axis (longform) |
| `fact-reviewer` | Opus | Gold | **(v3.1, Step 6.5 — cold/headless)** Cold re-verification on the frozen/pivoted version (web search): F1 verifiable claims · F2 quote precision · F3 number attribution · F4 source quality. 🔴/🟡/🟢 + pivot-risk subsection; deliberate redundancy with `fact-checker` to catch a pivot premise that arrived after Step 5 (longform) |
**Rule:** Always read `assets/voice-samples/` before generating content.
**Invocation form:** Commands invoke plugin agents by their **namespaced** type —
`subagent_type: linkedin-studio:<name>` — never the bare `<name>` (a bare
type does not resolve and the `Task` call fails).
**Reload requirement:** Adding a NEW agent file under `agents/` registers it only after
a Claude Code **session reload** — the plugin agent set is built at session start, so a
freshly-added agent (e.g. `fact-checker`, `persona-reviewer` when first added) is not
invokable until the session reloads. After adding an agent, reload before invoking it.
## Content Quality Rules
1. Hook: 110-140 characters (mobile cutoff)
2. Post length: 1,200-1,800 chars (standard), 150-500 chars (quick)
3. No external links in post body (correlate with lower reach; see `references/algorithm-signals-reference.md`)
4. No corporate buzzwords: leverage, synergy, paradigm shift, thought leader, disruptive, value proposition, ecosystem, holistic approach
5. Topic must align with user's 5 core expertise areas (topic-relevance signal)
6. Topic rotation: no back-to-back same pillar, no pillar >50% in 14 days (warn-only)
7. Progressive onboarding: personalization score hidden until 3+ posts; voice guardian suppressed until 5+ voice samples