antigravity-ai-kit 2.1.0 → 3.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.
Files changed (114) hide show
  1. package/.agent/README.md +4 -4
  2. package/.agent/agents/README.md +16 -12
  3. package/.agent/agents/architect.md +1 -0
  4. package/.agent/agents/backend-specialist.md +11 -0
  5. package/.agent/agents/code-reviewer.md +1 -0
  6. package/.agent/agents/database-architect.md +11 -0
  7. package/.agent/agents/devops-engineer.md +11 -0
  8. package/.agent/agents/e2e-runner.md +1 -0
  9. package/.agent/agents/explorer-agent.md +11 -0
  10. package/.agent/agents/frontend-specialist.md +11 -0
  11. package/.agent/agents/mobile-developer.md +11 -0
  12. package/.agent/agents/performance-optimizer.md +11 -0
  13. package/.agent/agents/planner.md +1 -0
  14. package/.agent/agents/refactor-cleaner.md +1 -0
  15. package/.agent/agents/reliability-engineer.md +11 -0
  16. package/.agent/agents/security-reviewer.md +1 -0
  17. package/.agent/agents/sprint-orchestrator.md +10 -0
  18. package/.agent/agents/tdd-guide.md +1 -0
  19. package/.agent/commands/code-review.md +1 -0
  20. package/.agent/commands/debug.md +1 -0
  21. package/.agent/commands/deploy.md +1 -0
  22. package/.agent/commands/help.md +252 -31
  23. package/.agent/commands/plan.md +1 -0
  24. package/.agent/commands/status.md +1 -0
  25. package/.agent/commands/tdd.md +1 -0
  26. package/.agent/contexts/brainstorm.md +26 -0
  27. package/.agent/contexts/debug.md +28 -0
  28. package/.agent/contexts/implement.md +29 -0
  29. package/.agent/contexts/review.md +27 -0
  30. package/.agent/contexts/ship.md +28 -0
  31. package/.agent/engine/identity.json +13 -0
  32. package/.agent/engine/loading-rules.json +23 -1
  33. package/.agent/engine/marketplace-index.json +29 -0
  34. package/.agent/engine/reliability-config.json +14 -0
  35. package/.agent/engine/sdlc-map.json +44 -0
  36. package/.agent/engine/workflow-state.json +28 -2
  37. package/.agent/hooks/hooks.json +27 -25
  38. package/.agent/manifest.json +12 -4
  39. package/.agent/rules.md +2 -1
  40. package/.agent/skills/README.md +10 -5
  41. package/.agent/skills/i18n-localization/SKILL.md +191 -0
  42. package/.agent/skills/mcp-integration/SKILL.md +224 -0
  43. package/.agent/skills/parallel-agents/SKILL.md +1 -1
  44. package/.agent/skills/shell-conventions/SKILL.md +92 -0
  45. package/.agent/skills/ui-ux-pro-max/SKILL.md +557 -0
  46. package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
  47. package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
  48. package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
  49. package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
  50. package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
  51. package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  52. package/.agent/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  53. package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  54. package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  55. package/.agent/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  56. package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  57. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  58. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  59. package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  60. package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  61. package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  62. package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  63. package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  64. package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  65. package/.agent/skills/ui-ux-pro-max/data/styles.csv +68 -0
  66. package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
  67. package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  68. package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  69. package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  70. package/.agent/skills/ui-ux-pro-max/scripts/core.py +253 -0
  71. package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  72. package/.agent/skills/ui-ux-pro-max/scripts/search.py +114 -0
  73. package/.agent/templates/adr-template.md +32 -0
  74. package/.agent/templates/bug-report.md +37 -0
  75. package/.agent/templates/feature-request.md +32 -0
  76. package/.agent/workflows/README.md +92 -78
  77. package/.agent/workflows/brainstorm.md +154 -100
  78. package/.agent/workflows/create.md +142 -75
  79. package/.agent/workflows/debug.md +157 -98
  80. package/.agent/workflows/deploy.md +195 -144
  81. package/.agent/workflows/enhance.md +157 -65
  82. package/.agent/workflows/orchestrate.md +171 -114
  83. package/.agent/workflows/plan.md +147 -72
  84. package/.agent/workflows/preview.md +140 -83
  85. package/.agent/workflows/quality-gate.md +196 -0
  86. package/.agent/workflows/retrospective.md +197 -0
  87. package/.agent/workflows/review.md +188 -0
  88. package/.agent/workflows/status.md +142 -91
  89. package/.agent/workflows/test.md +168 -95
  90. package/.agent/workflows/ui-ux-pro-max.md +181 -127
  91. package/README.md +215 -78
  92. package/bin/ag-kit.js +344 -10
  93. package/lib/agent-registry.js +214 -0
  94. package/lib/agent-reputation.js +351 -0
  95. package/lib/cli-commands.js +235 -0
  96. package/lib/conflict-detector.js +245 -0
  97. package/lib/engineering-manager.js +354 -0
  98. package/lib/error-budget.js +294 -0
  99. package/lib/hook-system.js +252 -0
  100. package/lib/identity.js +245 -0
  101. package/lib/loading-engine.js +208 -0
  102. package/lib/marketplace.js +298 -0
  103. package/lib/plugin-system.js +604 -0
  104. package/lib/security-scanner.js +309 -0
  105. package/lib/self-healing.js +434 -0
  106. package/lib/session-manager.js +261 -0
  107. package/lib/skill-sandbox.js +244 -0
  108. package/lib/task-governance.js +523 -0
  109. package/lib/task-model.js +317 -0
  110. package/lib/updater.js +201 -0
  111. package/lib/verify.js +240 -0
  112. package/lib/workflow-engine.js +353 -0
  113. package/lib/workflow-persistence.js +160 -0
  114. package/package.json +7 -3
package/bin/ag-kit.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Antigravity AI Kit CLI
5
5
  *
6
6
  * Usage:
7
- * npx @emredursun/antigravity-ai-kit init
7
+ * npx antigravity-ai-kit init
8
8
  * ag-kit init [options]
9
9
  *
10
10
  * @author Emre Dursun
@@ -14,7 +14,7 @@
14
14
  const fs = require('fs');
15
15
  const path = require('path');
16
16
 
17
- const VERSION = '2.1.0';
17
+ const VERSION = '3.0.0';
18
18
  const AGENT_FOLDER = '.agent';
19
19
 
20
20
  // ANSI colors
@@ -49,8 +49,9 @@ ${colors.reset}
49
49
  ${colors.green}🚀 Antigravity AI Kit v${VERSION}${colors.reset}
50
50
  ${colors.yellow} Transform Your IDE into an Autonomous Engineering Team${colors.reset}
51
51
 
52
- • 19 AI Agents • 27 Skills
53
- • 31 Commands • 11 Workflows
52
+ • 19 AI Agents • 31 Skills
53
+ • 31 Commands • 14 Workflows
54
+ • Runtime Engine • Error Budget
54
55
  `);
55
56
  }
56
57
 
@@ -60,7 +61,16 @@ function showHelp() {
60
61
  ${colors.bright}Usage:${colors.reset}
61
62
  ag-kit init [options] Install .agent folder to your project
62
63
  ag-kit update Update to latest version
63
- ag-kit status Check installation status
64
+ ag-kit status Check installation status (alias: dashboard)
65
+ ag-kit verify Run manifest integrity checks
66
+ ag-kit scan Run security scan
67
+ ag-kit plugin list List installed plugins
68
+ ag-kit plugin install <p> Install plugin from directory
69
+ ag-kit plugin remove <n> Remove installed plugin
70
+ ag-kit market search <q> Search marketplace plugins
71
+ ag-kit market info <name> Get marketplace plugin details
72
+ ag-kit market install <n> Install from marketplace
73
+ ag-kit heal [--file <f>] Detect and diagnose CI failures
64
74
  ag-kit --help Show this help message
65
75
  ag-kit --version Show version
66
76
 
@@ -69,11 +79,18 @@ ${colors.bright}Options:${colors.reset}
69
79
  --path <dir> Install to specific directory
70
80
  --quiet Suppress output (for CI/CD)
71
81
  --dry-run Preview actions without executing
82
+ --apply Apply self-healing patches (default: dry-run)
83
+ --file <path> CI log file for heal command
72
84
 
73
85
  ${colors.bright}Examples:${colors.reset}
74
86
  npx antigravity-ai-kit init
75
87
  ag-kit init --force
76
- ag-kit init --path ./my-project
88
+ ag-kit scan
89
+ ag-kit plugin list
90
+
91
+ ${colors.bright}IDE Reference:${colors.reset}
92
+ Type ${colors.cyan}/help${colors.reset} in your AI-powered IDE for the full reference:
93
+ commands, workflows, agents, skills, rules, and checklists.
77
94
  `);
78
95
  }
79
96
 
@@ -169,6 +186,10 @@ ${colors.bright}Next steps:${colors.reset}
169
186
  2. Run ${colors.cyan}/status${colors.reset} to verify
170
187
  3. Use ${colors.cyan}/help${colors.reset} to see available commands
171
188
 
189
+ ${colors.bright}Validate your installation:${colors.reset}
190
+ ${colors.cyan}ag-kit verify${colors.reset} Manifest integrity check
191
+ ${colors.cyan}ag-kit scan${colors.reset} Security scan
192
+
172
193
  ${colors.bright}Quick start:${colors.reset}
173
194
  ${colors.cyan}/plan${colors.reset} Create implementation plan
174
195
  ${colors.cyan}/implement${colors.reset} Execute the plan
@@ -196,9 +217,298 @@ function statusCommand() {
196
217
  const commands = countItems(path.join(agentPath, 'commands'), 'file');
197
218
  const workflows = countItems(path.join(agentPath, 'workflows'), 'file');
198
219
 
220
+ log(' ═══ Capabilities ═══', 'cyan');
199
221
  console.log(` 📦 Skills: ${skills}`);
200
222
  console.log(` ⌨️ Commands: ${commands}`);
201
- console.log(` 🔄 Workflows: ${workflows}\n`);
223
+ console.log(` 🔄 Workflows: ${workflows}`);
224
+
225
+ // Workflow phase + available transitions
226
+ try {
227
+ const workflowEngine = require('../lib/workflow-engine');
228
+ const phase = workflowEngine.getCurrentPhase(process.cwd());
229
+ const available = workflowEngine.getAvailableTransitions(process.cwd());
230
+ console.log(` 🔁 Phase: ${phase}`);
231
+ if (available.length > 0) {
232
+ const nextPhases = available.map((t) => t.to).join(', ');
233
+ console.log(` ➡️ Next: ${nextPhases}`);
234
+ }
235
+ } catch {
236
+ // Engine not available, skip silently
237
+ }
238
+
239
+ // Error budget
240
+ try {
241
+ const errorBudget = require('../lib/error-budget');
242
+ const report = errorBudget.getBudgetReport(process.cwd());
243
+ const statusIcon = report.status === 'HEALTHY' ? '🟢' : report.status === 'WARNING' ? '🟡' : '🔴';
244
+ console.log(` ${statusIcon} Budget: ${report.status}`);
245
+ if (report.violations.length > 0) {
246
+ log(` ⚠️ Violations: ${report.violations.join(', ')}`, 'yellow');
247
+ }
248
+ } catch {
249
+ // Budget not available, skip silently
250
+ }
251
+
252
+ // Task metrics
253
+ try {
254
+ const taskModel = require('../lib/task-model');
255
+ const metrics = taskModel.getTaskMetrics(process.cwd());
256
+ if (metrics.total > 0) {
257
+ console.log('');
258
+ log(' ═══ Tasks ═══', 'cyan');
259
+ console.log(` 📋 Open: ${metrics.counts.open || 0}`);
260
+ console.log(` 🔨 In Progress: ${metrics.counts['in-progress'] || 0}`);
261
+ console.log(` 👁️ In Review: ${metrics.counts.review || 0}`);
262
+ console.log(` ✅ Done: ${metrics.counts.done || 0}`);
263
+ console.log(` 🚫 Blocked: ${metrics.counts.blocked || 0}`);
264
+ if (metrics.completionRate > 0) {
265
+ console.log(` 📊 Completion: ${metrics.completionRate}%`);
266
+ }
267
+ }
268
+ } catch {
269
+ // Task model not available, skip silently
270
+ }
271
+
272
+ // Hook readiness
273
+ try {
274
+ const hookSystem = require('../lib/hook-system');
275
+ const hookReport = hookSystem.getHookReport(process.cwd());
276
+ console.log('');
277
+ log(' ═══ Hooks ═══', 'cyan');
278
+ console.log(` 🪝 Events: ${hookReport.events.length}`);
279
+ console.log(` ✅ Ready: ${hookReport.readyCount}/${hookReport.events.length}`);
280
+ } catch {
281
+ // Hook system not available, skip silently
282
+ }
283
+
284
+ // Developer identity
285
+ try {
286
+ const identity = require('../lib/identity');
287
+ const current = identity.getCurrentIdentity(process.cwd());
288
+ if (current) {
289
+ console.log('');
290
+ log(' ═══ Identity ═══', 'cyan');
291
+ console.log(` 👤 Developer: ${current.name}`);
292
+ console.log(` 🔑 Role: ${current.role}`);
293
+ }
294
+ } catch {
295
+ // Identity not available, skip silently
296
+ }
297
+
298
+ // Plugins
299
+ try {
300
+ const pluginSystem = require('../lib/plugin-system');
301
+ const plugins = pluginSystem.listPlugins(process.cwd());
302
+ if (plugins.length > 0) {
303
+ console.log('');
304
+ log(' ═══ Plugins ═══', 'cyan');
305
+ console.log(` 🔌 Installed: ${plugins.length}`);
306
+ for (const plugin of plugins) {
307
+ console.log(` • ${plugin.name} v${plugin.version}`);
308
+ }
309
+ }
310
+ } catch {
311
+ // Plugin system not available, skip silently
312
+ }
313
+
314
+ // Phase 4 dashboard sections (D-5, E-5)
315
+ try {
316
+ const cliCommands = require('../lib/cli-commands');
317
+ cliCommands.renderDashboardSections(process.cwd());
318
+ } catch {
319
+ // Phase 4 modules not available, skip silently
320
+ }
321
+
322
+ console.log('');
323
+ }
324
+
325
+ function verifyCommand() {
326
+ showBanner();
327
+ logStep('1/1', 'Running manifest integrity checks...\n');
328
+
329
+ try {
330
+ const verify = require('../lib/verify');
331
+ const report = verify.runAllChecks(process.cwd());
332
+
333
+ for (const result of report.results) {
334
+ const icon = result.status === 'pass' ? '✓' : result.status === 'fail' ? '✗' : '⚠';
335
+ const color = result.status === 'pass' ? 'green' : result.status === 'fail' ? 'red' : 'yellow';
336
+ log(` ${icon} ${result.message}`, color);
337
+ }
338
+
339
+ console.log('');
340
+ log(` Passed: ${report.passed} Failed: ${report.failed} Warnings: ${report.warnings}`, report.failed > 0 ? 'red' : 'green');
341
+ console.log('');
342
+
343
+ if (report.failed > 0) {
344
+ process.exit(1);
345
+ }
346
+ } catch (/** @type {any} */ error) {
347
+ log(` ✗ Verification failed: ${error.message}`, 'red');
348
+ process.exit(1);
349
+ }
350
+ }
351
+
352
+ function updateCommand(updateOptions) {
353
+ showBanner();
354
+
355
+ const agentPath = path.join(updateOptions.path || process.cwd(), '.agent');
356
+ if (!fs.existsSync(agentPath)) {
357
+ log('\n❌ No .agent/ folder found. Run: ag-kit init\n', 'red');
358
+ process.exit(1);
359
+ }
360
+
361
+ const sourceRoot = path.join(__dirname, '..');
362
+ const targetRoot = updateOptions.path || process.cwd();
363
+
364
+ try {
365
+ const updater = require('../lib/updater');
366
+ const isDryRun = updateOptions.dryRun;
367
+
368
+ if (isDryRun) {
369
+ log('\n🔍 Dry run mode — no changes will be made\n', 'cyan');
370
+ }
371
+
372
+ logStep('1/2', isDryRun ? 'Analyzing differences...' : 'Applying updates...');
373
+
374
+ const report = updater.applyUpdate(sourceRoot, targetRoot, isDryRun);
375
+
376
+ if (report.added.length > 0) {
377
+ log(`\n 📁 New files (${report.added.length}):`, 'green');
378
+ for (const file of report.added) {
379
+ log(` + ${file}`, 'green');
380
+ }
381
+ }
382
+
383
+ if (report.updated.length > 0) {
384
+ log(`\n 📝 Updated files (${report.updated.length}):`, 'cyan');
385
+ for (const file of report.updated) {
386
+ log(` ~ ${file}`, 'cyan');
387
+ }
388
+ }
389
+
390
+ if (report.skipped.length > 0) {
391
+ log(`\n 🔒 Preserved files (${report.skipped.length}):`, 'yellow');
392
+ for (const file of report.skipped) {
393
+ log(` ○ ${file}`, 'yellow');
394
+ }
395
+ }
396
+
397
+ logStep('2/2', 'Summary');
398
+ console.log(`\n Added: ${report.added.length} Updated: ${report.updated.length} Skipped: ${report.skipped.length} Unchanged: ${report.unchanged.length}\n`);
399
+
400
+ if (report.added.length === 0 && report.updated.length === 0) {
401
+ log(' ✅ Already up to date!\n', 'green');
402
+ } else if (!isDryRun) {
403
+ log(' ✅ Update complete!\n', 'green');
404
+ }
405
+ } catch (/** @type {any} */ error) {
406
+ log(` ✗ Update failed: ${error.message}`, 'red');
407
+ process.exit(1);
408
+ }
409
+ }
410
+
411
+ function scanCommand() {
412
+ showBanner();
413
+ logStep('1/1', 'Running enhanced security scan...\n');
414
+
415
+ try {
416
+ const scanner = require('../lib/security-scanner');
417
+ const report = scanner.getSecurityReport(process.cwd());
418
+
419
+ log(` 📂 Files scanned: ${report.filesScanned}`, 'cyan');
420
+ console.log('');
421
+
422
+ if (report.findings.length === 0) {
423
+ log(' ✅ No security findings — all clear!\n', 'green');
424
+ } else {
425
+ for (const finding of report.findings) {
426
+ const icon = finding.severity === 'critical' ? '🔴' : finding.severity === 'high' ? '🟠' : finding.severity === 'medium' ? '🟡' : '⚪';
427
+ log(` ${icon} [${finding.severity.toUpperCase()}] ${finding.detail}`, finding.severity === 'critical' ? 'red' : finding.severity === 'high' ? 'yellow' : 'reset');
428
+ console.log(` File: ${finding.file}${finding.line ? `:${finding.line}` : ''}`);
429
+ }
430
+ console.log('');
431
+ }
432
+
433
+ log(` 🔴 Critical: ${report.criticalCount} 🟠 High: ${report.highCount} 🟡 Medium: ${report.mediumCount} ⚪ Low: ${report.lowCount}`, report.clean ? 'green' : 'red');
434
+ console.log('');
435
+
436
+ if (!report.clean) {
437
+ process.exit(1);
438
+ }
439
+ } catch (/** @type {any} */ error) {
440
+ log(` ✗ Security scan failed: ${error.message}`, 'red');
441
+ process.exit(1);
442
+ }
443
+ }
444
+
445
+ function pluginCommand(subCommand, pluginArg) {
446
+ showBanner();
447
+
448
+ try {
449
+ const pluginSystem = require('../lib/plugin-system');
450
+
451
+ switch (subCommand) {
452
+ case 'list': {
453
+ const plugins = pluginSystem.listPlugins(process.cwd());
454
+ if (plugins.length === 0) {
455
+ log(' No plugins installed\n', 'yellow');
456
+ } else {
457
+ log(` ═══ Installed Plugins (${plugins.length}) ═══\n`, 'cyan');
458
+ for (const plugin of plugins) {
459
+ console.log(` 🔌 ${plugin.name} v${plugin.version}`);
460
+ console.log(` Author: ${plugin.author}`);
461
+ console.log(` Installed: ${plugin.installedAt}`);
462
+ console.log('');
463
+ }
464
+ }
465
+ break;
466
+ }
467
+ case 'install': {
468
+ if (!pluginArg) {
469
+ log(' ✗ Usage: ag-kit plugin install <path>\n', 'red');
470
+ process.exit(1);
471
+ }
472
+ const pluginPath = path.resolve(pluginArg);
473
+ logStep('1/1', `Installing plugin from ${pluginPath}...`);
474
+ const result = pluginSystem.installPlugin(pluginPath, process.cwd());
475
+ if (result.success) {
476
+ log('\n ✅ Plugin installed successfully!', 'green');
477
+ console.log(` Agents: ${result.installed.agents} Skills: ${result.installed.skills} Workflows: ${result.installed.workflows} Hooks: ${result.installed.hooks}\n`);
478
+ } else {
479
+ log('\n ✗ Plugin installation failed:', 'red');
480
+ for (const error of result.errors) {
481
+ log(` • ${error}`, 'red');
482
+ }
483
+ console.log('');
484
+ process.exit(1);
485
+ }
486
+ break;
487
+ }
488
+ case 'remove': {
489
+ if (!pluginArg) {
490
+ log(' ✗ Usage: ag-kit plugin remove <name>\n', 'red');
491
+ process.exit(1);
492
+ }
493
+ logStep('1/1', `Removing plugin: ${pluginArg}...`);
494
+ const result = pluginSystem.removePlugin(pluginArg, process.cwd());
495
+ if (result.success) {
496
+ log('\n ✅ Plugin removed successfully!\n', 'green');
497
+ } else {
498
+ log(`\n ✗ ${result.error}\n`, 'red');
499
+ process.exit(1);
500
+ }
501
+ break;
502
+ }
503
+ default:
504
+ log(' Usage: ag-kit plugin <list|install|remove>', 'yellow');
505
+ console.log('');
506
+ break;
507
+ }
508
+ } catch (/** @type {any} */ error) {
509
+ log(` ✗ Plugin command failed: ${error.message}`, 'red');
510
+ process.exit(1);
511
+ }
202
512
  }
203
513
 
204
514
  // Parse arguments
@@ -209,7 +519,9 @@ const options = {
209
519
  force: args.includes('--force'),
210
520
  quiet: args.includes('--quiet'),
211
521
  dryRun: args.includes('--dry-run'),
522
+ apply: args.includes('--apply'),
212
523
  path: null,
524
+ file: null,
213
525
  };
214
526
 
215
527
  // Parse --path option
@@ -218,21 +530,43 @@ if (pathIndex !== -1 && args[pathIndex + 1]) {
218
530
  options.path = args[pathIndex + 1];
219
531
  }
220
532
 
533
+ // Parse --file option
534
+ const fileIndex = args.indexOf('--file');
535
+ if (fileIndex !== -1 && args[fileIndex + 1]) {
536
+ options.file = args[fileIndex + 1];
537
+ }
538
+
221
539
  // Execute command
222
540
  switch (command) {
223
541
  case 'init':
224
542
  initCommand(options);
225
543
  break;
226
544
  case 'status':
545
+ case 'dashboard':
227
546
  statusCommand();
228
547
  break;
229
548
  case 'update':
230
- log('🔄 Update not yet implemented - reinstall with: npx antigravity-ai-kit init --force', 'yellow');
549
+ updateCommand(options);
231
550
  break;
232
551
  case 'verify':
233
- log('🔒 Manifest verification - coming in v2.2.0', 'cyan');
234
- log(' This will validate the integrity of all .agent/ files\n', 'cyan');
552
+ verifyCommand();
235
553
  break;
554
+ case 'scan':
555
+ scanCommand();
556
+ break;
557
+ case 'plugin':
558
+ pluginCommand(args[1], args[2]);
559
+ break;
560
+ case 'market': {
561
+ const cliCommands = require('../lib/cli-commands');
562
+ cliCommands.marketCommand(process.cwd(), args[1], args[2], options);
563
+ break;
564
+ }
565
+ case 'heal': {
566
+ const cliCmd = require('../lib/cli-commands');
567
+ cliCmd.healCommand(process.cwd(), { file: options.file, apply: options.apply });
568
+ break;
569
+ }
236
570
  case '--version':
237
571
  case '-v':
238
572
  console.log(VERSION);
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Antigravity AI Kit — Agent Registry
3
+ *
4
+ * Formalizes agent contracts by validating that every agent markdown
5
+ * file exposes required metadata structure.
6
+ *
7
+ * @module lib/agent-registry
8
+ * @author Emre Dursun
9
+ * @since v3.0.0
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ const AGENT_DIR = '.agent';
18
+ const AGENTS_SUBDIR = 'agents';
19
+ const MANIFEST_FILE = 'manifest.json';
20
+
21
+ /** Minimum expected file size for a valid agent file (bytes) */
22
+ const MIN_AGENT_SIZE = 100;
23
+ /** Maximum expected file size for a valid agent file (bytes) */
24
+ const MAX_AGENT_SIZE = 50000;
25
+
26
+ /**
27
+ * @typedef {object} AgentValidation
28
+ * @property {string} name - Agent name
29
+ * @property {boolean} valid - Overall validity
30
+ * @property {string[]} errors - Validation errors
31
+ * @property {string[]} warnings - Validation warnings
32
+ * @property {object} metadata - Extracted metadata
33
+ */
34
+
35
+ /**
36
+ * @typedef {object} RegistryReport
37
+ * @property {number} total - Total agents checked
38
+ * @property {number} valid - Number of valid agents
39
+ * @property {number} invalid - Number of invalid agents
40
+ * @property {AgentValidation[]} agents - Individual agent results
41
+ */
42
+
43
+ /**
44
+ * Extracts metadata from an agent markdown file by parsing its structure.
45
+ *
46
+ * @param {string} content - Raw markdown content
47
+ * @returns {object} Extracted metadata
48
+ */
49
+ function extractAgentMetadata(content) {
50
+ const lines = content.split('\n');
51
+ const metadata = {
52
+ hasTitle: false,
53
+ title: '',
54
+ hasRoleDescription: false,
55
+ hasCapabilities: false,
56
+ hasOutputFormat: false,
57
+ headingCount: 0,
58
+ lineCount: lines.length,
59
+ };
60
+
61
+ for (const line of lines) {
62
+ const trimmed = line.trim();
63
+
64
+ // Check for title (# heading)
65
+ if (trimmed.startsWith('# ') && !metadata.hasTitle) {
66
+ metadata.hasTitle = true;
67
+ metadata.title = trimmed.slice(2).trim();
68
+ }
69
+
70
+ // Count all headings
71
+ if (trimmed.startsWith('#')) {
72
+ metadata.headingCount += 1;
73
+ }
74
+
75
+ // Check for role/responsibility keywords
76
+ const roleLower = trimmed.toLowerCase();
77
+ if (roleLower.includes('role') || roleLower.includes('responsibility') || roleLower.includes('purpose') || roleLower.includes('identity')) {
78
+ metadata.hasRoleDescription = true;
79
+ }
80
+
81
+ // Check for capabilities/skills mentions
82
+ if (roleLower.includes('capabilit') || roleLower.includes('skill') || roleLower.includes('tool') || roleLower.includes('expertise')) {
83
+ metadata.hasCapabilities = true;
84
+ }
85
+
86
+ // Check for output format
87
+ if (roleLower.includes('output') || roleLower.includes('format') || roleLower.includes('deliver') || roleLower.includes('produce')) {
88
+ metadata.hasOutputFormat = true;
89
+ }
90
+ }
91
+
92
+ return metadata;
93
+ }
94
+
95
+ /**
96
+ * Validates a single agent file against contract requirements.
97
+ *
98
+ * @param {string} agentName - Name of the agent
99
+ * @param {string} projectRoot - Root directory of the project
100
+ * @returns {AgentValidation}
101
+ */
102
+ function validateAgent(agentName, projectRoot) {
103
+ const agentPath = path.join(projectRoot, AGENT_DIR, AGENTS_SUBDIR, `${agentName}.md`);
104
+ /** @type {string[]} */
105
+ const errors = [];
106
+ /** @type {string[]} */
107
+ const warnings = [];
108
+
109
+ if (!fs.existsSync(agentPath)) {
110
+ return { name: agentName, valid: false, errors: [`File not found: ${agentName}.md`], warnings: [], metadata: {} };
111
+ }
112
+
113
+ const stats = fs.statSync(agentPath);
114
+ const content = fs.readFileSync(agentPath, 'utf-8');
115
+ const metadata = extractAgentMetadata(content);
116
+
117
+ // Size checks
118
+ if (stats.size < MIN_AGENT_SIZE) {
119
+ errors.push(`File too small (${stats.size} bytes) — likely incomplete`);
120
+ }
121
+ if (stats.size > MAX_AGENT_SIZE) {
122
+ warnings.push(`File very large (${stats.size} bytes) — consider splitting`);
123
+ }
124
+
125
+ // Contract checks
126
+ if (!metadata.hasTitle) {
127
+ errors.push('Missing title header (# AgentName)');
128
+ }
129
+ if (!metadata.hasRoleDescription) {
130
+ warnings.push('No role/responsibility section detected');
131
+ }
132
+ if (!metadata.hasCapabilities) {
133
+ warnings.push('No capabilities/skills section detected');
134
+ }
135
+ if (metadata.headingCount < 2) {
136
+ warnings.push('Very few headings — agent file may lack structure');
137
+ }
138
+
139
+ return {
140
+ name: agentName,
141
+ valid: errors.length === 0,
142
+ errors,
143
+ warnings,
144
+ metadata,
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Validates all agents registered in the manifest.
150
+ *
151
+ * @param {string} projectRoot - Root directory of the project
152
+ * @returns {RegistryReport}
153
+ */
154
+ function validateAllAgents(projectRoot) {
155
+ const manifestPath = path.join(projectRoot, AGENT_DIR, MANIFEST_FILE);
156
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
157
+ const agents = manifest.capabilities?.agents?.items || [];
158
+
159
+ const results = agents.map((agent) => validateAgent(agent.name, projectRoot));
160
+ const validCount = results.filter((r) => r.valid).length;
161
+
162
+ return {
163
+ total: results.length,
164
+ valid: validCount,
165
+ invalid: results.length - validCount,
166
+ agents: results,
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Loads the full agent registry from manifest + filesystem.
172
+ *
173
+ * @param {string} projectRoot - Root directory of the project
174
+ * @returns {{ agents: object[], totalCount: number }}
175
+ */
176
+ function loadRegistry(projectRoot) {
177
+ const manifestPath = path.join(projectRoot, AGENT_DIR, MANIFEST_FILE);
178
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
179
+ const agents = manifest.capabilities?.agents?.items || [];
180
+
181
+ return {
182
+ agents: agents.map((agent) => ({
183
+ name: agent.name,
184
+ file: agent.file,
185
+ domain: agent.domain,
186
+ })),
187
+ totalCount: agents.length,
188
+ };
189
+ }
190
+
191
+ /**
192
+ * Finds agents matching a domain keyword.
193
+ *
194
+ * @param {string} domain - Domain keyword to search for
195
+ * @param {string} projectRoot - Root directory of the project
196
+ * @returns {object[]} Matching agents
197
+ */
198
+ function getAgentByDomain(domain, projectRoot) {
199
+ const { agents } = loadRegistry(projectRoot);
200
+ const lowerDomain = domain.toLowerCase();
201
+
202
+ return agents.filter((agent) =>
203
+ agent.domain.toLowerCase().includes(lowerDomain) ||
204
+ agent.name.toLowerCase().includes(lowerDomain)
205
+ );
206
+ }
207
+
208
+ module.exports = {
209
+ validateAgent,
210
+ validateAllAgents,
211
+ loadRegistry,
212
+ getAgentByDomain,
213
+ extractAgentMetadata,
214
+ };