antigravity-seo-kit 1.2.8 → 2.0.1
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 +10 -11
- package/lib/downloader.js +18 -1
- package/lib/installer.js +8 -4
- package/lib/utils.js +81 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SEO Kit for Google Antigravity
|
|
2
2
|
|
|
3
|
-
> **Professional SEO
|
|
3
|
+
> **Professional Agentic SEO Platform** — Comprehensive autonomous AI-powered SEO analysis with specialized skills for technical audit, E-E-A-T, schema markup, GEO optimization, and more. Built for [Google Antigravity 2](https://deepmind.google/technologies/antigravity/) AI agent platform.
|
|
4
4
|
|
|
5
5
|
## ⚡ Quick Install
|
|
6
6
|
|
|
@@ -30,15 +30,14 @@ npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
|
|
|
30
30
|
|
|
31
31
|
## Features
|
|
32
32
|
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **Extension System** for third-party SEO data providers
|
|
33
|
+
- **Autonomous Auto-Pilot Mode (`/seo-auto-run`)** — Runs full SEO lifecycle sequentially without manual intervention, outputting structured reports and directly applying fixes.
|
|
34
|
+
- **Dynamic Multi-Agent Auto-Routing** — Smart routing delegating tasks to 23 specialized directors across Technical, Content, Off-Page, and R&D departments.
|
|
35
|
+
- **Full SEO Lifecycle** — Phase-aware execution covering Onboard, Research, Audit, Strategy, Execute, and Monitor.
|
|
36
|
+
- **Smart Configuration Protection** — Smart Deep Merge automatically preserves user-specific API keys and custom settings during package updates.
|
|
37
|
+
- **Generative Engine Optimization (GEO)** — Optimizes and monitors content visibility across AI Search engines like Google AIO, ChatGPT, and Perplexity.
|
|
38
|
+
- **Technical SEO Auto-Fixes** — Deep audits for crawlability, indexability, Core Web Vitals, and auto-generates schema, meta tags, redirects, and robots.txt.
|
|
39
|
+
- **E-E-A-T & Topical Authority** — Content quality evaluation mapped to Google Quality Raters Guidelines, semantic clustering, and Information Gain analysis.
|
|
40
|
+
- **Multi-Client Dashboard & MCP Server** — Visual HTML tracking for multiple domains coupled with a native Model Context Protocol server for direct A2A agent integration.
|
|
42
41
|
|
|
43
42
|
## CLI Commands
|
|
44
43
|
|
|
@@ -70,7 +69,7 @@ npx antigravity-seo-kit uninstall --confirm
|
|
|
70
69
|
|
|
71
70
|
- **Node.js** ≥ 18 (for CLI installer)
|
|
72
71
|
- **Python** ≥ 3.11 (for analysis scripts)
|
|
73
|
-
- **Google Antigravity** or compatible AI agent platform
|
|
72
|
+
- **Google Antigravity 2** or compatible AI agent platform
|
|
74
73
|
|
|
75
74
|
## License Management
|
|
76
75
|
|
package/lib/downloader.js
CHANGED
|
@@ -4,6 +4,7 @@ const https = require('https');
|
|
|
4
4
|
const zlib = require('zlib');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
|
+
const { smartMergeJsonFile } = require('./utils');
|
|
7
8
|
|
|
8
9
|
// ─── Download ───────────────────────────────────────────────────────────────
|
|
9
10
|
|
|
@@ -145,8 +146,24 @@ function extractTarGz(gzBuffer, targetDir) {
|
|
|
145
146
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
146
147
|
} else if (typeFlag === ASCII_0 || typeFlag === 0) {
|
|
147
148
|
// Regular file
|
|
149
|
+
const isConfigJson = fullName.endsWith('.json') &&
|
|
150
|
+
(fullName.startsWith('config/') ||
|
|
151
|
+
fullName.startsWith('.agent/config/') ||
|
|
152
|
+
fullName.includes('/config/'));
|
|
153
|
+
|
|
148
154
|
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
149
|
-
|
|
155
|
+
|
|
156
|
+
if (isConfigJson && fs.existsSync(targetPath)) {
|
|
157
|
+
const tempPath = targetPath + '.tmp';
|
|
158
|
+
fs.writeFileSync(tempPath, tarBuffer.subarray(offset, offset + size));
|
|
159
|
+
smartMergeJsonFile(tempPath, targetPath);
|
|
160
|
+
try {
|
|
161
|
+
fs.unlinkSync(tempPath);
|
|
162
|
+
} catch (e) {}
|
|
163
|
+
} else {
|
|
164
|
+
fs.writeFileSync(targetPath, tarBuffer.subarray(offset, offset + size));
|
|
165
|
+
}
|
|
166
|
+
|
|
150
167
|
files.push(fullName);
|
|
151
168
|
count++;
|
|
152
169
|
}
|
package/lib/installer.js
CHANGED
|
@@ -455,14 +455,16 @@ async function installPlugin(licenseKey) {
|
|
|
455
455
|
const pluginJson = {
|
|
456
456
|
name: "antigravity-seo-kit",
|
|
457
457
|
version: PACKAGE_VERSION,
|
|
458
|
-
description: "Professional SEO
|
|
458
|
+
description: "Professional Agentic SEO Platform for Google Antigravity 2 AI Agent — 44 specialized skills covering technical audit, E-E-A-T, schema, GEO, local SEO & more",
|
|
459
459
|
author: {
|
|
460
|
-
name: "Antigravity SEO Kit"
|
|
460
|
+
name: "Antigravity SEO Kit",
|
|
461
|
+
email: "admin@solann.io",
|
|
461
462
|
},
|
|
463
|
+
repository: "https://solann.io/antigravity-seo-kit",
|
|
462
464
|
license: "SEE LICENSE IN LICENSE",
|
|
463
465
|
keywords: [
|
|
464
466
|
"seo",
|
|
465
|
-
"
|
|
467
|
+
"agentic-seo",
|
|
466
468
|
"ai-agent",
|
|
467
469
|
"antigravity",
|
|
468
470
|
"seo-geo",
|
|
@@ -528,7 +530,7 @@ function setupWorkspace(cwd) {
|
|
|
528
530
|
// Only copy necessary directories. agents and rules are loaded globally via the plugin.
|
|
529
531
|
// skills are copied but filtered to exclude .md files to save space and avoid duplicate prompts/instructions.
|
|
530
532
|
const directoriesToCopy = ['.shared', 'config', 'dashboard', 'docs', 'scripts', 'workflows'];
|
|
531
|
-
const filesToCopy = ['
|
|
533
|
+
const filesToCopy = ['seo-architecture.md'];
|
|
532
534
|
|
|
533
535
|
let count = 0;
|
|
534
536
|
for (const dir of directoriesToCopy) {
|
|
@@ -541,6 +543,8 @@ function setupWorkspace(cwd) {
|
|
|
541
543
|
overwrite: true,
|
|
542
544
|
filter: (filePath) => !filePath.endsWith('.md')
|
|
543
545
|
});
|
|
546
|
+
} else if (dir === 'config') {
|
|
547
|
+
count += copyRecursive(src, dest, { overwrite: true, mergeJson: true });
|
|
544
548
|
} else {
|
|
545
549
|
count += copyRecursive(src, dest, { overwrite: true });
|
|
546
550
|
}
|
package/lib/utils.js
CHANGED
|
@@ -88,11 +88,80 @@ function spinner(message) {
|
|
|
88
88
|
|
|
89
89
|
// ─── File Operations ────────────────────────────────────────────────────────
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Check if a value is a plain object.
|
|
93
|
+
*/
|
|
94
|
+
function isObject(item) {
|
|
95
|
+
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Recursively merge two JSON objects (deep merge).
|
|
100
|
+
* Prioritizes properties from sourceObj (user config) while preserving/appending new properties from targetObj (template config).
|
|
101
|
+
*/
|
|
102
|
+
function deepMergeJson(targetObj, sourceObj) {
|
|
103
|
+
const output = { ...targetObj };
|
|
104
|
+
if (isObject(targetObj) && isObject(sourceObj)) {
|
|
105
|
+
for (const key of Object.keys(sourceObj)) {
|
|
106
|
+
if (isObject(sourceObj[key])) {
|
|
107
|
+
if (!(key in targetObj)) {
|
|
108
|
+
output[key] = sourceObj[key];
|
|
109
|
+
} else {
|
|
110
|
+
output[key] = deepMergeJson(targetObj[key], sourceObj[key]);
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
output[key] = sourceObj[key];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return output;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Merges JSON file from srcPath (new template) into destPath (existing user config) safely.
|
|
122
|
+
*/
|
|
123
|
+
function smartMergeJsonFile(srcPath, destPath) {
|
|
124
|
+
if (!fs.existsSync(srcPath)) return;
|
|
125
|
+
|
|
126
|
+
if (!fs.existsSync(destPath)) {
|
|
127
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
128
|
+
fs.copyFileSync(srcPath, destPath);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let newJson;
|
|
133
|
+
try {
|
|
134
|
+
newJson = JSON.parse(fs.readFileSync(srcPath, 'utf-8'));
|
|
135
|
+
} catch (err) {
|
|
136
|
+
fs.copyFileSync(srcPath, destPath);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let oldJson;
|
|
141
|
+
try {
|
|
142
|
+
oldJson = JSON.parse(fs.readFileSync(destPath, 'utf-8'));
|
|
143
|
+
} catch (err) {
|
|
144
|
+
const bakPath = destPath + '.bak';
|
|
145
|
+
try {
|
|
146
|
+
fs.copyFileSync(destPath, bakPath);
|
|
147
|
+
warn(`File cấu hình bị lỗi cú pháp JSON và đã được sao lưu thành: ${path.basename(bakPath)}`);
|
|
148
|
+
} catch (bakErr) {
|
|
149
|
+
warn(`Không thể sao lưu file cấu hình lỗi: ${bakErr.message}`);
|
|
150
|
+
}
|
|
151
|
+
fs.copyFileSync(srcPath, destPath);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const merged = deepMergeJson(newJson, oldJson);
|
|
156
|
+
fs.writeFileSync(destPath, JSON.stringify(merged, null, 2), 'utf-8');
|
|
157
|
+
}
|
|
158
|
+
|
|
91
159
|
/**
|
|
92
160
|
* Recursively copy a directory, merging with existing content.
|
|
93
161
|
* Does not overwrite existing files unless `overwrite` is true.
|
|
162
|
+
* Supports smart JSON merging if `mergeJson` is enabled.
|
|
94
163
|
*/
|
|
95
|
-
function copyRecursive(src, dest, { overwrite = false, fileCallback = null, filter = null } = {}) {
|
|
164
|
+
function copyRecursive(src, dest, { overwrite = false, fileCallback = null, filter = null, mergeJson = false } = {}) {
|
|
96
165
|
if (!fs.existsSync(src)) return 0;
|
|
97
166
|
if (filter && !filter(src)) return 0;
|
|
98
167
|
|
|
@@ -105,12 +174,17 @@ function copyRecursive(src, dest, { overwrite = false, fileCallback = null, filt
|
|
|
105
174
|
count += copyRecursive(
|
|
106
175
|
path.join(src, entry),
|
|
107
176
|
path.join(dest, entry),
|
|
108
|
-
{ overwrite, fileCallback, filter }
|
|
177
|
+
{ overwrite, fileCallback, filter, mergeJson }
|
|
109
178
|
);
|
|
110
179
|
}
|
|
111
180
|
} else {
|
|
112
181
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
113
|
-
|
|
182
|
+
const isJson = src.endsWith('.json');
|
|
183
|
+
if (isJson && mergeJson && fs.existsSync(dest)) {
|
|
184
|
+
smartMergeJsonFile(src, dest);
|
|
185
|
+
count = 1;
|
|
186
|
+
if (fileCallback) fileCallback(dest);
|
|
187
|
+
} else if (overwrite || !fs.existsSync(dest)) {
|
|
114
188
|
fs.copyFileSync(src, dest);
|
|
115
189
|
count = 1;
|
|
116
190
|
if (fileCallback) fileCallback(dest);
|
|
@@ -171,7 +245,7 @@ function isValidKeyFormat(key) {
|
|
|
171
245
|
const BANNER = `
|
|
172
246
|
${colorize('cyan', '╔═══════════════════════════════════════════════════════╗')}
|
|
173
247
|
${colorize('cyan', '║')} ${colorize('bold', '🔍 SEO Kit for Google Antigravity')} ${colorize('cyan', '║')}
|
|
174
|
-
${colorize('cyan', '║')} ${colorize('dim', '
|
|
248
|
+
${colorize('cyan', '║')} ${colorize('dim', 'v2.0.1 — Professional Agentic SEO Platform')} ${colorize('cyan', '║')}
|
|
175
249
|
${colorize('cyan', '╚═══════════════════════════════════════════════════════╝')}
|
|
176
250
|
`;
|
|
177
251
|
|
|
@@ -299,5 +373,7 @@ module.exports = {
|
|
|
299
373
|
writeLicenseFile,
|
|
300
374
|
removeLicenseFile,
|
|
301
375
|
LICENSE_FILE,
|
|
302
|
-
PACKAGE_VERSION: '
|
|
376
|
+
PACKAGE_VERSION: '2.0.1',
|
|
377
|
+
deepMergeJson,
|
|
378
|
+
smartMergeJsonFile,
|
|
303
379
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antigravity-seo-kit",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Professional SEO
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Professional Agentic SEO Platform for Google Antigravity 2 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": {
|
|
7
7
|
"antigravity-seo-kit": "bin/cli.js"
|