{"id":"8aeb5042-c3f6-4874-9568-f030ce2a22ea","shortId":"vWX6ND","kind":"skill","title":"where-your-customer-lives","tagline":"Given a product utility and ICP, researches the internet to find the specific channels. Where your customer actually lives, ranked by reachability with a full per-channel playbook. Returns evidence that your ICP is there, one entry tactic, one content angle, and specific anti-pat","description":"# Where Your Customer Lives\n\nGiven a product utility and ICP, trace real ICP pain posts back to their source communities. Layer in competitor discussion signals. Discover Slack/Discord/newsletter/podcast/conference channels via DuckDuckGo. Score every channel by ICP signal count, size, activity, and competitor presence. Output a ranked playbook: evidence, entry tactic, content angle, anti-patterns -- one per channel. No guessing. Signal-traced channels only.\n\n---\n\n**Critical rule:** Every channel name in the output must exist in either the Reddit API response or DuckDuckGo search results from this run. Every member count must come from the `about.json` API or a search snippet -- never estimated. Every ICP signal count must match the raw data. If a channel type returns 0 results, report 0 -- do not fabricate channels.\n\n---\n\n## Common Mistakes\n\n| The agent will want to... | Why that's wrong |\n|---|---|\n| Recommend generic channels (\"LinkedIn\", \"Twitter\") | Every channel must be specific with a name, member count, and URL. \"LinkedIn Group: DevOps for Enterprise Teams (45K members)\" -- not just \"LinkedIn\". |\n| Use the same channels for every ICP | Signal-trace is ICP-specific. A DevOps ICP and a Finance ICP produce entirely different channel lists. Run the script fresh per ICP. |\n| Invent member counts or community names | Every channel name must come from DuckDuckGo results or Reddit API. Every member count must come from the API or a search snippet. If unavailable, write \"member count not found\". |\n| Skip the competitor layer | Where competitors are discussed = your ICP is evaluating alternatives = hottest outreach context. Always run competitor search even if the user did not ask. |\n| Write entry tactics that are product pitches | \"Post about your product in r/devops\" is not an entry tactic. Entry tactics name the specific thread type, content format, and community norm. |\n| Treat Reddit as the only channel type | The output must include at least 3 channel types. If only Reddit is found, explicitly search DuckDuckGo for Slack/Discord/newsletter/conference before stopping. |\n\n---\n\n## Step 1: Setup Check\n\n```bash\necho \"GITHUB_TOKEN: ${GITHUB_TOKEN:-not set -- competitor layer runs at 60 req/hr unauthenticated}\"\necho \"\"\necho \"Data sources this run will use:\"\necho \"  Reddit public JSON   (no auth, signal-trace)\"\necho \"  Reddit about.json    (no auth, subreddit metadata)\"\necho \"  HN Algolia API       (no auth, signal-trace)\"\necho \"  DuckDuckGo HTML      (no auth, channel discovery)\"\necho \"  GitHub API           (${GITHUB_TOKEN:+authenticated, }optional for competitor enrichment)\"\n```\n\nIf `GITHUB_TOKEN` is not set: continue. All core channel discovery works without it.\n\n---\n\n## Step 2: Parse ICP\n\nCollect from the conversation:\n- `product` -- what the product does (one sentence)\n- `icp_role` -- who the ICP is (e.g. \"technical co-founders\", \"DevOps engineers at Series A\")\n- `icp_pain` -- their primary problem (e.g. \"customer acquisition\", \"alert fatigue\")\n- `category` -- market category keywords (e.g. \"startup gtm sales\", \"devops monitoring\")\n- `competitors` -- optional competitor names (e.g. \"Clay, Apollo, HubSpot\")\n\n**ICP cascade:**\n1. If the user's prompt contains product + icp_role + icp_pain: extract them directly and proceed.\n2. If the prompt is thin (only category or only product name): check `docs/icp.md` for a saved ICP profile. Merge with prompt details.\n3. If still insufficient (missing icp_role or icp_pain): ask these 3 questions, one at a time:\n   - \"What does your product do in one sentence?\"\n   - \"Who is your ideal customer? (role, company type, team size)\"\n   - \"What is their primary problem before they find your product?\"\n4. Save the final ICP to `docs/icp.md` so other skills can reuse it.\n\nSave ICP file if docs/icp.md does not already contain this product:\n\n```bash\npython3 << 'PYEOF'\nimport json, os\n\nicp = {\n    \"product\": \"PRODUCT_HERE\",\n    \"icp_role\": \"ICP_ROLE_HERE\",\n    \"icp_pain\": \"ICP_PAIN_HERE\",\n    \"competitors\": [\"COMP_1\", \"COMP_2\"],\n    \"category\": \"CATEGORY_HERE\"\n}\n\nos.makedirs(\"docs\", exist_ok=True)\nwith open(\"/tmp/wcl-input.json\", \"w\") as f:\n    json.dump(icp, f, indent=2)\n\n# Update docs/icp.md\nicp_md_path = \"docs/icp.md\"\nnew_block = f\"\"\"## {icp['product']}\n- **ICP role:** {icp['icp_role']}\n- **ICP pain:** {icp['icp_pain']}\n- **Competitors:** {', '.join(icp['competitors']) if icp['competitors'] else 'none'}\n- **Category:** {icp['category']}\n\"\"\"\nexisting = open(icp_md_path).read() if os.path.exists(icp_md_path) else \"\"\nif icp['product'] not in existing:\n    with open(icp_md_path, \"a\") as f:\n        f.write(new_block)\n    print(f\"ICP saved to {icp_md_path}\")\nelse:\n    print(f\"ICP already in {icp_md_path}\")\n\nprint(f\"Product: {icp['product']}\")\nprint(f\"ICP role: {icp['icp_role']}\")\nprint(f\"ICP pain: {icp['icp_pain']}\")\nprint(f\"Competitors: {', '.join(icp['competitors']) if icp['competitors'] else 'none'}\")\nPYEOF\n```\n\n---\n\n## Step 3: Run the Standalone Data Collection Script\n\nCheck if the script exists:\n\n```bash\nls scripts/fetch.py 2>/dev/null && echo \"script available\" || echo \"not found\"\n```\n\nRun channel discovery:\n\n```bash\nGITHUB_TOKEN=\"${GITHUB_TOKEN:-}\" python3 scripts/fetch.py \\\n    \"$(python3 -c \"import json; d=json.load(open('/tmp/wcl-input.json')); print(d['category'])\")\" \\\n    --icp-role \"$(python3 -c \"import json; d=json.load(open('/tmp/wcl-input.json')); print(d['icp_role'])\")\" \\\n    --icp-pain \"$(python3 -c \"import json; d=json.load(open('/tmp/wcl-input.json')); print(d['icp_pain'])\")\" \\\n    --product \"$(python3 -c \"import json; d=json.load(open('/tmp/wcl-input.json')); print(d['product'])\")\" \\\n    --competitors \"$(python3 -c \"import json; d=json.load(open('/tmp/wcl-input.json')); print(','.join(d['competitors']))\")\" \\\n    --output /tmp/wcl-raw.json\n```\n\nWait for completion (allow up to 5 minutes -- Reddit + DuckDuckGo searches take ~120 seconds total).\n\nVerify output:\n\n```bash\npython3 -c \"\nimport json\nwith open('/tmp/wcl-raw.json') as f:\n    d = json.load(f)\nprint(f'Reddit posts found: {d[\\\"reddit_posts_found\\\"]}')\nprint(f'HN signals found:   {d[\\\"hn_signals_found\\\"]}')\nprint(f'Channels discovered: {d[\\\"summary\\\"][\\\"total_channels\\\"]}')\nprint(f'Top priority:        {len(d[\\\"summary\\\"][\\\"top_priority\\\"])}')\nprint(f'By type:             {d[\\\"summary\\\"][\\\"by_type\\\"]}')\nprint(f'Competitor layer ran: {d[\\\"summary\\\"][\\\"competitor_layer_ran\\\"]}')\n\"\n```\n\nIf total_channels < 3: tell the user: \"Fewer than 3 channels found. The ICP description may be too narrow for Reddit/DDG coverage. Try broader category keywords, or add competitor names to activate the competitor layer.\" Then attempt one retry with broader category keywords before stopping.\n\n---\n\n## Step 4: Print Channel Summary\n\nLoad the raw data and print a ranked summary table:\n\n```bash\npython3 -c \"\nimport json\nwith open('/tmp/wcl-raw.json') as f:\n    d = json.load(f)\nchannels = d['channels_discovered']\nprint(f'Channels found: {len(channels)}')\nprint()\nprint(f'{'#':<4} {'Channel':<35} {'Type':<14} {'Members':<12} {'ICP signals':<13} {'Score':<8} Tier')\nprint('-' * 100)\nfor i, ch in enumerate(channels[:15], 1):\n    members = ch.get('members', 0)\n    m_str = f'{members//1000}K' if members >= 1000 else str(members) if members else '?'\n    print(f'{i:<4} {ch[\\\"name\\\"]:<35} {ch[\\\"type\\\"]:<14} {m_str:<12} {ch.get(\\\"icp_signal_count\\\",0):<13} {ch.get(\\\"channel_score\\\",0):<8} {ch.get(\\\"tier\\\",\\\"\\\")}')\n\"\n```\n\nPrint the top 3 evidence posts from the highest-scoring channel:\n\n```bash\npython3 -c \"\nimport json\nwith open('/tmp/wcl-raw.json') as f:\n    d = json.load(f)\nchannels = d['channels_discovered']\nif channels:\n    top = channels[0]\n    print(f'Top channel: {top[\\\"name\\\"]}')\n    print(f'Evidence posts:')\n    for ep in top.get('evidence_posts', [])[:3]:\n        print(f'  [{ep.get(\\\"score\\\",0):.0f}] {ep.get(\\\"title\\\",\\\"\\\")}')\n        print(f'       {ep.get(\\\"url\\\",\\\"\\\")}')\n\"\n```\n\n---\n\n## Step 5: AI Channel Enrichment\n\nYou now have the raw channel data. For each channel in the top-priority and high tiers, generate a playbook entry.\n\nLoad all channels:\n\n```bash\npython3 -c \"\nimport json\nwith open('/tmp/wcl-raw.json') as f:\n    d = json.load(f)\ntop_channels = [ch for ch in d['channels_discovered'] if ch.get('tier') in ('top-priority', 'high')]\nprint(json.dumps(top_channels, indent=2))\n\"\n```\n\nFor each channel above, generate:\n\n**who_is_here:** 2 sentences describing the specific type of ICP present in this channel. Derive from the evidence posts, subreddit description, and ICP profile. Do NOT write \"your target audience\" -- be specific. Example: \"DevOps engineers at companies of 50-500 who own the infra stack without a dedicated SRE team. They post about on-call burnout, Kubernetes sprawl, and choosing between cloud-native and self-hosted observability.\"\n\n**entry_tactic:** One specific, actionable entry move. Name the thread type, posting format, and community norm. NOT \"engage with the community.\" Example: \"Find the weekly 'What are you working on?' thread (posted every Monday by automoderator). Reply with a 3-sentence technical challenge you solved -- what broke, what you tried, what worked. No product mention. Build karma before posting standalone content.\"\n\n**content_angle:** The content format that gets highest engagement in this specific channel, derived from evidence post titles and scores. Example: \"Technical post-mortems outperform product announcements 5:1 here. Format: 'We migrated 200K users from X to Y -- here is what broke and why.' Concrete numbers + what failed = most upvotes.\"\n\n**anti_patterns:** 2-3 specific behaviors that get posts removed or reputation destroyed in this community. Derive from subreddit rules (if available in description) and evidence post patterns. Example: [\"Posting product links in non-promotional threads -- moderators remove within hours\", \"Asking 'what tools do you use?' without specific context -- flagged as market research farming\"]\n\nWrite the enriched playbook to `/tmp/wcl-channels.json`:\n\n```json\n{\n  \"playbook\": [\n    {\n      \"channel\": \"r/devops\",\n      \"evidence\": \"34 ICP signals traced here, avg pain score 180\",\n      \"who_is_here\": \"...\",\n      \"entry_tactic\": \"...\",\n      \"content_angle\": \"...\",\n      \"anti_patterns\": [\"...\", \"...\"]\n    }\n  ]\n}\n```\n\n```bash\npython3 -c \"\nimport json\nwith open('/tmp/wcl-channels.json') as f:\n    d = json.load(f)\nprint(f'Playbook entries: {len(d[\\\"playbook\\\"])}')\nfor p in d['playbook']:\n    print(f'  {p[\\\"channel\\\"]}')\n\"\n```\n\n---\n\n## Step 6: Generate Full Ranked Output\n\nWrite the complete ranked playbook to `/tmp/wcl-output.json`:\n\n```bash\npython3 << 'PYEOF'\nimport json\nfrom datetime import datetime\n\nwith open('/tmp/wcl-input.json') as f:\n    inp = json.load(f)\nwith open('/tmp/wcl-raw.json') as f:\n    raw = json.load(f)\nwith open('/tmp/wcl-channels.json') as f:\n    enriched = json.load(f)\n\nplaybook_by_channel = {p['channel']: p for p in enriched['playbook']}\nchannels = raw['channels_discovered']\n\noutput = {\n    \"date\": raw['date'],\n    \"product\": inp['product'],\n    \"icp_role\": inp['icp_role'],\n    \"icp_pain\": inp['icp_pain'],\n    \"competitors\": inp.get('competitors', []),\n    \"total_channels\": raw['summary']['total_channels'],\n    \"channels\": []\n}\n\nfor ch in channels:\n    name = ch['name']\n    playbook = playbook_by_channel.get(name, {})\n    output['channels'].append({\n        \"rank\": channels.index(ch) + 1,\n        \"name\": name,\n        \"type\": ch['type'],\n        \"url\": ch['url'],\n        \"members\": ch.get('members', 0),\n        \"active_users\": ch.get('active_users', 0),\n        \"icp_signal_count\": ch.get('icp_signal_count', 0),\n        \"competitor_mentions\": ch.get('competitor_mentions', 0),\n        \"channel_score\": ch.get('channel_score', 0),\n        \"tier\": ch.get('tier', ''),\n        \"entry_type\": ch.get('entry_type', 'open'),\n        \"evidence_posts\": ch.get('evidence_posts', []),\n        \"who_is_here\": playbook.get('who_is_here', ''),\n        \"entry_tactic\": playbook.get('entry_tactic', ''),\n        \"content_angle\": playbook.get('content_angle', ''),\n        \"anti_patterns\": playbook.get('anti_patterns', []),\n    })\n\nwith open('/tmp/wcl-output.json', 'w') as f:\n    json.dump(output, f, indent=2)\n\nprint(f\"Output written: /tmp/wcl-output.json\")\nprint(f\"Total channels: {len(output['channels'])}\")\nPYEOF\n```\n\n---\n\n## Step 7: Self-QA\n\n```bash\npython3 -c \"\nimport json\n\nwith open('/tmp/wcl-raw.json') as f:\n    raw = json.load(f)\nwith open('/tmp/wcl-output.json') as f:\n    output = json.load(f)\n\nfull_text = json.dumps(output)\nraw_channel_names = {ch['name'].lower() for ch in raw['channels_discovered']}\npasses = 0\nfails = 0\n\n# Check 1: No em dashes\nif chr(8212) in full_text:\n    print('FAIL: em dash found in output -- replace with hyphen')\n    fails += 1\nelse:\n    print('PASS: no em dashes')\n    passes += 1\n\n# Check 2: No banned words\nbanned = ['powerful', 'robust', 'seamless', 'innovative', 'game-changing',\n          'streamline', 'leverage', 'transform', 'revolutionize']\nfound = [w for w in banned if w.lower() in full_text.lower()]\nif found:\n    print(f'FAIL: banned words: {found}')\n    fails += 1\nelse:\n    print('PASS: no banned words')\n    passes += 1\n\n# Check 3: At least 3 channel types\ntypes = {ch['type'] for ch in output['channels']}\nif len(types) < 3:\n    print(f'FAIL: only {len(types)} channel type(s) in output: {types}')\n    fails += 1\nelse:\n    print(f'PASS: {len(types)} channel types: {types}')\n    passes += 1\n\n# Check 4: All channel names exist in raw data\nfor ch in output['channels']:\n    if ch['name'].lower() not in raw_channel_names:\n        print(f'FAIL: channel not in raw data: {ch[\\\"name\\\"]}')\n        fails += 1\n\nif fails == 0:\n    print('PASS: all channel names verified in raw data')\n    passes += 1\n\n# Check 5: No generic entry tactics\ngeneric_phrases = ['engage with the community', 'post about your product', 'share your content']\nfor ch in output['channels']:\n    tactic = ch.get('entry_tactic', '').lower()\n    for phrase in generic_phrases:\n        if phrase in tactic:\n            print(f'FAIL: generic entry tactic in {ch[\\\"name\\\"]}: contains \\\"{phrase}\\\"')\n            fails += 1\n\nif fails == 0:\n    print('PASS: entry tactics are channel-specific')\n\nprint()\nprint(f'Result: {passes} passed, {fails} failed')\nif fails > 0:\n    print('Fix failures before saving.')\nelse:\n    print('All checks passed. Ready to save.')\n\"\n```\n\nFix any failures before proceeding to Step 8.\n\n---\n\n## Step 8: Save Output and Clean Up\n\n```bash\npython3 << 'PYEOF'\nimport json, os, re\nfrom datetime import datetime\n\nwith open('/tmp/wcl-input.json') as f:\n    inp = json.load(f)\nwith open('/tmp/wcl-raw.json') as f:\n    raw = json.load(f)\nwith open('/tmp/wcl-output.json') as f:\n    output = json.load(f)\n\nslug = re.sub(r'[^a-z0-9]+', '-', (inp.get('icp_role') or inp['category']).lower()).strip('-')[:40]\ndate = datetime.now().strftime('%Y-%m-%d')\nos.makedirs('docs/channel-map', exist_ok=True)\n\noutpath_md = f\"docs/channel-map/{slug}-{date}.md\"\noutpath_json = f\"docs/channel-map/{slug}-{date}.json\"\n\nchannels = output['channels']\nby_type = {}\nfor ch in channels:\n    by_type.setdefault(ch['type'], []).append(ch)\n\nlines = [\n    f\"# Where Your Customer Lives: {inp['product'] or inp['category'].title()}\",\n    f\"ICP: {inp['icp_role']} | Date: {date} | Channels found: {len(channels)}\",\n    \"\",\n    \"---\",\n    \"\",\n    \"## Channel Ranking\",\n    \"\",\n]\n\ntier_labels = {\"top-priority\": \"TOP PRIORITY\", \"high\": \"HIGH\", \"medium\": \"MEDIUM\", \"low\": \"LOW\"}\n\nfor ch in channels:\n    members = ch.get('members', 0)\n    m_str = f\"{members//1000}K\" if members >= 1000 else str(members) if members else \"member count not found\"\n    tier_label = tier_labels.get(ch.get('tier', ''), ch.get('tier', '').upper())\n    \n    lines.append(f\"### #{ch['rank']}: {ch['name']} [score: {ch['channel_score']}] -- {tier_label}\")\n    \n    active = ch.get('active_users', 0)\n    active_str = f\" | Active: {active//1000}K/day\" if active >= 1000 else f\" | Active: {active}/day\" if active else \"\"\n    lines.append(f\"Type: {ch['type'].title()} | Members: {m_str}{active_str} | {ch.get('entry_type', 'open').title()} to join\")\n    \n    evidence_str = f\"{ch['icp_signal_count']} ICP signals traced here\" if ch['icp_signal_count'] > 0 else \"Discovered via DuckDuckGo search\"\n    lines.append(f\"Evidence: {evidence_str}\")\n    \n    if ch.get('competitor_mentions', 0) > 0 and inp.get('competitors'):\n        lines.append(f\"Competitor mentions: {ch['competitor_mentions']} across {', '.join(inp['competitors'][:3])}\")\n    \n    lines.append(\"\")\n    \n    if ch.get('who_is_here'):\n        lines.append(f\"**Who is here:** {ch['who_is_here']}\")\n        lines.append(\"\")\n    \n    if ch.get('entry_tactic'):\n        lines.append(f\"**Entry tactic:** {ch['entry_tactic']}\")\n        lines.append(\"\")\n    \n    if ch.get('content_angle'):\n        lines.append(f\"**Content angle:** {ch['content_angle']}\")\n        lines.append(\"\")\n    \n    if ch.get('anti_patterns'):\n        lines.append(\"**Anti-patterns:**\")\n        for ap in ch['anti_patterns']:\n            lines.append(f\"- {ap}\")\n        lines.append(\"\")\n    \n    lines.append(\"---\")\n    lines.append(\"\")\n\nlines += [\n    \"## Channel Summary by Type\",\n    \"\",\n    \"| Type | Count | Best channel | Score |\",\n    \"|---|---|---|---|\",\n]\nfor ch_type, chs in sorted(by_type.items(), key=lambda x: -max(c['channel_score'] for c in x[1])):\n    best = max(chs, key=lambda x: x['channel_score'])\n    lines.append(f\"| {ch_type.title()} | {len(chs)} | {best['name']} | {best['channel_score']} |\")\n\nlines += [\n    \"\",\n    \"---\",\n    \"\",\n    \"## Data Quality Notes\",\n    f\"- All channel names exist in Reddit API response or DuckDuckGo search results\",\n    f\"- Member counts from Reddit about.json API or search snippets\",\n    f\"- ICP signal counts match raw data ({raw['reddit_posts_found']} Reddit posts, {raw['hn_signals_found']} HN signals)\",\n    f\"- Competitor layer ran: {raw['summary']['competitor_layer_ran']}\",\n    f\"- Sources: Reddit signal-trace, HN signal-trace, DuckDuckGo channel discovery\",\n    \"\",\n    f\"Saved to: {outpath_md}\",\n    f\"JSON snapshot: {outpath_json}\",\n]\n\nwith open(outpath_md, 'w') as f:\n    f.write('\\n'.join(lines))\n\n# JSON snapshot\nsnapshot = {\n    \"input\": inp,\n    \"channels\": channels,\n    \"summary\": raw['summary'],\n    \"date\": date,\n}\nwith open(outpath_json, 'w') as f:\n    json.dump(snapshot, f, indent=2)\n\nprint(f\"Report saved: {outpath_md}\")\nprint(f\"JSON snapshot: {outpath_json}\")\nPYEOF\n```\n\nClean up temp files:\n\n```bash\nrm -f /tmp/wcl-input.json /tmp/wcl-raw.json /tmp/wcl-channels.json /tmp/wcl-output.json\necho \"Done. Channel map saved to docs/channel-map/\"\n```\n\nPresent the full contents of the saved `.md` file to the user.","tags":["where","your","customer","lives","opendirectory","varnan-tech","agent-skills","gtm","hermes-agent","marketing-skills","openclaw-skills","skill-pack"],"capabilities":["skill","source-varnan-tech","skill-where-your-customer-lives","topic-agent-skills","topic-gtm","topic-hermes-agent","topic-marketing-skills","topic-openclaw-skills","topic-skill-pack","topic-skills","topic-technical-seo"],"categories":["opendirectory"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/Varnan-Tech/opendirectory/where-your-customer-lives","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add Varnan-Tech/opendirectory","source_repo":"https://github.com/Varnan-Tech/opendirectory","install_from":"skills.sh"}},"qualityScore":"0.593","qualityRationale":"deterministic score 0.59 from registry signals: · indexed on github topic:agent-skills · 286 github stars · SKILL.md body (18,667 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:54:44.574Z","embedding":null,"createdAt":"2026-04-23T12:55:32.908Z","updatedAt":"2026-05-18T18:54:44.574Z","lastSeenAt":"2026-05-18T18:54:44.574Z","tsv":"'-3':1437 '-500':1290 '/1000':1079,2206,2251 '/day':2260 '/dev/null':794 '/tmp/wcl-channels.json':1494,1525,1587,2573 '/tmp/wcl-input.json':658,818,832,847,860,872,1571,2079,2571 '/tmp/wcl-output.json':1559,1728,1741,1770,2095,2574 '/tmp/wcl-raw.json':878,903,1029,1135,1216,1579,1762,2087,2572 '0':169,172,1074,1107,1112,1149,1171,1663,1669,1677,1683,1689,1793,1795,1953,2018,2037,2201,2245,2298,2313,2314 '0f':1172 '1':370,513,645,1070,1411,1651,1797,1818,1826,1863,1871,1904,1915,1950,1964,2015,2418 '100':1062 '1000':1083,2210,2255 '12':1054,1102 '120':891 '13':1057,1108 '14':1052,1099 '15':1069 '180':1508 '2':453,530,647,666,793,1244,1253,1436,1736,1828,2550 '200k':1416 '3':354,553,565,778,965,971,1119,1166,1360,1873,1876,1890,2329 '34':1500 '35':1050,1096 '4':599,1008,1048,1093,1917 '40':2116 '45k':211 '5':885,1180,1410,1966 '50':1289 '6':1548 '60':385 '7':1751 '8':1059,1113,2058,2060 '8212':1803 '9':2107 'a-z0':2104 'about.json':147,407,2460 'acquisit':490 'across':2325 'action':1325 'activ':91,993,1664,1667,2241,2243,2246,2249,2250,2254,2258,2259,2262,2273 'actual':23 'add':989 'agent':180 'ai':1181 'alert':491 'algolia':414 'allow':882 'alreadi':619,741 'altern':296 'alway':300 'angl':47,103,1383,1515,1717,1720,2361,2365,2368 'announc':1409 'anti':51,105,1434,1516,1721,1724,2372,2376,2382 'anti-pat':50 'anti-pattern':104,2375 'ap':2379,2386 'api':131,148,264,272,415,430,2449,2461 'apollo':509 'append':1647,2154 'ask':310,563,1475 'attempt':998 'audienc':1280 'auth':401,409,417,425 'authent':433 'automoder':1356 'avail':797,1455 'avg':1505 'back':68 'ban':1830,1832,1849,1859,1868 'bash':373,623,790,804,896,1022,1128,1209,1518,1560,1755,2066,2568 'behavior':1439 'best':2397,2419,2433,2435 'block':674,728 'broader':985,1002 'broke':1367,1425 'build':1376 'burnout':1307 'by_type.items':2406 'by_type.setdefault':2151 'c':812,826,841,854,866,898,1024,1130,1211,1520,1757,2411,2415 'call':1306 'cascad':512 'categori':493,495,537,648,649,697,699,821,986,1003,2113,2166 'ch':1065,1094,1097,1224,1226,1636,1640,1650,1655,1658,1783,1787,1880,1883,1926,1931,1947,1985,2010,2148,2152,2155,2195,2231,2233,2236,2267,2285,2294,2322,2341,2354,2366,2381,2401 'ch.get':1072,1103,1109,1114,1232,1661,1666,1673,1680,1686,1691,1695,1701,1990,2199,2224,2226,2242,2275,2310,2332,2347,2359,2371 'ch_type.title':2430 'challeng':1363 'chang':1839 'channel':19,33,80,85,109,115,120,166,176,190,194,219,240,255,346,355,426,447,802,929,934,964,972,1010,1035,1037,1041,1044,1049,1068,1110,1127,1141,1143,1146,1148,1153,1182,1189,1193,1208,1223,1229,1242,1247,1264,1394,1497,1546,1595,1597,1604,1606,1629,1633,1634,1638,1646,1684,1687,1745,1748,1781,1790,1877,1886,1897,1911,1919,1929,1937,1942,1957,1988,2025,2142,2144,2150,2175,2178,2179,2197,2237,2391,2398,2412,2426,2436,2444,2504,2532,2533,2577 'channel-specif':2024 'channels.index':1649 'check':372,542,785,1796,1827,1872,1916,1965,2046 'choos':1311 'chr':1802 'chs':2403,2421,2432 'clay':508 'clean':2064,2564 'cloud':1314 'cloud-nat':1313 'co':476 'co-found':475 'collect':456,783 'come':144,258,269 'common':177 'communiti':72,252,339,1335,1341,1449,1976 'comp':644,646 'compani':585,1287 'competitor':75,93,286,289,302,381,436,503,505,643,688,691,694,767,770,773,864,876,954,959,990,995,1625,1627,1678,1681,2311,2317,2320,2323,2328,2485,2490 'complet':881,1555 'concret':1428 'contain':519,620,2012 'content':46,102,336,1381,1382,1385,1514,1716,1719,1983,2360,2364,2367,2585 'context':299,1483 'continu':444 'convers':459 'core':446 'count':89,142,158,202,250,267,281,1106,1672,1676,2218,2288,2297,2396,2457,2468 'coverag':983 'critic':117 'custom':4,22,55,489,583,2160 'd':815,820,829,834,844,849,857,862,869,875,906,914,923,931,940,948,957,1032,1036,1138,1142,1219,1228,1528,1536,1541,2122 'dash':1800,1810,1824 'data':163,390,782,1015,1190,1924,1946,1962,2439,2471 'date':1609,1611,2117,2133,2140,2173,2174,2537,2538 'datetim':1566,1568,2074,2076 'datetime.now':2118 'dedic':1298 'deriv':1265,1395,1450 'describ':1255 'descript':976,1271,1457 'destroy':1446 'detail':552 'devop':207,231,478,501,1284 'differ':239 'direct':527 'discov':78,930,1038,1144,1230,1607,1791,2300 'discoveri':427,448,803,2505 'discuss':76,291 'doc':652 'docs/channel-map':2124,2131,2138,2581 'docs/icp.md':543,605,616,668,672 'done':2576 'duckduckgo':82,134,260,364,422,888,2302,2452,2503 'e.g':473,488,497,507 'echo':374,388,389,396,405,412,421,428,795,798,2575 'either':128 'els':695,711,737,774,1084,1089,1819,1864,1905,2043,2211,2216,2256,2263,2299 'em':1799,1809,1823 'engag':1338,1390,1973 'engin':479,1285 'enrich':437,1183,1491,1590,1602 'enterpris':209 'entir':238 'entri':43,100,312,327,329,1205,1321,1326,1512,1534,1693,1696,1711,1714,1969,1991,2007,2021,2276,2348,2352,2355 'enumer':1067 'ep':1161 'ep.get':1169,1173,1177 'estim':154 'evalu':295 'even':304 'everi':84,119,140,155,193,221,254,265,1353 'evid':36,99,1120,1158,1164,1268,1397,1459,1499,1699,1702,2282,2306,2307 'exampl':1283,1342,1402,1462 'exist':126,653,700,717,789,1921,2125,2446 'explicit':362 'extract':525 'f':661,664,675,725,730,739,747,752,759,766,905,908,910,919,928,936,945,953,1031,1034,1040,1047,1077,1091,1137,1140,1151,1157,1168,1176,1218,1221,1527,1530,1532,1544,1573,1576,1581,1584,1589,1592,1731,1734,1738,1743,1764,1767,1772,1775,1857,1892,1907,1940,2004,2029,2081,2084,2089,2092,2097,2100,2130,2137,2157,2168,2204,2230,2248,2257,2265,2284,2305,2319,2337,2351,2363,2385,2429,2442,2455,2465,2484,2493,2506,2511,2522,2545,2548,2552,2558,2570 'f.write':726,2523 'fabric':175 'fail':1431,1794,1808,1817,1858,1862,1893,1903,1941,1949,1952,2005,2014,2017,2033,2034,2036 'failur':2040,2053 'farm':1488 'fatigu':492 'fewer':969 'file':614,2567,2590 'final':602 'financ':235 'find':16,596,1343 'fix':2039,2051 'flag':1484 'format':337,1333,1386,1413 'found':283,361,800,913,917,922,926,973,1042,1811,1844,1855,1861,2176,2220,2475,2481 'founder':477 'fresh':245 'full':30,1550,1776,1805,2584 'full_text.lower':1853 'game':1838 'game-chang':1837 'generat':1202,1249,1549 'generic':189,1968,1971,1997,2006 'get':1388,1441 'github':375,377,429,431,439,805,807 'given':6,57 'group':206 'gtm':499 'guess':111 'high':1200,1238,2188,2189 'highest':1125,1389 'highest-scor':1124 'hn':413,920,924,2479,2482,2499 'host':1319 'hottest':297 'hour':1474 'html':423 'hubspot':510 'hyphen':1816 'icp':11,39,62,65,87,156,222,228,232,236,247,293,455,467,471,483,511,521,523,547,558,561,603,613,629,633,635,638,640,663,669,676,678,680,681,683,685,686,690,693,698,702,708,713,720,731,734,740,743,749,753,755,756,760,762,763,769,772,823,835,838,850,975,1055,1104,1260,1273,1501,1615,1618,1620,1623,1670,1674,2109,2169,2171,2286,2289,2295,2466 'icp-pain':837 'icp-rol':822 'icp-specif':227 'ideal':582 'import':626,813,827,842,855,867,899,1025,1131,1212,1521,1563,1567,1758,2069,2075 'includ':351 'indent':665,1243,1735,2549 'infra':1294 'innov':1836 'inp':1574,1613,1617,1622,2082,2112,2162,2165,2170,2327,2531 'inp.get':1626,2108,2316 'input':2530 'insuffici':556 'internet':14 'invent':248 'join':689,768,874,2281,2326,2525 'json':399,627,814,828,843,856,868,900,1026,1132,1213,1495,1522,1564,1759,2070,2136,2141,2512,2515,2527,2542,2559,2562 'json.dump':662,1732,2546 'json.dumps':1240,1778 'json.load':816,830,845,858,870,907,1033,1139,1220,1529,1575,1583,1591,1766,1774,2083,2091,2099 'k':1080,2207 'k/day':2252 'karma':1377 'key':2407,2422 'keyword':496,987,1004 'kubernet':1308 'label':2182,2222,2240 'lambda':2408,2423 'layer':73,287,382,955,960,996,2486,2491 'least':353,1875 'len':939,1043,1535,1746,1888,1895,1909,2177,2431 'leverag':1841 'line':2156,2390,2438,2526 'lines.append':2229,2264,2304,2318,2330,2336,2345,2350,2357,2362,2369,2374,2384,2387,2388,2389,2428 'link':1465 'linkedin':191,205,215 'list':241 'live':5,24,56,2161 'load':1012,1206 'low':2192,2193 'lower':1785,1933,1993,2114 'ls':791 'm':1075,1100,2121,2202,2271 'map':2578 'market':494,1486 'match':160,2469 'max':2410,2420 'may':977 'md':670,703,709,721,735,744,2129,2134,2510,2519,2556,2589 'medium':2190,2191 'member':141,201,212,249,266,280,1053,1071,1073,1078,1082,1086,1088,1660,1662,2198,2200,2205,2209,2213,2215,2217,2270,2456 'mention':1375,1679,1682,2312,2321,2324 'merg':549 'metadata':411 'migrat':1415 'minut':886 'miss':557 'mistak':178 'moder':1471 'monday':1354 'monitor':502 'mortem':1406 'move':1327 'must':125,143,159,195,257,268,350 'n':2524 'name':121,200,253,256,331,506,541,991,1095,1155,1328,1639,1641,1644,1652,1653,1782,1784,1920,1932,1938,1948,1958,2011,2234,2434,2445 'narrow':980 'nativ':1315 'never':153 'new':673,727 'non':1468 'non-promot':1467 'none':696,775 'norm':340,1336 'note':2441 'number':1429 'observ':1320 'ok':654,2126 'on-cal':1304 'one':42,45,107,465,567,577,999,1323 'open':657,701,719,817,831,846,859,871,902,1028,1134,1215,1524,1570,1578,1586,1698,1727,1761,1769,2078,2086,2094,2278,2517,2540 'option':434,504 'os':628,2071 'os.makedirs':651,2123 'os.path.exists':707 'outpath':2128,2135,2509,2514,2518,2541,2555,2561 'outperform':1407 'output':95,124,349,877,895,1552,1608,1645,1733,1739,1747,1773,1779,1813,1885,1901,1928,1987,2062,2098,2143 'outreach':298 'p':1539,1545,1596,1598,1600 'pain':66,484,524,562,639,641,684,687,761,764,839,851,1506,1621,1624 'pars':454 'pass':1792,1821,1825,1866,1870,1908,1914,1955,1963,2020,2031,2032,2047 'pat':52 'path':671,704,710,722,736,745 'pattern':106,1435,1461,1517,1722,1725,2373,2377,2383 'per':32,108,246 'per-channel':31 'phrase':1972,1995,1998,2000,2013 'pitch':317 'playbook':34,98,1204,1492,1496,1533,1537,1542,1557,1593,1603,1642 'playbook.get':1707,1713,1718,1723 'playbook_by_channel.get':1643 'post':67,318,912,916,1121,1159,1165,1269,1302,1332,1352,1379,1398,1405,1442,1460,1463,1700,1703,1977,2474,2477 'post-mortem':1404 'power':1833 'presenc':94 'present':1261,2582 'primari':486,592 'print':729,738,746,751,758,765,819,833,848,861,873,909,918,927,935,944,952,1009,1017,1039,1045,1046,1061,1090,1116,1150,1156,1167,1175,1239,1531,1543,1737,1742,1807,1820,1856,1865,1891,1906,1939,1954,2003,2019,2027,2028,2038,2044,2551,2557 'prioriti':938,943,1198,1237,2185,2187 'problem':487,593 'proceed':529,2055 'produc':237 'product':8,59,316,321,460,463,520,540,574,598,622,630,631,677,714,748,750,852,863,1374,1408,1464,1612,1614,1980,2163 'profil':548,1274 'promot':1469 'prompt':518,533,551 'public':398 'pyeof':625,776,1562,1749,2068,2563 'python3':624,809,811,825,840,853,865,897,1023,1129,1210,1519,1561,1756,2067 'qa':1754 'qualiti':2440 'question':566 'r':2103 'r/devops':323,1498 'ran':956,961,2487,2492 'rank':25,97,1019,1551,1556,1648,2180,2232 'raw':162,1014,1188,1582,1605,1610,1630,1765,1780,1789,1923,1936,1945,1961,2090,2470,2472,2478,2488,2535 're':2072 're.sub':2102 'reachabl':27 'read':705 'readi':2048 'real':64 'recommend':188 'reddit':130,263,342,359,397,406,887,911,915,2448,2459,2473,2476,2495 'reddit/ddg':982 'remov':1443,1472 'replac':1814 'repli':1357 'report':171,2553 'reput':1445 'req/hr':386 'research':12,1487 'respons':132,2450 'result':136,170,261,2030,2454 'retri':1000 'return':35,168 'reus':610 'revolution':1843 'rm':2569 'robust':1834 'role':468,522,559,584,634,636,679,682,754,757,824,836,1616,1619,2110,2172 'rule':118,1453 'run':139,242,301,383,393,779,801 'sale':500 'save':546,600,612,732,2042,2050,2061,2507,2554,2579,2588 'score':83,1058,1111,1126,1170,1401,1507,1685,1688,2235,2238,2399,2413,2427,2437 'script':244,784,788,796 'scripts/fetch.py':792,810 'seamless':1835 'search':135,151,275,303,363,889,2303,2453,2463 'second':892 'self':1318,1753 'self-host':1317 'self-qa':1752 'sentenc':466,578,1254,1361 'seri':481 'set':380,443 'setup':371 'share':1981 'signal':77,88,113,157,224,403,419,921,925,1056,1105,1502,1671,1675,2287,2290,2296,2467,2480,2483,2497,2501 'signal-trac':112,223,402,418,2496,2500 'size':90,588 'skill':608 'skill-where-your-customer-lives' 'skip':284 'slack/discord/newsletter/conference':366 'slack/discord/newsletter/podcast/conference':79 'slug':2101,2132,2139 'snapshot':2513,2528,2529,2547,2560 'snippet':152,276,2464 'solv':1365 'sort':2405 'sourc':71,391,2494 'source-varnan-tech' 'specif':18,49,197,229,333,1257,1282,1324,1393,1438,1482,2026 'sprawl':1309 'sre':1299 'stack':1295 'standalon':781,1380 'startup':498 'step':369,452,777,1007,1179,1547,1750,2057,2059 'still':555 'stop':368,1006 'str':1076,1085,1101,2203,2212,2247,2272,2274,2283,2308 'streamlin':1840 'strftime':2119 'strip':2115 'subreddit':410,1270,1452 'summari':932,941,949,958,1011,1020,1631,2392,2489,2534,2536 'tabl':1021 'tactic':44,101,313,328,330,1322,1513,1712,1715,1970,1989,1992,2002,2008,2022,2349,2353,2356 'take':890 'target':1279 'team':210,587,1300 'technic':474,1362,1403 'tell':966 'temp':2566 'text':1777,1806 'thin':535 'thread':334,1330,1351,1470 'tier':1060,1115,1201,1233,1690,1692,2181,2221,2225,2227,2239 'tier_labels.get':2223 'time':570 'titl':1174,1399,2167,2269,2279 'token':376,378,432,440,806,808 'tool':1477 'top':937,942,1118,1147,1152,1154,1197,1222,1236,1241,2184,2186 'top-prior':1196,1235,2183 'top.get':1163 'topic-agent-skills' 'topic-gtm' 'topic-hermes-agent' 'topic-marketing-skills' 'topic-openclaw-skills' 'topic-skill-pack' 'topic-skills' 'topic-technical-seo' 'total':893,933,963,1628,1632,1744 'trace':63,114,225,404,420,1503,2291,2498,2502 'transform':1842 'treat':341 'tri':984,1370 'true':655,2127 'twitter':192 'type':167,335,347,356,586,947,951,1051,1098,1258,1331,1654,1656,1694,1697,1878,1879,1881,1889,1896,1898,1902,1910,1912,1913,2146,2153,2266,2268,2277,2394,2395,2402 'unauthent':387 'unavail':278 'updat':667 'upper':2228 'upvot':1433 'url':204,1178,1657,1659 'use':216,395,1480 'user':307,516,968,1417,1665,1668,2244,2593 'util':9,60 'verifi':894,1959 'via':81,2301 'w':659,1729,1845,1847,2520,2543 'w.lower':1851 'wait':879 'want':182 'week':1345 'where-your-customer-l':1 'within':1473 'without':450,1296,1481 'word':1831,1860,1869 'work':449,1349,1372 'write':279,311,1277,1489,1553 'written':1740 'wrong':187 'x':1419,2409,2417,2424,2425 'y':1421,2120 'z0':2106","prices":[{"id":"a5847733-85c5-4b1f-b4e9-f31a79dcd7c5","listingId":"8aeb5042-c3f6-4874-9568-f030ce2a22ea","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"Varnan-Tech","category":"opendirectory","install_from":"skills.sh"},"createdAt":"2026-04-23T12:55:32.908Z"}],"sources":[{"listingId":"8aeb5042-c3f6-4874-9568-f030ce2a22ea","source":"github","sourceId":"Varnan-Tech/opendirectory/where-your-customer-lives","sourceUrl":"https://github.com/Varnan-Tech/opendirectory/tree/main/skills/where-your-customer-lives","isPrimary":false,"firstSeenAt":"2026-04-23T12:55:32.908Z","lastSeenAt":"2026-05-18T18:54:44.574Z"}],"details":{"listingId":"8aeb5042-c3f6-4874-9568-f030ce2a22ea","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"Varnan-Tech","slug":"where-your-customer-lives","github":{"repo":"Varnan-Tech/opendirectory","stars":286,"topics":["agent-skills","gtm","hermes-agent","marketing-skills","openclaw-skills","skill-pack","skills","technical-seo"],"license":"mit","html_url":"https://github.com/Varnan-Tech/opendirectory","pushed_at":"2026-05-18T18:27:10Z","description":" AI Agent Skills built for Founders who hate Marketing","skill_md_sha":"9efcf056d8dce9323a7c53c69728c6d2d33765ea","skill_md_path":"skills/where-your-customer-lives/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/Varnan-Tech/opendirectory/tree/main/skills/where-your-customer-lives"},"layout":"multi","source":"github","category":"opendirectory","frontmatter":{"name":"where-your-customer-lives","description":"Given a product utility and ICP, researches the internet to find the specific channels. Where your customer actually lives, ranked by reachability with a full per-channel playbook. Returns evidence that your ICP is there, one entry tactic, one content angle, and specific anti-patterns per channel. Use when asked where my customer hangs out, what communities should I post in, where is my ICP, find channels for outreach, what forums does my ICP use, where should I spend time for distribution, or which communities are right for my product.","compatibility":"[claude-code, gemini-cli, github-copilot]"},"skills_sh_url":"https://skills.sh/Varnan-Tech/opendirectory/where-your-customer-lives"},"updatedAt":"2026-05-18T18:54:44.574Z"}}