refactor(linkedin)!: rename plugin linkedin-thought-leadership → linkedin-studio (v3.0.0)
BREAKING CHANGE: the marketplace slug, the agent namespace (linkedin-studio:<agent>), and the runtime state-file path (~/.claude/linkedin-studio.local.md) all change. Reinstall required; existing state migrated in place (post metrics, streak, history preserved). The /linkedin:* commands are unchanged — the command namespace is set per-command in frontmatter and was always independent of the plugin slug. Functionality is byte-identical to v2.4.0; this release is pure identity. - dir + manifests: plugins/linkedin-studio + plugin.json + root marketplace.json - agent namespace updated in commands/newsletter.md (only functional invoker) - state path updated in 4 hook scripts + topic-rotation prompt + state template - catch-all skill dir renamed skills/linkedin-studio (5 functional skills unchanged) - docs + version bump to 3.0.0 across README badge, CHANGELOG, root README/CLAUDE.md - historical records (CHANGELOG past entries, docs/ build artifacts, config-audit v5.0.0 snapshots) intentionally retain the old slug Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9df3de795c
commit
b6bb61246b
196 changed files with 164 additions and 138 deletions
30
plugins/linkedin-studio/config/REMEMBER.template.md
Normal file
30
plugins/linkedin-studio/config/REMEMBER.template.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# LinkedIn Studio — Session State
|
||||
|
||||
**Last updated:** [Auto-filled by session-start hook]
|
||||
|
||||
## Last Session Summary
|
||||
<!-- Brief recap of what was done last session -->
|
||||
|
||||
## Recent Posts
|
||||
<!-- Posts created in recent sessions -->
|
||||
<!-- Format: - [YYYY-MM-DD] "Hook text..." — topic -->
|
||||
|
||||
## Active Content Plan
|
||||
<!-- Current week's plan and upcoming topics -->
|
||||
|
||||
## Pending Tasks
|
||||
<!-- Actionable items for next session -->
|
||||
- [ ] Posts to publish
|
||||
- [ ] Analytics to import
|
||||
- [ ] Engagement tasks (5x5x5)
|
||||
|
||||
## Current Strategy
|
||||
<!-- Phase and focus area -->
|
||||
**Phase:** [Foundation / Growth / Authority / Scale]
|
||||
**Focus:** [Current strategic priority]
|
||||
|
||||
## Recommendations
|
||||
<!-- Top 3 actionable suggestions from last session -->
|
||||
|
||||
## Notes
|
||||
<!-- Free-form session notes -->
|
||||
18
plugins/linkedin-studio/config/content-history.template.md
Normal file
18
plugins/linkedin-studio/config/content-history.template.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Content History Log
|
||||
|
||||
Tracks all LinkedIn posts created through the plugin. Append-only — never edit existing entries.
|
||||
|
||||
Auto-initialized from `config/content-history.template.md` when the first post is logged.
|
||||
|
||||
## Format
|
||||
|
||||
| Date | Hook | Topic | Format | Words | Chars | Source |
|
||||
|------|------|-------|--------|-------|-------|--------|
|
||||
|
||||
<!-- Entries are appended below by the Stop hook -->
|
||||
<!-- Format: | YYYY-MM-DD | "Hook text (60 chars max)..." | topic_area | post/quick/react/video | word_count | char_count | original/url/curated | -->
|
||||
|
||||
## Content Log
|
||||
|
||||
| Date | Hook | Topic | Format | Words | Chars | Source |
|
||||
|------|------|-------|--------|-------|-------|--------|
|
||||
28
plugins/linkedin-studio/config/edition-config.template.json
Normal file
28
plugins/linkedin-studio/config/edition-config.template.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"_doc": {
|
||||
"purpose": "Schema + starter for edition-config.json — the STATIC per-edition delivery metadata that render/build-linkedin.mjs reads (calendar, freshness, cover credit, captions). Complements edition-state.json (machine resumption state) and edition-delingstekst.md (distribution copy).",
|
||||
"decision": "G — production lives in the series root, NOT in the plugin. Copy this template to <serie>/linkedin/edition-config.json and fill it in. This file is the schema-defining TEMPLATE only.",
|
||||
"location": "<serie>/linkedin/edition-config.json (read relative to cwd = series root; OUT_ROOT = <cwd>/linkedin)",
|
||||
"graceful": "render/build-linkedin.mjs loadEditionConfig() falls back to empty defaults if this file is missing or malformed — every field below is optional. Provide it for a complete delivery page (calendar slot, freshness banner, cover credit, alt-text caption).",
|
||||
"keys": "Article keys are zero-padded strings mirroring edition-state.json + the NN-prefix of each NN-utkast.md draft: \"01\", \"02\", ..., plus \"samle\" for the collected post.",
|
||||
"fields": {
|
||||
"calendar[NN]": "{ dag: human date label e.g. \"Mandag 02.06\", klokke: \"HH:MM\" } — the scheduled slot shown on POST.html. Default if absent: { dag: \"—\", klokke: \"08:00\" }.",
|
||||
"freshness[NN]": "string — a freshness/recency note rendered in the amber banner (e.g. \"Tall fra Q1 2026; sjekk før publisering etter 01.07\"). Omit for no banner.",
|
||||
"coverCredit": "string — global cover-image credit line (\"Add credit and caption\" field). One value for the whole edition.",
|
||||
"captions[NN]": "string — per-article cover-image caption / alt text. Default if absent: \"—\".",
|
||||
"carousel": "list of zero-padded NN strings (e.g. [\"03\",\"06\"]) — the editions that ship an optional carousel/document post. POST.html shows a carousel block only for these NN. Empty/absent → no carousel block. (S14/F6: replaces the old hardcoded Seres set.)"
|
||||
}
|
||||
},
|
||||
"calendar": {
|
||||
"01": { "dag": "<Ukedag DD.MM>", "klokke": "08:00" },
|
||||
"samle": { "dag": "<Ukedag DD.MM>", "klokke": "08:00" }
|
||||
},
|
||||
"freshness": {
|
||||
"01": "<optional freshness note shown in the banner — omit the key for no banner>"
|
||||
},
|
||||
"coverCredit": "<cover-image credit line, or empty string>",
|
||||
"captions": {
|
||||
"01": "<cover-image caption / alt text for article 01>"
|
||||
},
|
||||
"carousel": []
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<!--
|
||||
TEMPLATE — edition-delingstekst.md (distribution copy for a newsletter edition)
|
||||
|
||||
Purpose : the per-edition LinkedIn distribution text that render/build-linkedin.mjs
|
||||
folds into each POST.html "all-in-one-place" deliverable. This is the
|
||||
feed copy the reader sees BEFORE "…see more" — the hook that earns the
|
||||
click (gated in /linkedin:newsletter Step 9).
|
||||
Decision: G — production lives in the series root, NOT the plugin. Copy this to
|
||||
<serie>/linkedin/edition-delingstekst.md and fill it in.
|
||||
Location: <serie>/linkedin/edition-delingstekst.md (cwd = series root).
|
||||
Graceful: render/build-linkedin.mjs degrades if this file is missing (no
|
||||
distribution copy is folded in; the article POST.html still builds).
|
||||
Provide it for a complete delivery.
|
||||
|
||||
GRAMMAR (exactly what parseDelingstekst() recognizes — do not improvise):
|
||||
- A section starts with a heading: "## Del N — <title>" (N = article number,
|
||||
mapped to zero-padded key "0N") OR "## Samle <…>" (the collected post,
|
||||
key "samle").
|
||||
- "## SYSTEM …" headings are ignored.
|
||||
- Inside a section, until the next "## " heading or a "---" line:
|
||||
* "**Første kommentar:** <text>" → first-comment text (one line).
|
||||
* a line beginning with "#" + non-space (e.g. "#KI #offentligsektor")
|
||||
→ the hashtag line.
|
||||
* a "> …" blockquote line → ignored (use it for NB/notes to yourself).
|
||||
* every other line → part of the share text (the hook + body shown in feed).
|
||||
Keys MUST match the NN-prefix of the draft (NN-utkast.md) and edition-config.json.
|
||||
-->
|
||||
|
||||
## Del 1 — <edition title>
|
||||
|
||||
<First line = the krok/hook: the single line that must stop the scroll. Keep the
|
||||
strongest claim or tension here; this is what shows before "…see more".>
|
||||
|
||||
<Then 2–4 short lines that pay off the hook and point at the article. Tighten,
|
||||
never pad — this is feed copy, not the article.>
|
||||
|
||||
**Første kommentar:** <the first-comment text — e.g. a link, a question to seed
|
||||
discussion, or the "full edition here" pointer. LinkedIn suppresses links in the
|
||||
body, so the link belongs here.>
|
||||
|
||||
#hashtag1 #hashtag2 #hashtag3
|
||||
|
||||
> NB to self (ignored by the renderer): note any freshness caveat or A/B variant
|
||||
> you want to remember for this edition.
|
||||
|
||||
---
|
||||
|
||||
## Samle <collected-post title, if shipping a roundup of the series>
|
||||
|
||||
<Hook for the collected/summary post. Same grammar. Omit this whole section if the
|
||||
edition has no samle post.>
|
||||
|
||||
**Første kommentar:** <first comment for the samle post>
|
||||
|
||||
#hashtag1 #hashtag2
|
||||
65
plugins/linkedin-studio/config/edition-state.template.json
Normal file
65
plugins/linkedin-studio/config/edition-state.template.json
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"_doc": {
|
||||
"purpose": "Schema for edition-state.json — deterministic resumption state for a newsletter edition in production. Holds the current phase + per-article status so /linkedin:newsletter (Step 0) can resume exactly where a prior session stopped.",
|
||||
"decision": "G — production state lives in the serie-mappe (e.g. /Users/ktg/repos/maskinrommet/serier/<slug>/linkedin/edition-state.json), NOT in the plugin. This file is the schema-defining TEMPLATE only; copy + fill it in the serie-mappe when producing an edition.",
|
||||
"complements": "edition-config.json (static: calendar, freshness, captions) and <serie>/STATE.md (human-readable narrative state, overwritten each phase per the ONE-system continuity rule — there is no edition-HANDOVER.md). edition-state.json is the machine-readable companion: deterministic resumption + the durable fact-check log, immutable rules, and persona verdicts that the old HANDOVER §4/§5 used to carry.",
|
||||
"lifecycle": "/linkedin:newsletter reads this in Step 0 and rewrites it at every phase transition. Article keys mirror edition-config.json (zero-padded strings: \"01\", \"02\", ..., or \"samle\").",
|
||||
"phases": [
|
||||
"load-context — read <serie>/STATE.md, voice profile, persona library, series brief (Step 0)",
|
||||
"brief-calibration — angle, voice, audience personas, key points, leader-takeaway (Step 1)",
|
||||
"research — parallel scoped mandates → verified notes, triangulation (Step 2)",
|
||||
"skeleton-pitch — five-line skeleton (premise/problem/recommendation/payoff/forward) + section pitches, operator gate + persona-skjelett-sweep BEFORE prose (Step 2.5)",
|
||||
"spine-prose — one paragraph per section against the gated skeleton, operator gate BEFORE full expansion (Step 3a)",
|
||||
"draft — full prose expansion against the gated spine; may span sessions (Step 3b)",
|
||||
"consistency-quality — threads, premise→conclusion arc, AI-slop removal, formatting dose (Step 4)",
|
||||
"factcheck-sweep — risk-sorted, guilty-until-disproven, verification log (Step 5)",
|
||||
"editorial-review — editor's craft gate: prose-craft (em-dash density, verbatim repetition, postulated numbers, contradictions, versal-tic) + narrative-architecture (concrete instantiation, theory-anchored hypotheses, series-title symmetry, equal action per addressee, un-overloaded conclusion), ≤10 flags BLOCK/REWORK/NICE, operator-gated via SendUserFile BEFORE the persona sweep (Step 5.5)",
|
||||
"persona-sweep-prelock — reader jury, primary wins, convergence to clean YES (Step 6)",
|
||||
"annotation — optional annotatable review HTML for a manual pass (Step 7)",
|
||||
"visual-assets — cover (+ optional inline figures) or carousel deck: brief → generate → operator-gate → approve, BEFORE lock so build-linkedin.mjs picks them up (Step 7.5)",
|
||||
"lock-delivery — LOCK → POST.html all-in-one-place deliverable (Step 8)",
|
||||
"hook-conversion-gate — persona gate on distribution text post-lock: would YOU click? (Step 9)",
|
||||
"scheduling — register edition in plugin queue/state for native LinkedIn scheduling (Step 10)"
|
||||
],
|
||||
"articleStatusValues": ["pending", "in-progress", "locked", "scheduled"],
|
||||
"editorialReview": "Per-article editorial-review record written by Step 5.5 (editorial-review phase). Runs AFTER fact-check (Step 5) and BEFORE the persona sweep (Step 6): the editorial-reviewer agent judges CRAFT (prose-craft + narrative-architecture), not reader-response, mirroring the Maskinrommet skrivekontrakt §C2. The report (≤10 flags, each with kategori P1–P5/A1–A5, quote/line-ref, direction, severity BLOCK/REWORK/NICE) is surfaced to the operator via SendUserFile; the operator decides which flags fold in. Shape: { reportPath, flagCount, byAxis: { prosa, arkitektur }, bySeverity: { block, rework, nice }, foldedIn, waived, status }. status ladder: pending → reviewed → folded. null until Step 5.5 runs. This is the craft companion to factcheckLog (truth) and personaSweep (response).",
|
||||
"visualAssets": "Per-article visual-asset record written by Step 7.5 (visual-assets phase). Runs BEFORE lock because render/build-linkedin.mjs picks up linkedin/NN/cover.png + the edition-config credit/caption when it builds POST.html — generating images after lock would force a re-render. Shape: { format: \"standard\" | \"carousel\"; cover: { brief, route, candidates[], approved, status }; figures: [ { id, brief, placement, status } ]; carousel: null | { source, pdf, status } }. format \"standard\" = cover + optional inline figures (cover.png is mandatory per the KTG cover-directive); format \"carousel\" = typografisk deck via render/build-carousel.mjs instead of cover+inline (cover/figures stay empty). route: \"mcp-image\" (default, via mcp__mcp-image__generate_image) | \"external\" (DALL·E / Midjourney / photographer → linkedin/NN/cover-raw.png). status ladder: pending → briefed → generated → approved. candidates[] holds the cover-v<N>-kandidat.png attempts; approved is the fixed approved name (\"cover.png\") once the operator-gate passes. figures[].id = \"fig1\"..; placement = section reference in NN-utkast.md (figures are referenced in the draft via  and uploaded manually in the LinkedIn editor — build-linkedin.mjs does NOT embed them). Naming convention: cover.png (approved, fixed — what build-linkedin.mjs reads) | cover-v<N>-kandidat.png (attempts) | cover-raw.png (optional external pre-edit source) | fig<N>.png (inline). credit + caption are recorded in <serie>/linkedin/image-credit-caption.md and flow into edition-config.json coverCredit + captions[NN]."
|
||||
},
|
||||
"schemaVersion": 1,
|
||||
"series": {
|
||||
"slug": "<series-slug>",
|
||||
"title": "<Series title>"
|
||||
},
|
||||
"currentArticle": "01",
|
||||
"currentPhase": "load-context",
|
||||
"updatedAt": "<ISO-8601 timestamp>",
|
||||
"articles": {
|
||||
"01": {
|
||||
"title": "<Article 1 title>",
|
||||
"phase": "load-context",
|
||||
"status": "pending",
|
||||
"immutableRules": null,
|
||||
"factcheckLog": null,
|
||||
"editorialReview": null,
|
||||
"personaSweep": {
|
||||
"skeleton": null,
|
||||
"resonance": null,
|
||||
"conversion": null
|
||||
},
|
||||
"visualAssets": {
|
||||
"format": "standard",
|
||||
"cover": {
|
||||
"brief": null,
|
||||
"route": null,
|
||||
"candidates": [],
|
||||
"approved": null,
|
||||
"status": "pending"
|
||||
},
|
||||
"figures": [],
|
||||
"carousel": null
|
||||
},
|
||||
"locked": false,
|
||||
"scheduled": null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# Bilde-credit + caption — cover per edition
|
||||
|
||||
> **TEMPLATE.** Copy this to `<serie>/linkedin/image-credit-caption.md` and fill it
|
||||
> in per series. `/linkedin:newsletter` Step 7.5 (visual-assets phase) reads it and
|
||||
> updates the row for the edition in production; the values flow into
|
||||
> `<serie>/linkedin/edition-config.json` → `coverCredit` + `captions[NN]`, which
|
||||
> `render/build-linkedin.mjs` reads when it builds `POST.html` (Step 8). This file
|
||||
> is the human-readable source of truth for *motif + credit + caption*; the JSON is
|
||||
> the machine copy the renderer consumes.
|
||||
|
||||
LinkedIn-editoren har et **«Add credit and caption»**-felt under hvert bilde. Fyll
|
||||
inn per cover. Caption = én kort linje som koder artikkelens signal (det leseren
|
||||
skal sitte igjen med), ikke en bildebeskrivelse.
|
||||
|
||||
> Format i editoren: ofte ett felt. Lim «Caption — Credit» eller bruk feltene hver
|
||||
> for seg om de finnes.
|
||||
|
||||
## Verifiseringsplikt — credit skal være ærlig
|
||||
|
||||
Er coveret **KI-generert** (Nano Banana Pro / Gemini / DALL·E / Midjourney) →
|
||||
credit MÅ si det. Aldri la et AI-bilde framstå som foto eller egenprodusert
|
||||
illustrasjon. Eksempel-credit for AI-cover:
|
||||
|
||||
**Felles credit (alle editions):** `Illustrasjon generert med <verktøy>` — f.eks.
|
||||
`Illustrasjon generert med Google Gemini (Nano Banana Pro)`.
|
||||
|
||||
Er coveret et ekte foto eller en håndlaget figur → bytt til den ærlige creditten
|
||||
(`Foto: <fotograf>`, `Egenprodusert figur`). Avvik fra felles-creditten føres under.
|
||||
|
||||
**Per-edition credit-avvik:** _(list any edition whose credit differs from the
|
||||
felles-credit, with the reason — e.g. «Del 3: Egenprodusert figur (kodet SVG)».
|
||||
None by default.)_
|
||||
|
||||
## Motiv + caption per edition
|
||||
|
||||
| Del | Cover (motiv) | Caption |
|
||||
|-----|---------------|---------|
|
||||
| 01 | _<one-line motif — what the cover depicts>_ | _<one-line caption — the article's signal>_ |
|
||||
| 02 | _…_ | _…_ |
|
||||
| samle | _<optional samle-post badge/motif>_ | _<optional>_ |
|
||||
|
||||
## Naming-konvensjon (cover-filer)
|
||||
|
||||
- `cover.png` — **godkjent, fast navn**. Det eneste filnavnet `build-linkedin.mjs`
|
||||
leser. Operator-gaten i Step 7.5 kopierer den godkjente kandidaten hit.
|
||||
- `cover-v<N>-kandidat.png` — genererings-forsøk (mcp-image eller etterbehandlet).
|
||||
Flere kan ligge side om side uten å overskrive den godkjente.
|
||||
- `cover-raw.png` — valgfri ekstern pre-edit-kilde (DALL·E / Midjourney / fotograf).
|
||||
- `fig<N>.png` — inline-figur (`fig1.png`, `fig2.png`, …), referert fra utkast-markdown
|
||||
med `` og **lastet opp manuelt** i editoren
|
||||
(`build-linkedin.mjs` embedder ikke figurer).
|
||||
|
||||
## Carousel-utgaver
|
||||
|
||||
Carousel-editions (typografisk deck via `render/build-carousel.mjs`) har som regel
|
||||
**ingen foto-cover** → ingen bilde-credit nødvendig. Slide-kilden er
|
||||
`linkedin/NN/carousel.md`, rendret til `linkedin/NN/carousel.pdf`. En carousel-edition
|
||||
som *også* legger en feed-cover trenger likevel en rad over.
|
||||
|
||||
## Samle-post
|
||||
|
||||
Ev. Maskinrommet-/serie-badge (egen asset) → ingen credit. Lenken til serien ligger i
|
||||
første kommentar, ikke i bildet.
|
||||
134
plugins/linkedin-studio/config/personas.template.md
Normal file
134
plugins/linkedin-studio/config/personas.template.md
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
# Reader Persona Library
|
||||
|
||||
Reusable reader profiles for the long-form pipeline (`/linkedin:newsletter`).
|
||||
A reader persona is **not** a target-audience demographic — it is a named
|
||||
reader who reads a finished draft *read-only* and judges whether it **lands**
|
||||
(not whether it is "correct"). Personas give direction; the editor holds the
|
||||
pen. Personas never write text.
|
||||
|
||||
Copy this file to `personas.local.md` and adjust the active set per project:
|
||||
|
||||
```bash
|
||||
cp config/personas.template.md config/personas.local.md
|
||||
```
|
||||
|
||||
`personas.local.md` is gitignored (via `*.local.md`) so your active overrides
|
||||
stay local. The template ships the three Seres seed personas below; clone,
|
||||
trim, or extend them per series.
|
||||
|
||||
---
|
||||
|
||||
## How the library is used
|
||||
|
||||
- **Per-project selection.** `/linkedin:newsletter` (Step 1) picks the relevant
|
||||
personas from this library and marks the primary in the edition brief.
|
||||
- **«primær trumfer».** Exactly one persona is the **primær** reader. On
|
||||
conflict between personas, the primær weighs highest. A *secondary* NO caused
|
||||
by role mismatch or an expertise ceiling («this I already know cold») is a
|
||||
SIGNAL that the gate works — accept it, do not distort the text to chase it.
|
||||
A *primær* NO is **not** accepted: the text is revised until the primær
|
||||
reaches a clean YES.
|
||||
- **Two sweep modes** (same `persona-reviewer` agent): resonance mode (Step 6,
|
||||
BEFORE lock — «does the point land for this reader?») and conversion mode
|
||||
(Step 9, after lock — binary «would YOU click?» on the hook only).
|
||||
|
||||
### The click-gate is blocking (bar = primær ekte JA)
|
||||
|
||||
The persona sweep is not advisory — it returns a **blocking verdict**
|
||||
(PASS / REWORK / BLOCK), and the bar is the **primær reader's genuine, unqualified
|
||||
JA**. The three Seres seed personas are the canonical set: **A = IT-divisjonsdirektør**
|
||||
(sekundær), **B = KI-seksjonsleder** (sekundær), **C = Linjeleder** (PRIMÆR — trumfer).
|
||||
|
||||
- **Bar = C ekte JA.** A clean, unqualified yes from the primær. **«JA med store
|
||||
forbehold» = NEI.**
|
||||
- ⛔ **Hard fail (= omskriv, ikke annotér):** the verdict is BLOCK, regardless of
|
||||
the other axes, when the primær —
|
||||
- «mistet meg» (disengaged before the takeaway), or
|
||||
- does not own the action (the takeaway is someone else's job), or
|
||||
- hits a **sjargong-mur** (a wall of technical vocabulary their `sjargong`
|
||||
rejects), or
|
||||
- hits a **modell-/navne-katalog** (product/model/benchmark names listed for
|
||||
completeness).
|
||||
- These are **rewrite triggers**, not annotations the editor can wave through. A
|
||||
*sekundær* NO from a role/expertise ceiling stays a SIGNAL the gate works —
|
||||
never distort the text to chase it.
|
||||
|
||||
Each persona documents five fields. Keep the lowercase field keys exactly — the
|
||||
pipeline and the structural check key off them:
|
||||
|
||||
- **rolle** — who they are and what they own.
|
||||
- **avkobler** — what disconnects them / makes them stop reading.
|
||||
- **overbeviser** — what convinces them / earns their trust.
|
||||
- **ekspertise** — expertise level, including any ceiling that makes basics fall flat.
|
||||
- **sjargong** — jargon tolerance (which vocabulary lands, which repels).
|
||||
|
||||
---
|
||||
|
||||
## Seed personas (Seres series, public-sector AI adoption)
|
||||
|
||||
### Persona 1 — IT-divisjonsdirektør (sekundær)
|
||||
|
||||
- **rolle** — Leder IT-divisjonen i en stor offentlig virksomhet; eier drift,
|
||||
sikkerhet, arkitektur og leverandørforhold med budsjett- og risikoansvar.
|
||||
- **avkobler** — Hype uten driftskonsekvenser; «AI løser alt»; manglende kobling
|
||||
til sikkerhet, forvaltningskrav og totalkostnad; abstrakt strategiprat uten et
|
||||
klart hvem-eier-hva.
|
||||
- **overbeviser** — Konkret arkitektur og driftsmodell, etterlevelse/sikkerhet,
|
||||
realistisk totalkostnad, referanser fra sammenlignbar virksomhet, og en tydelig
|
||||
ansvarsdeling.
|
||||
- **ekspertise** — Høy teknisk og organisatorisk. Ekspertise-tak på grunnleggende
|
||||
IT-forklaringer: en post som forklarer systemintegrasjon fra bunnen lander ikke
|
||||
(sekundær-NEI her er et signal, ikke en svikt).
|
||||
- **sjargong** — Høy toleranse for IT-/arkitektur-sjargong; lav for AI-buzzwords
|
||||
og konsulentspråk.
|
||||
|
||||
### Persona 2 — KI-seksjonsleder (sekundær)
|
||||
|
||||
- **rolle** — Leder en KI-seksjon; bygger AI-kapabilitet, rådgir ledelsen og
|
||||
balanserer eksperimentering mot forvaltningskrav.
|
||||
- **avkobler** — Overforenkling av hva AI er; ignorering av governance, EU AI Act
|
||||
og personvern; «bare kjør i gang»-holdning; manglende erkjennelse av at
|
||||
dømmekraften ikke kan settes ut.
|
||||
- **overbeviser** — Nyansert forståelse av hva AI kan og ikke kan, konkret kobling
|
||||
til forvaltningsverdier, erfaringsbasert framfor teoretisk, og ærlighet om
|
||||
begrensninger.
|
||||
- **ekspertise** — Høy i AI-domenet. Ekspertise-tak: kjenner modellene og
|
||||
teknikkene, så en «hva er en LLM»-post faller flatt. Verdien ligger i syntese
|
||||
og dømmekraft, ikke grunnkurs.
|
||||
- **sjargong** — Høy toleranse for AI-/ML-sjargong; lav for vagt lederspråk og
|
||||
overdreven popularisering.
|
||||
|
||||
### Persona 3 — Linjeleder (primær)
|
||||
|
||||
> **Dette er primær-personaen.** Ved konflikt mellom personaer vekter denne
|
||||
> høyest. En primær-NEI godtas ikke — teksten revideres til ren primær-JA.
|
||||
|
||||
- **rolle** — Mellomleder med fag- og personalansvar i offentlig virksomhet; skal
|
||||
beslutte om og hvordan AI tas i bruk i egen enhet, uten dyp teknisk bakgrunn.
|
||||
- **avkobler** — Teknisk dypdykk uten «hva betyr dette for meg og mine»;
|
||||
frykt-retorikk; abstrakt policy; språk som forutsetter at hen kan koden.
|
||||
- **overbeviser** — Konkrete eksempler fra arbeidshverdagen, et klart ansvars- og
|
||||
dømmekraftsbilde, trygghet på at hen kan ta gode beslutninger uten å være
|
||||
tekniker, og en leder-takeaway hen kan handle på allerede i morgen.
|
||||
- **ekspertise** — Lav-til-middels teknisk; høy på ledelse og forvaltning. Trenger
|
||||
oversettelse, ikke nedlatenhet.
|
||||
- **sjargong** — Lav toleranse for teknisk sjargong; setter pris på presise,
|
||||
hverdagsnære formuleringer.
|
||||
|
||||
---
|
||||
|
||||
## Adding a persona
|
||||
|
||||
Copy the block below into `personas.local.md` and fill every field. Mark at most
|
||||
one persona as `primær` per project; if you add a new primary, demote the old one
|
||||
to sekundær.
|
||||
|
||||
```markdown
|
||||
### Persona N — [Title] ([primær | sekundær])
|
||||
|
||||
- **rolle** — [Who they are and what they own.]
|
||||
- **avkobler** — [What makes them stop reading.]
|
||||
- **overbeviser** — [What earns their trust.]
|
||||
- **ekspertise** — [Expertise level + any ceiling that makes basics fall flat.]
|
||||
- **sjargong** — [Which vocabulary lands, which repels.]
|
||||
```
|
||||
61
plugins/linkedin-studio/config/state-file.template.md
Normal file
61
plugins/linkedin-studio/config/state-file.template.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
# LinkedIn Studio State
|
||||
# Auto-managed by the linkedin-studio plugin
|
||||
# Copy to ~/.claude/linkedin-studio.local.md
|
||||
|
||||
# Posting metrics
|
||||
last_post_date: null
|
||||
first_post_date: null # YYYY-MM-DD, set once on first post, never changed
|
||||
last_post_topic: "" # Should match an expertise_areas value for pillar tracking
|
||||
posts_this_week: 0
|
||||
weekly_goal: 3
|
||||
current_streak: 0
|
||||
longest_streak: 0
|
||||
|
||||
# Week tracking (ISO week)
|
||||
current_week: ""
|
||||
|
||||
# Analytics tracking
|
||||
last_import_date: null
|
||||
last_import_week: ""
|
||||
|
||||
# Milestone tracking
|
||||
follower_count: 0
|
||||
follower_target: 10000
|
||||
target_date: "2026-12-31"
|
||||
monthly_growth: []
|
||||
projected_10k_date: ""
|
||||
growth_rate_needed: 0
|
||||
|
||||
# Planning
|
||||
next_planned_topic: ""
|
||||
pending_5x5x5: false
|
||||
content_series_active: ""
|
||||
|
||||
# Profile
|
||||
expertise_areas:
|
||||
- "general"
|
||||
- ""
|
||||
- ""
|
||||
- ""
|
||||
- ""
|
||||
---
|
||||
|
||||
# LinkedIn Session State
|
||||
|
||||
## Recent Posts
|
||||
|
||||
<!-- Updated automatically by Stop hook -->
|
||||
<!-- Format: [YYYY-MM-DD] "Hook text..." (chars) - topic_area -->
|
||||
|
||||
## Session Notes
|
||||
|
||||
<!-- Free-form notes from sessions -->
|
||||
|
||||
## Planned Content
|
||||
|
||||
<!-- Upcoming posts and topics -->
|
||||
|
||||
## Milestone Log
|
||||
|
||||
<!-- Updated when follower_count changes. Format: [YYYY-MM] count (+delta) -->
|
||||
126
plugins/linkedin-studio/config/user-profile.template.md
Normal file
126
plugins/linkedin-studio/config/user-profile.template.md
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
# User Profile Configuration
|
||||
|
||||
Copy this file to `user-profile.local.md` and customize for your needs.
|
||||
|
||||
```bash
|
||||
cp config/user-profile.template.md config/user-profile.local.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PERSONALIZATION SETTINGS
|
||||
|
||||
### User Profile Context
|
||||
|
||||
**Name:** [Your Name]
|
||||
**Current Role:** [Your Role] (posting as private individual, not representing employer)
|
||||
**Organization:** [Not disclosed / Your Company]
|
||||
**Industry/Domain:** [Your Industry]
|
||||
|
||||
**Important Disclaimer:** All articles and posts are written as a private individual. Views expressed are personal and do not represent any employer.
|
||||
|
||||
**Core Expertise Areas (5 topics):**
|
||||
1. [Topic 1]
|
||||
2. [Topic 2]
|
||||
3. [Topic 3]
|
||||
4. [Topic 4]
|
||||
5. [Topic 5]
|
||||
|
||||
**Target Audience:**
|
||||
- **Primary:** [Who are you primarily writing for?]
|
||||
- **Secondary:** [Secondary audience]
|
||||
- **Geographic focus:** [Region/Country]
|
||||
|
||||
**LinkedIn Goals (ranked by priority):**
|
||||
1. [ ] Build thought leadership & authority
|
||||
2. [ ] Attract speaking opportunities
|
||||
3. [ ] Network with peers/influencers
|
||||
4. [ ] Generate qualified leads
|
||||
5. [ ] Monetization (consulting/courses)
|
||||
6. [ ] Recruit talent
|
||||
|
||||
---
|
||||
|
||||
### Voice & Style Profile
|
||||
|
||||
**Tone Preferences (select what applies):**
|
||||
- [ ] Professional & authoritative
|
||||
- [ ] Conversational & approachable
|
||||
- [ ] Storytelling-focused
|
||||
- [ ] Data-driven & analytical
|
||||
- [ ] Empathetic & supportive
|
||||
- [ ] Provocative & contrarian
|
||||
|
||||
**Content Style Mix:**
|
||||
- Story-based posts
|
||||
- Framework/how-to posts
|
||||
- Data/research posts
|
||||
- Opinion/commentary posts
|
||||
- Case study posts
|
||||
- Personal reflection posts
|
||||
|
||||
**Signature Elements:**
|
||||
- **Key frameworks you've developed:** [Your frameworks, or "None yet"]
|
||||
- **Recurring themes/angles:** [Your themes]
|
||||
- **Phrases you commonly use:** [Your phrases]
|
||||
- **Topics to AVOID:** [Topics you never discuss]
|
||||
|
||||
**Writing Quirks & Preferences:**
|
||||
- **Preferred post length:** [Short 150-500 / Medium 1,200-1,800 / Long 2,000+]
|
||||
- **Emoji usage:** [None / Minimal 1-2 / Moderate 3-5]
|
||||
- **Question style CTAs:** [Always / Sometimes / Never]
|
||||
- **Use of personal anecdotes:** [Always / Sometimes / Rarely]
|
||||
- **Technical depth:** [Beginner / Intermediate / Advanced / Adaptive]
|
||||
|
||||
---
|
||||
|
||||
### Voice Profile Summary
|
||||
|
||||
**[Your Name] writes with:**
|
||||
|
||||
1. **[Quality 1]:** [Description]
|
||||
2. **[Quality 2]:** [Description]
|
||||
3. **[Quality 3]:** [Description]
|
||||
4. **[Quality 4]:** [Description]
|
||||
5. **[Quality 5]:** [Description]
|
||||
|
||||
**DO:**
|
||||
- [What you always do in your writing]
|
||||
- [Another thing you do]
|
||||
|
||||
**DON'T:**
|
||||
- [What you never do]
|
||||
- [Another thing to avoid]
|
||||
|
||||
**Universal anti-patterns (keep these — they hold for every author):**
|
||||
- **Modell-/navne-katalog.** Do not reel off product names, model names, or
|
||||
benchmarks for completeness. Pick ONE concrete, verifiable (preferably local)
|
||||
case over a list — a name-dump is a jargon wall to a non-technical reader.
|
||||
- **Fullstendighet over leser-handling.** Serve what the primary reader can DO
|
||||
from their chair, not everything the author knows. Completeness is not a virtue.
|
||||
- **Selvrefererende overhead-åpning.** No meta-commentary about what the text will
|
||||
or will not do, no warm-ups. Start on the reader's problem.
|
||||
- **«ikke bare X, men Y», reflex rule-of-three, tacked-on summaries, hedging.**
|
||||
|
||||
**Language:** [English / Norwegian / Other]
|
||||
|
||||
---
|
||||
|
||||
### Strategic Context
|
||||
|
||||
**Current LinkedIn Status:**
|
||||
- **Follower count:** [Your current count]
|
||||
- **90-day growth goal:** [Your goal]
|
||||
- **Posting frequency:** [Daily / 3x week / 2x week]
|
||||
- **Optimal posting times:** [Your best times, or "To be determined"]
|
||||
|
||||
---
|
||||
|
||||
### Asset Utilization Preferences
|
||||
|
||||
**When creating content, Claude should:**
|
||||
- [ ] Check `/assets/examples/` for past post patterns
|
||||
- [ ] Reference frameworks from `/assets/frameworks/`
|
||||
- [ ] Pull case studies from `/assets/case-studies/`
|
||||
- [ ] Incorporate voice samples from `/assets/voice-samples/`
|
||||
- [ ] Use research/data from `/assets/research/`
|
||||
Loading…
Add table
Add a link
Reference in a new issue