antigravity-seo-kit 2.7.4 → 2.9.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 CHANGED
@@ -14,7 +14,7 @@ npx antigravity-seo-kit install-plugin --key=SK-XXXX-XXXX-XXXX
14
14
  # OR: npx antigravity-seo-kit install --global --key=SK-XXXX-XXXX-XXXX
15
15
  ```
16
16
 
17
- When you start work in a new workspace, run the following command to sync the agent rules and folders locally:
17
+ When you start work in a new workspace, run the following command to sync the `.agents/` structure locally:
18
18
  ```bash
19
19
  npx antigravity-seo-kit setup-workspace
20
20
  ```
@@ -45,12 +45,15 @@ npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
45
45
  # Install globally as a plugin (recommended)
46
46
  npx antigravity-seo-kit install-plugin --key=SK-XXXX-XXXX-XXXX
47
47
 
48
- # Replicate .agent config directory from global plugin to local workspace
48
+ # Replicate .agents/ workspace structure from global plugin
49
49
  npx antigravity-seo-kit setup-workspace
50
50
 
51
51
  # Install locally into current workspace
52
52
  npx antigravity-seo-kit install --key=SK-XXXX-XXXX-XXXX
53
53
 
54
+ # Migrate from v2.x (.agent/) to v3.0 (.agents/)
55
+ npx antigravity-seo-kit migrate
56
+
54
57
  # Update to latest version
55
58
  npx antigravity-seo-kit update
56
59
 
package/bin/cli.js CHANGED
@@ -75,6 +75,12 @@ async function main() {
75
75
  break;
76
76
  }
77
77
 
78
+ case 'migrate': {
79
+ showBanner();
80
+ installer.migrate(cwd);
81
+ break;
82
+ }
83
+
78
84
  case 'update': {
79
85
  showBanner();
80
86
  await installer.update(cwd);
package/lib/downloader.js CHANGED
@@ -149,6 +149,7 @@ function extractTarGz(gzBuffer, targetDir) {
149
149
  const isConfigJson = fullName.endsWith('.json') &&
150
150
  (fullName.startsWith('config/') ||
151
151
  fullName.startsWith('.agent/config/') ||
152
+ fullName.startsWith('.agents/config/') ||
152
153
  fullName.includes('/config/'));
153
154
 
154
155
  fs.mkdirSync(path.dirname(targetPath), { recursive: true });
package/lib/installer.js CHANGED
@@ -69,7 +69,46 @@ async function install(licenseKey, cwd) {
69
69
  process.exit(1);
70
70
  }
71
71
 
72
- // Step 3: Save license info + manifest
72
+ // Step 3: Restructure into .agents/ flat format if server sent legacy .agent/
73
+ const legacyAgentDir = path.join(cwd, '.agent');
74
+ const newAgentsDir = path.join(cwd, '.agents');
75
+
76
+ if (fs.existsSync(legacyAgentDir) && !fs.existsSync(newAgentsDir)) {
77
+ const spinMigrate = spinner('Restructuring to .agents/ format...').start();
78
+ try {
79
+ fs.mkdirSync(newAgentsDir, { recursive: true });
80
+
81
+ // ALL dirs go directly into .agents/ (flat workspace structure)
82
+ const allDirs = ['skills', 'rules', 'agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
83
+ let migrateCount = 0;
84
+ for (const dir of allDirs) {
85
+ const src = path.join(legacyAgentDir, dir);
86
+ const dest = path.join(newAgentsDir, dir);
87
+ if (fs.existsSync(src)) {
88
+ migrateCount += copyRecursive(src, dest, { overwrite: true });
89
+ }
90
+ }
91
+
92
+ // Root-level files (.md, .json) → .agents/
93
+ for (const f of fs.readdirSync(legacyAgentDir)) {
94
+ const src = path.join(legacyAgentDir, f);
95
+ if (fs.statSync(src).isFile()) {
96
+ fs.copyFileSync(src, path.join(newAgentsDir, f));
97
+ migrateCount++;
98
+ }
99
+ }
100
+
101
+ // Remove legacy .agent/
102
+ removeRecursive(legacyAgentDir);
103
+
104
+ spinMigrate.succeed(`Restructured to .agents/ format (${migrateCount} files)`);
105
+ } catch (err) {
106
+ spinMigrate.fail('Restructuring failed, keeping .agent/ as-is');
107
+ warn(`You can manually run: npx antigravity-seo-kit migrate`);
108
+ }
109
+ }
110
+
111
+ // Step 4: Save license info + manifest
73
112
  writeLicenseFile(cwd, {
74
113
  key: licenseKey,
75
114
  deviceId,
@@ -122,6 +161,10 @@ async function update(cwd) {
122
161
  process.exit(1);
123
162
  }
124
163
 
164
+ // Detect structure: v3.0 (.agents/) or v2.x (.agent/)
165
+ const isV3 = fs.existsSync(path.join(cwd, '.agents'));
166
+ const isV2 = fs.existsSync(path.join(cwd, '.agent'));
167
+
125
168
  // Download latest assets from server
126
169
  console.log('');
127
170
  const spinDl = spinner('Downloading latest SEO Kit assets...').start();
@@ -136,6 +179,13 @@ async function update(cwd) {
136
179
  process.exit(1);
137
180
  }
138
181
 
182
+ // If user was on v2 (.agent/) and download brings v3 (.agents/), inform about migrate
183
+ if (isV2 && !isV3 && fs.existsSync(path.join(cwd, '.agents'))) {
184
+ console.log('');
185
+ info('v3.0 structure detected in update. Run migrate to complete:');
186
+ console.log(` ${colorize('cyan', 'npx antigravity-seo-kit migrate')}`);
187
+ }
188
+
139
189
  // Update license file
140
190
  config.version = PACKAGE_VERSION;
141
191
  config.updatedAt = new Date().toISOString();
@@ -160,7 +210,7 @@ async function uninstall(cwd) {
160
210
  let totalRemoved = 0;
161
211
 
162
212
  if (config.installedFiles && config.installedFiles.length > 0) {
163
- // New approach: use manifest from license file
213
+ // Manifest-based removal
164
214
  for (const filePath of config.installedFiles) {
165
215
  const target = path.join(cwd, filePath);
166
216
  if (fs.existsSync(target)) {
@@ -168,10 +218,11 @@ async function uninstall(cwd) {
168
218
  totalRemoved++;
169
219
  }
170
220
  }
171
- // Clean up empty directories
221
+ // Clean up empty directories for both v2 and v3 structures
172
222
  cleanEmptyDirsUp(path.join(cwd, '.agent'));
223
+ cleanEmptyDirsUp(path.join(cwd, '.agents'));
173
224
  } else {
174
- // Legacy fallback: use hardcoded arrays
225
+ // Legacy fallback: use prefix scan
175
226
  totalRemoved += legacyUninstall(cwd);
176
227
  }
177
228
 
@@ -253,24 +304,36 @@ async function status(cwd) {
253
304
 
254
305
  // Count installed files
255
306
  if (config.installedFiles && config.installedFiles.length > 0) {
256
- // New: count from manifest
307
+ // Manifest-based count
257
308
  let existingFiles = 0;
258
309
  for (const f of config.installedFiles) {
259
310
  if (fs.existsSync(path.join(cwd, f))) existingFiles++;
260
311
  }
261
312
  console.log(` ${colorize('cyan', 'Files:')} ${existingFiles}/${config.installedFiles.length} present`);
262
313
  } else {
263
- // Legacy: scan for seo-* prefixed entries
264
- const agentDir = path.join(cwd, '.agent');
314
+ // Legacy: scan for seo-* prefixed entries in both .agent/ and .agents/
265
315
  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++;
316
+ for (const baseDir of ['.agent', '.agents']) {
317
+ const agentDir = path.join(cwd, baseDir);
318
+ if (!fs.existsSync(agentDir)) continue;
319
+ for (const subDir of LEGACY_DIRS) {
320
+ const dirPath = path.join(agentDir, subDir);
321
+ if (!fs.existsSync(dirPath)) continue;
322
+ for (const entry of fs.readdirSync(dirPath)) {
323
+ if (entry.startsWith(LEGACY_SEO_PREFIX) || entry === 'seo') totalLegacy++;
324
+ }
271
325
  }
272
326
  }
273
- console.log(` ${colorize('cyan', 'Components:')} ${totalLegacy} installed (legacy)`);
327
+ console.log(` ${colorize('cyan', 'Components:')} ${totalLegacy} installed`);
328
+ }
329
+
330
+ // Detect structure version
331
+ const hasV3 = fs.existsSync(path.join(cwd, '.agents'));
332
+ const hasV2 = fs.existsSync(path.join(cwd, '.agent'));
333
+ const structureVersion = hasV3 ? 'v3.0 (.agents/)' : hasV2 ? 'v2.x (.agent/)' : 'unknown';
334
+ console.log(` ${colorize('cyan', 'Structure:')} ${structureVersion}`);
335
+ if (hasV2 && !hasV3) {
336
+ warn('Using legacy v2.x structure. Run: npx antigravity-seo-kit migrate');
274
337
  }
275
338
  console.log('');
276
339
 
@@ -436,51 +499,72 @@ async function installPlugin(licenseKey) {
436
499
  process.exit(1);
437
500
  }
438
501
 
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);
502
+ // Step 3: Restructure into .agents/ plugin format
503
+ // v3.0: Downloaded assets arrive in .agents/ structure already
504
+ // Handle legacy .agent/ if server still serves old format
505
+ const legacyAgentDir = path.join(globalPluginDir, '.agent');
506
+ const newAgentsDir = path.join(globalPluginDir, '.agents');
507
+
508
+ if (fs.existsSync(legacyAgentDir) && !fs.existsSync(newAgentsDir)) {
509
+ // Legacy format: flatten .agent/ into plugin root
510
+ const entries = fs.readdirSync(legacyAgentDir);
443
511
  for (const entry of entries) {
444
- const srcPath = path.join(agentDir, entry);
512
+ const srcPath = path.join(legacyAgentDir, entry);
445
513
  const destPath = path.join(globalPluginDir, entry);
446
514
  if (fs.existsSync(destPath)) {
447
515
  removeRecursive(destPath);
448
516
  }
449
517
  fs.renameSync(srcPath, destPath);
450
518
  }
451
- removeRecursive(agentDir);
519
+ removeRecursive(legacyAgentDir);
520
+ } else if (fs.existsSync(newAgentsDir)) {
521
+ // v3.0 format: move plugin contents (skills, rules) to plugin root
522
+ const pluginSrcDir = path.join(newAgentsDir, 'plugins', 'antigravity-seo-kit');
523
+ if (fs.existsSync(pluginSrcDir)) {
524
+ for (const entry of fs.readdirSync(pluginSrcDir)) {
525
+ const srcPath = path.join(pluginSrcDir, entry);
526
+ const destPath = path.join(globalPluginDir, entry);
527
+ if (fs.existsSync(destPath)) {
528
+ removeRecursive(destPath);
529
+ }
530
+ fs.renameSync(srcPath, destPath);
531
+ }
532
+ }
533
+ // Keep workspace-level dirs (agents, workflows) for setupWorkspace
534
+ const workspaceDirs = ['agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
535
+ for (const dir of workspaceDirs) {
536
+ const srcDir = path.join(newAgentsDir, dir);
537
+ const destDir = path.join(globalPluginDir, `_workspace_${dir}`);
538
+ if (fs.existsSync(srcDir)) {
539
+ if (fs.existsSync(destDir)) removeRecursive(destDir);
540
+ fs.renameSync(srcDir, destDir);
541
+ }
542
+ }
543
+ // Copy seo-architecture.md
544
+ const archFile = path.join(newAgentsDir, 'seo-architecture.md');
545
+ if (fs.existsSync(archFile)) {
546
+ fs.copyFileSync(archFile, path.join(globalPluginDir, '_workspace_seo-architecture.md'));
547
+ }
548
+ removeRecursive(newAgentsDir);
452
549
  }
453
550
 
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 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
- author: {
460
- name: "Antigravity SEO Kit",
461
- email: "admin@solann.io",
462
- },
463
- repository: "https://solann.io/antigravity-seo-kit",
464
- license: "SEE LICENSE IN LICENSE",
465
- keywords: [
466
- "seo",
467
- "agentic-seo",
468
- "ai-agent",
469
- "antigravity",
470
- "seo-geo",
471
- "seo-audit",
472
- "seo-toolkit",
473
- "agent-skills",
474
- "seo-analysis",
475
- "technical-seo",
476
- "eeat"
477
- ]
478
- };
479
- fs.writeFileSync(path.join(globalPluginDir, 'plugin.json'), JSON.stringify(pluginJson, null, 2), 'utf-8');
551
+ // Step 4: Ensure plugin.json and installed_version.json
552
+ const pluginJsonPath = path.join(globalPluginDir, 'plugin.json');
553
+ if (!fs.existsSync(pluginJsonPath)) {
554
+ const pluginJson = {
555
+ name: "antigravity-seo-kit",
556
+ version: PACKAGE_VERSION,
557
+ description: "Professional Agentic SEO Platform — 44+ specialized skills",
558
+ author: { name: "Solann", email: "admin@solann.io" },
559
+ repository: "https://solann.io/antigravity-seo-kit",
560
+ license: "SEE LICENSE IN LICENSE",
561
+ keywords: ["seo", "agentic-seo", "ai-agent", "antigravity"]
562
+ };
563
+ fs.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2), 'utf-8');
564
+ }
480
565
  fs.writeFileSync(path.join(globalPluginDir, 'installed_version.json'), JSON.stringify({ version: PACKAGE_VERSION }), 'utf-8');
481
566
 
482
567
  // Step 5: Save global license info + manifest
483
- const LICENSE_FILE = '.seo-kit-license';
484
568
  writeLicenseFile(globalPluginDir, {
485
569
  key: licenseKey,
486
570
  deviceId,
@@ -488,19 +572,19 @@ async function installPlugin(licenseKey) {
488
572
  version: PACKAGE_VERSION,
489
573
  installedAt: new Date().toISOString(),
490
574
  plan: verifyResult?.license?.planName || verifyResult?.license?.plan || 'unknown',
491
- installedFiles: downloadResult.files.map(f => f.replace(/^\.agent\//, '')),
575
+ installedFiles: downloadResult.files.map(f => f.replace(/^\.agents?\//, '')),
492
576
  });
493
577
 
494
578
  // Done!
495
579
  console.log('');
496
580
  console.log(colorize('green', '═══════════════════════════════════════════════════════'));
497
- success(`SEO Kit v${PACKAGE_VERSION} installed successfully as a global Antigravity plugin!`);
581
+ success(`SEO Kit v${PACKAGE_VERSION} installed as global Antigravity plugin!`);
498
582
  console.log(colorize('green', '═══════════════════════════════════════════════════════'));
499
583
  console.log('');
500
584
 
501
585
  info('Next steps:');
502
586
  console.log(` ${colorize('yellow', '1.')} Restart or open any workspace in ${colorize('bold', 'Google Antigravity')}`);
503
- console.log(` ${colorize('yellow', '2.')} The SEO Kit plugin will automatically load globally.`);
587
+ console.log(` ${colorize('yellow', '2.')} Plugin loads globally. Run ${colorize('cyan', 'npx antigravity-seo-kit setup-workspace')} in a project.`);
504
588
  console.log('');
505
589
 
506
590
  if (verifyResult?.devicesUsed != null) {
@@ -511,10 +595,10 @@ async function installPlugin(licenseKey) {
511
595
 
512
596
  function setupWorkspace(cwd) {
513
597
  const globalDir = getGlobalPluginDir();
514
- const localAgentDir = path.join(cwd, '.agent');
598
+ const localAgentsDir = path.join(cwd, '.agents');
515
599
 
516
- if (fs.existsSync(localAgentDir)) {
517
- info('Existing .agent directory found. Re-synchronizing and updating files...');
600
+ if (fs.existsSync(localAgentsDir)) {
601
+ info('Existing .agents directory found. Re-synchronizing...');
518
602
  }
519
603
 
520
604
  if (!fs.existsSync(globalDir)) {
@@ -523,40 +607,82 @@ function setupWorkspace(cwd) {
523
607
  process.exit(1);
524
608
  }
525
609
 
526
- const spin = spinner('Replicating .agent directory to local workspace...').start();
610
+ const spin = spinner('Setting up .agents/ workspace structure...').start();
527
611
  try {
528
- fs.mkdirSync(localAgentDir, { recursive: true });
612
+ fs.mkdirSync(localAgentsDir, { recursive: true });
529
613
 
530
- // Only copy necessary directories. agents and rules are loaded globally via the plugin.
531
- // skills are copied but filtered to exclude .md files to save space and avoid duplicate prompts/instructions.
532
- const directoriesToCopy = ['.shared', 'config', 'dashboard', 'docs', 'scripts', 'workflows'];
533
- const filesToCopy = ['seo-architecture.md'];
614
+ // Copy workspace-level dirs from global plugin to local .agents/
615
+ // Skills & rules are NOT copied Antigravity loads them from global plugin
616
+ const workspaceDirs = ['agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
617
+ const rootFiles = ['seo-architecture.md'];
534
618
 
535
619
  let count = 0;
536
- for (const dir of directoriesToCopy) {
537
- const src = path.join(globalDir, dir);
538
- const dest = path.join(localAgentDir, dir);
620
+ for (const dir of workspaceDirs) {
621
+ // Try _workspace_ prefixed dirs first (v3.0 install format)
622
+ let src = path.join(globalDir, `_workspace_${dir}`);
623
+ if (!fs.existsSync(src)) {
624
+ src = path.join(globalDir, dir);
625
+ }
626
+ const dest = path.join(localAgentsDir, dir);
539
627
  if (fs.existsSync(src)) {
540
628
  count += copyRecursive(src, dest, { overwrite: true });
541
629
  }
542
630
  }
543
- for (const file of filesToCopy) {
544
- const src = path.join(globalDir, file);
545
- const dest = path.join(localAgentDir, file);
631
+
632
+ // Copy root-level files
633
+ for (const f of rootFiles) {
634
+ let src = path.join(globalDir, `_workspace_${f}`);
635
+ if (!fs.existsSync(src)) {
636
+ src = path.join(globalDir, f);
637
+ }
638
+ const dest = path.join(localAgentsDir, f);
546
639
  if (fs.existsSync(src)) {
547
640
  fs.copyFileSync(src, dest);
548
641
  count++;
549
642
  }
550
643
  }
551
644
 
552
- const LICENSE_FILE = '.seo-kit-license';
553
- const globalLicense = path.join(globalDir, LICENSE_FILE);
554
- const localLicense = path.join(cwd, LICENSE_FILE);
645
+ // Copy hooks.json to .agents/ root if exists in global plugin
646
+ const hooksFiles = ['hooks.json', '_workspace_hooks.json'];
647
+ for (const hf of hooksFiles) {
648
+ const hooksSrc = path.join(globalDir, hf);
649
+ if (fs.existsSync(hooksSrc)) {
650
+ const hooksDest = path.join(localAgentsDir, 'hooks.json');
651
+ if (!fs.existsSync(hooksDest)) {
652
+ fs.copyFileSync(hooksSrc, hooksDest);
653
+ count++;
654
+ }
655
+ break;
656
+ }
657
+ }
658
+
659
+ // Copy mcp_config.json to .agents/ root if exists in global plugin
660
+ const mcpFiles = ['mcp_config.json', '_workspace_mcp_config.json'];
661
+ for (const mf of mcpFiles) {
662
+ const mcpSrc = path.join(globalDir, mf);
663
+ if (fs.existsSync(mcpSrc)) {
664
+ const mcpDest = path.join(localAgentsDir, 'mcp_config.json');
665
+ if (!fs.existsSync(mcpDest)) {
666
+ fs.copyFileSync(mcpSrc, mcpDest);
667
+ count++;
668
+ }
669
+ break;
670
+ }
671
+ }
672
+
673
+ // Copy license file to workspace
674
+ const LICENSE_FILE_NAME = '.seo-kit-license';
675
+ const globalLicense = path.join(globalDir, LICENSE_FILE_NAME);
676
+ const localLicense = path.join(cwd, LICENSE_FILE_NAME);
555
677
  if (fs.existsSync(globalLicense) && !fs.existsSync(localLicense)) {
556
678
  fs.copyFileSync(globalLicense, localLicense);
557
679
  }
558
680
 
559
- spin.succeed(`Workspace setup complete! Copied ${count} files to .agent/`);
681
+ spin.succeed(`Workspace setup complete! Copied ${count} files to .agents/`);
682
+ console.log('');
683
+ info('Skills and rules are loaded from global plugin automatically.');
684
+ info('Workspace-level files (workflows, agents, scripts) are now local.');
685
+ console.log('');
560
686
  } catch (err) {
561
687
  spin.fail('Workspace setup failed');
562
688
  error(err.message);
@@ -564,6 +690,62 @@ function setupWorkspace(cwd) {
564
690
  }
565
691
  }
566
692
 
693
+ // ─── Migrate Command (v2.x → v3.0) ─────────────────────────────────────────
694
+
695
+ function migrate(cwd) {
696
+ const oldAgentDir = path.join(cwd, '.agent');
697
+ const newAgentsDir = path.join(cwd, '.agents');
698
+
699
+ if (!fs.existsSync(oldAgentDir)) {
700
+ if (fs.existsSync(newAgentsDir)) {
701
+ info('Already using v3.0 .agents/ structure. No migration needed.');
702
+ return;
703
+ }
704
+ error('No .agent/ directory found. Nothing to migrate.');
705
+ process.exit(1);
706
+ }
707
+
708
+ if (fs.existsSync(newAgentsDir)) {
709
+ warn('.agents/ already exists. Migration will merge/overwrite.');
710
+ }
711
+
712
+ const spin = spinner('Migrating .agent/ → .agents/ (v2.x → v3.0)...').start();
713
+ try {
714
+ fs.mkdirSync(newAgentsDir, { recursive: true });
715
+ let count = 0;
716
+
717
+ // Copy ALL directories directly into .agents/ (flat workspace structure)
718
+ const allDirs = ['skills', 'rules', 'agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
719
+ for (const dir of allDirs) {
720
+ const src = path.join(oldAgentDir, dir);
721
+ const dest = path.join(newAgentsDir, dir);
722
+ if (fs.existsSync(src)) {
723
+ count += copyRecursive(src, dest, { overwrite: true, mergeJson: true });
724
+ }
725
+ }
726
+
727
+ // Copy root-level files (.md, .json, etc.)
728
+ for (const f of fs.readdirSync(oldAgentDir)) {
729
+ const src = path.join(oldAgentDir, f);
730
+ if (fs.statSync(src).isFile()) {
731
+ fs.copyFileSync(src, path.join(newAgentsDir, f));
732
+ count++;
733
+ }
734
+ }
735
+
736
+ spin.succeed(`Migration complete! ${count} files moved to .agents/`);
737
+ console.log('');
738
+ info('The old .agent/ directory has been preserved as backup.');
739
+ info('After verifying everything works, you can remove it:');
740
+ console.log(` ${colorize('gray', 'rm -rf .agent/')}`);
741
+ console.log('');
742
+ } catch (err) {
743
+ spin.fail('Migration failed');
744
+ error(err.message);
745
+ process.exit(1);
746
+ }
747
+ }
748
+
567
749
  // ─── Exports ────────────────────────────────────────────────────────────────
568
750
 
569
751
  module.exports = {
@@ -575,4 +757,5 @@ module.exports = {
575
757
  deviceRemove,
576
758
  installPlugin,
577
759
  setupWorkspace,
760
+ migrate,
578
761
  };
package/lib/utils.js CHANGED
@@ -307,7 +307,8 @@ function showHelp() {
307
307
  console.log(`${colorize('bold', 'Commands:')}`);
308
308
  console.log(` ${colorize('green', 'install')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit into current workspace`);
309
309
  console.log(` ${colorize('green', 'install-plugin')} --key=SK-XXXX-XXXX-XXXX Install SEO Kit globally as an Antigravity plugin`);
310
- console.log(` ${colorize('green', 'setup-workspace')} Replicate .agent config directory to current workspace`);
310
+ console.log(` ${colorize('green', 'setup-workspace')} Replicate .agents config directory to current workspace`);
311
+ console.log(` ${colorize('green', 'migrate')} Migrate .agent/ to .agents/ (v2.x → v3.0)`);
311
312
  console.log(` ${colorize('green', 'update')} Update to latest version`);
312
313
  console.log(` ${colorize('green', 'uninstall')} Remove SEO Kit from workspace`);
313
314
  console.log(` ${colorize('green', 'status')} Show license & installation info`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antigravity-seo-kit",
3
- "version": "2.7.4",
3
+ "version": "2.9.8",
4
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": {