antigravity-seo-kit 1.2.6 → 1.2.7

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
@@ -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 SEO Kit
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
- await installer.install(key, cwd);
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,183 @@ 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
+ const directoriesToCopy = ['.shared', 'agents', 'config', 'dashboard', 'docs', 'mcp-server', 'rules', 'scripts', 'skills', 'workflows'];
529
+ const filesToCopy = ['ARCHITECTURE.md'];
530
+
531
+ let count = 0;
532
+ for (const dir of directoriesToCopy) {
533
+ const src = path.join(globalDir, dir);
534
+ const dest = path.join(localAgentDir, dir);
535
+ if (fs.existsSync(src)) {
536
+ count += copyRecursive(src, dest, { overwrite: true });
537
+ }
538
+ }
539
+ for (const file of filesToCopy) {
540
+ const src = path.join(globalDir, file);
541
+ const dest = path.join(localAgentDir, file);
542
+ if (fs.existsSync(src)) {
543
+ fs.copyFileSync(src, dest);
544
+ count++;
545
+ }
546
+ }
547
+
548
+ const LICENSE_FILE = '.seo-kit-license';
549
+ const globalLicense = path.join(globalDir, LICENSE_FILE);
550
+ const localLicense = path.join(cwd, LICENSE_FILE);
551
+ if (fs.existsSync(globalLicense) && !fs.existsSync(localLicense)) {
552
+ fs.copyFileSync(globalLicense, localLicense);
553
+ }
554
+
555
+ spin.succeed(`Workspace setup complete! Copied ${count} files to .agent/`);
556
+ } catch (err) {
557
+ spin.fail('Workspace setup failed');
558
+ error(err.message);
559
+ process.exit(1);
560
+ }
561
+ }
562
+
386
563
  // ─── Exports ────────────────────────────────────────────────────────────────
387
564
 
388
565
  module.exports = {
@@ -392,4 +569,6 @@ module.exports = {
392
569
  status,
393
570
  devices,
394
571
  deviceRemove,
572
+ installPlugin,
573
+ setupWorkspace,
395
574
  };
package/lib/utils.js CHANGED
@@ -185,15 +185,19 @@ function showHelp() {
185
185
  console.log(`${colorize('bold', 'Usage:')} npx antigravity-seo-kit <command> [options]`);
186
186
  console.log('');
187
187
  console.log(`${colorize('bold', 'Commands:')}`);
188
- console.log(` ${colorize('green', 'install')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit into current workspace`);
189
- console.log(` ${colorize('green', 'update')} Update to latest version`);
190
- console.log(` ${colorize('green', 'uninstall')} Remove SEO Kit from workspace`);
191
- console.log(` ${colorize('green', 'status')} Show license & installation info`);
192
- console.log(` ${colorize('green', 'devices')} List activated devices`);
193
- console.log(` ${colorize('green', 'devices remove')} <deviceId> Remove a device from license`);
188
+ console.log(` ${colorize('green', 'install')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit into current workspace`);
189
+ console.log(` ${colorize('green', 'install-plugin')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit globally as an Antigravity plugin`);
190
+ console.log(` ${colorize('green', 'setup-workspace')} Replicate .agent config directory to current workspace`);
191
+ console.log(` ${colorize('green', 'update')} Update to latest version`);
192
+ console.log(` ${colorize('green', 'uninstall')} Remove SEO Kit from workspace`);
193
+ console.log(` ${colorize('green', 'status')} Show license & installation info`);
194
+ console.log(` ${colorize('green', 'devices')} List activated devices`);
195
+ console.log(` ${colorize('green', 'devices remove')} <deviceId> Remove a device from license`);
194
196
  console.log('');
195
197
  console.log(`${colorize('bold', 'Examples:')}`);
196
198
  console.log(` ${colorize('gray', 'npx antigravity-seo-kit install --key=SK-A1B2-C3D4-E5F6')}`);
199
+ console.log(` ${colorize('gray', 'npx antigravity-seo-kit install-plugin --key=SK-A1B2-C3D4-E5F6')}`);
200
+ console.log(` ${colorize('gray', 'npx antigravity-seo-kit setup-workspace')}`);
197
201
  console.log(` ${colorize('gray', 'npx antigravity-seo-kit devices')}`);
198
202
  console.log(` ${colorize('gray', 'npx antigravity-seo-kit devices remove a1b2c3d4')}`);
199
203
  console.log('');
@@ -205,8 +209,15 @@ function showHelp() {
205
209
 
206
210
  const LICENSE_FILE = '.seo-kit-license';
207
211
 
212
+ function getGlobalPluginDir() {
213
+ return path.join(require('os').homedir(), '.gemini', 'config', 'plugins', 'antigravity-seo-kit');
214
+ }
215
+
208
216
  function readLicenseFile(cwd) {
209
- const licensePath = path.join(cwd, LICENSE_FILE);
217
+ let licensePath = path.join(cwd, LICENSE_FILE);
218
+ if (!fs.existsSync(licensePath)) {
219
+ licensePath = path.join(getGlobalPluginDir(), LICENSE_FILE);
220
+ }
210
221
  if (!fs.existsSync(licensePath)) return null;
211
222
  try {
212
223
  const data = JSON.parse(fs.readFileSync(licensePath, 'utf-8'));
@@ -282,9 +293,10 @@ module.exports = {
282
293
  isValidKeyFormat,
283
294
  showBanner,
284
295
  showHelp,
296
+ getGlobalPluginDir,
285
297
  readLicenseFile,
286
298
  writeLicenseFile,
287
299
  removeLicenseFile,
288
300
  LICENSE_FILE,
289
- PACKAGE_VERSION: '1.2.6',
301
+ PACKAGE_VERSION: '1.2.7',
290
302
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antigravity-seo-kit",
3
- "version": "1.2.6",
3
+ "version": "1.2.7",
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
  }