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:
Kjell Tore Guttormsen 2026-05-29 11:32:02 +02:00
commit b6bb61246b
196 changed files with 164 additions and 138 deletions

View file

@ -0,0 +1,123 @@
export interface PostAnalytics {
id: string; // Hash of title + date
title: string; // First ~100 chars of post content
publishedDate: string; // YYYY-MM-DD
metrics: PostMetrics;
importedAt: string; // ISO datetime
exportSource: string; // Original CSV filename
}
export interface PostMetrics {
impressions: number;
reactions: number;
comments: number;
shares: number;
clicks: number;
engagementRate: number; // (reactions+comments+shares+clicks)/impressions * 100
}
export interface AnalyticsBatch {
batchId: string; // UUID-like identifier
importedAt: string; // ISO datetime
exportFilename: string;
dateRange: { from: string; to: string };
postCount: number;
posts: PostAnalytics[];
}
export interface WeeklyReport {
week: string; // ISO week e.g. "2026-W05"
generatedAt: string;
summary: {
totalPosts: number;
totalImpressions: number;
totalReactions: number;
totalComments: number;
totalShares: number;
totalClicks: number;
avgEngagementRate: number;
avgImpressionsPerPost: number;
};
topPerformers: PostAnalytics[];
underperformers: PostAnalytics[];
trends: {
impressionsTrend: TrendDirection;
engagementTrend: TrendDirection;
comparedTo: string;
percentChange: {
impressions: number;
engagement: number;
};
};
alerts: Alert[];
}
export type TrendDirection = "up" | "down" | "stable";
export interface Alert {
type: "spike" | "drop" | "milestone";
severity: "info" | "warning" | "critical";
metric: string;
message: string;
postId?: string;
value: number;
baseline: number;
deviations: number;
}
export interface DayOfWeekMetrics {
dayName: string; // "Monday" through "Sunday"
dayIndex: number; // 1=Monday, 7=Sunday (ISO weekday)
postCount: number;
avgImpressions: number;
avgEngagementRate: number;
bestPost?: PostAnalytics;
}
export interface HeatmapReport {
generatedAt: string;
postsAnalyzed: number;
dateRange: { from: string; to: string };
byDayOfWeek: DayOfWeekMetrics[]; // 7 entries, Mon-Sun ordered
bestDayImpressions: string;
bestDayEngagement: string;
}
export interface MonthlyReport {
month: string; // "YYYY-MM"
generatedAt: string;
summary: {
totalPosts: number;
totalImpressions: number;
totalReactions: number;
totalComments: number;
totalShares: number;
totalClicks: number;
avgEngagementRate: number;
avgImpressionsPerPost: number;
};
topPerformers: PostAnalytics[];
byWeek: {
week: string;
postCount: number;
avgImpressions: number;
avgEngagementRate: number;
}[];
trends: {
comparedTo: string | null;
percentChange: {
impressions: number | null;
engagement: number | null;
postCount: number | null;
};
};
alerts: Alert[];
}
export const ALERT_THRESHOLDS = {
spike: 2.0,
drop: -1.5,
weeklyDropWarning: -30,
weeklyDropCritical: -50,
weeklySpikeInfo: 100,
} as const;