agentsclimarketplace

Skill ai mindshare map

Skill unfamiliar-city/skill-ai-mindshare-map

Claude Code skill that measures how visible a company or market is to AI assistants (ChatGPT) and maps who gets recommended and why.

Install
npx -y skills add unfamiliar-city/skill-ai-mindshare-map

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

AI Mindshare Map measures how visible a company or market is to AI assistants: which companies ChatGPT recommends, how prominently, and which sources shape the answer. Roleplays audience personas, runs their questions through GPT-5.2 under a ChatGPT-like system prompt with web search, and builds a competitive leaderboard from the answers and their citations. Data collection and analysis only; produces structured JSON for downstream orchestrators. Use when: AI visibility mapping, competitive mapping, citation analysis, source gap identification. Triggers: "mindshare map", "AI mindshare", "AI visibility map", "AI visibility", "competitive mapping", "citation analysis", "source gap analysis", "who does AI recommend".

SKILL.md

12.5 KB, as published. Nobody here has run it

AI Mindshare Map

Competitive intelligence tool: discover your audience, query AI systems, analyze responses, build competitive leaderboards, identify source gaps.

Command Syntax

/mindshare-map --entity <url> [--frame "..."] [--name <slug>] [--skip-validation] [--intents-per-track=N] [--intents=N]
  Entity mode: tracks a specific company/brand.

/mindshare-map --market "<description>" [--frame "..."] [--name <slug>] [--skip-validation] [--intents-per-track=N] [--intents=N]
  Market mode: landscape analysis without a focal entity.

Options:

  • --frame "..." Intent/persona dial — who is searching and why (default: buyers researching options)
  • --name <slug> Work directory name (default: derived from URL domain or market description)
  • --skip-validation Skip ICP confirmation (use inferred ICPs; buyer → default tracks, other → trackless)
  • --intents-per-track=N Intents per track in tracked mode (default: 6)
  • --intents=N Intents per ICP in trackless mode (default: 12)

Examples:

  • /mindshare-map --entity https://example.comwork/example-com-20260213/
  • /mindshare-map --market "creative agencies"work/creative-agencies-20260213/
  • /mindshare-map --entity https://foo.com --name=foo-q1-2026work/foo-q1-2026/
  • /mindshare-map --entity https://foo.com --frame "investors assessing category leaders"

Dependencies

  • Playwright MCP: Audience discovery research
  • WebFetch: Audience discovery research
  • Bash: Running pipeline
  • OpenAI API: GPT-5.2 for queries, GPT-5-mini for full-tier source assessment, GPT-5-nano for extraction/analysis/light-tier assessment
  • tuff-lil-unit: Pipeline execution — crash recovery, step memoisation, concurrency

Work Directory

Each run gets a dated directory under work/:

work/creative-agencies-20260213/
  audience-profile.json       # ICPs + intents + target_focus (project identity)
  subject-context.json        # Research knowledge
  tuff.db                     # SQLite: tuff steps + domain tables (queryable)
  distillation.json           # Full competitive landscape output

Outputs

  1. distillation.json — single file with full competitive landscape:
    • meta — schema version, run ID, mode, timestamp, query count, response rate, primary entity types
    • landscape — query_answer entities grouped by type (company, product, …), ranked by reach
    • other_entities — authority_source/platform entities grouped by type
    • by_icp — per-ICP breakdown: { icp_001: { landscape: {…}, other_entities: {…} } }
    • sources.market — by_publisher_type, per-domain assessments (each with source_type, is_competitor, authority, citation_count, citation_count_by_icp)
    • client — position, category_position, salience, visibility, reputation (entity mode only)
  2. tuff.db — queryable via sqlite3: step status, token usage, domain tables

DB: detail behind distillation summaries

tuff.db retains full detail that distillation summarises. Query with sqlite3 tuff.db:

WantTable → column
Source authority reasoning + signalsassessments.resultauthority
Source format + competitor relationshipassessmentssource_type, is_competitor
All cited URLs per domainassessments.resulturls
Per-response mention detail (salience, ICP, query)analysed.mentions
Full GPT response textqueries.response
Fetched source page contentsources.content
Raw entity extractions per sourceextractions.entities

Setup (first run)

A SessionStart hook installs tuff-lil-unit into ${CLAUDE_PLUGIN_DATA} automatically and re-runs if package.json changes. Confirm OPENAI_API_KEY is set via shell (Keychain-backed recommended, exported from ~/.zshenv — see README). Playwright MCP is optional (entity-mode site research falls back to WebFetch without it).

If a pipeline phase fails with Could not locate the bindings file (a better-sqlite3 native-binding error), the install skipped its native build step. Fix: cd ${CLAUDE_PLUGIN_DATA} && npm rebuild better-sqlite3, then retry the phase.


Phase 0: Work Directory Setup

Before anything else, resolve the work directory:

  1. Derive slug from input:
    • --entity: extract domain, slugify → example-com
    • --market: slugify description → creative-agencies
    • --name= flag overrides (no date suffix added)
  2. Add date suffix: ${slug}-${YYYYMMDD} (e.g., creative-agencies-20260213)
    • Skip if --name= was provided (user controls full name)
  3. Set WORK_DIR = work/${slug}-${YYYYMMDD}/
  4. Check if exists: if WORK_DIR already contains data, prompt user:

    work/creative-agencies-20260213/ already exists. Overwrite, or use a different name?

  5. Create directory: mkdir -p ${WORK_DIR}

All subsequent phases use --work-dir=${WORK_DIR}.


Phase 1: Audience Discovery

Subagent-driven research + user validation. Produces audience-profile.json.

Step 1.0: Frame

Capture --frame flag (default: buyer frame).

Step 1.1: Generate ICPs

Task({
  subagent_type: 'general-purpose',
  prompt: `Execute: references/${'entity' in subject
    ? 'entity-mode-instructions' : 'market-mode-instructions'}.md\n\n${
    'entity' in subject ? `Entity URL: ${subject.entity}` : `Market: "${subject.market}"`}\n\nWORK_DIR: ${WORK_DIR} — write subject-context.json into this directory, not a hardcoded work/ path.`
})

Step 1.2: Validate ICPs

Present proposed ICPs to user. Collect feedback, refine if needed. Skip if --skip-validation.

If discovery returned research_limited (entity mode, a JS-rendered site WebFetch couldn't read), tell the user — even under --skip-validation:

{entity} looks JS-rendered, so these ICPs lean more on general web research than on its site. Installing Playwright MCP would let me read the full site — add it and re-run discovery, or proceed with these?

Step 1.2a: Track Selection

After ICPs are confirmed, decide market-mapping tracks:

FrameWith --skip-validationInteractive
BuyerDefault tracks (4)Offer defaults or trackless
CustomTracklessPropose custom tracks or trackless

Default tracks: landscape, recommendation, specialization, scenario. All tracks must be entity-surfacing. See references/intent-query-generation-instructions.md for phrasing guidance.

Step 1.3: Generate Intents + Queries

One subagent per ICP, in parallel. Build a roleplay brief for each ICP using three neutral slots interpreted through the frame:

SlotBuyerInvestorJournalist
motivationsgoalsinvestment thesisbeat and angle
constraintspain pointsdue diligence concernseditorial constraints
contextcurrent situationportfolio contextcurrent assignments

Record the constructed brief in the ICP's brief block in audience-profile.json before sending to the subagent.

Use tracked or trackless template from references/intent-query-generation-instructions.md. Tracked: --intents-per-track=N (default 6), intent JSON includes track. Trackless: --intents=N (default 12), track omitted.

const icpResults = await Promise.all(confirmedICPs.map(icp =>
  Task({
    subagent_type: 'general-purpose',
    model: 'sonnet',
    prompt: buildRoleplayBrief(icp, confirmedTracks, trackless)
  })
))

Step 1.3b: Query Review

Single review subagent (Sonnet) scans all generated queries for methodology problems. Returns flagged queries with reasons; orchestrator fixes or drops before presenting to user.

Task({
  subagent_type: 'general-purpose',
  model: 'sonnet',
  prompt: `Review these generated queries for research methodology problems...\n${allQueries}`
  // See references/query-review-instructions.md for criteria and output format
})

Step 1.4: Validate Intents + Write Profile

Present intents to user, collect feedback. Write ${WORK_DIR}/audience-profile.json. Skip validation if --skip-validation.


Phase 2: Pipeline (task-based, background jobs)

Step 2.1: Create Tasks + Set Dependencies

const query = TaskCreate({
  subject: "Query GPT for all ICPs",
  description: "Bash({ run_in_background: true, command: 'NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:query -- --work-dir=${WORK_DIR}' })",
  activeForm: "Querying GPT"
})

const fetch = TaskCreate({
  subject: "Fetch cited URLs",
  description: "Bash({ run_in_background: true, command: 'NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:fetch -- --work-dir=${WORK_DIR}' })",
  activeForm: "Fetching URLs"
})

const extract = TaskCreate({
  subject: "Extract entities from sources",
  description: "Bash({ run_in_background: true, command: 'NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:extract -- --work-dir=${WORK_DIR}' })",
  activeForm: "Extracting entities"
})

const assess = TaskCreate({
  subject: "Assess source authority",
  description: "Bash({ run_in_background: true, command: 'NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:assess -- --work-dir=${WORK_DIR}' })",
  activeForm: "Assessing sources"
})

const analyse = TaskCreate({
  subject: "Analyse GPT responses",
  description: "Bash({ run_in_background: true, command: 'NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:analyse -- --work-dir=${WORK_DIR}' })",
  activeForm: "Analysing responses"
})

const distill = TaskCreate({
  subject: "Distill competitive landscape",
  description: "Bash({ run_in_background: true, command: 'NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:distill -- --work-dir=${WORK_DIR}' }). Outputs: distillation.json",
  activeForm: "Distilling landscape"
})

// Dependency graph:
//   Query → Fetch → Extract → Assess ─┐
//     └──→ Analyse ────────────────────┴→ Distill
TaskUpdate({ taskId: fetch.id, addBlockedBy: [query.id] })
TaskUpdate({ taskId: extract.id, addBlockedBy: [fetch.id] })
TaskUpdate({ taskId: assess.id, addBlockedBy: [extract.id] })
TaskUpdate({ taskId: analyse.id, addBlockedBy: [query.id] })
TaskUpdate({ taskId: distill.id, addBlockedBy: [assess.id, analyse.id] })

Step 2.2: Execute Task Graph

Begin with query. On each completion: mark task done, start unblocked dependents.

Monitoring progress — each phase writes to DB per-item. Check progress any time:

NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:progress -- --work-dir=${WORK_DIR} query    # single phase: "query: 24/24"
NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline:progress -- --work-dir=${WORK_DIR}          # all phases

On crash or interruption: re-run the failed phase — tuff step memoisation skips completed items.

Full pipeline (non-interactive): NODE_PATH=${CLAUDE_PLUGIN_DATA}/node_modules npm run --prefix ${CLAUDE_PLUGIN_ROOT} pipeline -- --work-dir=${WORK_DIR} runs all 6 phases sequentially.


Phase 3: Delivery

Once pipeline completes, present outputs to user:

**AI Mindshare Map complete** → `${WORK_DIR}/`

**Outputs:**
- `${WORK_DIR}/distillation.json` — competitive landscape data
- `${WORK_DIR}/audience-profile.json` — ICPs + intents

**Key Findings:**
- Entities discovered: {{entities_discovered}}
- Source-backed: {{source_backed_count}}
- Target rank: #{{rank}} of {{rank_of}} *(entity mode only)*

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.