antigravity-seo-kit 1.2.6 → 1.2.8
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 +25 -1
- package/bin/cli.js +30 -1
- package/lib/installer.js +191 -2
- package/lib/utils.js +23 -10
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -4,6 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
## ⚡ Quick Install
|
|
6
6
|
|
|
7
|
+
You can install SEO Kit either globally as an Antigravity plugin (recommended) or locally into a specific workspace.
|
|
8
|
+
|
|
9
|
+
### 1. Global Plugin Installation (Recommended)
|
|
10
|
+
This installs SEO Kit globally into your Antigravity config directory so it is available across all workspaces.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx antigravity-seo-kit install-plugin --key=SK-XXXX-XXXX-XXXX
|
|
14
|
+
# OR: npx antigravity-seo-kit install --global --key=SK-XXXX-XXXX-XXXX
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
When you start work in a new workspace, run the following command to sync the agent rules and folders locally:
|
|
18
|
+
```bash
|
|
19
|
+
npx antigravity-seo-kit setup-workspace
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. Local Workspace Installation
|
|
23
|
+
This installs SEO Kit files directly into your current workspace.
|
|
24
|
+
|
|
7
25
|
```bash
|
|
8
26
|
npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
|
|
9
27
|
```
|
|
@@ -25,7 +43,13 @@ npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
|
|
|
25
43
|
## CLI Commands
|
|
26
44
|
|
|
27
45
|
```bash
|
|
28
|
-
# Install
|
|
46
|
+
# Install globally as a plugin (recommended)
|
|
47
|
+
npx antigravity-seo-kit install-plugin --key=SK-XXXX-XXXX-XXXX
|
|
48
|
+
|
|
49
|
+
# Replicate .agent config directory from global plugin to local workspace
|
|
50
|
+
npx antigravity-seo-kit setup-workspace
|
|
51
|
+
|
|
52
|
+
# Install locally into current workspace
|
|
29
53
|
npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
|
|
30
54
|
|
|
31
55
|
# Update to latest version
|
package/bin/cli.js
CHANGED
|
@@ -42,7 +42,36 @@ async function main() {
|
|
|
42
42
|
error('Invalid key format. Expected: SK-XXXX-XXXX-XXXX');
|
|
43
43
|
process.exit(1);
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
if (getFlag('global')) {
|
|
46
|
+
await installer.installPlugin(key);
|
|
47
|
+
} else {
|
|
48
|
+
await installer.install(key, cwd);
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
case 'install-plugin': {
|
|
54
|
+
showBanner();
|
|
55
|
+
const key = getArg('key');
|
|
56
|
+
if (!key) {
|
|
57
|
+
error('License key required.');
|
|
58
|
+
console.log('');
|
|
59
|
+
console.log(` Usage: ${colorize('cyan', 'npx antigravity-seo-kit install-plugin --key=SK-XXXX-XXXX-XXXX')}`);
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log(` Purchase: ${colorize('cyan', 'https://antigravity-seokit.solann.io/')}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
if (!isValidKeyFormat(key)) {
|
|
65
|
+
error('Invalid key format. Expected: SK-XXXX-XXXX-XXXX');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
await installer.installPlugin(key);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
case 'setup-workspace': {
|
|
73
|
+
showBanner();
|
|
74
|
+
await installer.setupWorkspace(cwd);
|
|
46
75
|
break;
|
|
47
76
|
}
|
|
48
77
|
|
package/lib/installer.js
CHANGED
|
@@ -4,9 +4,9 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const {
|
|
6
6
|
success, error, warn, info, step, file, dir,
|
|
7
|
-
spinner, removeRecursive,
|
|
7
|
+
spinner, removeRecursive, copyRecursive,
|
|
8
8
|
writeLicenseFile, removeLicenseFile, readLicenseFile,
|
|
9
|
-
colorize, PACKAGE_VERSION,
|
|
9
|
+
colorize, PACKAGE_VERSION, getGlobalPluginDir,
|
|
10
10
|
} = require('./utils');
|
|
11
11
|
const { generateFingerprint, getDeviceName } = require('./fingerprint');
|
|
12
12
|
const api = require('./api');
|
|
@@ -383,6 +383,193 @@ function maskKey(key) {
|
|
|
383
383
|
return key.substring(0, 7) + '*'.repeat(key.length - 11) + key.substring(key.length - 4);
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
async function installPlugin(licenseKey) {
|
|
387
|
+
const globalPluginDir = getGlobalPluginDir();
|
|
388
|
+
const deviceId = generateFingerprint();
|
|
389
|
+
const deviceName = getDeviceName();
|
|
390
|
+
|
|
391
|
+
// Step 1: Verify license
|
|
392
|
+
const spin = spinner('Verifying license key...').start();
|
|
393
|
+
let verifyResult;
|
|
394
|
+
try {
|
|
395
|
+
verifyResult = await api.verifyLicense(licenseKey, deviceId, deviceName);
|
|
396
|
+
spin.succeed('License verified!');
|
|
397
|
+
} catch (err) {
|
|
398
|
+
spin.fail('License verification failed');
|
|
399
|
+
const errCode = err.responseData?.error?.code || '';
|
|
400
|
+
if (errCode.includes('DeviceLimitReached') || err.message.includes('Device limit')) {
|
|
401
|
+
console.log('');
|
|
402
|
+
error(`Device limit reached. You have ${err.responseData?.error?.data?.current || '?'}/${err.responseData?.error?.data?.max || 3} devices activated.`);
|
|
403
|
+
console.log('');
|
|
404
|
+
info('Run the following to manage your devices:');
|
|
405
|
+
console.log(` ${colorize('gray', 'npx antigravity-seo-kit devices')}`);
|
|
406
|
+
console.log(` ${colorize('gray', 'npx antigravity-seo-kit devices remove <deviceId>')}`);
|
|
407
|
+
} else if (err.isNotFound || errCode.includes('LicenseNotFound')) {
|
|
408
|
+
error('Invalid license key. Please check your key and try again.');
|
|
409
|
+
console.log(` Purchase: ${colorize('cyan', 'https://antigravitykit.solann.io/')}`);
|
|
410
|
+
} else if (errCode.includes('LicenseExpired')) {
|
|
411
|
+
error('License has expired. Please renew your license.');
|
|
412
|
+
console.log(` Renew: ${colorize('cyan', 'https://antigravitykit.solann.io/')}`);
|
|
413
|
+
} else if (errCode.includes('LicenseSuspended') || errCode.includes('LicenseRevoked')) {
|
|
414
|
+
error('License has been suspended or revoked. Contact support.');
|
|
415
|
+
} else {
|
|
416
|
+
error(err.message);
|
|
417
|
+
}
|
|
418
|
+
process.exit(1);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Ensure global plugin directory exists
|
|
422
|
+
fs.mkdirSync(globalPluginDir, { recursive: true });
|
|
423
|
+
|
|
424
|
+
// Step 2: Download assets from server
|
|
425
|
+
console.log('');
|
|
426
|
+
const spinDl = spinner('Downloading SEO Kit assets...').start();
|
|
427
|
+
let downloadResult;
|
|
428
|
+
try {
|
|
429
|
+
const downloadUrl = api.getAssetsDownloadUrl(PACKAGE_VERSION);
|
|
430
|
+
downloadResult = await downloadAndExtract(downloadUrl, licenseKey, globalPluginDir);
|
|
431
|
+
spinDl.succeed(`Downloaded and installed ${downloadResult.count} files`);
|
|
432
|
+
} catch (err) {
|
|
433
|
+
spinDl.fail('Asset download failed');
|
|
434
|
+
error(err.message);
|
|
435
|
+
info('If this persists, contact support@solann.io');
|
|
436
|
+
process.exit(1);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Step 3: Move files/folders inside the `.agent/` subdirectory up to the plugin root
|
|
440
|
+
const agentDir = path.join(globalPluginDir, '.agent');
|
|
441
|
+
if (fs.existsSync(agentDir)) {
|
|
442
|
+
const entries = fs.readdirSync(agentDir);
|
|
443
|
+
for (const entry of entries) {
|
|
444
|
+
const srcPath = path.join(agentDir, entry);
|
|
445
|
+
const destPath = path.join(globalPluginDir, entry);
|
|
446
|
+
if (fs.existsSync(destPath)) {
|
|
447
|
+
removeRecursive(destPath);
|
|
448
|
+
}
|
|
449
|
+
fs.renameSync(srcPath, destPath);
|
|
450
|
+
}
|
|
451
|
+
removeRecursive(agentDir);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Step 4: Generate plugin.json and installed_version.json
|
|
455
|
+
const pluginJson = {
|
|
456
|
+
name: "antigravity-seo-kit",
|
|
457
|
+
version: PACKAGE_VERSION,
|
|
458
|
+
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",
|
|
459
|
+
author: {
|
|
460
|
+
name: "Antigravity SEO Kit"
|
|
461
|
+
},
|
|
462
|
+
license: "SEE LICENSE IN LICENSE",
|
|
463
|
+
keywords: [
|
|
464
|
+
"seo",
|
|
465
|
+
"universal-seo-kit",
|
|
466
|
+
"ai-agent",
|
|
467
|
+
"antigravity",
|
|
468
|
+
"seo-geo",
|
|
469
|
+
"seo-audit",
|
|
470
|
+
"seo-toolkit",
|
|
471
|
+
"agent-skills",
|
|
472
|
+
"seo-analysis",
|
|
473
|
+
"technical-seo",
|
|
474
|
+
"eeat"
|
|
475
|
+
]
|
|
476
|
+
};
|
|
477
|
+
fs.writeFileSync(path.join(globalPluginDir, 'plugin.json'), JSON.stringify(pluginJson, null, 2), 'utf-8');
|
|
478
|
+
fs.writeFileSync(path.join(globalPluginDir, 'installed_version.json'), JSON.stringify({ version: PACKAGE_VERSION }), 'utf-8');
|
|
479
|
+
|
|
480
|
+
// Step 5: Save global license info + manifest
|
|
481
|
+
const LICENSE_FILE = '.seo-kit-license';
|
|
482
|
+
writeLicenseFile(globalPluginDir, {
|
|
483
|
+
key: licenseKey,
|
|
484
|
+
deviceId,
|
|
485
|
+
deviceName,
|
|
486
|
+
version: PACKAGE_VERSION,
|
|
487
|
+
installedAt: new Date().toISOString(),
|
|
488
|
+
plan: verifyResult?.license?.planName || verifyResult?.license?.plan || 'unknown',
|
|
489
|
+
installedFiles: downloadResult.files.map(f => f.replace(/^\.agent\//, '')),
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// Done!
|
|
493
|
+
console.log('');
|
|
494
|
+
console.log(colorize('green', '═══════════════════════════════════════════════════════'));
|
|
495
|
+
success(`SEO Kit v${PACKAGE_VERSION} installed successfully as a global Antigravity plugin!`);
|
|
496
|
+
console.log(colorize('green', '═══════════════════════════════════════════════════════'));
|
|
497
|
+
console.log('');
|
|
498
|
+
|
|
499
|
+
info('Next steps:');
|
|
500
|
+
console.log(` ${colorize('yellow', '1.')} Restart or open any workspace in ${colorize('bold', 'Google Antigravity')}`);
|
|
501
|
+
console.log(` ${colorize('yellow', '2.')} The SEO Kit plugin will automatically load globally.`);
|
|
502
|
+
console.log('');
|
|
503
|
+
|
|
504
|
+
if (verifyResult?.devicesUsed != null) {
|
|
505
|
+
info(`Devices: ${verifyResult.devicesUsed}/${verifyResult.maxDevices} activated`);
|
|
506
|
+
}
|
|
507
|
+
console.log('');
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function setupWorkspace(cwd) {
|
|
511
|
+
const globalDir = getGlobalPluginDir();
|
|
512
|
+
const localAgentDir = path.join(cwd, '.agent');
|
|
513
|
+
|
|
514
|
+
if (fs.existsSync(localAgentDir)) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (!fs.existsSync(globalDir)) {
|
|
519
|
+
error('Global SEO Kit plugin is not installed.');
|
|
520
|
+
info('Please run: npx antigravity-seo-kit install-plugin --key=YOUR_KEY');
|
|
521
|
+
process.exit(1);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const spin = spinner('Replicating .agent directory to local workspace...').start();
|
|
525
|
+
try {
|
|
526
|
+
fs.mkdirSync(localAgentDir, { recursive: true });
|
|
527
|
+
|
|
528
|
+
// Only copy necessary directories. agents and rules are loaded globally via the plugin.
|
|
529
|
+
// skills are copied but filtered to exclude .md files to save space and avoid duplicate prompts/instructions.
|
|
530
|
+
const directoriesToCopy = ['.shared', 'config', 'dashboard', 'docs', 'scripts', 'workflows'];
|
|
531
|
+
const filesToCopy = ['ARCHITECTURE.md'];
|
|
532
|
+
|
|
533
|
+
let count = 0;
|
|
534
|
+
for (const dir of directoriesToCopy) {
|
|
535
|
+
const src = path.join(globalDir, dir);
|
|
536
|
+
const dest = path.join(localAgentDir, dir);
|
|
537
|
+
if (fs.existsSync(src)) {
|
|
538
|
+
if (dir === 'skills') {
|
|
539
|
+
// Keep scripts and assets, but exclude instruction/documentation markdown files
|
|
540
|
+
count += copyRecursive(src, dest, {
|
|
541
|
+
overwrite: true,
|
|
542
|
+
filter: (filePath) => !filePath.endsWith('.md')
|
|
543
|
+
});
|
|
544
|
+
} else {
|
|
545
|
+
count += copyRecursive(src, dest, { overwrite: true });
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
for (const file of filesToCopy) {
|
|
550
|
+
const src = path.join(globalDir, file);
|
|
551
|
+
const dest = path.join(localAgentDir, file);
|
|
552
|
+
if (fs.existsSync(src)) {
|
|
553
|
+
fs.copyFileSync(src, dest);
|
|
554
|
+
count++;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const LICENSE_FILE = '.seo-kit-license';
|
|
559
|
+
const globalLicense = path.join(globalDir, LICENSE_FILE);
|
|
560
|
+
const localLicense = path.join(cwd, LICENSE_FILE);
|
|
561
|
+
if (fs.existsSync(globalLicense) && !fs.existsSync(localLicense)) {
|
|
562
|
+
fs.copyFileSync(globalLicense, localLicense);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
spin.succeed(`Workspace setup complete! Copied ${count} files to .agent/`);
|
|
566
|
+
} catch (err) {
|
|
567
|
+
spin.fail('Workspace setup failed');
|
|
568
|
+
error(err.message);
|
|
569
|
+
process.exit(1);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
386
573
|
// ─── Exports ────────────────────────────────────────────────────────────────
|
|
387
574
|
|
|
388
575
|
module.exports = {
|
|
@@ -392,4 +579,6 @@ module.exports = {
|
|
|
392
579
|
status,
|
|
393
580
|
devices,
|
|
394
581
|
deviceRemove,
|
|
582
|
+
installPlugin,
|
|
583
|
+
setupWorkspace,
|
|
395
584
|
};
|
package/lib/utils.js
CHANGED
|
@@ -92,8 +92,9 @@ function spinner(message) {
|
|
|
92
92
|
* Recursively copy a directory, merging with existing content.
|
|
93
93
|
* Does not overwrite existing files unless `overwrite` is true.
|
|
94
94
|
*/
|
|
95
|
-
function copyRecursive(src, dest, { overwrite = false, fileCallback = null } = {}) {
|
|
95
|
+
function copyRecursive(src, dest, { overwrite = false, fileCallback = null, filter = null } = {}) {
|
|
96
96
|
if (!fs.existsSync(src)) return 0;
|
|
97
|
+
if (filter && !filter(src)) return 0;
|
|
97
98
|
|
|
98
99
|
let count = 0;
|
|
99
100
|
|
|
@@ -104,7 +105,7 @@ function copyRecursive(src, dest, { overwrite = false, fileCallback = null } = {
|
|
|
104
105
|
count += copyRecursive(
|
|
105
106
|
path.join(src, entry),
|
|
106
107
|
path.join(dest, entry),
|
|
107
|
-
{ overwrite, fileCallback }
|
|
108
|
+
{ overwrite, fileCallback, filter }
|
|
108
109
|
);
|
|
109
110
|
}
|
|
110
111
|
} else {
|
|
@@ -185,15 +186,19 @@ function showHelp() {
|
|
|
185
186
|
console.log(`${colorize('bold', 'Usage:')} npx antigravity-seo-kit <command> [options]`);
|
|
186
187
|
console.log('');
|
|
187
188
|
console.log(`${colorize('bold', 'Commands:')}`);
|
|
188
|
-
console.log(` ${colorize('green', 'install')}
|
|
189
|
-
console.log(` ${colorize('green', '
|
|
190
|
-
console.log(` ${colorize('green', '
|
|
191
|
-
console.log(` ${colorize('green', '
|
|
192
|
-
console.log(` ${colorize('green', '
|
|
193
|
-
console.log(` ${colorize('green', '
|
|
189
|
+
console.log(` ${colorize('green', 'install')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit into current workspace`);
|
|
190
|
+
console.log(` ${colorize('green', 'install-plugin')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit globally as an Antigravity plugin`);
|
|
191
|
+
console.log(` ${colorize('green', 'setup-workspace')} Replicate .agent config directory to current workspace`);
|
|
192
|
+
console.log(` ${colorize('green', 'update')} Update to latest version`);
|
|
193
|
+
console.log(` ${colorize('green', 'uninstall')} Remove SEO Kit from workspace`);
|
|
194
|
+
console.log(` ${colorize('green', 'status')} Show license & installation info`);
|
|
195
|
+
console.log(` ${colorize('green', 'devices')} List activated devices`);
|
|
196
|
+
console.log(` ${colorize('green', 'devices remove')} <deviceId> Remove a device from license`);
|
|
194
197
|
console.log('');
|
|
195
198
|
console.log(`${colorize('bold', 'Examples:')}`);
|
|
196
199
|
console.log(` ${colorize('gray', 'npx antigravity-seo-kit install --key=SK-A1B2-C3D4-E5F6')}`);
|
|
200
|
+
console.log(` ${colorize('gray', 'npx antigravity-seo-kit install-plugin --key=SK-A1B2-C3D4-E5F6')}`);
|
|
201
|
+
console.log(` ${colorize('gray', 'npx antigravity-seo-kit setup-workspace')}`);
|
|
197
202
|
console.log(` ${colorize('gray', 'npx antigravity-seo-kit devices')}`);
|
|
198
203
|
console.log(` ${colorize('gray', 'npx antigravity-seo-kit devices remove a1b2c3d4')}`);
|
|
199
204
|
console.log('');
|
|
@@ -205,8 +210,15 @@ function showHelp() {
|
|
|
205
210
|
|
|
206
211
|
const LICENSE_FILE = '.seo-kit-license';
|
|
207
212
|
|
|
213
|
+
function getGlobalPluginDir() {
|
|
214
|
+
return path.join(require('os').homedir(), '.gemini', 'config', 'plugins', 'antigravity-seo-kit');
|
|
215
|
+
}
|
|
216
|
+
|
|
208
217
|
function readLicenseFile(cwd) {
|
|
209
|
-
|
|
218
|
+
let licensePath = path.join(cwd, LICENSE_FILE);
|
|
219
|
+
if (!fs.existsSync(licensePath)) {
|
|
220
|
+
licensePath = path.join(getGlobalPluginDir(), LICENSE_FILE);
|
|
221
|
+
}
|
|
210
222
|
if (!fs.existsSync(licensePath)) return null;
|
|
211
223
|
try {
|
|
212
224
|
const data = JSON.parse(fs.readFileSync(licensePath, 'utf-8'));
|
|
@@ -282,9 +294,10 @@ module.exports = {
|
|
|
282
294
|
isValidKeyFormat,
|
|
283
295
|
showBanner,
|
|
284
296
|
showHelp,
|
|
297
|
+
getGlobalPluginDir,
|
|
285
298
|
readLicenseFile,
|
|
286
299
|
writeLicenseFile,
|
|
287
300
|
removeLicenseFile,
|
|
288
301
|
LICENSE_FILE,
|
|
289
|
-
PACKAGE_VERSION: '1.2.
|
|
302
|
+
PACKAGE_VERSION: '1.2.8',
|
|
290
303
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antigravity-seo-kit",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
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": {
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"cursor",
|
|
19
19
|
"gemini-cli",
|
|
20
20
|
"antigravity",
|
|
21
|
+
"antigravity-plugin",
|
|
22
|
+
"antigravity-seo-kit-plugin",
|
|
21
23
|
"seo-geo",
|
|
22
24
|
"seo-audit",
|
|
23
25
|
"seo-toolkit",
|
|
@@ -31,5 +33,10 @@
|
|
|
31
33
|
"homepage": "https://antigravityseokit.solann.io/",
|
|
32
34
|
"engines": {
|
|
33
35
|
"node": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"pack-assets": "node scripts/pack-assets.js",
|
|
39
|
+
"pack-npm": "npm pack --pack-destination dist",
|
|
40
|
+
"pack-all": "node scripts/pack-assets.js && npm pack --pack-destination dist"
|
|
34
41
|
}
|
|
35
42
|
}
|