[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>
73 lines
2.5 KiB
Markdown
73 lines
2.5 KiB
Markdown
# 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`](../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)
|
|
|
|
```ts
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
cd scripts/trends
|
|
npm install
|
|
npm test # deterministic store: normalize/id, load/save, dedup+union, query, history
|
|
npm run build
|
|
```
|