feat(linkedin-studio): N5 — /linkedin:trends discovery-kommando + trend-spotter pin-fjerning + triage [skip-docs]
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: b69d02cd-d30d-478b-95a5-bd06113c648a
This commit is contained in:
parent
95b1521ae5
commit
a8e3cacee3
10 changed files with 154 additions and 14 deletions
|
|
@ -84,6 +84,7 @@ directly when you do.
|
|||
| `/linkedin:multiplatform` | Adapt content for Twitter/X, slides, YouTube (long-form → newsletter) |
|
||||
| `/linkedin:batch` | Create a full week of content in one session |
|
||||
| `/linkedin:pipeline` | End-to-end single-post workflow (idea → draft → schedule → analyze) |
|
||||
| `/linkedin:trends` | Trend discovery pass — scan your sources, persist candidates + morning brief, triage per id |
|
||||
| `/linkedin:newsletter` | **Long-form spine.** Newsletter editions, essays, series articles. The single long-form entry point |
|
||||
| `/linkedin:headless-review` | Cold adversarial re-read of a FROZEN long-form draft before lock (ideally in a fresh session) |
|
||||
| `/linkedin:pivot` | Re-open a long-form edition after a late change so cleared gates re-run |
|
||||
|
|
@ -161,6 +162,7 @@ If the user's intent is clear from context:
|
|||
- Mentions "react" or "this article" or "this url" or "turn this into" or "share this news" → Route to `/linkedin:react`
|
||||
- Mentions "quick" or "fast" → Route to `/linkedin:quick`
|
||||
- Mentions "pipeline" or "end to end" → Route to `/linkedin:pipeline`
|
||||
- Mentions "trends" or "trending" or "discovery pass" or "morning brief" or "what should I write about" → Route to `/linkedin:trends`
|
||||
- Mentions "batch" or "week of content" → Route to `/linkedin:batch`
|
||||
- Mentions "calendar" or "schedule" or "queue" or "upcoming posts" or "what's scheduled" → Route to `/linkedin:calendar`
|
||||
- Mentions "publish" or "mark as published" or "posted today" or "just published" or "post is live" → Route to `/linkedin:calendar` (publish action)
|
||||
|
|
|
|||
138
commands/trends.md
Normal file
138
commands/trends.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
---
|
||||
name: linkedin:trends
|
||||
description: |
|
||||
Run a trend discovery pass over the user's own content pillars and source list:
|
||||
delegate the scan to the trend-spotter agent, make sure kept candidates are persisted
|
||||
to the trend store (dedup) and the dated morning brief is written, then return a
|
||||
triage-ranked candidate list the user resolves per id (act/skip). Default scoring mode
|
||||
is long-form (chronicle/newsletter material); `--mode kortform` overrides for feed posts.
|
||||
Use when the user wants a discovery pass, a trend scan, or a morning-brief refresh.
|
||||
Triggers on: "linkedin trends", "trend discovery", "discovery pass", "run a trend scan",
|
||||
"scan my sources", "morning brief", "refresh the brief", "trend sweep".
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Bash
|
||||
- Task
|
||||
- AskUserQuestion
|
||||
---
|
||||
|
||||
# LinkedIn Trend Discovery
|
||||
|
||||
You are a thin discovery orchestrator. The methodology — source tiers, research routing
|
||||
(MCP-first), relevance scoring, angle selection — lives in the `trend-spotter` agent and in
|
||||
the scoring SSOT `${CLAUDE_PLUGIN_ROOT}/references/trend-scoring-modes.md`. Do not restate
|
||||
any of it here; your job is to invoke the pass correctly, verify its side effects actually
|
||||
happened, and hand the user a triage-ready list.
|
||||
|
||||
Data dir shorthand used below: `${DATA}` = `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}`.
|
||||
Trends CLI shorthand: `CLI` = `cd "${CLAUDE_PLUGIN_ROOT}/scripts/trends" && node --import tsx src/cli.ts`.
|
||||
|
||||
## Step 0: Parse flags
|
||||
|
||||
All flags are optional, given after the command name:
|
||||
|
||||
| Flag | Meaning | Default |
|
||||
|------|---------|---------|
|
||||
| `--mode kortform\|long-form` | Scoring mode (see the SSOT for what each rewards) | **long-form** — no arguments means a long-form discovery pass |
|
||||
| `--fresh-days N` | Freshness window for the morning brief | CLI default (7) |
|
||||
| `--brief-only` | Skip the discovery poll entirely; render the brief from the existing store | off |
|
||||
| `--dry-run` | Poll + score, but persist nothing: no capture, no brief, no status writes, no last-run marker | off |
|
||||
|
||||
Note the mode inversion deliberately: the **agent's** own default is kortform, this
|
||||
**command's** default is long-form. That is why Step 2 must always pass the mode explicitly.
|
||||
|
||||
## Step 1: Load context
|
||||
|
||||
1. **Pillars:** Read `${DATA}/profile/user-profile.md` and extract the content pillars /
|
||||
expertise areas. If the file does not exist, ask the user for their pillars before
|
||||
proceeding (one question, comma-separated answer).
|
||||
2. **Source list:** Resolve which list this pass will use — `${DATA}/trends/sources.md` if it
|
||||
exists, otherwise the shipped defaults `${CLAUDE_PLUGIN_ROOT}/config/trends-sources.template.md`.
|
||||
Tell the user which one applies. Do not read research-tooling or route research yourself —
|
||||
the agent owns Research Routing (its own "Research Routing" section reads the profile's
|
||||
`### Research Tooling` block); duplicating it here would drift.
|
||||
|
||||
## Step 2: Run the discovery pass
|
||||
|
||||
**If `--brief-only`:** skip the agent entirely — go to Step 3 and render the brief from the
|
||||
existing store.
|
||||
|
||||
Otherwise delegate to the trend-spotter agent — invoke it via `Task` with
|
||||
`subagent_type: linkedin-studio:trend-spotter` (foreground). The prompt MUST state explicitly:
|
||||
|
||||
- **The scoring mode** from Step 0 (default long-form). Never omit it — the agent falls back
|
||||
to kortform when the caller is silent.
|
||||
- The pillars and the resolved source-list path from Step 1.
|
||||
- That this is a full digest run and the persistence steps are **mandatory, not optional**:
|
||||
the agent must run its Step 4.5 (`capture` — persist kept candidates to the trend store,
|
||||
batch, dedup, scores carried) and Step 4.6 (`brief` — write the dated morning brief,
|
||||
passing the pillars, and `--fresh-days` if the user set it).
|
||||
- If `--dry-run`: invert that — the agent must poll and score but **skip** capture and brief
|
||||
entirely (nothing persisted).
|
||||
- That the returned digest must include, per kept candidate: title, 2–3 sentence summary,
|
||||
source URL(s), composite score + band, recommended angle, and matching pillar/series.
|
||||
|
||||
## Step 3: Verify the side effects (skip on `--dry-run`)
|
||||
|
||||
Trust but verify — the pass is only done when its artifacts exist:
|
||||
|
||||
1. **Store:** `CLI status --json` — confirm the store mutated (captured count reflects the
|
||||
run; on a no-new-trends day `{added: 0, merged: N}` is a fine outcome, not a failure).
|
||||
2. **Brief:** confirm today's file exists: `${DATA}/trends/morning-brief/<today YYYY-MM-DD>.md`.
|
||||
If the agent captured but failed to render the brief, render it directly — the brief is
|
||||
deterministic: `CLI brief --pillars "<pillar1,pillar2,…>"` (add `--fresh-days N` if set).
|
||||
3. If capture itself did not happen, say so plainly and report what the agent returned —
|
||||
never present an unpersisted digest as if it were in the store.
|
||||
|
||||
## Step 4: Present the triage-ranked list
|
||||
|
||||
Present the candidates ranked highest composite first (the agent's digest already carries the
|
||||
ranking — do not re-rank). Per candidate, the contract is:
|
||||
|
||||
```
|
||||
N. [Title] (id: <trend-id>)
|
||||
Score: X.X — [Band] | Pillar: [pillar/series]
|
||||
[2–3 sentence summary]
|
||||
Source: [URL(s)]
|
||||
Angle: [recommended angle]
|
||||
```
|
||||
|
||||
Include each candidate's store id (shown in the brief and via `CLI list --json`) — the triage
|
||||
step below resolves per id. On `--dry-run`, present the same list but say clearly that nothing
|
||||
was persisted and there are no store ids to triage.
|
||||
|
||||
## Step 5: Triage (skip on `--dry-run`)
|
||||
|
||||
Resolve the top of the queue now instead of leaving it as homework. For the candidates in the
|
||||
top bands (Immediate + High; cap at 8), use AskUserQuestion — one question per candidate, up
|
||||
to 4 candidates per call, options:
|
||||
|
||||
- **Act** — writing about it now/soon: mark handled so the brief stops re-surfacing it
|
||||
- **Skip** — not for me: same effect, opposite verdict
|
||||
- **Leave** — keep it in the queue untouched
|
||||
|
||||
Then apply each decision through the store CLI, one call per resolved id:
|
||||
|
||||
```bash
|
||||
CLI act --id <id> # or: skip --id <id>
|
||||
```
|
||||
|
||||
"Leave" means no call. Finish with a one-line summary: N acted, N skipped, N left in queue.
|
||||
(The CLI currently takes one `--id` per call; a `selected` status and `--ids` batching are
|
||||
planned upgrades — keep decisions per-id so this step absorbs them without contract change.)
|
||||
|
||||
## Step 6: Write the last-run marker (skip on `--dry-run`)
|
||||
|
||||
On completed runs (including `--brief-only`), stamp the marker so other surfaces can tell when
|
||||
discovery last ran:
|
||||
|
||||
```bash
|
||||
mkdir -p "${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/trends" && \
|
||||
date -u +"%Y-%m-%dT%H:%M:%SZ" > "${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/trends/.last-run"
|
||||
```
|
||||
|
||||
## Reference Files
|
||||
|
||||
- `${CLAUDE_PLUGIN_ROOT}/references/trend-scoring-modes.md` — scoring SSOT (modes, weights, bands)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/trends-sources.template.md` — shipped source-list defaults (user override: `${DATA}/trends/sources.md`)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/agents/trend-spotter.md` — the discovery methodology this command invokes
|
||||
Loading…
Add table
Add a link
Reference in a new issue