@growthub/cli 0.3.50 → 0.3.53

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 (38) hide show
  1. package/assets/worker-kits/growthub-geo-seo-v1/.env.example +12 -0
  2. package/assets/worker-kits/growthub-geo-seo-v1/QUICKSTART.md +138 -0
  3. package/assets/worker-kits/growthub-geo-seo-v1/brands/NEW-CLIENT.md +104 -0
  4. package/assets/worker-kits/growthub-geo-seo-v1/brands/_template/brand-kit.md +116 -0
  5. package/assets/worker-kits/growthub-geo-seo-v1/brands/growthub/brand-kit.md +117 -0
  6. package/assets/worker-kits/growthub-geo-seo-v1/bundles/growthub-geo-seo-v1.json +54 -0
  7. package/assets/worker-kits/growthub-geo-seo-v1/docs/geo-seo-fork-integration.md +244 -0
  8. package/assets/worker-kits/growthub-geo-seo-v1/docs/pdf-report-layer.md +139 -0
  9. package/assets/worker-kits/growthub-geo-seo-v1/docs/scoring-methodology.md +230 -0
  10. package/assets/worker-kits/growthub-geo-seo-v1/docs/subagent-dispatch.md +273 -0
  11. package/assets/worker-kits/growthub-geo-seo-v1/examples/citability-sample.md +155 -0
  12. package/assets/worker-kits/growthub-geo-seo-v1/examples/geo-audit-sample.md +126 -0
  13. package/assets/worker-kits/growthub-geo-seo-v1/examples/pdf-report-sample.md +207 -0
  14. package/assets/worker-kits/growthub-geo-seo-v1/examples/prospect-proposal-sample.md +184 -0
  15. package/assets/worker-kits/growthub-geo-seo-v1/growthub-meta/README.md +124 -0
  16. package/assets/worker-kits/growthub-geo-seo-v1/growthub-meta/kit-standard.md +116 -0
  17. package/assets/worker-kits/growthub-geo-seo-v1/kit.json +102 -0
  18. package/assets/worker-kits/growthub-geo-seo-v1/output/README.md +114 -0
  19. package/assets/worker-kits/growthub-geo-seo-v1/output-standards.md +143 -0
  20. package/assets/worker-kits/growthub-geo-seo-v1/runtime-assumptions.md +175 -0
  21. package/assets/worker-kits/growthub-geo-seo-v1/setup/check-deps.sh +80 -0
  22. package/assets/worker-kits/growthub-geo-seo-v1/setup/clone-fork.sh +56 -0
  23. package/assets/worker-kits/growthub-geo-seo-v1/setup/verify-env.mjs +152 -0
  24. package/assets/worker-kits/growthub-geo-seo-v1/skills.md +359 -0
  25. package/assets/worker-kits/growthub-geo-seo-v1/templates/brand-visibility-report.md +101 -0
  26. package/assets/worker-kits/growthub-geo-seo-v1/templates/citability-analysis.md +131 -0
  27. package/assets/worker-kits/growthub-geo-seo-v1/templates/client-proposal.md +172 -0
  28. package/assets/worker-kits/growthub-geo-seo-v1/templates/content-analysis.md +136 -0
  29. package/assets/worker-kits/growthub-geo-seo-v1/templates/crawler-access-report.md +115 -0
  30. package/assets/worker-kits/growthub-geo-seo-v1/templates/geo-audit-brief.md +114 -0
  31. package/assets/worker-kits/growthub-geo-seo-v1/templates/geo-score-summary.md +113 -0
  32. package/assets/worker-kits/growthub-geo-seo-v1/templates/llmstxt-plan.md +173 -0
  33. package/assets/worker-kits/growthub-geo-seo-v1/templates/remediation-roadmap.md +150 -0
  34. package/assets/worker-kits/growthub-geo-seo-v1/templates/schema-validation.md +177 -0
  35. package/assets/worker-kits/growthub-geo-seo-v1/templates/technical-foundations.md +108 -0
  36. package/assets/worker-kits/growthub-geo-seo-v1/validation-checklist.md +139 -0
  37. package/assets/worker-kits/growthub-geo-seo-v1/workers/geo-seo-operator/CLAUDE.md +320 -0
  38. package/package.json +1 -1
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ // verify-env.mjs — Verify the geo-seo-claude environment is ready
3
+ // Usage: node setup/verify-env.mjs
4
+ // No network calls are made. All checks are local filesystem only.
5
+
6
+ import { existsSync, readFileSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { resolve, join } from "path";
9
+
10
+ // ─── Helpers ───────────────────────────────────────────────────────────────
11
+
12
+ function parseEnvFile(filePath) {
13
+ if (!existsSync(filePath)) return {};
14
+ const lines = readFileSync(filePath, "utf8").split("\n");
15
+ const env = {};
16
+ for (const line of lines) {
17
+ const trimmed = line.trim();
18
+ if (!trimmed || trimmed.startsWith("#")) continue;
19
+ const eqIdx = trimmed.indexOf("=");
20
+ if (eqIdx === -1) continue;
21
+ const key = trimmed.slice(0, eqIdx).trim();
22
+ const val = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
23
+ env[key] = val;
24
+ }
25
+ return env;
26
+ }
27
+
28
+ function pass(label, note = "") {
29
+ console.log(` PASS ${label}${note ? " — " + note : ""}`);
30
+ }
31
+
32
+ function fail(label, message) {
33
+ console.log(` FAIL ${label} — ${message}`);
34
+ failures.push(label);
35
+ }
36
+
37
+ function warn(label, message) {
38
+ console.log(` WARN ${label} — ${message}`);
39
+ }
40
+
41
+ // ─── State ─────────────────────────────────────────────────────────────────
42
+
43
+ const failures = [];
44
+
45
+ // ─── Load .env ─────────────────────────────────────────────────────────────
46
+
47
+ const envPath = resolve(process.cwd(), ".env");
48
+ const envExamplePath = resolve(process.cwd(), ".env.example");
49
+
50
+ console.log("=== Growthub GEO SEO Studio — Environment Verification ===");
51
+ console.log("");
52
+
53
+ let env = {};
54
+ if (existsSync(envPath)) {
55
+ env = parseEnvFile(envPath);
56
+ pass(".env file", `found at ${envPath}`);
57
+ } else if (existsSync(envExamplePath)) {
58
+ warn(".env file", ".env not found — using .env.example for reference only. Run: cp .env.example .env");
59
+ } else {
60
+ warn(".env file", ".env and .env.example both missing — proceeding with process.env only");
61
+ }
62
+
63
+ // Merge with process.env (process.env takes priority over .env file)
64
+ const config = { ...env, ...process.env };
65
+
66
+ console.log("");
67
+ console.log("--- Fork Path Check ---");
68
+
69
+ // ─── Fork Path ─────────────────────────────────────────────────────────────
70
+
71
+ const forkPathRaw = config["GEO_SEO_FORK_PATH"] || join(homedir(), "geo-seo-claude");
72
+ const forkPath = resolve(forkPathRaw);
73
+
74
+ if (existsSync(forkPath)) {
75
+ pass("GEO_SEO_FORK_PATH", `fork found at ${forkPath}`);
76
+
77
+ // Check key scripts exist in the fork
78
+ const requiredScripts = [
79
+ "scripts/fetch_page.py",
80
+ "scripts/citability_scorer.py",
81
+ "scripts/brand_scanner.py",
82
+ "scripts/generate_pdf_report.py",
83
+ "scripts/llmstxt_generator.py",
84
+ ];
85
+
86
+ for (const scriptPath of requiredScripts) {
87
+ const fullPath = join(forkPath, scriptPath);
88
+ if (existsSync(fullPath)) {
89
+ pass(scriptPath);
90
+ } else {
91
+ warn(scriptPath, `not found in fork at ${fullPath} — may be in a different path in this fork version`);
92
+ }
93
+ }
94
+ } else {
95
+ warn(
96
+ "GEO_SEO_FORK_PATH",
97
+ `fork not found at ${forkPath}. Run: bash setup/clone-fork.sh\n Agent-only mode is available without the fork.`
98
+ );
99
+ }
100
+
101
+ console.log("");
102
+ console.log("--- API Key Check ---");
103
+
104
+ // ─── Anthropic API Key (optional) ─────────────────────────────────────────
105
+
106
+ const anthropicKey = config["ANTHROPIC_API_KEY"];
107
+ if (!anthropicKey) {
108
+ warn("ANTHROPIC_API_KEY", "not set — agent-enhanced analysis requires this key. Core Python analysis works without it.");
109
+ } else if (!anthropicKey.startsWith("sk-ant-")) {
110
+ fail("ANTHROPIC_API_KEY", `key does not start with 'sk-ant-' — this may be an invalid key. Check https://console.anthropic.com`);
111
+ } else if (anthropicKey.length < 40) {
112
+ fail("ANTHROPIC_API_KEY", "key appears too short — verify you copied the full key from https://console.anthropic.com");
113
+ } else {
114
+ pass("ANTHROPIC_API_KEY", "key format looks valid (starts with sk-ant-, adequate length)");
115
+ }
116
+
117
+ // ─── Optional Config ───────────────────────────────────────────────────────
118
+
119
+ console.log("");
120
+ console.log("--- Optional Config ---");
121
+
122
+ const flaskPort = config["FLASK_PORT"] || "5000 (default)";
123
+ pass("FLASK_PORT", `${flaskPort} — Flask CRM dashboard will use this port`);
124
+
125
+ const outputRoot = config["GEO_OUTPUT_ROOT"] || "./output (default)";
126
+ pass("GEO_OUTPUT_ROOT", outputRoot);
127
+
128
+ const playwrightBrowser = config["PLAYWRIGHT_BROWSER"] || "chromium (default)";
129
+ pass("PLAYWRIGHT_BROWSER", playwrightBrowser);
130
+
131
+ // ─── Summary ───────────────────────────────────────────────────────────────
132
+
133
+ console.log("");
134
+ console.log("=== Summary ===");
135
+
136
+ if (failures.length === 0) {
137
+ const forkReady = existsSync(forkPath);
138
+ if (forkReady) {
139
+ console.log("Environment is ready. Fork found. Run your first audit with /geo audit.");
140
+ } else {
141
+ console.log("Environment OK. Fork not found — agent-only mode available.");
142
+ console.log("To enable local-fork mode: bash setup/clone-fork.sh");
143
+ }
144
+ process.exit(0);
145
+ } else {
146
+ console.log(`${failures.length} check(s) failed:`);
147
+ for (const f of failures) {
148
+ console.log(` - ${f}`);
149
+ }
150
+ console.log("Resolve these before running local-fork mode workflows.");
151
+ process.exit(1);
152
+ }
@@ -0,0 +1,359 @@
1
+ # GEO SEO Operator — Master Skill Doc
2
+
3
+ **Source of truth for methodology. Read this file completely before beginning any task.**
4
+
5
+ ---
6
+
7
+ ## QUICK REFERENCE TABLE
8
+
9
+ | Resource | Path |
10
+ |---|---|
11
+ | Agent operating law | `workers/geo-seo-operator/CLAUDE.md` |
12
+ | Brand kit template | `brands/_template/brand-kit.md` |
13
+ | Growthub example brand kit | `brands/growthub/brand-kit.md` |
14
+ | Output contract | `output-standards.md` |
15
+ | Runtime assumptions | `runtime-assumptions.md` |
16
+ | Fork integration notes | `docs/geo-seo-fork-integration.md` |
17
+ | Subagent dispatch | `docs/subagent-dispatch.md` |
18
+ | Scoring methodology | `docs/scoring-methodology.md` |
19
+ | PDF report layer | `docs/pdf-report-layer.md` |
20
+ | GEO audit brief | `templates/geo-audit-brief.md` |
21
+ | Citability analysis | `templates/citability-analysis.md` |
22
+ | Crawler access report | `templates/crawler-access-report.md` |
23
+ | Brand visibility report | `templates/brand-visibility-report.md` |
24
+ | GEO score summary | `templates/geo-score-summary.md` |
25
+ | Content analysis | `templates/content-analysis.md` |
26
+ | Schema validation | `templates/schema-validation.md` |
27
+ | Technical foundations | `templates/technical-foundations.md` |
28
+ | llms.txt plan | `templates/llmstxt-plan.md` |
29
+ | Remediation roadmap | `templates/remediation-roadmap.md` |
30
+ | Client proposal | `templates/client-proposal.md` |
31
+ | Sample audit brief | `examples/geo-audit-sample.md` |
32
+ | Sample citability | `examples/citability-sample.md` |
33
+ | Sample PDF data | `examples/pdf-report-sample.md` |
34
+ | Sample proposal | `examples/prospect-proposal-sample.md` |
35
+
36
+ ---
37
+
38
+ ## STEP 0 — BEFORE ANY TASK, ANSWER THESE QUESTIONS
39
+
40
+ Before producing anything, confirm:
41
+
42
+ 1. Which client or brand is this for?
43
+ 2. What is the target URL or domain?
44
+ 3. What is the audit scope: quick / citability-only / full / specific command?
45
+ 4. What delivery format is required: Markdown only / PDF / both?
46
+ 5. Is the geo-seo-claude fork available locally?
47
+ 6. What execution mode: local-fork / agent-only / hybrid?
48
+
49
+ If any of these are unknown after the 3-question gate in CLAUDE.md, stop and ask.
50
+
51
+ ---
52
+
53
+ ## STEP 1 — LOAD THE BRAND KIT
54
+
55
+ Read `brands/<client-slug>/brand-kit.md` if it exists. Otherwise start from `brands/_template/brand-kit.md`.
56
+
57
+ Extract:
58
+ - client identity (name, slug, industry)
59
+ - target URL and competitor URLs
60
+ - audit scope and delivery format preference
61
+ - messaging tone and guardrails
62
+ - agency context (prospect stage, retainer range)
63
+ - existing deliverables log
64
+
65
+ The brand kit drives all output naming, tone calibration, and proposal pricing context.
66
+
67
+ ---
68
+
69
+ ## STEP 2 — CHECK THE WORKING SUBSTRATE
70
+
71
+ If the user has a local geo-seo-claude fork, inspect it before planning anything.
72
+
73
+ ### Source-of-truth file order in the fork
74
+
75
+ 1. `README.md`
76
+ 2. `geo/` — main skill entry point and command routing
77
+ 3. `skills/` — 14 sub-skill definition files
78
+ 4. `agents/` — 5 subagent definition files
79
+ 5. `scripts/fetch_page.py` — fetches and parses pages via Playwright
80
+ 6. `scripts/citability_scorer.py` — runs the 5-metric citability algorithm
81
+ 7. `scripts/brand_scanner.py` — scans platforms for brand mentions
82
+ 8. `scripts/generate_pdf_report.py` — produces branded PDF via ReportLab
83
+ 9. `scripts/llmstxt_generator.py` — generates llms.txt and llms-full.txt
84
+ 10. `scripts/crm_dashboard.py` — Flask-based CRM dashboard
85
+ 11. `schema/` — 6 JSON-LD templates for structured data recommendations
86
+
87
+ ### What to verify in the fork
88
+
89
+ - Which of the 14 commands are implemented and callable
90
+ - Whether Playwright is installed and chromium browser is available
91
+ - Whether `requirements.txt` dependencies are installed
92
+ - What the Python version is (`python3 --version`)
93
+ - Whether `schema/` contains JSON-LD templates for all common types
94
+ - Whether `agents/` has definitions for all 5 subagents
95
+
96
+ If the fork cannot be inspected, use the frozen assumptions in `runtime-assumptions.md` and label outputs `assumption-based`.
97
+
98
+ ---
99
+
100
+ ## STEP 3 — COMMAND SELECTION LOGIC
101
+
102
+ Select the narrowest command that satisfies the real job.
103
+
104
+ | Command | Primary Use | Phase 2 Subagents? | PDF Output? |
105
+ |---|---|---|---|
106
+ | `/geo audit` | Full GEO + SEO audit, all components | Yes | Optional |
107
+ | `/geo citability` | Citability score only, fast | No | No |
108
+ | `/geo crawlers` | AI crawler permission check | No | No |
109
+ | `/geo brands` | Brand mention and authority scan | No | No |
110
+ | `/geo report` | Structured Markdown report from existing data | No | No |
111
+ | `/geo report-pdf` | Branded PDF report via ReportLab | No | Yes |
112
+ | `/geo content` | E-E-A-T and content quality | Partial | No |
113
+ | `/geo schema` | Structured data validation | No | No |
114
+ | `/geo technical` | Server headers and technical health | No | No |
115
+ | `/geo llmstxt` | Generate llms.txt plan or file | No | No |
116
+ | `/geo quick` | 60-second AI visibility snapshot | No | No |
117
+ | `/geo proposal` | Client proposal with pricing | No | No |
118
+ | `/geo prospect` | Prospect qualification scan | Partial | No |
119
+ | `/geo compare` | Side-by-side GEO comparison of 2+ URLs | Yes | Optional |
120
+
121
+ Default selection rules:
122
+ - "Full audit" → `/geo audit`
123
+ - "Quick look" or "first pass" → `/geo quick`
124
+ - "Check if crawlers can access" → `/geo crawlers`
125
+ - "Can AI cite this page?" → `/geo citability`
126
+ - "Build a proposal for this prospect" → `/geo proposal`
127
+ - "Compare to competitors" → `/geo compare`
128
+
129
+ ---
130
+
131
+ ## STEP 4 — PHASE 1: FETCH AND PARSE LOGIC
132
+
133
+ `fetch_page.py` uses Playwright (chromium) to load the target URL dynamically and extract all signals needed for Phase 2.
134
+
135
+ ### What to extract
136
+
137
+ | Signal | Source | Notes |
138
+ |---|---|---|
139
+ | `robots.txt` | `https://domain.com/robots.txt` | Parse Disallow/Allow rules for each of the 14 AI crawler user-agents |
140
+ | `llms.txt` | `https://domain.com/llms.txt` | Exists / missing / malformed — record file contents if present |
141
+ | `llms-full.txt` | `https://domain.com/llms-full.txt` | Exists / missing |
142
+ | `sitemap.xml` | `https://domain.com/sitemap.xml` | URL count, lastmod dates, priority values |
143
+ | HTML `<title>` | Page source | Record exact value |
144
+ | `<meta description>` | Page source | Record exact value |
145
+ | `<link rel="canonical">` | Page source | Record exact value |
146
+ | Open Graph tags | Page source | og:title, og:description, og:type, og:image |
147
+ | HTTP response headers | Server response | Server, Cache-Control, Content-Type, X-Robots-Tag, Strict-Transport-Security |
148
+ | Page word count | Rendered HTML | After JS execution — Playwright renders dynamic content |
149
+ | Heading hierarchy | Rendered HTML | H1 count, H2 count, nesting order |
150
+ | Structured data | Page source | JSON-LD blocks, Microdata, RDFa |
151
+ | HTTPS status | URL scheme + redirect | Confirm HTTPS redirect from HTTP |
152
+
153
+ In agent-only mode, perform this extraction manually by reading the page via fetch/curl equivalent and parsing visible content.
154
+
155
+ ---
156
+
157
+ ## STEP 5 — PHASE 2: SUBAGENT DISPATCH LOGIC
158
+
159
+ After Phase 1 completes, dispatch all 5 subagents in parallel. Each subagent receives the Phase 1 data as input.
160
+
161
+ ### geo-ai-visibility (25% of GEO Score)
162
+
163
+ **Scope:** AI crawler access and citation format quality
164
+
165
+ **Inputs:** robots.txt parsed rules, llms.txt contents (if any), page HTML structure
166
+
167
+ **What it checks:**
168
+ - Permission status for each of the 14 AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Bingbot, Applebot-Extended, Anthropic-AI, cohere-ai, Meta-ExternalFetcher, YouBot, DuckAssistBot, Scrapy, CCBot, ia_archiver)
169
+ - Whether llms.txt exists and follows the correct format
170
+ - Whether llms-full.txt exists
171
+ - Citation format quality — does the page structure support clean citation by AI systems?
172
+ - Presence of clean canonical URLs, no JavaScript-only content walls
173
+
174
+ **Outputs:** Crawler permission matrix (14 rows), llms.txt status, citation format score (0–100)
175
+
176
+ ---
177
+
178
+ ### geo-content (20% of GEO Score)
179
+
180
+ **Scope:** E-E-A-T signals, answer block quality, content self-containment
181
+
182
+ **Inputs:** Rendered page HTML, word count, heading structure, author markup
183
+
184
+ **What it checks:**
185
+ - Experience signals: case studies, original data, first-person examples
186
+ - Expertise signals: author credentials, bylines, About page depth
187
+ - Authoritativeness signals: external citations, backlink signals (if available), Wikipedia mentions
188
+ - Trustworthiness signals: HTTPS, contact info, privacy policy, review count
189
+ - Answer block quality: does the page contain self-contained answer paragraphs that AI systems can quote directly?
190
+ - Self-containment check: word count vs. pronoun density — pages with high pronoun density relative to noun density score lower
191
+ - Statistical density: presence of percentages, numbered lists, data references
192
+ - Uniqueness signals: original research, proprietary data, non-generic claims
193
+
194
+ **Outputs:** E-E-A-T score (0–100), content quality score (0–100), top 3 content gaps
195
+
196
+ ---
197
+
198
+ ### geo-platform-analysis (10% of GEO Score)
199
+
200
+ **Scope:** Readiness for specific AI search platforms
201
+
202
+ **Inputs:** Page structure, schema markup, llms.txt status, content signals
203
+
204
+ **What it checks:**
205
+ - ChatGPT readiness: Browse with Bing access, clean URL structure, answer-block format
206
+ - Perplexity readiness: Direct URL crawlability, citation format, structured answers
207
+ - Google AI Overviews readiness: E-E-A-T signals, structured data, FAQ schema, featured snippet optimization
208
+ - Gemini readiness: Google entity graph signals, Knowledge Panel readiness, schema breadth
209
+
210
+ **Outputs:** Platform readiness table (4 platforms × 5 signals × score), composite platform score (0–100)
211
+
212
+ ---
213
+
214
+ ### geo-schema (10% of GEO Score)
215
+
216
+ **Scope:** Structured data coverage and validation
217
+
218
+ **Inputs:** Page source JSON-LD blocks, Microdata, RDFa markup
219
+
220
+ **What it checks:**
221
+ - Which schema types are present (Organization, WebSite, Article, BreadcrumbList, FAQPage, HowTo, Product, LocalBusiness, etc.)
222
+ - Validation errors (missing required properties, incorrect value types)
223
+ - Missing recommended schema types for the page type
224
+ - Schema richness score — number of types × completeness per type
225
+
226
+ **Outputs:** Schema type coverage table, validation error list, missing types list, schema score (0–100)
227
+
228
+ ---
229
+
230
+ ### geo-technical (15% of GEO Score)
231
+
232
+ **Scope:** Technical SEO and server health
233
+
234
+ **Inputs:** HTTP response headers, HTTPS status, page load signals, robots.txt
235
+
236
+ **What it checks:**
237
+ - HTTPS enforcement (redirect from HTTP, HSTS header)
238
+ - Mobile friendliness signals (viewport meta tag, responsive CSS indicators)
239
+ - robots.txt validity (valid syntax, no wildcard blocks on critical paths)
240
+ - Sitemap accessibility (sitemap.xml found, linked from robots.txt)
241
+ - Core Web Vitals signals (from Lighthouse or page source — LCP hints, CLS hints, FID/INP hints)
242
+ - Server headers (Cache-Control, Content-Encoding, CDN indicators)
243
+ - Page speed indicators (image optimization signals, script loading strategy)
244
+
245
+ **Outputs:** Server headers table, Core Web Vitals signal table, technical score (0–100), critical fixes list
246
+
247
+ ---
248
+
249
+ ## STEP 6 — GEO SCORE SYNTHESIS
250
+
251
+ Apply the weighted formula after all subagent results are collected.
252
+
253
+ ### GEO Score Formula
254
+
255
+ ```
256
+ GEO Score = (AI Citability × 0.25) + (Brand Authority × 0.20) + (Content Quality × 0.20) +
257
+ (Technical Foundations × 0.15) + (Structured Data × 0.10) + (Platform Optimization × 0.10)
258
+ ```
259
+
260
+ ### Component Score Normalization
261
+
262
+ Each component subagent returns a raw score 0–100. If a component cannot be scored (data gap), use 50 as the neutral default and flag the component as `data-gap`.
263
+
264
+ ### Letter Grade Thresholds
265
+
266
+ | Grade | Score Range | Meaning |
267
+ |---|---|---|
268
+ | A | 85–100 | Highly optimized for AI search — strong citability, clean access, rich schema |
269
+ | B | 70–84 | Good AI visibility — some gaps, addressable in one sprint cycle |
270
+ | C | 55–69 | Moderate visibility — missing key citability signals, schema gaps, crawler issues |
271
+ | D | 40–54 | Poor AI visibility — likely blocked or thin content, major remediation needed |
272
+ | F | Below 40 | Not AI-search-ready — crawlers blocked, no schema, low citability |
273
+
274
+ ### Score Interpretation for Client Communication
275
+
276
+ - **A (85+):** "Your site is well-positioned for AI-driven search. We recommend ongoing monitoring and targeted improvements to maintain this position."
277
+ - **B (70–84):** "Good foundation. Targeted improvements in [lowest component] can push you into the A tier within 30–60 days."
278
+ - **C (55–69):** "Moderate visibility. You are not capturing significant AI-referred traffic yet. A full remediation roadmap is recommended."
279
+ - **D (40–54):** "Your site has significant AI search blindspots. AI systems may not be citing or recommending your content at all."
280
+ - **F (below 40):** "Critical issues detected. AI crawlers may be blocked outright. Immediate technical and content remediation required."
281
+
282
+ ---
283
+
284
+ ## STEP 7 — CITABILITY ALGORITHM
285
+
286
+ The citability score measures how well a page can be cleanly quoted and cited by AI systems.
287
+
288
+ ### 5-Metric Algorithm
289
+
290
+ | Metric | Weight | What It Measures |
291
+ |---|---|---|
292
+ | Answer Block Quality | 30% | Do paragraphs contain complete, self-sufficient answers AI can quote verbatim? |
293
+ | Self-Containment | 25% | Can a paragraph be understood without reading surrounding context? Low pronoun-to-noun ratio = better. |
294
+ | Structural Readability | 20% | Does the page use headings, short paragraphs, and numbered lists to enable AI parsing? |
295
+ | Statistical Density | 15% | Does the page contain specific numbers, percentages, and data references AI prefers to cite? |
296
+ | Uniqueness Signals | 10% | Does the content contain proprietary claims, original research, or data not found elsewhere? |
297
+
298
+ ### Computing Each Metric
299
+
300
+ - **Answer Block Quality:** Score each paragraph 0–10 on: clear subject, predicate, supporting evidence, no unresolved pronouns. Average across all paragraphs.
301
+ - **Self-Containment:** Count pronoun references (it, they, this, that) as a fraction of total noun references. Lower ratio = higher score.
302
+ - **Structural Readability:** Check presence of: H1 (required), H2s (≥2), numbered/bulleted lists (≥1), paragraph length ≤150 words, no wall-of-text sections.
303
+ - **Statistical Density:** Count numerical data references (% signs, numbered lists, dates with years, dollar figures) per 1000 words. Optimal: 8–15 data points per 1000 words.
304
+ - **Uniqueness Signals:** Check for: "first-party study," "based on our data," "internal research," proprietary methodology references, or unique terminology.
305
+
306
+ ---
307
+
308
+ ## STEP 8 — REMEDIATION ROADMAP LOGIC
309
+
310
+ Build the roadmap by ranking all findings by impact × urgency.
311
+
312
+ ### Priority Matrix
313
+
314
+ | Priority | Impact | Urgency | Action |
315
+ |---|---|---|---|
316
+ | P0 — Critical | High | Immediate | Fix this week — crawlers blocked, HTTPS broken, major schema errors |
317
+ | P1 — High | High | This sprint | Add llms.txt, fix citability blockers, add missing schema types |
318
+ | P2 — Medium | Medium | Week 2–3 | E-E-A-T improvements, statistical density, answer block rewrites |
319
+ | P3 — Low | Low | Week 4+ | Brand authority campaigns, platform optimization, monitoring setup |
320
+
321
+ ### 4-Week Sprint Structure
322
+
323
+ - **Week 1:** P0 and P1 items — all technical and crawler-access blockers
324
+ - **Week 2:** P2 items — content quality improvements, schema additions
325
+ - **Week 3:** P2 continuation — E-E-A-T depth, self-containment rewrites
326
+ - **Week 4:** P3 items — brand platform seeding, monitoring, reporting loop setup
327
+
328
+ ---
329
+
330
+ ## STEP 9 — OUTPUT ORDER
331
+
332
+ Produce artifacts in this strict order:
333
+
334
+ 1. GEO Audit Brief (`templates/geo-audit-brief.md`)
335
+ 2. Citability Analysis (`templates/citability-analysis.md`)
336
+ 3. Crawler Access Report (`templates/crawler-access-report.md`)
337
+ 4. Brand Visibility Report (`templates/brand-visibility-report.md`)
338
+ 5. GEO Score Summary (`templates/geo-score-summary.md`)
339
+ 6. Content Analysis (`templates/content-analysis.md`)
340
+ 7. Schema Validation (`templates/schema-validation.md`)
341
+ 8. Technical Foundations (`templates/technical-foundations.md`)
342
+ 9. llms.txt Plan (`templates/llmstxt-plan.md`)
343
+ 10. Remediation Roadmap (`templates/remediation-roadmap.md`)
344
+ 11. Client Proposal (`templates/client-proposal.md`) — only if requested
345
+
346
+ ---
347
+
348
+ ## STEP 10 — QUALITY BAR
349
+
350
+ Good output looks like this:
351
+
352
+ - All scores derived from actual page data — no invented numbers
353
+ - GEO Score uses the exact formula defined in Step 6 — no rounding before final aggregate
354
+ - Citability analysis applies all 5 metrics, not just the top 2
355
+ - Crawler access report covers all 14 AI crawlers by exact user-agent string
356
+ - Remediation roadmap is sequenced by impact × urgency, not alphabetically
357
+ - Client proposal grounds ROI projections in AI search traffic trend data
358
+ - Every output file can be handed to a client or developer and acted on immediately
359
+ - No filler paragraphs — every sentence either presents data, explains a finding, or specifies an action
@@ -0,0 +1,101 @@
1
+ # Brand Visibility Report
2
+
3
+ > Template: `templates/brand-visibility-report.md`
4
+ > Save output to: `output/<client-slug>/<project-slug>/BrandVisibilityReport_v<N>_<YYYYMMDD>.md`
5
+
6
+ ---
7
+
8
+ ## Brand Audited
9
+
10
+ | Field | Value |
11
+ |---|---|
12
+ | Brand Name | <!-- client_name --> |
13
+ | Primary Domain | <!-- https://domain.com --> |
14
+ | Brand Slug | <!-- brand-slug --> |
15
+ | Scan Date | <!-- YYYY-MM-DD --> |
16
+ | Execution Mode | <!-- local-fork (brand_scanner.py) / agent-only --> |
17
+ | Script Used | <!-- scripts/brand_scanner.py / manual --> |
18
+
19
+ ---
20
+
21
+ ## Platform Scan Results
22
+
23
+ | Platform | Brand Present | Mention Count | Sentiment | Primary URL Found | Notes |
24
+ |---|---|---|---|---|---|
25
+ | YouTube | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral / negative / mixed --> | <!-- https://... --> | <!-- channel / mentions in videos --> |
26
+ | Reddit | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral / negative / mixed --> | <!-- subreddit or post URL --> | <!-- notable threads --> |
27
+ | Wikipedia | <!-- yes / no / partial --> | <!-- N --> | <!-- neutral --> | <!-- https://... --> | <!-- article or mention in related article --> |
28
+ | LinkedIn | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral / mixed --> | <!-- https://... --> | <!-- company page / employee mentions --> |
29
+ | Twitter / X | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral / negative / mixed --> | <!-- https://x.com/... --> | <!-- handle / mentions --> |
30
+ | GitHub | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral --> | <!-- https://github.com/... --> | <!-- repos / mentions --> |
31
+ | Quora | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral / negative --> | <!-- https://... --> | <!-- answers mentioning brand --> |
32
+ | Hacker News | <!-- yes / no / partial --> | <!-- N --> | <!-- positive / neutral / negative --> | <!-- https://news.ycombinator.com/... --> | <!-- posts / comments --> |
33
+
34
+ ---
35
+
36
+ ## Platform Detail Notes
37
+
38
+ ### YouTube
39
+ <!-- Describe what was found: official channel exists / brand mentioned in competitor content / no presence found -->
40
+
41
+ ### Reddit
42
+ <!-- Describe key threads, subreddits where brand appears, sentiment breakdown -->
43
+
44
+ ### Wikipedia
45
+ <!-- Note: own Wikipedia article / mentioned in industry article / no presence -->
46
+
47
+ ### LinkedIn
48
+ <!-- Official company page status, follower count if visible, employee mention density -->
49
+
50
+ ### Twitter / X
51
+ <!-- Official handle / mention volume / notable brand advocates or critics -->
52
+
53
+ ### GitHub
54
+ <!-- Open source repos / developer tools / mentions in issues or discussions -->
55
+
56
+ ### Quora
57
+ <!-- Questions answered by brand representatives / brand mentioned in answers -->
58
+
59
+ ### Hacker News
60
+ <!-- Any "Show HN" posts / brand mentioned in discussions / competitor comparisons -->
61
+
62
+ ---
63
+
64
+ ## Brand Authority Score
65
+
66
+ | Component | Score (0–100) | Weight | Weighted Score | Notes |
67
+ |---|---|---|---|---|
68
+ | Platform presence breadth | <!-- N --> | 30% | <!-- N × 0.30 --> | <!-- # platforms with meaningful presence / 8 --> |
69
+ | Sentiment quality | <!-- N --> | 25% | <!-- N × 0.25 --> | <!-- ratio of positive to negative mentions --> |
70
+ | Mention volume | <!-- N --> | 20% | <!-- N × 0.20 --> | <!-- total mentions normalized vs. category benchmark --> |
71
+ | Wikipedia or authority link | <!-- N --> | 15% | <!-- N × 0.15 --> | <!-- Wikipedia presence = 100, none = 0 --> |
72
+ | Developer / technical community | <!-- N --> | 10% | <!-- N × 0.10 --> | <!-- GitHub + HN combined signal --> |
73
+ | **TOTAL Brand Authority Score** | | **100%** | <!-- sum --> | |
74
+
75
+ ---
76
+
77
+ ## Gap Analysis
78
+
79
+ **Platforms with no meaningful presence:**
80
+ - <!-- Platform: why it matters and what to build there -->
81
+ - <!-- Platform: why it matters and what to build there -->
82
+
83
+ **Sentiment risks:**
84
+ - <!-- Any platform with negative-dominant sentiment: what is being said -->
85
+
86
+ **Brand authority gaps vs. competitors:**
87
+ | Gap | Competitor Advantage | Recommended Response |
88
+ |---|---|---|
89
+ | <!-- gap --> | <!-- competitor URL or example --> | <!-- recommended action --> |
90
+ | <!-- gap --> | <!-- competitor URL or example --> | <!-- recommended action --> |
91
+
92
+ ---
93
+
94
+ ## Recommended Actions
95
+
96
+ | Priority | Platform | Action | Timeline | Expected Impact |
97
+ |---|---|---|---|---|
98
+ | P1 | <!-- platform --> | <!-- specific action --> | <!-- Week 1-2 --> | <!-- High / Medium --> |
99
+ | P1 | <!-- platform --> | <!-- specific action --> | <!-- Week 1-2 --> | <!-- High / Medium --> |
100
+ | P2 | <!-- platform --> | <!-- specific action --> | <!-- Week 2-4 --> | <!-- Medium --> |
101
+ | P3 | <!-- platform --> | <!-- specific action --> | <!-- Week 4+ --> | <!-- Low / Long-term --> |