linkedin-studio/scripts/trends/README.md
Kjell Tore Guttormsen be21788321 feat(linkedin-studio): trends store — research-engine inventory (§5 slice 1)
[skip-docs] internal plumbing — standalone store, no command/agent/pipeline
surface change until slice 2 wiring (mirrors specifics-bank slice 2). CLAUDE.md
"Telling"/counts untouched; lint stays 84/0/0.

Research-engine §5 (foundation layer) slice 1: the deterministic STORE half of
the persistent trend store — a topic-tagged, provenance-bearing inventory of
trend signals captured over time, so the research engine accumulates HISTORY
instead of starting amnesiac each session. Trend-side twin of the lived-specifics
bank (same store/dedup/query discipline; dedupe key is normalized title+URL, not
free-text content). Generic by architecture: nothing niche-specific lives here —
topics and source are free-form, decided upstream via config/profile.

scripts/trends/ (sibling to specifics-bank, same tsx convention):
- src/types.ts — TrendRecord/TrendStore schema (schemaVersion 1), minimal
  generic core: title, url, source, capturedAt, topics[], optional summary
- src/store.ts — pure store: normalizeField, title+url-hash id (= dedupe key),
  load/save, addTrend (dedupe + topic union on re-capture; first-sighting
  source/capturedAt kept), queryByTopic (overlap-ranked then recency), history
  (time-scoped, since/limit)
- src/cli.ts — add / query / list; default store under
  ${LINKEDIN_STUDIO_DATA:-~/.claude/linkedin-studio}/trends/ so trend history
  survives plugin upgrades/reinstalls (M0 data-path seam)
- tests/store.test.ts — 21/21 green; tsc clean
- README + .gitignore for node_modules/build

Capture/scoring agent + MCP-first routing land in slice 2; the CI binding guard
is deferred to wiring, mirroring the specifics-bank timeline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:08:21 +02:00

2.5 KiB

linkedin-trends-store

Persistent trend store — the foundation layer of the research engine (retning §5). A topic-tagged, provenance-bearing inventory of trend signals captured over time, so the engine accumulates history instead of starting amnesiac each session.

Twin of scripts/specifics-bank: same deterministic store / dedup / query discipline, different dedupe key — a trend is identified by its normalized title+URL, not by free-text content.

Generic by architecture

Nothing niche-specific lives here. A TrendRecord carries free-form topics tags and a free-form source string; which topics matter and which sources to poll are decided upstream (config/profile + the capture agent), never hard-coded in this module. The same store serves any niche.

Data location

The store lives under the per-user data dir (M0 data-path convention), so trend history survives plugin upgrades/reinstalls:

${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/trends/trends.json

LINKEDIN_STUDIO_DATA overrides the root. No path is hard-coded in prose.

Record shape (minimal generic core)

interface TrendRecord {
  id: string;          // sha256(normalized title+url).slice(0,12) — also the dedupe key
  title: string;       // headline, verbatim
  url: string;         // source URL, verbatim
  source: string;      // "tavily" | "websearch" | "manual" | <mcp-name>
  capturedAt: string;  // ISO-8601 date
  topics: string[];    // query tags; unioned across re-captures
  summary?: string;    // optional, verbatim
}

Fields (relevance score, first-mover timing, status) can be added in a later slice without breaking the shape.

CLI

# Capture a freshly-polled trend (dedupes on title+url; unions topics on re-capture)
node --import tsx src/cli.ts add \
  --title "Agentic workflows hit production" \
  --url "https://example.com/agentic" \
  --topics "agents,engineering" --source tavily \
  --summary "Teams ship multi-step agents past the demo stage."

# Topic-scoped history — trends matching these topics, ranked by overlap then recency
node --import tsx src/cli.ts query --topics "agents,engineering" [--json]

# Time-scoped history — newest first, optionally windowed/capped
node --import tsx src/cli.ts list [--since 2026-06-01] [--limit 10] [--json]

Re-running add with the same title+url never appends a duplicate.

Tests

cd scripts/trends
npm install
npm test     # deterministic store: normalize/id, load/save, dedup+union, query, history
npm run build