docs(linkedin-studio): M0-15 — repoint remaining prose families + route ab-tests/plans

This commit is contained in:
Kjell Tore Guttormsen 2026-06-18 13:04:18 +02:00
commit 6bd263144f
35 changed files with 167 additions and 130 deletions

View file

@ -34,11 +34,11 @@ ${CLAUDE_PLUGIN_ROOT}/references/algorithm-signals-reference.md
Check for existing state and analytics data:
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests/ 2>/dev/null | head -20
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/ 2>/dev/null | head -20
```
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/posts/ 2>/dev/null | grep -E '\.json$' | head -10
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/ 2>/dev/null | grep -E '\.json$' | head -10
```
If `~/.claude/linkedin-studio.local.md` exists, read it for user context (posting frequency, follower level, topics).
@ -184,13 +184,13 @@ Present the complete test plan:
Create the ab-tests directory if it does not exist:
```bash
mkdir -p ${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests
mkdir -p ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests
```
Save the test plan as a markdown file:
```
${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests/[test-name].md
${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/[test-name].md
```
Use the test name slug (e.g., `hook-question-vs-statement.md`).
@ -206,7 +206,7 @@ Confirm to the user: "Test plan saved. When you publish your first post, come ba
Scan for active tests:
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests/ 2>/dev/null | grep -E '\.md$'
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/ 2>/dev/null | grep -E '\.md$'
```
If no tests exist, tell the user: "No active tests found. Use option 1 to design a new test first."
@ -218,7 +218,7 @@ If tests exist, present them and ask which test to log for using AskUserQuestion
Read the selected test file:
```bash
cat ${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests/[test-name].md
cat ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/[test-name].md
```
### 2b.3: Collect Post Metrics
@ -267,7 +267,7 @@ If minimum sample size (3 per variant) is reached, suggest: "You have enough dat
List tests with sufficient data (3+ posts per variant):
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests/ 2>/dev/null | grep -E '\.md$'
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/ 2>/dev/null | grep -E '\.md$'
```
Read each file and check if both variants have 3+ posts logged. Present only tests ready for analysis. If no tests have sufficient data, tell the user how many more posts are needed.
@ -281,10 +281,10 @@ Read the test file. For each variant:
### 2c.3: Cross-Reference Analytics Data
If analytics CLI data is available in `assets/analytics/posts/`, cross-reference the test period data with weekly reports for additional context (baseline comparison, trend alignment).
If analytics CLI data is available in `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/`, cross-reference the test period data with weekly reports for additional context (baseline comparison, trend alignment).
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/weekly-reports/ 2>/dev/null | grep -E '\.json$' | head -10
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/ 2>/dev/null | grep -E '\.json$' | head -10
```
### 2c.4: Present Analysis
@ -349,7 +349,7 @@ Update the test file status from ACTIVE to COMPLETED. Add the conclusion and rec
### 2d.1: Scan All Tests
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/ab-tests/ 2>/dev/null | grep -E '\.md$'
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/ 2>/dev/null | grep -E '\.md$'
```
If no tests exist: "No test history yet. Design your first test with option 1."
@ -396,8 +396,8 @@ Read each test file and extract: test name, variable tested, status, verdict, ke
Check what data is available:
1. **Test history:** Read `assets/analytics/ab-tests/` for completed tests
2. **Analytics data:** Check `assets/analytics/posts/` for performance data
1. **Test history:** Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/` for completed tests
2. **Analytics data:** Check `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/` for performance data
3. **User context:** Read state file for posting patterns and goals
### 2e.2: Generate Suggestions
@ -472,7 +472,7 @@ After any action, offer relevant next steps:
## Error Handling
### No Tests Directory
If `assets/analytics/ab-tests/` does not exist and the user selects options 2-4:
If `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/ab-tests/` does not exist and the user selects options 2-4:
- Inform the user: "No tests found. The test directory will be created when you design your first test."
- Redirect to option 1 (Design) or option 5 (Suggestions).

View file

@ -38,7 +38,7 @@ Use AskUserQuestion to understand the situation:
## Step 2: Gather Data
If imported analytics data exists (`assets/analytics/`), delegate audience-pattern discovery to the `analytics-interpreter` agent (interpret mode) — invoke it via `Task` with `subagent_type: linkedin-studio:analytics-interpreter` (foreground, from this command layer) — to ground the diagnosis in what the data actually shows before relying on self-report.
If imported analytics data exists (`${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/`), delegate audience-pattern discovery to the `analytics-interpreter` agent (interpret mode) — invoke it via `Task` with `subagent_type: linkedin-studio:analytics-interpreter` (foreground, from this command layer) — to ground the diagnosis in what the data actually shows before relying on self-report.
Based on their answer, ask relevant follow-up questions:

View file

@ -21,12 +21,12 @@ You are a LinkedIn content strategy auditor. Conduct a thorough review of the us
Load all available data:
- Read `~/.claude/linkedin-studio.local.md` for posting history
- Read `${CLAUDE_PLUGIN_ROOT}/assets/plans/` for planned content
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/plans/` for planned content
- Read `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-studio/SKILL.md` for strategy reference
- Check for any analytics data in `${CLAUDE_PLUGIN_ROOT}/assets/analytics/`
- Read `assets/audience-insights/demographics.md` for audience composition — compare intended vs actual audience
- Read `assets/audience-insights/engagement-patterns.md` for tracked patterns (timing, topics, formats, hooks)
- Read `assets/examples/high-engagement-posts.md` for proven success patterns to benchmark against
- Check for any analytics data in `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/`
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/demographics.md` for audience composition — compare intended vs actual audience
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/engagement-patterns.md` for tracked patterns (timing, topics, formats, hooks)
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/examples/high-engagement-posts.md` for proven success patterns to benchmark against
Ask the user to provide:
- Screenshot of LinkedIn analytics (last 90 days) or key metrics

View file

@ -25,8 +25,8 @@ You are a LinkedIn batch content creator. Help the user create an entire week's
Load state and personalization:
- Read `~/.claude/linkedin-studio.local.md` for recent topics and weekly goals
- Read `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-studio/SKILL.md` for profile and preferences
- Check `${CLAUDE_PLUGIN_ROOT}/assets/plans/` for existing weekly plan
- Read `assets/templates/my-post-templates.md` for proven templates — vary templates across the batch for format diversity
- Check `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/plans/` for existing weekly plan
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/templates/my-post-templates.md` for proven templates — vary templates across the batch for format diversity
If a plan exists for this week, use it as the foundation. If not, create one first.
@ -99,8 +99,8 @@ Follow the standard structure:
- Voice matches profile
### 3c. Save Draft
Write each post to `${CLAUDE_PLUGIN_ROOT}/assets/drafts/`:
- Create directory if needed: `assets/drafts/week-[WXX]/`
Write each post to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/`:
- Create directory if needed: `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/week-[WXX]/`
- Filename: `[day]-[topic-slug].md`
- Include metadata header:
@ -122,7 +122,7 @@ status: scheduled
After saving each draft, add it to the queue:
```bash
node --input-type=module -e "import { queueAdd } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueAdd('[YYYY-WXX-day-topic-slug]', 'assets/drafts/week-[WXX]/[day]-[topic-slug].md', '[YYYY-MM-DD]', '[HH:MM]', '[pillar]', '[format]', '[hook preview first 50 chars]', [character_count]));"
node --input-type=module -e "import { queueAdd } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueAdd('[YYYY-WXX-day-topic-slug]', '${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/week-[WXX]/[day]-[topic-slug].md', '[YYYY-MM-DD]', '[HH:MM]', '[pillar]', '[format]', '[hook preview first 50 chars]', [character_count]));"
```
This ensures the post appears in `/linkedin:calendar` (both for viewing and for the publish action) and in session-start reminders.
@ -138,7 +138,7 @@ Batch Summary: [X] posts created
2. [Day] — "[Hook preview...]" (X chars) — [format]
3. [Day] — "[Hook preview...]" (X chars) — [format]
Saved to: assets/drafts/week-[WXX]/
Saved to: ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/week-[WXX]/
Content mix: X educational / Y inspirational / Z entertaining
Pillars covered: [list]
@ -180,7 +180,7 @@ import { generateIcalFromQueue, writeIcalFile } from '${CLAUDE_PLUGIN_ROOT}/hook
const upcoming = queueUpcoming(14);
if (upcoming.length === 0) { console.log('No upcoming posts to schedule.'); process.exit(0); }
const events = generateIcalFromQueue(upcoming);
const icsPath = '${CLAUDE_PLUGIN_ROOT}/assets/drafts/week-[WXX]/schedule.ics';
const icsPath = '${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/week-[WXX]/schedule.ics';
writeIcalFile(icsPath, events);
console.log('Calendar file: ' + icsPath + ' (' + events.length + ' events)');
"
@ -191,7 +191,7 @@ Replace `[WXX]` with the actual ISO week number used for the batch directory.
Show the user:
```
Calendar file generated: assets/drafts/week-[WXX]/schedule.ics
Calendar file generated: ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/week-[WXX]/schedule.ics
Import this file into your calendar app:
- macOS: Double-click the .ics file → Calendar.app imports it
@ -209,4 +209,4 @@ Each scheduled post has a 15-minute reminder before posting time.
- `${CLAUDE_PLUGIN_ROOT}/references/scheduling-strategy.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/templates/weekly-content-calendar-2-3x.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/checklists/quality-scorecard.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/queue.json`

View file

@ -199,4 +199,4 @@ After showing the calendar (or after a publish action loops back), provide brief
- `${CLAUDE_PLUGIN_ROOT}/references/scheduling-strategy.md`
- `${CLAUDE_PLUGIN_ROOT}/references/engagement-frameworks.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/queue.json`

View file

@ -130,7 +130,7 @@ Generate a visual for each slide using mcp-image (Nano Banana Pro). If mcp-image
1. **Create output directory:**
```bash
mkdir -p assets/drafts/carousel-$(date +%Y%m%d)-SLUG
mkdir -p ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-$(date +%Y%m%d)-SLUG
```
Replace SLUG with a short kebab-case version of the carousel topic (e.g., `ai-governance`).
@ -144,11 +144,11 @@ Generate a visual for each slide using mcp-image (Nano Banana Pro). If mcp-image
3. **For each slide (1 through N),** call `mcp__mcp-image__generate_image` with:
- **prompt:** `"Professional LinkedIn carousel slide. [TEMPLATE STYLE from above]. Background: [consistent color scheme across all slides]. Bold header text: '[SLIDE HEADER]' in large white sans-serif font near the top. Body text below: '[SLIDE BODY lines]' in smaller matching font. Slide [N] of [TOTAL]. Portrait orientation, clean minimal professional design."`
- **aspect_ratio:** `"3:4"` (closest available to LinkedIn's 4:5)
- **output_path:** `assets/drafts/carousel-[date]-[slug]/slide-[N].png`
- **output_path:** `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-[date]-[slug]/slide-[N].png`
4. **After all slides are generated,** verify the output directory contains the expected number of images:
```bash
ls -la assets/drafts/carousel-$(date +%Y%m%d)-SLUG/
ls -la ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-$(date +%Y%m%d)-SLUG/
```
**On failure:** If any mcp-image call fails, log the error and continue with remaining slides. If ALL calls fail, fall back to the text-only design guide in Step 6.
@ -162,7 +162,7 @@ Show all slides in order with their text content, then the caption.
```
SLIDE IMAGES
━━━━━━━━━━━━
Generated [N] slide images in assets/drafts/carousel-[date]-[slug]/
Generated [N] slide images in ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-[date]-[slug]/
To publish:
1. Download the slide images from the folder above

View file

@ -34,7 +34,7 @@ For data format details and directory structure, see `assets/analytics/README.md
First, check if any CSV files exist in the exports directory:
```bash
ls -lh ${CLAUDE_PLUGIN_ROOT}/assets/analytics/exports/*.csv 2>/dev/null || echo "No CSV files found"
ls -lh ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/exports/*.csv 2>/dev/null || echo "No CSV files found"
```
**If files found:** Skip to Step 3.
@ -59,7 +59,7 @@ Options:
On file selection, copy the file to the exports directory:
```bash
cp "<selected-file>" ${CLAUDE_PLUGIN_ROOT}/assets/analytics/exports/
cp "<selected-file>" ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/exports/
```
Then continue to Step 4.
@ -88,10 +88,10 @@ After the script completes, continue to Step 4.
1. Go to [linkedin.com/analytics/creator/content/](https://linkedin.com/analytics/creator/content/)
2. Click the **"Export"** button (top right)
3. LinkedIn will download a CSV file
4. Move it to: `${CLAUDE_PLUGIN_ROOT}/assets/analytics/exports/`
4. Move it to: `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/exports/`
```bash
mv ~/Downloads/linkedin_analytics_export*.csv ${CLAUDE_PLUGIN_ROOT}/assets/analytics/exports/
mv ~/Downloads/linkedin_analytics_export*.csv ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/exports/
```
Once done, run `/linkedin:import` again.
@ -152,7 +152,7 @@ Alerts:
- Post "The future of no-code..." (2026-01-22): Viral threshold reached (10k+ impressions)
Data saved to:
- ${CLAUDE_PLUGIN_ROOT}/assets/analytics/posts/YYYY-WXX.json
- ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/YYYY-WXX.json
```
### Step 5b: Import Analysis & Anomaly Detection
@ -174,7 +174,7 @@ Compare the imported week's data against existing baselines (if available from p
**Read baselines for comparison:**
```bash
cat ${CLAUDE_PLUGIN_ROOT}/assets/analytics/baselines.json 2>/dev/null
cat ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/baselines.json 2>/dev/null
```
**If baselines exist**, compare each imported post's metrics against baseline means. If no baselines exist yet, note that this is the first import and baselines will be established.
@ -290,10 +290,10 @@ Present using AskUserQuestion with the top 3 most relevant suggestions.
## Step 8: Demographics Sync Suggestion
After completing the import workflow, check if `assets/audience-insights/demographics.md` still has placeholder data:
After completing the import workflow, check if `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/demographics.md` still has placeholder data:
```bash
grep -c '\[Industry name\]\|\[Function\]\|\[Country\]\|\[X\]%' ${CLAUDE_PLUGIN_ROOT}/assets/audience-insights/demographics.md 2>/dev/null
grep -c '\[Industry name\]\|\[Function\]\|\[Country\]\|\[X\]%' ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/demographics.md 2>/dev/null
```
If placeholder count is > 10 (still mostly unfilled), suggest:
@ -305,7 +305,7 @@ If placeholder count is > 10 (still mostly unfilled), suggest:
If the import fails:
1. **Check the CSV format** - LinkedIn sometimes changes export format
2. **Verify the file path** - Ensure the file is in `assets/analytics/exports/`
2. **Verify the file path** - Ensure the file is in `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/exports/`
3. **Check file permissions** - The CLI needs read access
4. **Show the error message** and suggest solutions
@ -318,9 +318,9 @@ If the import fails:
## Reference Files
The import system creates:
- `assets/analytics/posts/YYYY-WXX.json` - Weekly post data
- `assets/analytics/metadata.json` - Import tracking and baseline metrics
- `assets/analytics/baselines.json` - Statistical baselines for anomaly detection
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/YYYY-WXX.json` - Weekly post data
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/metadata.json` - Import tracking and baseline metrics
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/baselines.json` - Statistical baselines for anomaly detection
## State Tracking

View file

@ -21,7 +21,7 @@ intent in one question and route. **You do not run the analysis here.**
## Step 0: Quick context (optional)
If `assets/analytics/` holds imported data, you may note "last import: [date]" in one
If `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/` holds imported data, you may note "last import: [date]" in one
line so the user knows whether a fresh import is needed first. Do not block on it.
## Step 1: Identify what they need

View file

@ -21,7 +21,7 @@ You are a multi-platform content strategist. Help the user adapt their LinkedIn
## Step 0: Load Source Content
Ask the user to provide their LinkedIn content or read from drafts:
- Read `${CLAUDE_PLUGIN_ROOT}/assets/drafts/` for recent content
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/` for recent content
- Read `~/.claude/linkedin-studio.local.md` for recent posts
## Step 1: Select Target Platform
@ -106,7 +106,7 @@ YouTube tips:
## Step 2: Adapt and Save
After creating the adaptation:
- Save to `${CLAUDE_PLUGIN_ROOT}/assets/drafts/multiplatform/[platform]-[slug].md`
- Save to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/multiplatform/[platform]-[slug].md`
- Auto-copy the adapted content to clipboard silently:
```bash
printf '%s' '<ADAPTED_CONTENT>' | node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/clipboard-helper.mjs

View file

@ -1486,7 +1486,7 @@ now a first-class scheduled post.
node -e 'import("'"${CLAUDE_PLUGIN_ROOT}"'/hooks/scripts/queue-manager.mjs").then(q => q.queueAdd("<series-slug>-NN","<serie-mappe>/linkedin/NN/POST.html","YYYY-MM-DD","HH:MM","<pillar>","newsletter","<hook ~80c>",<charCount>))'
```
The function appends to `assets/drafts/queue.json` with `status:
The function appends to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/queue.json` with `status:
"scheduled"` and returns the new entry.
3. **Persist + close the edition.** Set the article's `status: "scheduled"`,
@ -1497,7 +1497,7 @@ now a first-class scheduled post.
```
Scheduling.
- Queue entry: <series-slug>-NN → assets/drafts/queue.json (status: scheduled)
- Queue entry: <series-slug>-NN → ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/queue.json (status: scheduled)
- Slot: YYYY-MM-DD HH:MM format: newsletter
- Article status: scheduled
Edition complete. Visible in /linkedin:calendar; mark live via /linkedin:calendar (publish action).

View file

@ -155,7 +155,7 @@ file must contain no `<!-- VOICE_PLACEHOLDER -->`.
4. 5 expertise areas (these become your content pillars)
5. Target audience description
Save to `config/user-profile.local.md`.
Save to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/profile/user-profile.md`.
After setup, recalculate and show updated score.

View file

@ -27,7 +27,7 @@ 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 `${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 `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/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
Display status:
@ -110,7 +110,7 @@ If the user chooses to queue the post:
node --input-type=module -e "import { queueUpcoming, queueFormatSummary } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueFormatSummary(queueUpcoming(14)));"
```
3. Suggest the next available optimal slot
4. Save the draft to `assets/drafts/week-[WXX]/[day]-[topic-slug].md` with `scheduled_date` and `scheduled_time` in frontmatter
4. Save the draft to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/week-[WXX]/[day]-[topic-slug].md` with `scheduled_date` and `scheduled_time` in frontmatter
5. Add to queue:
```bash
node --input-type=module -e "import { queueAdd } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueAdd('[id]', '[draft_path]', '[date]', '[time]', '[pillar]', '[format]', '[hook preview]', [chars]));"
@ -208,4 +208,4 @@ Replace placeholders with actual post data. Set `next_planned_topic` manually if
- `${CLAUDE_PLUGIN_ROOT}/references/scheduling-strategy.md`
- `${CLAUDE_PLUGIN_ROOT}/assets/checklists/quality-scorecard.md`
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/`
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/queue.json`

View file

@ -37,9 +37,9 @@ Check weekly progress:
Check for existing assets:
- `${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
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/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.**
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/templates/my-post-templates.md` - User's proven post templates with success rates. **Prefer these over generic structures.**
## Step 1: Understand the Input
@ -65,7 +65,7 @@ If they provide a URL, use WebFetch to extract the content first.
Read `references/thought-leadership-angles.md` for the 8 universal angles.
**Industry-specific angles:** If `config/user-profile.local.md` exists and has an `industry` field, check the "Industry Angle Variants" section in `thought-leadership-angles.md` for the matching industry table. Use the industry-specific starter questions and example hooks to generate more targeted angle suggestions.
**Industry-specific angles:** If `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/profile/user-profile.md` exists and has an `industry` field, check the "Industry Angle Variants" section in `thought-leadership-angles.md` for the matching industry table. Use the industry-specific starter questions and example hooks to generate more targeted angle suggestions.
Select the strongest angle based on the content and user's expertise areas. Present ONE recommended angle with brief reasoning:

View file

@ -27,7 +27,7 @@ For data format details and directory structure, see `assets/analytics/README.md
First, verify that analytics data exists:
```bash
ls -1 ${CLAUDE_PLUGIN_ROOT}/assets/analytics/posts/ 2>/dev/null | grep -E '\.json$' | head -10
ls -1 ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/ 2>/dev/null | grep -E '\.json$' | head -10
```
If no JSON files exist, tell the user:
@ -101,7 +101,7 @@ If the user chose monthly:
"${CLAUDE_PLUGIN_ROOT}/scripts/analytics/node_modules/.bin/tsx" "${CLAUDE_PLUGIN_ROOT}/scripts/analytics/src/cli.ts" report --month <YYYY-MM>
```
Read the generated JSON from `assets/analytics/monthly-reports/<YYYY-MM>.json`. Present the monthly summary with MoM comparison deltas, weekly breakdown, and top performers. Then jump to Step 7 for deep-dive options.
Read the generated JSON from `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/monthly-reports/<YYYY-MM>.json`. Present the monthly summary with MoM comparison deltas, weekly breakdown, and top performers. Then jump to Step 7 for deep-dive options.
### Step 2c: Heatmap
@ -127,14 +127,14 @@ Execute the report CLI command:
```
The CLI will generate:
- `assets/analytics/weekly-reports/YYYY-WXX.json` - Structured report data
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/YYYY-WXX.json` - Structured report data
## Step 4: Read Generated Report Data
Read the generated JSON report:
```bash
cat ${CLAUDE_PLUGIN_ROOT}/assets/analytics/weekly-reports/<YYYY-WXX>.json
cat ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/<YYYY-WXX>.json
```
The report contains:
@ -195,7 +195,7 @@ After the initial trend data, automatically run trend analysis for the key metri
Construct the 4-week table by reading available weekly report files:
```bash
ls ${CLAUDE_PLUGIN_ROOT}/assets/analytics/weekly-reports/*.json 2>/dev/null | sort | tail -4
ls ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/*.json 2>/dev/null | sort | tail -4
```
Read each file and extract the summary metrics to populate the table columns.
@ -220,7 +220,7 @@ Automatically flag these conditions based on the report data and trend analysis:
**Detect alerts by comparing current week data against baselines:**
```bash
cat ${CLAUDE_PLUGIN_ROOT}/assets/analytics/baselines.json 2>/dev/null
cat ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/baselines.json 2>/dev/null
```
Compare current week's `aggregateMetrics` against baseline means and standard deviations. Flag any metric that is:
@ -372,7 +372,7 @@ If user wants to analyze specific posts:
Read the weekly post data directly:
```bash
cat ${CLAUDE_PLUGIN_ROOT}/assets/analytics/posts/<YYYY-WXX>.json | jq '.posts[] | select(.title | contains("search term"))'
cat ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/<YYYY-WXX>.json | jq '.posts[] | select(.title | contains("search term"))'
```
Show detailed metrics for that post and suggest what made it perform well/poorly.
@ -382,7 +382,7 @@ Show detailed metrics for that post and suggest what made it perform well/poorly
**If report generation fails:**
1. **Week not found**: No data imported for that week
- List available weeks: `ls ${CLAUDE_PLUGIN_ROOT}/assets/analytics/posts/`
- List available weeks: `ls ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/`
- Suggest importing data for that week
2. **No posts in week**: Week file exists but is empty
@ -406,10 +406,10 @@ Read `~/.claude/linkedin-studio.local.md` and suggest:
## Reference Files
Reports use data from:
- `assets/analytics/posts/YYYY-WXX.json` - Raw weekly post data
- `assets/analytics/weekly-reports/YYYY-WXX.json` - Computed report
- `assets/analytics/baselines.json` - Statistical baselines for comparison
- `assets/analytics/metadata.json` - Import history and tracking
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/YYYY-WXX.json` - Raw weekly post data
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/YYYY-WXX.json` - Computed report
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/baselines.json` - Statistical baselines for comparison
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/metadata.json` - Import history and tracking
## Step 8b: Export Options
@ -419,12 +419,12 @@ If the user chooses option 4 ("Export report as markdown file") from the deep di
1. Read the JSON report data:
```bash
cat ${CLAUDE_PLUGIN_ROOT}/assets/analytics/weekly-reports/<YYYY-WXX>.json
cat ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/<YYYY-WXX>.json
```
2. Format the data using this template and write to file:
Save to: `${CLAUDE_PLUGIN_ROOT}/assets/analytics/weekly-reports/YYYY-WXX-report.md`
Save to: `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/YYYY-WXX-report.md`
```markdown
# LinkedIn Performance Report — Week YYYY-WXX
@ -476,13 +476,13 @@ Save to: `${CLAUDE_PLUGIN_ROOT}/assets/analytics/weekly-reports/YYYY-WXX-report.
```
**Important notes:**
- The `assets/analytics/` directory is gitignored — exported reports contain personal analytics data and should not be committed
- The `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/` directory is gitignored — exported reports contain personal analytics data and should not be committed
- Use the `-report.md` suffix to distinguish from the JSON data files (e.g., `2026-W05-report.md` vs `2026-W05.json`)
- Include all sections: metrics, trends, alerts, top performers, and recommendations for a complete standalone document
After saving, confirm to the user:
```
Report exported to: assets/analytics/weekly-reports/YYYY-WXX-report.md
Report exported to: ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/weekly-reports/YYYY-WXX-report.md
Note: This file is in your gitignored analytics directory — it won't be committed to the repository.
```

View file

@ -27,13 +27,13 @@ Read these 8 asset files and detect placeholder patterns to calculate the curren
| Category | Weight | File/Directory | Placeholder Detection |
|----------|--------|----------------|----------------------|
| 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`) |
| High-engagement posts | 10 | `assets/examples/high-engagement-posts.md` | Count `## Post N:` headers |
| Demographics | 8 | `assets/audience-insights/demographics.md` | Count `[Industry name]`, `[Function]`, `[Country]`, `[X]%` |
| Engagement patterns | 7 | `assets/audience-insights/engagement-patterns.md` | Count `[Day]`, `[Time]`, `[Topic]`, `[Format]`, `[Hook type]` |
| Post templates | 5 | `assets/templates/my-post-templates.md` | Count `[Name - e.g.` vs total `## Template N:` headers |
| User profile | 20 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/profile/user-profile.md` | Check if file exists; count `[Your ` placeholders |
| Case studies | 15 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/case-studies/*.md` | Count non-template `.md` files (exclude `case-study-template.md`) |
| Frameworks | 10 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/frameworks/*.md` | Count non-template `.md` files (exclude `framework-template.md`) |
| High-engagement posts | 10 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/examples/high-engagement-posts.md` | Count `## Post N:` headers |
| Demographics | 8 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/demographics.md` | Count `[Industry name]`, `[Function]`, `[Country]`, `[X]%` |
| Engagement patterns | 7 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/engagement-patterns.md` | Count `[Day]`, `[Time]`, `[Topic]`, `[Format]`, `[Hook type]` |
| Post templates | 5 | `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/templates/my-post-templates.md` | Count `[Name - e.g.` vs total `## Template N:` headers |
**Scoring rules:**
- Full points: Asset has real data (few/no placeholders remaining)
@ -117,7 +117,7 @@ Based on their answer, run the corresponding sub-workflow below.
## Step 3b: Case Study Builder
**Goal:** Create a new case study file in `assets/case-studies/`.
**Goal:** Create a new case study file in `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/case-studies/`.
Conduct a 6-question interview:
@ -130,7 +130,7 @@ Conduct a 6-question interview:
After the interview, read `assets/case-studies/case-study-template.md` for structure reference, then create a new file:
**Filename:** `assets/case-studies/[slug].md` (derive slug from the challenge topic, e.g., `ai-procurement-transformation.md`)
**Filename:** `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/case-studies/[slug].md` (derive slug from the challenge topic, e.g., `ai-procurement-transformation.md`)
**File structure:**
```markdown
@ -172,7 +172,7 @@ Ask "Would you like to document another case study?" when done.
## Step 3c: Framework Documenter
**Goal:** Create a new framework file in `assets/frameworks/`.
**Goal:** Create a new framework file in `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/frameworks/`.
Conduct a 5-question interview:
@ -184,7 +184,7 @@ Conduct a 5-question interview:
After the interview, read `assets/frameworks/framework-template.md` for structure reference, then create:
**Filename:** `assets/frameworks/[slug].md` (e.g., `ai-maturity-model.md`)
**Filename:** `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/frameworks/[slug].md` (e.g., `ai-maturity-model.md`)
**File structure:**
```markdown
@ -228,12 +228,12 @@ Ask "Would you like to document another framework?" when done.
## Step 3d: Post Analysis
**Goal:** Document high-engagement posts in `assets/examples/high-engagement-posts.md`.
**Goal:** Document high-engagement posts in `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/examples/high-engagement-posts.md`.
Two approaches — ask which they prefer:
### Option A: Analytics Data Available
If the user has imported analytics data (check `assets/analytics/posts/` for JSON files):
If the user has imported analytics data (check `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/posts/` for JSON files):
1. Read the most recent analytics data files
2. Identify the top 3-5 posts by engagement rate
@ -257,7 +257,7 @@ If no analytics data available:
- **Pattern extraction:** What's replicable?
- **Mistakes identified:** What could be improved?
3. Read the existing `assets/examples/high-engagement-posts.md`
3. Read the existing `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/examples/high-engagement-posts.md`
4. **Append** new posts after existing entries (don't overwrite)
5. Update the "Patterns Across All High-Performing Posts" section based on all posts
@ -265,7 +265,7 @@ Ask "Would you like to add more posts?" when done.
## Step 3e: Demographics Sync
**Goal:** Populate `assets/audience-insights/demographics.md` with real LinkedIn Analytics data.
**Goal:** Populate `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/demographics.md` with real LinkedIn Analytics data.
Guide the user step by step through the LinkedIn Analytics UI:
@ -286,7 +286,7 @@ Guide the user step by step through the LinkedIn Analytics UI:
- Record the actual data
- Ask about trends ("Is this similar to previous months?")
5. Read the existing `assets/audience-insights/demographics.md`
5. Read the existing `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/audience-insights/demographics.md`
6. Replace the placeholder tables with real data
7. Fill in the "Key insights" sections based on the data patterns
8. Update the "Last Updated" date
@ -300,7 +300,7 @@ If the user says they don't have LinkedIn Analytics access or data yet, suggest:
## Step 3f: User Profile Setup
**Goal:** Create or update `config/user-profile.local.md`.
**Goal:** Create or update `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/profile/user-profile.md`.
Guide through each section of the profile:
@ -337,7 +337,7 @@ Guide through each section of the profile:
- "90-day growth goal?"
7. Read `config/user-profile.template.md` for structure
8. Write the completed profile to `config/user-profile.local.md`
8. Write the completed profile to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/profile/user-profile.md`
**Important:** This file is gitignored (`.local.md` pattern), so personal data stays private.

View file

@ -294,7 +294,7 @@ For the canonical profile-alignment audit (headline/About/Experience/Featured/Sk
### Identify Signature Content
Ask the user to identify their top-performing posts (or read analytics from `${CLAUDE_PLUGIN_ROOT}/assets/analytics/`).
Ask the user to identify their top-performing posts (or read analytics from `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/`).
**Signature content criteria:**
- High saves — bookmarking is a strong authority signal; read the count from your native LinkedIn post analytics (this tool does not capture saves)

View file

@ -40,7 +40,7 @@ Load video-specific references:
Check for existing assets:
- `${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
- `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/examples/high-engagement-posts.md` — Study successful patterns
## Step 1: Choose Video Type
@ -190,7 +190,7 @@ Iterate until satisfied.
## Step 8: Save and Update State
Save the final script to `assets/drafts/`:
Save the final script to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/`:
```
video-[YYYY-MM-DD]-[slug]-[type]-[length].md