antigravity-seo-kit 1.0.0 → 1.0.2

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SEO Kit for Google Antigravity
2
2
 
3
- > **Professional SEO Analysis Toolkit** — 35 specialized skills organized into a 5-phase SEO lifecycle for comprehensive audits, E-E-A-T analysis, schema markup, GEO optimization, keyword research, audience analysis, AI prompt research, and more. Built for [Google Antigravity](https://deepmind.google/technologies/antigravity/) AI agent platform.
3
+ > **Professional SEO Analysis Toolkit** — Comprehensive AI-powered SEO analysis with specialized skills for technical audit, E-E-A-T, schema markup, GEO optimization, and more. Built for [Google Antigravity](https://deepmind.google/technologies/antigravity/) AI agent platform.
4
4
 
5
5
  ## ⚡ Quick Install
6
6
 
@@ -12,36 +12,17 @@ npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
12
12
 
13
13
  ## Features
14
14
 
15
- - **35 specialized SEO skills** organized into a 5-phase lifecycle
16
- - **Master Orchestrator** (`/seo-run`) auto-detects project phase, suggests next step
17
- - **Technical SEO Audit** with 9 categories (crawlability, indexability, Core Web Vitals, etc.)
18
- - **E-E-A-T Content Quality** analysis with Sept 2025 QRG update
19
- - **Schema Markup** detection, validation, and JSON-LD generation
20
- - **AI Search Optimization (GEO)** for AI Overviews, ChatGPT, Perplexity
21
- - **Agentic SEO** audit Action schema, A2A readiness, API discoverability
22
- - **Content Strategy** — gap analysis, topical authority, entity SEO, 30/60/90 roadmap
23
- - **Keyword Research** seed expansion, volume/difficulty, intent classification, clustering
24
- - **Audience Analysis** — persona definition, journey mapping, community language mining
25
- - **AI Prompt Research** — conversational query patterns, multi-turn intent chains
26
- - **Backlink Analysis** — profile, toxic links, competitor link gap
27
- - **Local SEO** with GBP, NAP consistency, citations, reviews, Maps intelligence
28
- - **Programmatic SEO** for pages at scale with quality gates
29
- - **Google Search Console & Analytics** integration
30
- - **Auto-Fix Generator** — ready-to-use meta tags, schema, robots.txt, redirects
31
- - **SEO Experiment Tracking** — A/B tests with baseline/measurement cycle
32
- - **Extension System** for DataForSEO, Ahrefs, Semrush, and AI image generation
33
-
34
- ## SEO Lifecycle
15
+ - **Full SEO Lifecycle** Onboard, Research, Audit, Strategy, Execute, Monitor
16
+ - **Technical SEO Audit** — Crawlability, indexability, Core Web Vitals, and more
17
+ - **E-E-A-T Content Quality** analysis aligned with latest Google QRG
18
+ - **Schema Markup** Detection, validation, and JSON-LD generation
19
+ - **AI Search Optimization (GEO)** — Visibility in AI Overviews, ChatGPT, Perplexity
20
+ - **Content Strategy** Gap analysis, topical authority, entity SEO
21
+ - **Local SEO** — GBP, NAP consistency, Maps intelligence
22
+ - **Auto-Fix Generator** — Ready-to-use meta tags, schema, robots.txt, redirects
23
+ - **Extension System** for third-party SEO data providers
35
24
 
36
- ```
37
- 📋 ONBOARD → 🔎 RESEARCH → 🔍 AUDIT → 🧠 STRATEGY → ⚡ EXECUTE → 📈 MONITOR → (re-audit)
38
- ```
39
-
40
- **Just remember one command:** `/seo-run <domain>` — it guides you through everything.
41
-
42
- ## Commands
43
-
44
- ### CLI Commands
25
+ ## CLI Commands
45
26
 
46
27
  ```bash
47
28
  # Install SEO Kit
@@ -53,84 +34,33 @@ npx antigravity-seo-kit update
53
34
  # Check installation status
54
35
  npx antigravity-seo-kit status
55
36
 
56
- # List activated devices
37
+ # Manage devices
57
38
  npx antigravity-seo-kit devices
58
-
59
- # Remove a device
60
39
  npx antigravity-seo-kit devices remove <deviceId>
61
40
 
62
41
  # Uninstall
63
42
  npx antigravity-seo-kit uninstall --confirm
64
43
  ```
65
44
 
66
- ### SEO Workflows (inside Antigravity)
67
-
68
- | Workflow | Phase | Skills | Purpose |
69
- |----------|-------|--------|---------|
70
- | `/seo-run` | Master | Delegates | Auto-detect phase, suggest next step |
71
- | `/seo-onboard` | 1 | 4 | Project setup, API check, brand identity, personas |
72
- | `/seo-research` | Research | 5 | Keyword research, audience, prompt patterns |
73
- | `/seo-audit` | 2 | 9 | Full website diagnostic, Health Score |
74
- | `/seo-strategy` | 3 | 10 | Content gaps, entity, authority, roadmap |
75
- | `/seo-execute` | 4 | 6 | Code fixes, schema, redirects, content |
76
- | `/seo-monitor` | 5 | 6 | Experiments, AI citability, traffic |
77
- | `/seo-local-suite` | Special | 2 | Local SEO + Maps intelligence |
78
- | `/seo-page` | Utility | 4 | Deep single-page analysis |
79
-
80
- > **Direct Skill Access**: You can always call any of the 35 skills directly by name (e.g., "Run seo-entity for example.com") without going through the lifecycle.
81
-
82
45
  ## System Requirements
83
46
 
84
47
  - **Node.js** ≥ 18 (for CLI installer)
85
48
  - **Python** ≥ 3.11 (for analysis scripts)
86
49
  - **Google Antigravity** or compatible AI agent platform
87
50
 
88
- ## Setup After Installation
89
-
90
- ```bash
91
- # 1. Install Python dependencies
92
- pip install -r requirements.txt
93
-
94
- # 2. (Optional) Install Google API dependencies
95
- pip install -r requirements-google.txt
96
-
97
- # 3. (Optional) Install Playwright for visual analysis
98
- pip install playwright && playwright install chromium
99
-
100
- # 4. Open your workspace in Google Antigravity
101
- # 5. Start with: /seo-run yourdomain.com
102
- ```
103
-
104
- ## Extensions
105
-
106
- | Extension | What it Adds |
107
- |-----------|-------------|
108
- | **DataForSEO** | 22 commands: live SERP, keywords, backlinks, on-page analysis, AI visibility |
109
- | **Banana Image Gen** | 6 commands: OG image, hero, product, infographic, custom, batch via Gemini AI |
110
- | **Ahrefs MCP** | DR/UR, backlink quality, content gap, referring domains |
111
- | **Semrush MCP** | Keyword gap, toxic links, backlink audit, domain analytics |
112
-
113
51
  ## License Management
114
52
 
115
- Each license key supports up to **3 devices** simultaneously. Manage your devices:
116
-
117
- ```bash
118
- # View activated devices
119
- npx antigravity-seo-kit devices
120
-
121
- # Remove a device to free up a slot
122
- npx antigravity-seo-kit devices remove <deviceId>
123
- ```
53
+ Each license key supports multiple devices simultaneously. Manage your devices with the `devices` command.
124
54
 
125
55
  ## License
126
56
 
127
57
  This software is distributed under a **Commercial License**. See [LICENSE](LICENSE) for full terms.
128
58
 
129
- - ✅ Use on up to 3-20 devices per license
59
+ - ✅ Use on multiple devices per license
130
60
  - ✅ Modify for personal/business use
131
61
  - ❌ Redistribution prohibited
132
62
  - ❌ Sublicensing prohibited
133
63
 
134
64
  ## Support
135
65
 
136
- For license inquiries and support, visit: [https://antigravityseokit.solann.io/](https://antigravityseokit.solann.io/)
66
+ For license inquiries and support: [https://antigravityseokit.solann.io/](https://antigravityseokit.solann.io/)
package/lib/downloader.js CHANGED
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  const https = require('https');
4
- const http = require('http');
5
4
  const zlib = require('zlib');
6
5
  const fs = require('fs');
7
6
  const path = require('path');
@@ -19,11 +18,17 @@ function downloadBuffer(url, headers = {}, { timeout = 60000, maxRedirects = 5 }
19
18
  }
20
19
 
21
20
  const parsed = new URL(url);
22
- const transport = parsed.protocol === 'https:' ? https : http;
21
+
22
+ // SECURITY: Reject HTTP — license key must never travel over cleartext
23
+ if (parsed.protocol !== 'https:') {
24
+ return reject(new Error('HTTPS required for secure asset downloads. Refusing HTTP connection.'));
25
+ }
26
+
27
+ const transport = https;
23
28
 
24
29
  const options = {
25
30
  hostname: parsed.hostname,
26
- port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
31
+ port: parsed.port || 443,
27
32
  path: parsed.pathname + parsed.search,
28
33
  method: 'GET',
29
34
  headers: {
@@ -34,9 +39,13 @@ function downloadBuffer(url, headers = {}, { timeout = 60000, maxRedirects = 5 }
34
39
  };
35
40
 
36
41
  const req = transport.request(options, (res) => {
37
- // Follow redirects
42
+ // Follow redirects — but only to HTTPS
38
43
  if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
39
- return downloadBuffer(res.headers.location, headers, { timeout, maxRedirects: maxRedirects - 1 })
44
+ const redirectUrl = new URL(res.headers.location, url);
45
+ if (redirectUrl.protocol !== 'https:') {
46
+ return reject(new Error('Blocked redirect from HTTPS to HTTP. Possible downgrade attack.'));
47
+ }
48
+ return downloadBuffer(redirectUrl.href, headers, { timeout, maxRedirects: maxRedirects - 1 })
40
49
  .then(resolve)
41
50
  .catch(reject);
42
51
  }
package/lib/installer.js CHANGED
@@ -12,41 +12,11 @@ const { generateFingerprint, getDeviceName } = require('./fingerprint');
12
12
  const api = require('./api');
13
13
  const { downloadAndExtract } = require('./downloader');
14
14
 
15
- // ─── Legacy arrays (for uninstall/status of older installs without manifest)
16
-
17
- const SEO_SKILL_DIRS = [
18
- 'seo', 'seo-agentic', 'seo-answer', 'seo-audience', 'seo-audit',
19
- 'seo-authority', 'seo-backlink', 'seo-brand-sentiment', 'seo-citemet',
20
- 'seo-coccoc-optimizer', 'seo-competitor-pages', 'seo-content',
21
- 'seo-content-gap', 'seo-dataforseo', 'seo-entity', 'seo-fan-out-generator',
22
- 'seo-fix', 'seo-geo', 'seo-geo-monitor', 'seo-google', 'seo-hreflang',
23
- 'seo-image-gen', 'seo-images', 'seo-keyword', 'seo-llmstxt', 'seo-local',
24
- 'seo-logs', 'seo-maps', 'seo-migration', 'seo-page', 'seo-plan',
25
- 'seo-programmatic', 'seo-prompt-research', 'seo-reddit-scraper',
26
- 'seo-schema', 'seo-sitemap', 'seo-social-zalo', 'seo-source-context',
27
- 'seo-technical', 'seo-test', 'seo-topical-authority', 'seo-video',
28
- 'seo-video-transcript', 'seo-visual-search',
29
- ];
30
-
31
- const SEO_WORKFLOW_FILES = [
32
- 'seo-audit.md', 'seo-auto-run.md', 'seo-execute.md',
33
- 'seo-llm-visibility.md', 'seo-local-suite.md', 'seo-monitor.md',
34
- 'seo-onboard.md', 'seo-page.md', 'seo-research.md', 'seo-run.md',
35
- 'seo-social-commerce.md', 'seo-strategy.md',
36
- ];
37
-
38
- const SEO_RULE_FILES = [
39
- 'seo-agent-security.md', 'seo-anti-hallucination.md',
40
- 'seo-auto-routing.md', 'seo-domain-project.md',
41
- 'seo-output-convention.md', 'seo-provider-priority.md',
42
- 'seo-report-format.md',
43
- ];
44
-
45
- const SEO_AGENT_FILES = [
46
- 'seo-auditor.md', 'seo-strategist.md', 'seo-content-writer.md',
47
- 'seo-ai-specialist.md', 'seo-local-expert.md', 'seo-growth-hacker.md',
48
- 'seo-data-analyst.md', 'seo-migration-expert.md',
49
- ];
15
+ // ─── Legacy cleanup (for uninstall of older installs without manifest) ───────
16
+ // No hardcoded names — scan directories for seo-* prefixed files/folders.
17
+
18
+ const LEGACY_SEO_PREFIX = 'seo-';
19
+ const LEGACY_DIRS = ['skills', 'workflows', 'rules', 'agents'];
50
20
 
51
21
  // ─── Install Command ────────────────────────────────────────────────────────
52
22
 
@@ -215,44 +185,26 @@ async function uninstall(cwd) {
215
185
 
216
186
  /**
217
187
  * Legacy uninstall for installs before v1.0.0 (without manifest).
188
+ * Scans for seo-* prefixed files/dirs instead of hardcoded names.
218
189
  */
219
190
  function legacyUninstall(cwd) {
220
191
  let totalRemoved = 0;
221
-
222
- // Remove skills
223
- const skillsDir = path.join(cwd, '.agent', 'skills');
224
- for (const skillDir of SEO_SKILL_DIRS) {
225
- const target = path.join(skillsDir, skillDir);
226
- totalRemoved += removeRecursive(target);
227
- }
228
-
229
- // Remove workflows
230
- const workflowsDir = path.join(cwd, '.agent', 'workflows');
231
- for (const wfFile of SEO_WORKFLOW_FILES) {
232
- const target = path.join(workflowsDir, wfFile);
233
- if (fs.existsSync(target)) {
234
- fs.unlinkSync(target);
235
- totalRemoved++;
236
- }
237
- }
238
-
239
- // Remove rules
240
- const rulesDir = path.join(cwd, '.agent', 'rules');
241
- for (const ruleFile of SEO_RULE_FILES) {
242
- const target = path.join(rulesDir, ruleFile);
243
- if (fs.existsSync(target)) {
244
- fs.unlinkSync(target);
245
- totalRemoved++;
246
- }
247
- }
248
-
249
- // Remove agents
250
- const agentsDir = path.join(cwd, '.agent', 'agents');
251
- for (const agentFile of SEO_AGENT_FILES) {
252
- const target = path.join(agentsDir, agentFile);
253
- if (fs.existsSync(target)) {
254
- fs.unlinkSync(target);
255
- totalRemoved++;
192
+ const agentDir = path.join(cwd, '.agent');
193
+
194
+ for (const subDir of LEGACY_DIRS) {
195
+ const dirPath = path.join(agentDir, subDir);
196
+ if (!fs.existsSync(dirPath)) continue;
197
+
198
+ const entries = fs.readdirSync(dirPath);
199
+ for (const entry of entries) {
200
+ if (!entry.startsWith(LEGACY_SEO_PREFIX) && entry !== 'seo') continue;
201
+ const target = path.join(dirPath, entry);
202
+ if (fs.statSync(target).isDirectory()) {
203
+ totalRemoved += removeRecursive(target);
204
+ } else {
205
+ fs.unlinkSync(target);
206
+ totalRemoved++;
207
+ }
256
208
  }
257
209
  }
258
210
 
@@ -308,20 +260,17 @@ async function status(cwd) {
308
260
  }
309
261
  console.log(` ${colorize('cyan', 'Files:')} ${existingFiles}/${config.installedFiles.length} present`);
310
262
  } else {
311
- // Legacy: check from hardcoded arrays
312
- const skillsDir = path.join(cwd, '.agent', 'skills');
313
- let installedSkills = 0;
314
- for (const s of SEO_SKILL_DIRS) {
315
- if (fs.existsSync(path.join(skillsDir, s))) installedSkills++;
316
- }
317
- console.log(` ${colorize('cyan', 'Skills:')} ${installedSkills}/${SEO_SKILL_DIRS.length} installed`);
318
-
319
- const workflowsDir = path.join(cwd, '.agent', 'workflows');
320
- let installedWorkflows = 0;
321
- for (const w of SEO_WORKFLOW_FILES) {
322
- if (fs.existsSync(path.join(workflowsDir, w))) installedWorkflows++;
263
+ // Legacy: scan for seo-* prefixed entries
264
+ const agentDir = path.join(cwd, '.agent');
265
+ let totalLegacy = 0;
266
+ for (const subDir of LEGACY_DIRS) {
267
+ const dirPath = path.join(agentDir, subDir);
268
+ if (!fs.existsSync(dirPath)) continue;
269
+ for (const entry of fs.readdirSync(dirPath)) {
270
+ if (entry.startsWith(LEGACY_SEO_PREFIX) || entry === 'seo') totalLegacy++;
271
+ }
323
272
  }
324
- console.log(` ${colorize('cyan', 'Workflows:')} ${installedWorkflows}/${SEO_WORKFLOW_FILES.length} installed`);
273
+ console.log(` ${colorize('cyan', 'Components:')} ${totalLegacy} installed (legacy)`);
325
274
  }
326
275
  console.log('');
327
276
 
package/lib/utils.js CHANGED
@@ -170,7 +170,7 @@ function isValidKeyFormat(key) {
170
170
  const BANNER = `
171
171
  ${colorize('cyan', '╔═══════════════════════════════════════════════════════╗')}
172
172
  ${colorize('cyan', '║')} ${colorize('bold', '🔍 SEO Kit for Google Antigravity')} ${colorize('cyan', '║')}
173
- ${colorize('cyan', '║')} ${colorize('dim', 'v1.0.0 — Professional SEO Analysis Toolkit')} ${colorize('cyan', '║')}
173
+ ${colorize('cyan', '║')} ${colorize('dim', 'v1.0.2 — Professional SEO Analysis Toolkit')} ${colorize('cyan', '║')}
174
174
  ${colorize('cyan', '╚═══════════════════════════════════════════════════════╝')}
175
175
  `;
176
176
 
@@ -209,7 +209,13 @@ function readLicenseFile(cwd) {
209
209
  const licensePath = path.join(cwd, LICENSE_FILE);
210
210
  if (!fs.existsSync(licensePath)) return null;
211
211
  try {
212
- return JSON.parse(fs.readFileSync(licensePath, 'utf-8'));
212
+ const data = JSON.parse(fs.readFileSync(licensePath, 'utf-8'));
213
+ // Deobfuscate the key if stored obfuscated
214
+ if (data._k && !data.key) {
215
+ data.key = deobfuscateKey(data._k);
216
+ delete data._k;
217
+ }
218
+ return data;
213
219
  } catch {
214
220
  return null;
215
221
  }
@@ -217,7 +223,37 @@ function readLicenseFile(cwd) {
217
223
 
218
224
  function writeLicenseFile(cwd, data) {
219
225
  const licensePath = path.join(cwd, LICENSE_FILE);
220
- fs.writeFileSync(licensePath, JSON.stringify(data, null, 2), 'utf-8');
226
+ // Obfuscate the key before writing
227
+ const toWrite = { ...data };
228
+ if (toWrite.key) {
229
+ toWrite._k = obfuscateKey(toWrite.key);
230
+ delete toWrite.key;
231
+ }
232
+ fs.writeFileSync(licensePath, JSON.stringify(toWrite, null, 2), 'utf-8');
233
+ }
234
+
235
+ /**
236
+ * Simple XOR obfuscation with machine-derived salt.
237
+ * NOT encryption — just prevents casual copy/paste of keys.
238
+ */
239
+ function obfuscateKey(key) {
240
+ const salt = require('os').hostname() + require('os').platform();
241
+ const buf = Buffer.from(key, 'utf-8');
242
+ const saltBuf = Buffer.from(salt, 'utf-8');
243
+ for (let i = 0; i < buf.length; i++) {
244
+ buf[i] ^= saltBuf[i % saltBuf.length];
245
+ }
246
+ return buf.toString('base64');
247
+ }
248
+
249
+ function deobfuscateKey(encoded) {
250
+ const salt = require('os').hostname() + require('os').platform();
251
+ const buf = Buffer.from(encoded, 'base64');
252
+ const saltBuf = Buffer.from(salt, 'utf-8');
253
+ for (let i = 0; i < buf.length; i++) {
254
+ buf[i] ^= saltBuf[i % saltBuf.length];
255
+ }
256
+ return buf.toString('utf-8');
221
257
  }
222
258
 
223
259
  function removeLicenseFile(cwd) {
@@ -250,5 +286,5 @@ module.exports = {
250
286
  writeLicenseFile,
251
287
  removeLicenseFile,
252
288
  LICENSE_FILE,
253
- PACKAGE_VERSION: '1.0.0',
289
+ PACKAGE_VERSION: '1.0.2',
254
290
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antigravity-seo-kit",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Professional SEO Analysis Toolkit for Google Antigravity AI Agent — 44 specialized skills covering technical audit, E-E-A-T, schema, GEO, local SEO & more",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {