antigravity-seo-kit 2.7.4 → 2.9.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 +5 -2
- package/bin/cli.js +6 -0
- package/lib/downloader.js +1 -0
- package/lib/installer.js +290 -67
- package/lib/utils.js +2 -1
- package/package.json +1 -1
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
|
|
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 .
|
|
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
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,70 @@ async function install(licenseKey, cwd) {
|
|
|
69
69
|
process.exit(1);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// Step 3:
|
|
72
|
+
// Step 3: Restructure into .agents/ 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
|
+
// Workspace-level dirs → .agents/
|
|
82
|
+
const workspaceDirs = ['agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
|
|
83
|
+
let migrateCount = 0;
|
|
84
|
+
for (const dir of workspaceDirs) {
|
|
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 .md files → .agents/
|
|
93
|
+
for (const f of fs.readdirSync(legacyAgentDir)) {
|
|
94
|
+
const src = path.join(legacyAgentDir, f);
|
|
95
|
+
if (fs.statSync(src).isFile() && f.endsWith('.md')) {
|
|
96
|
+
fs.copyFileSync(src, path.join(newAgentsDir, f));
|
|
97
|
+
migrateCount++;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// skills + rules → .agents/plugins/antigravity-seo-kit/
|
|
102
|
+
const pluginDir = path.join(newAgentsDir, 'plugins', 'antigravity-seo-kit');
|
|
103
|
+
fs.mkdirSync(pluginDir, { recursive: true });
|
|
104
|
+
|
|
105
|
+
const skillsSrc = path.join(legacyAgentDir, 'skills');
|
|
106
|
+
if (fs.existsSync(skillsSrc)) {
|
|
107
|
+
migrateCount += copyRecursive(skillsSrc, path.join(pluginDir, 'skills'), { overwrite: true });
|
|
108
|
+
}
|
|
109
|
+
const rulesSrc = path.join(legacyAgentDir, 'rules');
|
|
110
|
+
if (fs.existsSync(rulesSrc)) {
|
|
111
|
+
migrateCount += copyRecursive(rulesSrc, path.join(pluginDir, 'rules'), { overwrite: true });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Create plugin.json
|
|
115
|
+
const pluginJsonPath = path.join(pluginDir, 'plugin.json');
|
|
116
|
+
if (!fs.existsSync(pluginJsonPath)) {
|
|
117
|
+
fs.writeFileSync(pluginJsonPath, JSON.stringify({
|
|
118
|
+
name: 'antigravity-seo-kit',
|
|
119
|
+
version: PACKAGE_VERSION,
|
|
120
|
+
description: 'Professional Agentic SEO Platform — 44+ specialized skills',
|
|
121
|
+
author: { name: 'Solann', email: 'admin@solann.io' },
|
|
122
|
+
}, null, 2), 'utf-8');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Remove legacy .agent/ (downloaded files only, not user data)
|
|
126
|
+
removeRecursive(legacyAgentDir);
|
|
127
|
+
|
|
128
|
+
spinMigrate.succeed(`Restructured to .agents/ format (${migrateCount} files)`);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
spinMigrate.fail('Restructuring failed, keeping .agent/ as-is');
|
|
131
|
+
warn(`You can manually run: npx antigravity-seo-kit migrate`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Step 4: Save license info + manifest
|
|
73
136
|
writeLicenseFile(cwd, {
|
|
74
137
|
key: licenseKey,
|
|
75
138
|
deviceId,
|
|
@@ -122,6 +185,10 @@ async function update(cwd) {
|
|
|
122
185
|
process.exit(1);
|
|
123
186
|
}
|
|
124
187
|
|
|
188
|
+
// Detect structure: v3.0 (.agents/) or v2.x (.agent/)
|
|
189
|
+
const isV3 = fs.existsSync(path.join(cwd, '.agents'));
|
|
190
|
+
const isV2 = fs.existsSync(path.join(cwd, '.agent'));
|
|
191
|
+
|
|
125
192
|
// Download latest assets from server
|
|
126
193
|
console.log('');
|
|
127
194
|
const spinDl = spinner('Downloading latest SEO Kit assets...').start();
|
|
@@ -136,6 +203,13 @@ async function update(cwd) {
|
|
|
136
203
|
process.exit(1);
|
|
137
204
|
}
|
|
138
205
|
|
|
206
|
+
// If user was on v2 (.agent/) and download brings v3 (.agents/), inform about migrate
|
|
207
|
+
if (isV2 && !isV3 && fs.existsSync(path.join(cwd, '.agents'))) {
|
|
208
|
+
console.log('');
|
|
209
|
+
info('v3.0 structure detected in update. Run migrate to complete:');
|
|
210
|
+
console.log(` ${colorize('cyan', 'npx antigravity-seo-kit migrate')}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
139
213
|
// Update license file
|
|
140
214
|
config.version = PACKAGE_VERSION;
|
|
141
215
|
config.updatedAt = new Date().toISOString();
|
|
@@ -160,7 +234,7 @@ async function uninstall(cwd) {
|
|
|
160
234
|
let totalRemoved = 0;
|
|
161
235
|
|
|
162
236
|
if (config.installedFiles && config.installedFiles.length > 0) {
|
|
163
|
-
//
|
|
237
|
+
// Manifest-based removal
|
|
164
238
|
for (const filePath of config.installedFiles) {
|
|
165
239
|
const target = path.join(cwd, filePath);
|
|
166
240
|
if (fs.existsSync(target)) {
|
|
@@ -168,13 +242,20 @@ async function uninstall(cwd) {
|
|
|
168
242
|
totalRemoved++;
|
|
169
243
|
}
|
|
170
244
|
}
|
|
171
|
-
// Clean up empty directories
|
|
245
|
+
// Clean up empty directories for both v2 and v3 structures
|
|
172
246
|
cleanEmptyDirsUp(path.join(cwd, '.agent'));
|
|
247
|
+
cleanEmptyDirsUp(path.join(cwd, '.agents'));
|
|
173
248
|
} else {
|
|
174
|
-
// Legacy fallback: use
|
|
249
|
+
// Legacy fallback: use prefix scan
|
|
175
250
|
totalRemoved += legacyUninstall(cwd);
|
|
176
251
|
}
|
|
177
252
|
|
|
253
|
+
// Also clean .agents/plugins/antigravity-seo-kit/ if it exists (v3)
|
|
254
|
+
const v3PluginDir = path.join(cwd, '.agents', 'plugins', 'antigravity-seo-kit');
|
|
255
|
+
if (fs.existsSync(v3PluginDir)) {
|
|
256
|
+
totalRemoved += removeRecursive(v3PluginDir);
|
|
257
|
+
}
|
|
258
|
+
|
|
178
259
|
// Remove license file
|
|
179
260
|
removeLicenseFile(cwd);
|
|
180
261
|
|
|
@@ -253,24 +334,41 @@ async function status(cwd) {
|
|
|
253
334
|
|
|
254
335
|
// Count installed files
|
|
255
336
|
if (config.installedFiles && config.installedFiles.length > 0) {
|
|
256
|
-
//
|
|
337
|
+
// Manifest-based count
|
|
257
338
|
let existingFiles = 0;
|
|
258
339
|
for (const f of config.installedFiles) {
|
|
259
340
|
if (fs.existsSync(path.join(cwd, f))) existingFiles++;
|
|
260
341
|
}
|
|
261
342
|
console.log(` ${colorize('cyan', 'Files:')} ${existingFiles}/${config.installedFiles.length} present`);
|
|
262
343
|
} else {
|
|
263
|
-
// Legacy: scan for seo-* prefixed entries
|
|
264
|
-
const agentDir = path.join(cwd, '.agent');
|
|
344
|
+
// Legacy: scan for seo-* prefixed entries in both .agent/ and .agents/
|
|
265
345
|
let totalLegacy = 0;
|
|
266
|
-
for (const
|
|
267
|
-
const
|
|
268
|
-
if (!fs.existsSync(
|
|
269
|
-
for (const
|
|
270
|
-
|
|
346
|
+
for (const baseDir of ['.agent', '.agents']) {
|
|
347
|
+
const agentDir = path.join(cwd, baseDir);
|
|
348
|
+
if (!fs.existsSync(agentDir)) continue;
|
|
349
|
+
for (const subDir of LEGACY_DIRS) {
|
|
350
|
+
const dirPath = path.join(agentDir, subDir);
|
|
351
|
+
if (!fs.existsSync(dirPath)) continue;
|
|
352
|
+
for (const entry of fs.readdirSync(dirPath)) {
|
|
353
|
+
if (entry.startsWith(LEGACY_SEO_PREFIX) || entry === 'seo') totalLegacy++;
|
|
354
|
+
}
|
|
271
355
|
}
|
|
272
356
|
}
|
|
273
|
-
|
|
357
|
+
// Also count plugin dir if v3
|
|
358
|
+
const pluginSkillsDir = path.join(cwd, '.agents', 'plugins', 'antigravity-seo-kit', 'skills');
|
|
359
|
+
if (fs.existsSync(pluginSkillsDir)) {
|
|
360
|
+
totalLegacy += fs.readdirSync(pluginSkillsDir).length;
|
|
361
|
+
}
|
|
362
|
+
console.log(` ${colorize('cyan', 'Components:')} ${totalLegacy} installed`);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Detect structure version
|
|
366
|
+
const hasV3 = fs.existsSync(path.join(cwd, '.agents'));
|
|
367
|
+
const hasV2 = fs.existsSync(path.join(cwd, '.agent'));
|
|
368
|
+
const structureVersion = hasV3 ? 'v3.0 (.agents/)' : hasV2 ? 'v2.x (.agent/)' : 'unknown';
|
|
369
|
+
console.log(` ${colorize('cyan', 'Structure:')} ${structureVersion}`);
|
|
370
|
+
if (hasV2 && !hasV3) {
|
|
371
|
+
warn('Using legacy v2.x structure. Run: npx antigravity-seo-kit migrate');
|
|
274
372
|
}
|
|
275
373
|
console.log('');
|
|
276
374
|
|
|
@@ -436,51 +534,72 @@ async function installPlugin(licenseKey) {
|
|
|
436
534
|
process.exit(1);
|
|
437
535
|
}
|
|
438
536
|
|
|
439
|
-
// Step 3:
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
537
|
+
// Step 3: Restructure into .agents/ plugin format
|
|
538
|
+
// v3.0: Downloaded assets arrive in .agents/ structure already
|
|
539
|
+
// Handle legacy .agent/ if server still serves old format
|
|
540
|
+
const legacyAgentDir = path.join(globalPluginDir, '.agent');
|
|
541
|
+
const newAgentsDir = path.join(globalPluginDir, '.agents');
|
|
542
|
+
|
|
543
|
+
if (fs.existsSync(legacyAgentDir) && !fs.existsSync(newAgentsDir)) {
|
|
544
|
+
// Legacy format: flatten .agent/ into plugin root
|
|
545
|
+
const entries = fs.readdirSync(legacyAgentDir);
|
|
443
546
|
for (const entry of entries) {
|
|
444
|
-
const srcPath = path.join(
|
|
547
|
+
const srcPath = path.join(legacyAgentDir, entry);
|
|
445
548
|
const destPath = path.join(globalPluginDir, entry);
|
|
446
549
|
if (fs.existsSync(destPath)) {
|
|
447
550
|
removeRecursive(destPath);
|
|
448
551
|
}
|
|
449
552
|
fs.renameSync(srcPath, destPath);
|
|
450
553
|
}
|
|
451
|
-
removeRecursive(
|
|
554
|
+
removeRecursive(legacyAgentDir);
|
|
555
|
+
} else if (fs.existsSync(newAgentsDir)) {
|
|
556
|
+
// v3.0 format: move plugin contents (skills, rules) to plugin root
|
|
557
|
+
const pluginSrcDir = path.join(newAgentsDir, 'plugins', 'antigravity-seo-kit');
|
|
558
|
+
if (fs.existsSync(pluginSrcDir)) {
|
|
559
|
+
for (const entry of fs.readdirSync(pluginSrcDir)) {
|
|
560
|
+
const srcPath = path.join(pluginSrcDir, entry);
|
|
561
|
+
const destPath = path.join(globalPluginDir, entry);
|
|
562
|
+
if (fs.existsSync(destPath)) {
|
|
563
|
+
removeRecursive(destPath);
|
|
564
|
+
}
|
|
565
|
+
fs.renameSync(srcPath, destPath);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
// Keep workspace-level dirs (agents, workflows) for setupWorkspace
|
|
569
|
+
const workspaceDirs = ['agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
|
|
570
|
+
for (const dir of workspaceDirs) {
|
|
571
|
+
const srcDir = path.join(newAgentsDir, dir);
|
|
572
|
+
const destDir = path.join(globalPluginDir, `_workspace_${dir}`);
|
|
573
|
+
if (fs.existsSync(srcDir)) {
|
|
574
|
+
if (fs.existsSync(destDir)) removeRecursive(destDir);
|
|
575
|
+
fs.renameSync(srcDir, destDir);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
// Copy seo-architecture.md
|
|
579
|
+
const archFile = path.join(newAgentsDir, 'seo-architecture.md');
|
|
580
|
+
if (fs.existsSync(archFile)) {
|
|
581
|
+
fs.copyFileSync(archFile, path.join(globalPluginDir, '_workspace_seo-architecture.md'));
|
|
582
|
+
}
|
|
583
|
+
removeRecursive(newAgentsDir);
|
|
452
584
|
}
|
|
453
585
|
|
|
454
|
-
// Step 4:
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
email: "admin@solann.io",
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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');
|
|
586
|
+
// Step 4: Ensure plugin.json and installed_version.json
|
|
587
|
+
const pluginJsonPath = path.join(globalPluginDir, 'plugin.json');
|
|
588
|
+
if (!fs.existsSync(pluginJsonPath)) {
|
|
589
|
+
const pluginJson = {
|
|
590
|
+
name: "antigravity-seo-kit",
|
|
591
|
+
version: PACKAGE_VERSION,
|
|
592
|
+
description: "Professional Agentic SEO Platform — 44+ specialized skills",
|
|
593
|
+
author: { name: "Solann", email: "admin@solann.io" },
|
|
594
|
+
repository: "https://solann.io/antigravity-seo-kit",
|
|
595
|
+
license: "SEE LICENSE IN LICENSE",
|
|
596
|
+
keywords: ["seo", "agentic-seo", "ai-agent", "antigravity"]
|
|
597
|
+
};
|
|
598
|
+
fs.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2), 'utf-8');
|
|
599
|
+
}
|
|
480
600
|
fs.writeFileSync(path.join(globalPluginDir, 'installed_version.json'), JSON.stringify({ version: PACKAGE_VERSION }), 'utf-8');
|
|
481
601
|
|
|
482
602
|
// Step 5: Save global license info + manifest
|
|
483
|
-
const LICENSE_FILE = '.seo-kit-license';
|
|
484
603
|
writeLicenseFile(globalPluginDir, {
|
|
485
604
|
key: licenseKey,
|
|
486
605
|
deviceId,
|
|
@@ -488,19 +607,19 @@ async function installPlugin(licenseKey) {
|
|
|
488
607
|
version: PACKAGE_VERSION,
|
|
489
608
|
installedAt: new Date().toISOString(),
|
|
490
609
|
plan: verifyResult?.license?.planName || verifyResult?.license?.plan || 'unknown',
|
|
491
|
-
installedFiles: downloadResult.files.map(f => f.replace(/^\.
|
|
610
|
+
installedFiles: downloadResult.files.map(f => f.replace(/^\.agents?\//, '')),
|
|
492
611
|
});
|
|
493
612
|
|
|
494
613
|
// Done!
|
|
495
614
|
console.log('');
|
|
496
615
|
console.log(colorize('green', '═══════════════════════════════════════════════════════'));
|
|
497
|
-
success(`SEO Kit v${PACKAGE_VERSION} installed
|
|
616
|
+
success(`SEO Kit v${PACKAGE_VERSION} installed as global Antigravity plugin!`);
|
|
498
617
|
console.log(colorize('green', '═══════════════════════════════════════════════════════'));
|
|
499
618
|
console.log('');
|
|
500
619
|
|
|
501
620
|
info('Next steps:');
|
|
502
621
|
console.log(` ${colorize('yellow', '1.')} Restart or open any workspace in ${colorize('bold', 'Google Antigravity')}`);
|
|
503
|
-
console.log(` ${colorize('yellow', '2.')}
|
|
622
|
+
console.log(` ${colorize('yellow', '2.')} Plugin loads globally. Run ${colorize('cyan', 'npx antigravity-seo-kit setup-workspace')} in a project.`);
|
|
504
623
|
console.log('');
|
|
505
624
|
|
|
506
625
|
if (verifyResult?.devicesUsed != null) {
|
|
@@ -511,10 +630,10 @@ async function installPlugin(licenseKey) {
|
|
|
511
630
|
|
|
512
631
|
function setupWorkspace(cwd) {
|
|
513
632
|
const globalDir = getGlobalPluginDir();
|
|
514
|
-
const
|
|
633
|
+
const localAgentsDir = path.join(cwd, '.agents');
|
|
515
634
|
|
|
516
|
-
if (fs.existsSync(
|
|
517
|
-
info('Existing .
|
|
635
|
+
if (fs.existsSync(localAgentsDir)) {
|
|
636
|
+
info('Existing .agents directory found. Re-synchronizing...');
|
|
518
637
|
}
|
|
519
638
|
|
|
520
639
|
if (!fs.existsSync(globalDir)) {
|
|
@@ -523,40 +642,60 @@ function setupWorkspace(cwd) {
|
|
|
523
642
|
process.exit(1);
|
|
524
643
|
}
|
|
525
644
|
|
|
526
|
-
const spin = spinner('
|
|
645
|
+
const spin = spinner('Setting up .agents/ workspace structure...').start();
|
|
527
646
|
try {
|
|
528
|
-
fs.mkdirSync(
|
|
647
|
+
fs.mkdirSync(localAgentsDir, { recursive: true });
|
|
529
648
|
|
|
530
|
-
//
|
|
531
|
-
//
|
|
532
|
-
const
|
|
649
|
+
// v3.0: Copy workspace-level dirs (agents, workflows, scripts, etc.)
|
|
650
|
+
// Plugin contents (skills, rules) stay in ~/.gemini/config/plugins/
|
|
651
|
+
const workspaceDirs = ['agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
|
|
533
652
|
const filesToCopy = ['seo-architecture.md'];
|
|
534
653
|
|
|
535
654
|
let count = 0;
|
|
536
|
-
for (const dir of
|
|
537
|
-
|
|
538
|
-
|
|
655
|
+
for (const dir of workspaceDirs) {
|
|
656
|
+
// Try _workspace_ prefixed dirs first (v3.0 install format)
|
|
657
|
+
let src = path.join(globalDir, `_workspace_${dir}`);
|
|
658
|
+
if (!fs.existsSync(src)) {
|
|
659
|
+
// Fallback to flat dir (v2.x compat)
|
|
660
|
+
src = path.join(globalDir, dir);
|
|
661
|
+
}
|
|
662
|
+
const dest = path.join(localAgentsDir, dir);
|
|
539
663
|
if (fs.existsSync(src)) {
|
|
540
664
|
count += copyRecursive(src, dest, { overwrite: true });
|
|
541
665
|
}
|
|
542
666
|
}
|
|
543
|
-
for (const
|
|
544
|
-
|
|
545
|
-
|
|
667
|
+
for (const f of filesToCopy) {
|
|
668
|
+
let src = path.join(globalDir, `_workspace_${f}`);
|
|
669
|
+
if (!fs.existsSync(src)) {
|
|
670
|
+
src = path.join(globalDir, f);
|
|
671
|
+
}
|
|
672
|
+
const dest = path.join(localAgentsDir, f);
|
|
546
673
|
if (fs.existsSync(src)) {
|
|
547
674
|
fs.copyFileSync(src, dest);
|
|
548
675
|
count++;
|
|
549
676
|
}
|
|
550
677
|
}
|
|
551
678
|
|
|
552
|
-
|
|
553
|
-
const
|
|
554
|
-
|
|
679
|
+
// Create plugin symlink/reference in workspace
|
|
680
|
+
const pluginsDir = path.join(localAgentsDir, 'plugins', 'antigravity-seo-kit');
|
|
681
|
+
if (!fs.existsSync(pluginsDir)) {
|
|
682
|
+
fs.mkdirSync(pluginsDir, { recursive: true });
|
|
683
|
+
// Write a pointer file so workspace knows where the plugin lives
|
|
684
|
+
fs.writeFileSync(
|
|
685
|
+
path.join(pluginsDir, '_global_ref.json'),
|
|
686
|
+
JSON.stringify({ globalDir, version: PACKAGE_VERSION }, null, 2),
|
|
687
|
+
'utf-8'
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const LICENSE_FILE_NAME = '.seo-kit-license';
|
|
692
|
+
const globalLicense = path.join(globalDir, LICENSE_FILE_NAME);
|
|
693
|
+
const localLicense = path.join(cwd, LICENSE_FILE_NAME);
|
|
555
694
|
if (fs.existsSync(globalLicense) && !fs.existsSync(localLicense)) {
|
|
556
695
|
fs.copyFileSync(globalLicense, localLicense);
|
|
557
696
|
}
|
|
558
697
|
|
|
559
|
-
spin.succeed(`Workspace setup complete! Copied ${count} files to .
|
|
698
|
+
spin.succeed(`Workspace setup complete! Copied ${count} files to .agents/`);
|
|
560
699
|
} catch (err) {
|
|
561
700
|
spin.fail('Workspace setup failed');
|
|
562
701
|
error(err.message);
|
|
@@ -564,6 +703,89 @@ function setupWorkspace(cwd) {
|
|
|
564
703
|
}
|
|
565
704
|
}
|
|
566
705
|
|
|
706
|
+
// ─── Migrate Command (v2.x → v3.0) ─────────────────────────────────────────
|
|
707
|
+
|
|
708
|
+
function migrate(cwd) {
|
|
709
|
+
const oldAgentDir = path.join(cwd, '.agent');
|
|
710
|
+
const newAgentsDir = path.join(cwd, '.agents');
|
|
711
|
+
|
|
712
|
+
if (!fs.existsSync(oldAgentDir)) {
|
|
713
|
+
if (fs.existsSync(newAgentsDir)) {
|
|
714
|
+
info('Already using v3.0 .agents/ structure. No migration needed.');
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
error('No .agent/ directory found. Nothing to migrate.');
|
|
718
|
+
process.exit(1);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (fs.existsSync(newAgentsDir)) {
|
|
722
|
+
warn('.agents/ already exists. Migration will merge/overwrite.');
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
const spin = spinner('Migrating .agent/ → .agents/ (v2.x → v3.0)...').start();
|
|
726
|
+
try {
|
|
727
|
+
let count = 0;
|
|
728
|
+
|
|
729
|
+
// 1. Copy workspace-level dirs
|
|
730
|
+
const workspaceDirs = ['agents', 'workflows', 'scripts', 'config', 'dashboard', 'docs', '.shared'];
|
|
731
|
+
for (const dir of workspaceDirs) {
|
|
732
|
+
const src = path.join(oldAgentDir, dir);
|
|
733
|
+
const dest = path.join(newAgentsDir, dir);
|
|
734
|
+
if (fs.existsSync(src)) {
|
|
735
|
+
count += copyRecursive(src, dest, { overwrite: true, mergeJson: true });
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Copy root-level md files
|
|
740
|
+
const rootFiles = fs.readdirSync(oldAgentDir).filter(f => f.endsWith('.md'));
|
|
741
|
+
for (const f of rootFiles) {
|
|
742
|
+
const src = path.join(oldAgentDir, f);
|
|
743
|
+
const dest = path.join(newAgentsDir, f);
|
|
744
|
+
if (fs.statSync(src).isFile()) {
|
|
745
|
+
fs.copyFileSync(src, dest);
|
|
746
|
+
count++;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// 2. Copy skills + rules into plugin structure
|
|
751
|
+
const pluginDir = path.join(newAgentsDir, 'plugins', 'antigravity-seo-kit');
|
|
752
|
+
fs.mkdirSync(pluginDir, { recursive: true });
|
|
753
|
+
|
|
754
|
+
const skillsSrc = path.join(oldAgentDir, 'skills');
|
|
755
|
+
const skillsDest = path.join(pluginDir, 'skills');
|
|
756
|
+
if (fs.existsSync(skillsSrc)) {
|
|
757
|
+
count += copyRecursive(skillsSrc, skillsDest, { overwrite: true, mergeJson: true });
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
const rulesSrc = path.join(oldAgentDir, 'rules');
|
|
761
|
+
const rulesDest = path.join(pluginDir, 'rules');
|
|
762
|
+
if (fs.existsSync(rulesSrc)) {
|
|
763
|
+
count += copyRecursive(rulesSrc, rulesDest, { overwrite: true });
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// 3. Create plugin.json if missing
|
|
767
|
+
const pluginJsonPath = path.join(pluginDir, 'plugin.json');
|
|
768
|
+
if (!fs.existsSync(pluginJsonPath)) {
|
|
769
|
+
fs.writeFileSync(pluginJsonPath, JSON.stringify({
|
|
770
|
+
name: 'antigravity-seo-kit',
|
|
771
|
+
version: PACKAGE_VERSION,
|
|
772
|
+
description: 'Migrated from v2.x .agent/ structure',
|
|
773
|
+
}, null, 2), 'utf-8');
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
spin.succeed(`Migration complete! ${count} files moved to .agents/`);
|
|
777
|
+
console.log('');
|
|
778
|
+
info('The old .agent/ directory has been preserved as backup.');
|
|
779
|
+
info('After verifying everything works, you can remove it:');
|
|
780
|
+
console.log(` ${colorize('gray', 'rm -rf .agent/')}`);
|
|
781
|
+
console.log('');
|
|
782
|
+
} catch (err) {
|
|
783
|
+
spin.fail('Migration failed');
|
|
784
|
+
error(err.message);
|
|
785
|
+
process.exit(1);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
567
789
|
// ─── Exports ────────────────────────────────────────────────────────────────
|
|
568
790
|
|
|
569
791
|
module.exports = {
|
|
@@ -575,4 +797,5 @@ module.exports = {
|
|
|
575
797
|
deviceRemove,
|
|
576
798
|
installPlugin,
|
|
577
799
|
setupWorkspace,
|
|
800
|
+
migrate,
|
|
578
801
|
};
|
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 .
|
|
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
|
|
3
|
+
"version": "2.9.7",
|
|
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": {
|