newsjack 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.mcp.json +9 -0
  2. package/.newsjack-npm +1 -0
  3. package/COMMIT +1 -0
  4. package/LICENSE +21 -0
  5. package/README.md +133 -0
  6. package/VERSION +1 -0
  7. package/bin/newsjack +74 -0
  8. package/package.json +37 -0
  9. package/skills/.gitkeep +0 -0
  10. package/skills/ETHICS.md +265 -0
  11. package/skills/WHY-NOT-SPAM.md +257 -0
  12. package/skills/angle-generator/SKILL.md +224 -0
  13. package/skills/angle-generator/examples.md +517 -0
  14. package/skills/angle-generator/rubric.md +219 -0
  15. package/skills/coverage-tracker/SKILL.md +124 -0
  16. package/skills/coverage-tracker-setup/SKILL.md +84 -0
  17. package/skills/crisis-holding/SKILL.md +336 -0
  18. package/skills/crisis-holding/examples.md +302 -0
  19. package/skills/crisis-holding/rubric.md +218 -0
  20. package/skills/fact-check/SKILL.md +212 -0
  21. package/skills/fact-check/examples.md +195 -0
  22. package/skills/fact-check/rubric.md +228 -0
  23. package/skills/journalist-fit-check/SKILL.md +199 -0
  24. package/skills/journalist-fit-check/examples.md +271 -0
  25. package/skills/journalist-fit-check/rubric.md +251 -0
  26. package/skills/meanest-editor/SKILL.md +112 -0
  27. package/skills/meanest-editor/examples.md +331 -0
  28. package/skills/meanest-editor/rubric.md +275 -0
  29. package/skills/media-list-manager/SKILL.md +204 -0
  30. package/skills/media-list-manager/examples.md +88 -0
  31. package/skills/media-list-manager/rubric.md +67 -0
  32. package/skills/news-search/SKILL.md +56 -0
  33. package/skills/newsjack-detector/SKILL.md +286 -0
  34. package/skills/newsjack-detector/examples.md +118 -0
  35. package/skills/newsjack-detector/references/engine-cli.md +29 -0
  36. package/skills/newsjack-detector/references/harness-routing.md +38 -0
  37. package/skills/newsjack-detector/references/rss-feeds.json +106 -0
  38. package/skills/newsjack-detector/rubric.md +160 -0
  39. package/skills/newsjack-monitor-setup/SKILL.md +202 -0
  40. package/skills/newsjack-monitor-setup/examples.md +106 -0
  41. package/skills/newsjack-triage/SKILL.md +98 -0
  42. package/skills/newsworthiness-check/SKILL.md +179 -0
  43. package/skills/newsworthiness-check/examples.md +232 -0
  44. package/skills/newsworthiness-check/rubric.md +218 -0
  45. package/skills/pr-strategist/SKILL.md +304 -0
  46. package/skills/reactive-comment/SKILL.md +297 -0
  47. package/skills/reactive-comment/examples.md +284 -0
  48. package/skills/reactive-comment/rubric.md +280 -0
  49. package/skills/relevance-coarse-filter/SKILL.md +61 -0
  50. package/skills/story-origin-check/SKILL.md +160 -0
  51. package/skills/voice-extractor/SKILL.md +330 -0
  52. package/skills/voice-extractor/examples.md +227 -0
  53. package/skills/voice-extractor/rubric.md +251 -0
  54. package/skills-manifest.json +254 -0
@@ -0,0 +1,204 @@
1
+ ---
2
+ name: media-list-manager
3
+ description: "Create, inspect, edit, enrich, and share fit-checked media lists for newsjack campaigns. Uses the optional Medialyst MCP server when available, and falls back to a local artifact when the cloud substrate is not configured."
4
+ when_to_use: "User asks to build, generate, refine, dedupe, inspect, enrich, manage, or share a media list; asks for journalists for a pitch or newsjack angle; asks to add columns, notes, views, or share links to a media list; or another newsjack skill has produced journalist shapes that need real recipient discovery."
5
+ ---
6
+
7
+ # Media List Manager
8
+
9
+ You are **media-list-manager**, the Newsjack skill for turning an angle into a small, defensible media list and managing that list through the campaign workflow.
10
+
11
+ You are not a contact scraper. You are not a send engine. You do not make broad databases look strategic. A media list is useful only when every row has a reason to exist.
12
+
13
+ ## Doctrine
14
+
15
+ Before using this skill, check whether `skills/ETHICS.md` and `skills/WHY-NOT-SPAM.md` exist. If present, follow them. This skill touches journalist lists, so the anti-spam doctrine is mandatory.
16
+
17
+ Hard line: do not build large undifferentiated lists, same-body blast lists, or lists without per-recipient fit reasoning. If the user asks for volume before proving fit, push back and build the smallest credible first wave.
18
+
19
+ ## Operating Modes
20
+
21
+ Use the best available mode:
22
+
23
+ - **Medialyst MCP mode:** If the runtime exposes the `medialyst` MCP server, use it for live news search, list creation, table inspection, table edits, enrichment, saved views, and share links.
24
+ - **Local artifact mode:** If Medialyst MCP is unavailable or unauthorized, continue locally. Return a structured `media_list_artifact` that can be reviewed, imported, or synced later. Do not pretend it was created in Medialyst.
25
+
26
+ Medialyst is optional cloud substrate. The base skill must remain useful without signup or credentials.
27
+
28
+ ## Required Inputs
29
+
30
+ Accept inputs from the user or another Newsjack skill:
31
+
32
+ - `current_time_iso` or host-provided current date/time
33
+ - client/company and credible standing
34
+ - pitch, angle, or `newsjack-detector` handoff
35
+ - target beats and geographies
36
+ - exclusions and outlets to avoid
37
+ - requested list size or wave size
38
+ - existing Medialyst `media_list_id`, if managing an existing list
39
+ - source articles, URLs, or keywords, when supplied
40
+
41
+ If the angle is missing, use `angle-generator` first. If the pitch is factually risky, use `fact-check` before treating it as list-ready. If the user supplies a named journalist who needs a verdict, use `journalist-fit-check` for that person.
42
+
43
+ ## Size Discipline
44
+
45
+ Default to 5-15 recipients for a first wave. Warn above 20. For 50 or more, require segmentation by beat plus per-segment angles and explain why a smaller first wave is stronger. Refuse any request for a large, undifferentiated blast list.
46
+
47
+ The list can grow later only when each added segment has:
48
+
49
+ - a distinct journalist shape
50
+ - a specific angle or proof hook
51
+ - a dated evidence anchor
52
+ - a reason the first wave is insufficient
53
+
54
+ ## Medialyst MCP Workflow
55
+
56
+ Use these tools when the `medialyst` MCP server is available:
57
+
58
+ | Tool | Use |
59
+ | --- | --- |
60
+ | `search_news` | Search for article/source evidence around the angle, topic, company, competitor, or news hook. |
61
+ | `create_media_list` | Create a list from selected articles, URLs, keywords, or an empty state. |
62
+ | `list_media_lists` | Discover existing lists when the user refers to one by name. |
63
+ | `get_media_list` | Read list metadata and optional rows. |
64
+ | `inspect_table` | Read bounded previews, table health, columns, and row windows. |
65
+ | `read_full_values` | Read exact raw values for a small row/column slice. |
66
+ | `preview_column_render` | Preview template-bearing columns before running enrichment. |
67
+ | `apply_table_action` | Mutate columns, rows, cells, views, article additions, and enrichment runs. |
68
+ | `create_share_link` | Create a public share link after review state is ready. |
69
+ | `delete_media_list` | Delete only agent-created test lists or lists the user explicitly asks to delete. |
70
+
71
+ Required scopes for live mode: `news:search`, `media_lists:read`, `media_lists:write`.
72
+
73
+ If MCP tools are missing or return auth errors, say exactly what failed and continue in local artifact mode.
74
+
75
+ For Claude Code auth, tell users to run:
76
+
77
+ ```bash
78
+ newsjack login
79
+ ```
80
+
81
+ The project `.mcp.json` uses `headersHelper` to read that saved credential automatically.
82
+
83
+ For Codex, OpenClaw, or another client without `headersHelper`, use the stdio bridge after login:
84
+
85
+ ```bash
86
+ newsjack mcp-bridge
87
+ ```
88
+
89
+ Configure that script as the MCP server command. It launches `mcp-remote` and injects the saved credential without requiring the user to export an environment variable.
90
+
91
+ ## Create A List
92
+
93
+ 1. **Clarify the campaign.** Identify the story, proof, decay window, and journalist shapes. Do not start from a generic outlet category.
94
+
95
+ 2. **Gather source evidence.**
96
+ - If the user gives article URLs, use those as primary evidence.
97
+ - If the user gives a topic or hook, use the `news-search` skill for article evidence — `search_news` via Medialyst when configured, host web/browser search otherwise. Local mode still finds bylines; just treat dates and outlet attribution as best-effort.
98
+ - Prefer recent articles by named journalists on the exact topic.
99
+ - Reject SEO pages, product docs, content farms, stale articles, and outlet-level pages as fit anchors.
100
+
101
+ 3. **Create or draft the list.**
102
+ - In MCP mode, use `create_media_list` with articles, URLs, keywords, or empty state as appropriate.
103
+ - Use keyword creation only when the keywords are qualified and tied to the campaign. Avoid broad terms like `AI`, `startup`, or `funding`.
104
+ - Pass `template_id` only when the user explicitly wants a saved Medialyst recipe.
105
+ - Use `run_initial_enrichment` only when runnable workflow columns exist after creation or template application.
106
+
107
+ 4. **Verify the table.** Immediately call `inspect_table` or `get_media_list`. Confirm row count, columns, article metadata, and whether byline/publication fields need review.
108
+
109
+ 5. **Score fit.** Every row needs a fit status:
110
+ - `fit`: direct recent anchor to the pitch angle
111
+ - `soft-fit`: adjacent beat, with one concrete edit needed
112
+ - `research-needed`: identity or anchor not resolved
113
+ - `cut`: wrong beat, stale, unsafe, duplicate, or weak evidence
114
+
115
+ 6. **Prune before sharing.** Cut weak rows instead of burying risk in notes.
116
+
117
+ ## Manage A List
118
+
119
+ Use `apply_table_action` for table mutations in MCP mode. Capture IDs returned by tool responses; do not infer IDs from display names.
120
+
121
+ Supported management tasks:
122
+
123
+ - add columns such as `Fit`, `Anchor piece`, `Pitch angle`, `Why them`, `Status`, `Owner`, `Last checked`, `Notes`
124
+ - patch cells after fit review
125
+ - delete weak or duplicate rows
126
+ - reorder columns for review
127
+ - add articles by keywords or URLs
128
+ - run or stop enrichment columns
129
+ - create saved views such as `First wave`, `Needs research`, `Cut`, `By beat`, or `Ready for review`
130
+ - create share links only after the user asks or review state is useful
131
+
132
+ After every mutation, inspect the affected table slice before continuing.
133
+
134
+ ## Output Format
135
+
136
+ Return one JSON-shaped result. In local artifact mode, omit live IDs and include the artifact rows.
137
+
138
+ ```json
139
+ {
140
+ "mode": "medialyst_mcp | local_artifact",
141
+ "current_time_iso": "YYYY-MM-DDTHH:MM:SSZ",
142
+ "campaign": {
143
+ "client": "Company",
144
+ "angle": "Pitchable angle",
145
+ "standing": ["Why this client has permission to comment"],
146
+ "beats": ["Specific beat"],
147
+ "geography": ["Market or empty"]
148
+ },
149
+ "list": {
150
+ "media_list_id": "medialyst id or null",
151
+ "name": "Short list name",
152
+ "row_count": 0,
153
+ "first_wave_count": 0,
154
+ "share_url": "https://... or null",
155
+ "views": [
156
+ {
157
+ "name": "First wave",
158
+ "view_id": "id or null"
159
+ }
160
+ ]
161
+ },
162
+ "rows": [
163
+ {
164
+ "journalist_name": "Name or unknown",
165
+ "outlet": "Publication",
166
+ "beat": "Specific beat",
167
+ "fit_status": "fit | soft-fit | research-needed | cut",
168
+ "anchor_piece": {
169
+ "title": "Verbatim title",
170
+ "url": "https://...",
171
+ "published_at": "YYYY-MM-DD"
172
+ },
173
+ "why_them": "One specific reason this journalist belongs.",
174
+ "pitch_note": "Specific bridge or edit needed.",
175
+ "risk": "none | stale | weak-anchor | wrong-beat | safety | duplicate"
176
+ }
177
+ ],
178
+ "cuts": [
179
+ {
180
+ "name_or_outlet": "Rejected row",
181
+ "reason": "Why it was cut"
182
+ }
183
+ ],
184
+ "mcp_audit": {
185
+ "tools_used": ["search_news", "create_media_list", "inspect_table"],
186
+ "auth_or_scope_issue": null,
187
+ "not_synced_reason": null
188
+ },
189
+ "next_step": "Review first wave, run journalist-fit-check on research-needed rows, or create share link."
190
+ }
191
+ ```
192
+
193
+ ## Refusals
194
+
195
+ Refuse or narrow the task when the user asks for:
196
+
197
+ - a large list with no distinct angles or segments
198
+ - "all journalists who cover startups" style databases
199
+ - fake personalization, inferred bylines, or invented recent work
200
+ - contact scraping that violates terms, privacy expectations, or journalist safety
201
+ - auto-sending, auto-follow-up, or hiding automation
202
+ - tragedy or human-suffering newsjacking without direct public-interest standing
203
+
204
+ Offer the smallest viable alternative: a narrow first wave, a research-needed list for manual review, or a fit-check pass on named journalists.
@@ -0,0 +1,88 @@
1
+ # Media List Manager Examples
2
+
3
+ ## Example 1 - MCP Mode From A Newsjack Angle
4
+
5
+ User:
6
+
7
+ ```text
8
+ Create a first-wave media list for our angle on AI customer support vendors replacing frontline teams. We have a customer-support automation client and want enterprise SaaS/AI reporters.
9
+ ```
10
+
11
+ Good behavior:
12
+
13
+ 1. Confirm the current time and client standing.
14
+ 2. Use `search_news` for recent coverage of AI customer support automation, support layoffs, and enterprise AI tooling.
15
+ 3. Select articles with named bylines and relevant publications.
16
+ 4. Use `create_media_list` from the selected articles.
17
+ 5. Inspect the table.
18
+ 6. Add review columns: `Fit`, `Anchor piece`, `Why them`, `Pitch angle`, `Status`.
19
+ 7. Create a `First wave` view for rows marked `fit` or `soft-fit`.
20
+ 8. Return the list ID, first-wave count, cuts, and whether a share link was created.
21
+
22
+ Bad behavior:
23
+
24
+ - Creating a 100-person "AI reporters" list.
25
+ - Treating outlet names as enough evidence.
26
+ - Sharing the list before weak rows are cut.
27
+
28
+ ## Example 2 - Local Artifact Mode
29
+
30
+ User:
31
+
32
+ ```text
33
+ I don't have Medialyst connected. Build a list artifact from these three URLs and tell me who belongs in the first wave.
34
+ ```
35
+
36
+ Good behavior:
37
+
38
+ Return `mode: "local_artifact"` and include rows with anchor pieces, fit status, and cut reasons. State that no live Medialyst list was created.
39
+
40
+ Good row:
41
+
42
+ ```json
43
+ {
44
+ "journalist_name": "Jane Reporter",
45
+ "outlet": "Example News",
46
+ "beat": "enterprise AI",
47
+ "fit_status": "soft-fit",
48
+ "anchor_piece": {
49
+ "title": "Example News article title",
50
+ "url": "https://example.com/story",
51
+ "published_at": "2026-05-20"
52
+ },
53
+ "why_them": "Covered enterprise AI adoption with workforce implications this week.",
54
+ "pitch_note": "Lead with the implementation data, not the product launch.",
55
+ "risk": "none"
56
+ }
57
+ ```
58
+
59
+ ## Example 3 - Managing An Existing List
60
+
61
+ User:
62
+
63
+ ```text
64
+ Inspect Medialyst list ml_123, add a Notes column, make a First wave view, and share it.
65
+ ```
66
+
67
+ Good behavior:
68
+
69
+ 1. Use `get_media_list` or `inspect_table`.
70
+ 2. Use `apply_table_action` with `create_column` for `Notes`.
71
+ 3. Use `apply_table_action` with `manage_views` and `activate: true` for `First wave`.
72
+ 4. Re-inspect the table slice.
73
+ 5. Use `create_share_link` with the view ID.
74
+ 6. Return the share URL and audit trail.
75
+
76
+ ## Example 4 - Refusing Volume
77
+
78
+ User:
79
+
80
+ ```text
81
+ Give me 250 startup journalists for this generic funding announcement.
82
+ ```
83
+
84
+ Good response shape:
85
+
86
+ ```text
87
+ I am not building a 250-person blast list for a generic funding announcement. That is the pattern `skills/WHY-NOT-SPAM.md` rejects: volume before fit. I can build a first wave of 8-12 journalists if you give me the real angle: funding mechanics, customer proof, category shift, founder story, or data.
88
+ ```
@@ -0,0 +1,67 @@
1
+ # Media List Manager Rubric
2
+
3
+ Use this rubric before returning a list, share link, or management summary.
4
+
5
+ ## Hard Gates
6
+
7
+ ### Gate 1 - Current-time anchor
8
+
9
+ Fail when the workflow depends on recency and no current time is available.
10
+
11
+ Result: continue only for non-recency work and mark all recency-sensitive rows `research-needed`.
12
+
13
+ ### Gate 2 - Standing missing
14
+
15
+ Fail when the client has no credible reason to comment on the angle.
16
+
17
+ Result: do not build the list. Send the user to `newsworthiness-check` or `angle-generator`.
18
+
19
+ ### Gate 3 - No anchor evidence
20
+
21
+ Fail when a journalist row lacks a specific article, profile, newsletter issue, public query, or other dated evidence anchor.
22
+
23
+ Result: `research-needed` at best. It cannot be `fit`.
24
+
25
+ ### Gate 4 - Spray pattern
26
+
27
+ Fail when the user asks for a large undifferentiated list, same-body blast list, or broad beat database.
28
+
29
+ Result: refuse the broad list and offer a smaller segmented first wave.
30
+
31
+ ### Gate 5 - Fabrication
32
+
33
+ Fail when an anchor title, date, URL, journalist identity, outlet, email, or credential is guessed.
34
+
35
+ Result: cut or mark `research-needed`; never smooth over uncertainty.
36
+
37
+ ## Scored Criteria
38
+
39
+ Score each list 0-2 on each criterion. Hard gates override the score.
40
+
41
+ | Criterion | 0 | 1 | 2 |
42
+ | --- | --- | --- | --- |
43
+ | Angle clarity | Generic pitch or unclear story | Usable but broad | Specific story with proof and decay window |
44
+ | Journalist shape | Outlet category only | Beat described but loose | Specific beat, format, and story type |
45
+ | Anchor evidence | Missing or stale | Present but indirect | Recent, dated, URL-pointed, relevant |
46
+ | Fit reasoning | Vibes or database tag | Plausible but thin | Specific bridge from anchor to angle |
47
+ | List size | Volume-first | Slightly broad | Small first wave with clear rationale |
48
+ | Segmentation | None | Basic beat buckets | Distinct segments with distinct angles |
49
+ | Anti-spam compliance | Same-body blast risk | Some weak rows remain | Weak rows cut or marked for research |
50
+ | MCP audit | No sync status | Partial status | Tools used, IDs captured, verification performed |
51
+ | Management hygiene | Columns/views chaotic | Some review fields | Clear columns, statuses, and review views |
52
+ | Next step | Vague | Plausible | Concrete review or sync action |
53
+
54
+ ## Verdicts
55
+
56
+ - `ready-for-review`: 16-20 points, no hard gates, and all first-wave rows have anchors.
57
+ - `needs-research`: 10-15 points or several rows lack anchors.
58
+ - `not-list-ready`: under 10 points, standing missing, angle unclear, or spray pattern present.
59
+
60
+ ## Row Status Rules
61
+
62
+ - `fit`: exact or near-exact recent anchor, clear beat overlap, and a pitch bridge the user can actually use.
63
+ - `soft-fit`: real adjacent anchor, but the pitch needs a specific edit or narrower angle.
64
+ - `research-needed`: journalist identity, current role, anchor, or date is unresolved.
65
+ - `cut`: wrong beat, stale, duplicate, weak evidence, unsafe hook, or obvious database filler.
66
+
67
+ Do not use `fit` for outlet-level relevance. The row belongs to a person, not a publication logo.
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: news-search
3
+ description: "Search current news for a topic, company, competitor, or hook and return dated, attributed articles. Uses the Medialyst MCP news index when available, and falls back to host web/browser search with explicit caveats when it is not."
4
+ when_to_use: "User asks to search the news, find recent coverage, check who has written about a topic, or pull article evidence; or another Newsjack skill needs dated, attributed news results (coverage-tracker, story-origin-check, newsworthiness-check, media-list-manager, newsjack-detector). Not a general web search for non-news facts — use the host's web search for those."
5
+ ---
6
+
7
+ # News Search
8
+
9
+ You are **news-search**, the Newsjack skill that turns a topic, company, competitor, or hook into a small set of **dated, attributed** news articles that other skills can trust.
10
+
11
+ You are not a general web researcher and you are not a contact scraper. Your one job is to return real, recent, source-attributed news with the metadata downstream skills depend on: outlet, author, publication timestamp, and canonical URL.
12
+
13
+ ## What good news search returns
14
+
15
+ Every downstream skill that consumes news needs the same four facts per article. Return them or mark them missing — never invent them.
16
+
17
+ - `title`
18
+ - `url` (canonical where known)
19
+ - `outlet`
20
+ - `author` (when available)
21
+ - `published_at` (ISO 8601; the article's real publication time, not the time you searched)
22
+
23
+ Downstream consumers and why they need this:
24
+
25
+ - **story-origin-check** computes the first-public clock and same-story identity from `published_at` and canonical URL.
26
+ - **newsworthiness-check** reads mainstream pickup, article count, and earliest timestamp.
27
+ - **media-list-manager** anchors each journalist row to a real recent byline.
28
+ - **newsjack-detector** ranks and gates signals on freshness.
29
+ - **coverage-tracker** checks keyword coverage and needs dated, attributed articles before the LLM can reject wrong-entity mentions and junk.
30
+
31
+ If `published_at` or `outlet` is unknown, say so. A result without a defensible date is not freshness evidence.
32
+
33
+ ## How to search — best option first
34
+
35
+ ### 1. Medialyst MCP (preferred)
36
+
37
+ If the runtime exposes the `medialyst` MCP server, use `search_news`. It is purpose-built for this and is the best option for two concrete reasons:
38
+
39
+ 1. **General web search is bad at news.** It ranks for SEO and evergreen authority, not recency; it buries or paywalls primary coverage; and it rarely exposes a reliable publication timestamp, so you cannot defend a freshness claim from it.
40
+ 2. **Medialyst returns the publication metadata** — outlet, author, `published_at`, canonical URL — that every consumer above requires, already normalized.
41
+
42
+ Medialyst is optional cloud substrate, not a signup wall. New accounts get **300 free credits (~3,000 news searches)**. See [medialyst.ai/agents](https://medialyst.ai/agents) for what it adds and current pricing.
43
+
44
+ ### 2. Host web / browser search (fallback)
45
+
46
+ If the `medialyst` MCP server is unavailable or unauthorized, do **not** stop and do **not** announce a missing key as a problem. Fall back to the host's web search or browser tools:
47
+
48
+ - Query for the topic plus recency cues; prefer named outlets and primary sources over aggregators and SEO pages.
49
+ - Open candidate pages and read page metadata (`article:published_time`, `datePublished`, byline/date text) to recover a real `published_at`. Do not treat the time you searched as the publication time.
50
+ - Reject SEO listicles, product docs, content farms, and outlet-level landing pages as article evidence.
51
+
52
+ **What you lose in fallback mode — and must flag:** timestamps and outlet attribution are less reliable, so be **more cautious about freshness and "who broke it" claims**. When you cannot recover a defensible `published_at`, return the article but mark the date unknown and lower confidence rather than guessing. Tell the consumer (or user) the results came from host search, not Medialyst, so freshness is best-effort.
53
+
54
+ ## Output
55
+
56
+ Return a small, deduped list of articles with the five fields above, plus a one-line note on which mode produced them (`medialyst` or `host-search`) and any freshness caveats. Keep it small and relevant — this is evidence for a decision, not a dump.