Lifts the original v4.0.0 Non-Goal: an optional, manually-entered `saves`
metric through the analytics layer, built location-agnostic (option c) so
UI-brief §9b/M0 relocates the data dir in one place later.
- types: PostMetrics.saves? + Weekly/Monthly summary.totalSaves? (optional);
new RankableMetric type for the always-numeric index-access whitelist
- parser: dedicated parseOptionalCount() — blank/non-numeric/negative -> undefined
("unknown != 0"), genuine 0 kept; saves NOT folded into engagementRate
- reports: totalSaves set only when >=1 post carries saves (backward-compat)
- cli: saves surfaced in import summary + weekly/monthly totals + per-post
- S16-pre: onboarding.md allowed-tools gains Write (closes S15-deferred MAJOR)
- docs (three-doc rule): plugin README boundary + analytics README + root README
+ plugin CLAUDE.md + CHANGELOG; dwell stays explicitly unmeasurable
Independent /trekreview: brief-conformance 0 findings; code-correctness 2 MAJOR
(own lockstep misses) FIXED in-session (parseOptionalCount + edge tests). Gate:
tsc clean, analytics 116/116, lint 74/0/0, hooks 98/98. Within-v4.1.0 refinement
(no surface/count/version change).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| ab-tests | ||
| README.md | ||
LinkedIn Analytics Data
This directory contains imported analytics data from LinkedIn CSV exports.
How to Import
- Go to LinkedIn Creator Analytics
- Click Export to download a CSV of your content analytics
- Save the CSV file to
exports/directory - Run
/linkedin:importin Claude Code
Optional: add per-post saves (manual)
LinkedIn's CSV export does not include saves, and there is no self-serve API
to pull them — but the per-post save count is visible in your native post
analytics (since ~Sept 2025). To track it, add a Saves column to the CSV and
type the count you read off LinkedIn. The importer picks it up automatically when
the column is present:
"Content","Date","Impressions","Reactions","Comments","Shares","Clicks","Saves"
"My post...",2026-02-10,5000,100,30,15,200,42
A missing column — or a blank Saves cell — leaves saves unknown (never
counted as 0), and saves is not folded into the engagement rate (which stays
comparable to older imports). Saves is the strongest organic engagement signal,
so the reports surface it as its own line. Dwell time stays unmeasurable —
it is internal to LinkedIn for organic posts, with no count to transcribe.
Directory Structure
analytics/
├── exports/ # Place LinkedIn CSV exports here
├── posts/ # Auto-generated: imported post data (JSON)
├── weekly-reports/ # Auto-generated: weekly performance reports (JSON)
└── README.md # This file
Data Format
Post Analytics (posts/*.json)
Each file contains a batch of imported posts:
{
"batchId": "batch-...",
"importedAt": "2026-01-29T...",
"exportFilename": "content-analytics.csv",
"dateRange": { "from": "2026-01-13", "to": "2026-01-28" },
"postCount": 8,
"posts": [
{
"id": "abc123",
"title": "First 100 chars of post...",
"publishedDate": "2026-01-28",
"metrics": {
"impressions": 4523,
"reactions": 87,
"comments": 23,
"shares": 12,
"clicks": 156,
"engagementRate": 6.15
}
}
]
}
metrics.saves is optional — present only on posts where you supplied a
Saves column value (see "Optional: add per-post saves" above). Posts without
it omit the field entirely, so older imports round-trip unchanged.
Weekly Reports (weekly-reports/*.json)
Generated via /linkedin:report. Contains:
- Summary metrics (totals, averages)
- Top and underperforming posts
- Week-over-week trends
- Performance alerts (spikes, drops)
CLI Usage
The analytics CLI can also be invoked directly:
# Import a CSV export
ANALYTICS_ROOT=./assets/analytics node --import tsx scripts/analytics/src/cli.ts import <filename>
# Generate weekly report
ANALYTICS_ROOT=./assets/analytics node --import tsx scripts/analytics/src/cli.ts report --week 2026-W05
# Analyze trends
ANALYTICS_ROOT=./assets/analytics node --import tsx scripts/analytics/src/cli.ts trends --period month --metric impressions
Privacy
All data in this directory (except this README) is gitignored. Your analytics data stays local.