@opendirectory.dev/skills 0.1.50 → 0.1.52

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.
@@ -0,0 +1,166 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <title>[SUBJECT]</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
9
+ <!--[if mso]>
10
+ <noscript><xml><o:OfficeDocumentSettings><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml></noscript>
11
+ <![endif]-->
12
+ <style>
13
+ @media only screen and (max-width: 600px) {
14
+ .container { width: 100% !important; }
15
+ .hero-h1 { font-size: 30px !important; }
16
+ .h2 { font-size: 28px !important; }
17
+ .pad { padding-left: 24px !important; padding-right: 24px !important; }
18
+ }
19
+ </style>
20
+ </head>
21
+ <body style="margin:0;padding:0;background-color:#F0F0EE;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;">
22
+
23
+ <!-- Preview text -->
24
+ <span style="display:none;max-height:0;overflow:hidden;opacity:0;font-size:1px;color:#F0F0EE;">[PREVIEW TEXT]</span>
25
+
26
+ <table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:#F0F0EE;">
27
+ <tr>
28
+ <td align="center" style="padding:32px 16px;">
29
+
30
+ <table class="container" width="600" cellpadding="0" cellspacing="0" border="0" style="max-width:600px;width:100%;background-color:#FFFFFF;">
31
+
32
+
33
+ <!-- ══════════════════════════════════════════════════════
34
+ SECTION: HEADER
35
+ ═══════════════════════════════════════════════════════ -->
36
+ <tr>
37
+ <td bgcolor="#1A1A1A" style="background-color:#1A1A1A;padding:20px 40px;">
38
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
39
+ <tr>
40
+ <td style="font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-size:20px;font-weight:400;color:#FFFFFF;letter-spacing:-0.01em;">[BRAND NAME]</td>
41
+ <td align="right" style="font-family:Inter,Arial,Helvetica,sans-serif;font-size:11px;font-weight:500;color:#888888;letter-spacing:0.14em;text-transform:uppercase;white-space:nowrap;">Issue #[N] &nbsp;|&nbsp; [DATE]</td>
42
+ </tr>
43
+ </table>
44
+ </td>
45
+ </tr>
46
+
47
+ <!-- Brand strip -->
48
+ <tr>
49
+ <td bgcolor="[BRAND_COLOR]" style="background-color:[BRAND_COLOR];height:3px;font-size:1px;line-height:1px;">&nbsp;</td>
50
+ </tr>
51
+
52
+
53
+ <!-- ══════════════════════════════════════════════════════
54
+ SECTION: HERO (light — white bg)
55
+ ═══════════════════════════════════════════════════════ -->
56
+ <tr>
57
+ <td class="pad" bgcolor="#FFFFFF" style="background-color:#FFFFFF;padding:56px 40px 48px;">
58
+ <p style="margin:0 0 16px 0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:11px;font-weight:600;color:[BRAND_COLOR];letter-spacing:0.22em;text-transform:uppercase;">[CATEGORY LABEL]</p>
59
+ <h1 class="hero-h1" style="margin:0 0 20px 0;font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-size:46px;font-weight:400;line-height:1.05;color:#111111;letter-spacing:-0.02em;">[HERO HEADLINE]</h1>
60
+ <p style="margin:0 0 32px 0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:17px;line-height:1.6;color:#666666;">[HERO HOOK]</p>
61
+ <table cellpadding="0" cellspacing="0" border="0">
62
+ <tr>
63
+ <td align="center" bgcolor="#111111" style="background-color:#111111;border-radius:8px;">
64
+ <a href="[CTA_URL]" target="_blank" style="display:inline-block;padding:14px 32px;font-family:Inter,Arial,Helvetica,sans-serif;font-size:15px;font-weight:600;color:#FFFFFF;text-decoration:none;letter-spacing:0.01em;">[CTA BUTTON TEXT] &rarr;</a>
65
+ </td>
66
+ </tr>
67
+ </table>
68
+ </td>
69
+ </tr>
70
+
71
+
72
+ <!-- ══════════════════════════════════════════════════════
73
+ SECTION: INTRO
74
+ ═══════════════════════════════════════════════════════ -->
75
+ <tr>
76
+ <td class="pad" bgcolor="#FFFFFF" style="background-color:#FFFFFF;padding:32px 40px 0;">
77
+ <p style="margin:0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:16px;line-height:1.7;color:#555555;">[INTRO TEXT]</p>
78
+ </td>
79
+ </tr>
80
+
81
+
82
+ <!-- DIVIDER -->
83
+ <tr>
84
+ <td bgcolor="#FFFFFF" style="background-color:#FFFFFF;padding:32px 40px 0;">
85
+ <hr style="border:none;border-top:1px solid #EEEEEE;margin:0;">
86
+ </td>
87
+ </tr>
88
+
89
+
90
+ <!-- ══════════════════════════════════════════════════════
91
+ SECTION: MAIN CONTENT
92
+ ═══════════════════════════════════════════════════════ -->
93
+ <tr>
94
+ <td class="pad" bgcolor="#FFFFFF" style="background-color:#FFFFFF;padding:32px 40px 8px;">
95
+ <p style="margin:0 0 18px 0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:15px;line-height:1.75;color:#444444;"><strong style="color:#111111;font-weight:700;">[BOLD CALLOUT]</strong> [paragraph]</p>
96
+ <p style="margin:0 0 18px 0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:15px;line-height:1.75;color:#444444;"><strong style="color:#111111;font-weight:700;">[BOLD CALLOUT]</strong> [paragraph]</p>
97
+ <p style="margin:0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:15px;line-height:1.75;color:#444444;"><strong style="color:#111111;font-weight:700;">[BOLD CALLOUT]</strong> [paragraph]</p>
98
+ </td>
99
+ </tr>
100
+
101
+
102
+ <!-- ══════════════════════════════════════════════════════
103
+ SECTION: STAT CALLOUT (light version)
104
+ ═══════════════════════════════════════════════════════ -->
105
+ <tr>
106
+ <td class="pad" bgcolor="#FFFFFF" style="background-color:#FFFFFF;padding:24px 40px;">
107
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
108
+ <tr>
109
+ <td bgcolor="#F8F8F6" style="background-color:#F8F8F6;border-left:3px solid [BRAND_COLOR];padding:22px 24px;border-radius:0 6px 6px 0;">
110
+ <p style="margin:0 0 8px 0;font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-size:22px;font-weight:400;line-height:1.3;color:#111111;">"[STAT OR QUOTE]"</p>
111
+ <p style="margin:0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:12px;color:#999999;">[SOURCE]</p>
112
+ </td>
113
+ </tr>
114
+ </table>
115
+ </td>
116
+ </tr>
117
+
118
+
119
+ <!-- ══════════════════════════════════════════════════════
120
+ SECTION: CTA CALLOUT CARD (light — dark card)
121
+ ═══════════════════════════════════════════════════════ -->
122
+ <tr>
123
+ <td class="pad" bgcolor="#FFFFFF" style="background-color:#FFFFFF;padding:8px 32px 48px;">
124
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
125
+ <tr>
126
+ <td bgcolor="#111111" style="background-color:#111111;border-radius:12px;padding:48px 40px;text-align:center;">
127
+ <h2 style="margin:0 0 12px 0;font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-size:36px;font-weight:400;line-height:1.05;color:#F2F2F2;letter-spacing:-0.02em;">[CTA CALLOUT HEADLINE]</h2>
128
+ <p style="margin:0 0 28px 0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:16px;line-height:1.55;color:#AAAAAA;">[CTA CALLOUT BODY]</p>
129
+ <table cellpadding="0" cellspacing="0" border="0" style="margin:0 auto;">
130
+ <tr>
131
+ <td align="center" bgcolor="[BRAND_COLOR]" style="background-color:[BRAND_COLOR];border-radius:8px;">
132
+ <a href="[CTA_URL]" target="_blank" style="display:inline-block;padding:14px 32px;font-family:Inter,Arial,Helvetica,sans-serif;font-size:15px;font-weight:700;color:#0A0A0A;text-decoration:none;">[CTA BUTTON TEXT]</a>
133
+ </td>
134
+ </tr>
135
+ </table>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+ </td>
140
+ </tr>
141
+
142
+
143
+ <!-- ══════════════════════════════════════════════════════
144
+ SECTION: FOOTER (light)
145
+ ═══════════════════════════════════════════════════════ -->
146
+ <tr>
147
+ <td bgcolor="#F8F8F6" style="background-color:#F8F8F6;border-top:1px solid #EEEEEE;padding:36px 40px 44px;">
148
+ <p style="margin:0 0 6px 0;font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-size:18px;font-weight:400;color:#111111;text-align:center;">[BRAND NAME]</p>
149
+ <p style="margin:0 0 24px 0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:12px;line-height:1.5;color:#AAAAAA;text-align:center;">[COMPANY NAME] &nbsp;&middot;&nbsp; [CITY, COUNTRY]</p>
150
+ <hr style="border:none;border-top:1px solid #E8E8E8;margin:0 auto 24px;width:96px;">
151
+ <p style="margin:0;font-family:Inter,Arial,Helvetica,sans-serif;font-size:12px;line-height:1.5;color:#BBBBBB;text-align:center;">
152
+ <a href="[UNSUBSCRIBE_URL]" style="color:#AAAAAA;text-decoration:underline;">Unsubscribe</a>
153
+ &nbsp;&nbsp;|&nbsp;&nbsp;
154
+ <a href="[PREFERENCES_URL]" style="color:#AAAAAA;text-decoration:underline;">Manage preferences</a>
155
+ </p>
156
+ </td>
157
+ </tr>
158
+
159
+
160
+ </table>
161
+ </td>
162
+ </tr>
163
+ </table>
164
+
165
+ </body>
166
+ </html>
@@ -0,0 +1,7 @@
1
+ # linkedin-job-post-to-buyer-pain-map — Environment Variables
2
+ # ============================================================
3
+ # An LLM is required for pain map analysis and scoring.
4
+
5
+ # Required: Gemini API key for signal analysis and pain inference
6
+ # Get it: aistudio.google.com, Get API key
7
+ GEMINI_API_KEY=your_gemini_api_key_here
@@ -0,0 +1,144 @@
1
+ # linkedin-job-post-to-buyer-pain-map
2
+
3
+ <img src="cover.png" width="100%" alt="LinkedIn Job Post to Buyer Pain Map — Signal Decoder for GTM Teams" />
4
+
5
+ Turn LinkedIn job posts into an actionable buyer pain map with signal strength, urgency, and outreach angles for each account.
6
+
7
+ ## What It Does
8
+
9
+ - Parses 1–15 pasted job descriptions and groups them by company
10
+ - Extracts team, seniority, responsibility emphasis, requirement language, and tool/stack hints from each post
11
+ - Infers primary and secondary operational pains with cited evidence from the job text
12
+ - Scores each account on 3 dimensions: signal strength (1–10), urgency (1–10), ICP fit (1–10)
13
+ - Computes an overall priority score (10–100) using a transparent weighted formula
14
+ - Determines buy-vs-build posture and company stage from hiring language
15
+ - Generates 1–3 actionable outreach angles per account with talk-track bullets
16
+ - Produces a structured handoff object ready for `outreach-sequence-builder` consumption
17
+
18
+ ## Requirements
19
+
20
+ | Requirement | Purpose | How to Set Up |
21
+ |------------|---------|--------------|
22
+ | Gemini API key | Signal analysis, scoring, and pain inference | aistudio.google.com → Get API key |
23
+
24
+ ## Setup
25
+
26
+ ```bash
27
+ cp .env.example .env
28
+ ```
29
+
30
+ Fill in `GEMINI_API_KEY` (required).
31
+
32
+ No other dependencies. The skill runs entirely through agent instructions and Gemini API calls.
33
+
34
+ ## How to Use
35
+
36
+ Analyze a single job post:
37
+
38
+ ```
39
+ "Analyze this job post for buyer pain. My product is [X]. ICP: [Y]. Here's the post: [paste job description]"
40
+ ```
41
+
42
+ Batch analysis of multiple posts:
43
+
44
+ ```
45
+ "Build a pain map from these 5 job posts. Product: [X]. ICP: [Y]. Posts: [paste all posts]"
46
+ ```
47
+
48
+ Focus on positioning angles:
49
+
50
+ ```
51
+ "Decode these hiring descriptions for positioning angles. Focus on positioning. Product: [X]. ICP: [Y]. Posts: [paste posts]"
52
+ ```
53
+
54
+ Handoff to outreach:
55
+
56
+ ```
57
+ "Analyze these job posts and give me a handoff I can pass to outreach-sequence-builder"
58
+ ```
59
+
60
+ ## Input Format
61
+
62
+ Each job post should include at minimum:
63
+ - **Company name** and **job title** (required)
64
+ - **Job description text** — the full pasted content (required)
65
+ - Location, seniority, team/function, URL (optional — inferred if missing)
66
+
67
+ Posts can be pasted as plain text, numbered lists, or structured JSON objects.
68
+
69
+ ## Output
70
+
71
+ For each company analyzed, the skill produces:
72
+
73
+ 1. **Summary** — headline, overall score, score breakdown with explanations, stage guess, buy-vs-build posture
74
+ 2. **Buyer Pain Map** — primary and secondary pains, each with label, description, and cited evidence
75
+ 3. **Outreach Angles** — 1–3 angles with narrative and talk-track bullets
76
+ 4. **Handoff** — structured block for outreach-sequence-builder (account summary, key pain, personas, tone)
77
+
78
+ Reports are saved to `docs/pain-maps/` as dated markdown files.
79
+
80
+ ## Scoring Model
81
+
82
+ | Dimension | Weight | Measures |
83
+ |-----------|--------|----------|
84
+ | Signal Strength | 40% | Density and specificity of relevant hiring signals |
85
+ | Urgency | 30% | Time-sensitivity indicators in the job text |
86
+ | ICP Fit | 30% | Company profile match to user's ICP description |
87
+
88
+ **Overall Score** = `round((0.4 × signal + 0.3 × urgency + 0.3 × icp_fit) × 10)` → 10–100 scale.
89
+
90
+ See `references/scoring-rubric.md` for full scoring rules and modifiers.
91
+
92
+ ## Plays Well With
93
+
94
+ | Skill | How |
95
+ |-------|-----|
96
+ | `outreach-sequence-builder` | Feed the handoff block as input context to generate a multi-channel outreach sequence |
97
+ | `noise-to-linkedin-carousel` | Use primary pains and evidence quotes as content source material |
98
+ | `reddit-icp-monitor` | Cross-reference pain themes from job posts with Reddit discussions |
99
+
100
+ ## When NOT to Use
101
+
102
+ - Need to **find** companies hiring → use `linkedin-hiring-intent-scanner` or `yc-intent-radar-skill`
103
+ - Need to **write** outreach messages → use `outreach-sequence-builder`
104
+ - Need to **monitor** platforms for signals → use `reddit-icp-monitor` or `twitter-GTM-find-skill`
105
+ - Need contact data or email enrichment → this skill does not provide that
106
+
107
+ ## Project Structure
108
+
109
+ ```
110
+ linkedin-job-post-to-buyer-pain-map/
111
+ ├── SKILL.md
112
+ ├── README.md
113
+ ├── .env.example
114
+ ├── cover.png
115
+ ├── evals/
116
+ │ └── evals.json
117
+ └── references/
118
+ ├── scoring-rubric.md
119
+ └── examples.md
120
+ ```
121
+
122
+ ## License
123
+
124
+ MIT
125
+
126
+ ## Installation in Claude Desktop App
127
+
128
+ ### Video Tutorial
129
+ Watch this quick video to see how it's done:
130
+
131
+ https://github.com/user-attachments/assets/ee98a1b5-ebc4-452f-bbfb-c434f2935067
132
+
133
+ ### Step 1: Download the skill from GitHub
134
+ 1. Copy the URL of this specific skill folder from your browser's address bar.
135
+ 2. Go to [download-directory.github.io](https://download-directory.github.io/).
136
+ 3. Paste the URL and click **Enter** to download.
137
+
138
+ ### Step 2: Install the Skill in Claude
139
+ 1. Open your **Claude desktop app**.
140
+ 2. Go to the sidebar on the left side and click on the **Customize** section.
141
+ 3. Click on the **Skills** tab, then click on the **+** (plus) icon button to create a new skill.
142
+ 4. Choose the option to **Upload a skill**, and drag and drop the `.zip` file (or you can extract it and drop the folder, both work).
143
+
144
+ > **Note:** Always make sure you are uploading the specific folder that contains the `SKILL.md` file!
@@ -0,0 +1,301 @@
1
+ ---
2
+ name: linkedin-job-post-to-buyer-pain-map
3
+ description: Takes pasted LinkedIn job posts or hiring descriptions and converts them into a structured buyer pain map with inferred pains, capability gaps, buy-vs-build signal, account priority scores, and suggested outreach angles. Use when asked to analyze hiring posts, decode job descriptions for buyer intent, build a pain map from job listings, extract GTM signals from hiring activity, or prioritize accounts based on hiring data. Trigger when a user says "analyze these job posts", "what pain does this hiring signal", "build a pain map from these listings", "decode this job description", or "score these accounts from their hiring".
4
+ author: ajaycodesitbetter
5
+ version: 1.0.0
6
+ ---
7
+
8
+ # LinkedIn Job Post to Buyer Pain Map
9
+
10
+ Take LinkedIn job posts. Decode them into a structured buyer pain map with scores, pains, and outreach angles.
11
+
12
+ ---
13
+
14
+ **Critical rule:** Every inferred pain must cite specific language from the job description that supports it. Never hallucinate pains that are not grounded in the text. If a post is too generic to infer pain, say so explicitly and assign a low signal strength score.
15
+
16
+ **Ethical rule:** Do not infer personal attributes or protected characteristics about candidates. Focus strictly on company-level operational pain and organizational needs.
17
+
18
+ ---
19
+
20
+ ## Step 1: Setup Check
21
+
22
+ Confirm required env vars:
23
+
24
+ ```bash
25
+ echo "GEMINI_API_KEY: ${GEMINI_API_KEY:+set}"
26
+ ```
27
+
28
+ **If GEMINI_API_KEY is missing:**
29
+ Stop. Tell the user: "GEMINI_API_KEY is required. Get it at aistudio.google.com. Add it to your .env file."
30
+
31
+ ---
32
+
33
+ ## Step 2: Collect Inputs
34
+
35
+ The skill needs 3 required inputs. Collect them before proceeding.
36
+
37
+ ### 2a: Product Brief
38
+
39
+ Ask: "Describe your product in 2-5 sentences. What do you do, what is your core value prop, and who do you target?"
40
+
41
+ **If the user already included this in their prompt:** Extract it. Confirm: "Product brief captured: [summary]."
42
+
43
+ ### 2b: ICP Description
44
+
45
+ Ask: "Describe your ideal customer profile in 2-6 bullets: industries, company sizes, roles you sell to, tech stack hints."
46
+
47
+ **If the user already included this in their prompt:** Extract it. Confirm: "ICP captured: [summary]."
48
+
49
+ ### 2c: Hiring Posts
50
+
51
+ Ask: "Paste the job descriptions you want analyzed. For each post, include the company name, job title, and the full description text. You can paste 1-15 posts."
52
+
53
+ **Accepted formats:**
54
+ - Raw pasted text with company name and job title clearly labeled
55
+ - Structured JSON objects with fields: `company_name`, `job_title`, `location` (optional), `seniority` (optional), `team_or_function` (optional), `job_description_text`, `job_url` (optional)
56
+ - Multiple posts separated by clear delimiters (--- or numbered)
57
+
58
+ **If any field is missing:** Infer what you can from the description text. If company_name or job_description_text is missing, ask for it before proceeding.
59
+
60
+ ### 2d: Optional Inputs
61
+
62
+ If the user provides any of these, capture them:
63
+ - `account_notes`: additional context per company (funding, tech stack, known tools, contacts)
64
+ - `focus_dimension`: "pipeline" (bias toward scoring and prioritization), "positioning" (bias toward messaging angles), or "both" (default)
65
+
66
+ ---
67
+
68
+ ## Step 3: Extract Signals
69
+
70
+ For each job post, parse and extract:
71
+
72
+ 1. **Team / function:** Which team is this role on? (GTM, Product, Infra, Data, RevOps, CS, Engineering, etc.)
73
+ 2. **Seniority:** IC, Senior IC, Manager, Director, VP, C-level
74
+ 3. **Responsibilities emphasis:** Classify the dominant mode:
75
+ - Fire-fighting: "stabilize", "fix", "reduce downtime", "unblock"
76
+ - Building new: "build from scratch", "0→1", "greenfield", "design and implement"
77
+ - Optimizing: "scale", "optimize", "improve efficiency", "automate"
78
+ - Replacing: "replace legacy", "migrate from", "modernize"
79
+ 4. **Requirement language:** Note keywords that signal intent: "first X hire", "critical role", "immediate", "must have"
80
+ 5. **Tool / stack hints:** Any references to specific tools, platforms, or technology categories that overlap with the user's product area
81
+
82
+ **Group by company.** If multiple posts come from the same company, group their signals together.
83
+
84
+ State: "Extracted signals from X posts across Y companies."
85
+
86
+ ---
87
+
88
+ ## Step 4: Score with the LLM
89
+
90
+ Read `references/scoring-rubric.md` for the full scoring model.
91
+
92
+ Build the LLM request:
93
+
94
+ ```bash
95
+ cat > /tmp/pain-map-score-request.json << 'ENDJSON'
96
+ {
97
+ "system_instruction": {
98
+ "parts": [{
99
+ "text": "You are a GTM analyst who specializes in decoding hiring signals into buyer intent. For each account provided, you will score three dimensions and infer company context. Rules: (1) Every score must include a one-sentence plain-text explanation. (2) signal_strength measures how many and how specific the hiring signals are relative to the user's product area. (3) urgency measures how time-sensitive the hiring need appears. (4) icp_fit measures how closely the company matches the user's ICP description. (5) Each score is 1-10. (6) overall_score = round((0.4 * signal_strength + 0.3 * urgency + 0.3 * icp_fit) * 10). (7) Infer buy_vs_build from job language. Use EXACTLY one of these labels: 'Leaning build', 'Leaning buy', 'Hybrid (buy-and-build)', 'Unknown'. (8) Infer stage_guess from company clues: funding stage, employee count, company type. (9) Output valid JSON only."
100
+ }]
101
+ },
102
+ "contents": [{
103
+ "parts": [{
104
+ "text": "SCORING_CONTEXT_HERE"
105
+ }]
106
+ }],
107
+ "generationConfig": {
108
+ "temperature": 0.2,
109
+ "maxOutputTokens": 4096
110
+ }
111
+ }
112
+ ENDJSON
113
+ curl -s -X POST \
114
+ "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
115
+ -H "Content-Type: application/json" \
116
+ -d @/tmp/pain-map-score-request.json \
117
+ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['candidates'][0]['content']['parts'][0]['text'])"
118
+ ```
119
+
120
+ Replace `SCORING_CONTEXT_HERE` with:
121
+ - The product brief and ICP description from Step 2
122
+ - The extracted signals per company from Step 3
123
+ - The scoring rubric rules from `references/scoring-rubric.md`
124
+ - Instructions to output JSON with: `company_name`, `headline`, `overall_score`, `score_breakdown` (signal_strength, urgency, icp_fit — each with score and explanation), `stage_guess`, `buy_vs_build_guess`
125
+
126
+ ---
127
+
128
+ ## Step 5: Build Pain Map
129
+
130
+ For each account, use the extracted signals and LLM scoring context to build the buyer pain map.
131
+
132
+ ```bash
133
+ cat > /tmp/pain-map-analysis-request.json << 'ENDJSON'
134
+ {
135
+ "system_instruction": {
136
+ "parts": [{
137
+ "text": "You are a B2B pain analyst who reads job descriptions and identifies the operational pains a company is experiencing. Rules: (1) Every pain must have a short label, a 1-3 sentence description, and specific phrases quoted from the job post as supporting evidence. (2) Classify pains as primary (directly relevant to the user's product) or secondary (real pain but tangential to the product). (3) If a post is too generic to infer specific pain, state that explicitly — do not hallucinate. (4) For each account, also generate 1-3 recommended outreach angles. Each angle has: angle_name (short), narrative (1-2 sentences on how to lead), and talk_track_bullets (2-4 concrete talking points). (5) Outreach angles must reference specific pains and evidence, not generic value props. No banned words: synergy, leverage, innovative, cutting-edge, best-in-class, world-class, game-changing, disruptive, seamless, robust, comprehensive, revolutionize, transform, streamline. (6) Output valid JSON only."
138
+ }]
139
+ },
140
+ "contents": [{
141
+ "parts": [{
142
+ "text": "ANALYSIS_CONTEXT_HERE"
143
+ }]
144
+ }],
145
+ "generationConfig": {
146
+ "temperature": 0.4,
147
+ "maxOutputTokens": 8192
148
+ }
149
+ }
150
+ ENDJSON
151
+ curl -s -X POST \
152
+ "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
153
+ -H "Content-Type: application/json" \
154
+ -d @/tmp/pain-map-analysis-request.json \
155
+ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['candidates'][0]['content']['parts'][0]['text'])"
156
+ ```
157
+
158
+ Replace `ANALYSIS_CONTEXT_HERE` with:
159
+ - The product brief and ICP description
160
+ - Each company's job posts (full text)
161
+ - The scores and context from Step 4
162
+ - Account notes if provided
163
+ - The focus_dimension preference (pipeline / positioning / both)
164
+ - Instructions to output per-account: `buyer_pain_map` (primary_pains, secondary_pains) and `recommended_outreach_angles`
165
+
166
+ Read `references/examples.md` to calibrate the expected output quality and depth.
167
+
168
+ ---
169
+
170
+ ## Step 6: Build Handoff Object
171
+
172
+ For each account, generate a structured handoff block that `outreach-sequence-builder` can consume directly:
173
+
174
+ ```
175
+ handoff:
176
+ for_outreach_sequence_builder:
177
+ account_summary: 2-3 sentence recap of the company's situation and hiring context
178
+ key_pain: The single most actionable pain in one sentence
179
+ suggested_personas: 2-4 job titles of the people most likely to own this pain
180
+ tone: One sentence describing the recommended outreach tone
181
+ ```
182
+
183
+ The handoff must be concrete enough that someone could paste it into outreach-sequence-builder's prompt and get a usable sequence without re-researching the account.
184
+
185
+ ---
186
+
187
+ ## Step 7: Self-QA
188
+
189
+ Run every check and fix violations before presenting:
190
+
191
+ - [ ] Every inferred pain cites at least one specific phrase from the job description
192
+ - [ ] No pains hallucinated for generic/low-signal posts (check posts with signal_strength ≤ 3)
193
+ - [ ] All three scores (signal_strength, urgency, icp_fit) have a one-sentence explanation
194
+ - [ ] Overall score matches the formula: `round((0.4 × signal + 0.3 × urgency + 0.3 × icp_fit) × 10)`
195
+ - [ ] Buy-vs-build label is one of: "Leaning build", "Leaning buy", "Hybrid (buy-and-build)", "Unknown"
196
+ - [ ] No banned words in outreach angles: synergy, leverage, innovative, cutting-edge, best-in-class, world-class, game-changing, disruptive, seamless, robust, comprehensive, revolutionize, transform, streamline
197
+ - [ ] Each outreach angle has 2-4 talk track bullets, not generic value statements
198
+ - [ ] Out-of-ICP accounts are flagged with a clear recommendation to deprioritize
199
+ - [ ] Handoff objects are complete with all 4 fields (account_summary, key_pain, suggested_personas, tone)
200
+ - [ ] No personal attributes or protected characteristics inferred about candidates
201
+ - [ ] Posts grouped by company when multiple posts are from the same company
202
+
203
+ Fix any violation before presenting.
204
+
205
+ ---
206
+
207
+ ## Step 8: Output and Save
208
+
209
+ ### Human-readable output
210
+
211
+ Present the full analysis in this format:
212
+
213
+ ```
214
+ ## Buyer Pain Map — [YYYY-MM-DD]
215
+
216
+ **Product:** [product name from brief]
217
+ **Posts analyzed:** X posts across Y companies
218
+ **Focus:** [pipeline / positioning / both]
219
+
220
+ ---
221
+
222
+ ### [Company Name] — Score: [N]/100
223
+
224
+ **Headline:** [one-line summary of what the hiring reveals]
225
+
226
+ | Dimension | Score | Explanation |
227
+ |-----------|-------|-------------|
228
+ | Signal Strength | N/10 | [one sentence] |
229
+ | Urgency | N/10 | [one sentence] |
230
+ | ICP Fit | N/10 | [one sentence] |
231
+
232
+ **Stage:** [stage guess] | **Buy-vs-Build:** [posture label]
233
+
234
+ #### Primary Pains
235
+ - **[Pain label]:** [1-3 sentence description]
236
+ - Evidence: "[quoted phrase from job post]"
237
+
238
+ #### Secondary Pains
239
+ - **[Pain label]:** [1-3 sentence description]
240
+ - Evidence: "[quoted phrase from job post]"
241
+
242
+ #### Recommended Outreach Angles
243
+ 1. **[Angle name]:** [narrative]
244
+ - [bullet 1]
245
+ - [bullet 2]
246
+ - [bullet 3]
247
+
248
+ #### Handoff → outreach-sequence-builder
249
+ > **Summary:** [2-3 sentences]
250
+ > **Key pain:** [one sentence]
251
+ > **Suggested personas:** [list]
252
+ > **Tone:** [one sentence]
253
+
254
+ ---
255
+
256
+ [repeat for each company, ordered by overall_score descending]
257
+ ```
258
+
259
+ ### Save to file
260
+
261
+ ```bash
262
+ mkdir -p docs/pain-maps
263
+ OUTFILE="docs/pain-maps/$(date +%Y-%m-%d).md"
264
+ cat > "$OUTFILE" << 'EOF'
265
+ REPORT_CONTENT_HERE
266
+ EOF
267
+ echo "Pain map saved to $OUTFILE"
268
+ ```
269
+
270
+ If multiple companies are analyzed, also save individual files using slugified company names (lowercase, replace spaces and special characters with hyphens, strip trailing hyphens):
271
+
272
+ e.g., "ACME, Inc." → `acme-inc.md`, "CoolStartup Inc" → `coolstartup-inc.md`
273
+
274
+ ```bash
275
+ SLUG=$(echo "COMPANY_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/-$//')
276
+ cat > "docs/pain-maps/${SLUG}.md" << 'EOF'
277
+ INDIVIDUAL_ACCOUNT_CONTENT_HERE
278
+ EOF
279
+ ```
280
+
281
+ ---
282
+
283
+ ## When to Use
284
+
285
+ - You have 1-15 pasted job descriptions and want to know what pain each company is feeling
286
+ - You are planning account-based outreach and need structured pain analysis before writing sequences
287
+ - You want to prioritize which hiring-signal accounts to pursue first
288
+ - A PMM wants real-world pain language from job posts to refine positioning
289
+
290
+ ## When NOT to Use
291
+
292
+ - You need to **find** companies that are hiring (use `linkedin-hiring-intent-scanner` or `yc-intent-radar-skill` instead)
293
+ - You need to **write outreach messages** (use `outreach-sequence-builder` instead — feed it the handoff from this skill)
294
+ - You want to **monitor** a platform for signals over time (use `reddit-icp-monitor` or `twitter-GTM-find-skill` instead)
295
+ - You need contact information or email enrichment (this skill does not provide that)
296
+
297
+ ## Plays Well With
298
+
299
+ - **outreach-sequence-builder**: Pass the `handoff.for_outreach_sequence_builder` block directly as context when building a sequence.
300
+ - **noise-to-linkedin-carousel**: Use the primary pains and evidence quotes as source material for a carousel about buyer problems.
301
+ - **reddit-icp-monitor**: Cross-reference pain themes from job posts with pain themes showing up in Reddit discussions.