everything-gemini 1.1.1 → 1.8.0

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 (74) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
  3. package/.github/ISSUE_TEMPLATE/subagent_proposal.md +29 -0
  4. package/.github/workflows/ci.yml +72 -1
  5. package/.github/workflows/release.yml +17 -2
  6. package/.vscode/extensions.json +8 -0
  7. package/.vscode/settings.json +3 -0
  8. package/CHANGELOG.md +167 -0
  9. package/CONTRIBUTING.md +85 -4
  10. package/README.md +139 -18
  11. package/SECURITY.md +38 -0
  12. package/action.yml +35 -0
  13. package/agents/browser-qa.md +1 -1
  14. package/agents/database-migrator.md +26 -0
  15. package/agents/documentation-writer.md +27 -0
  16. package/agents/incident-responder.md +34 -0
  17. package/agents/performance-tuner.md +27 -0
  18. package/agents/release-engineer.md +34 -0
  19. package/bin/everything-gemini +1550 -86
  20. package/docs/COMMUNITY_SUBMISSIONS.md +88 -0
  21. package/docs/LAUNCH_KIT.md +148 -22
  22. package/docs/architecture/progressive-disclosure.md +3 -3
  23. package/docs/index.html +401 -37
  24. package/docs/launch-kit.md +163 -0
  25. package/examples/cli-workflows/README.md +45 -0
  26. package/examples/cli-workflows/demo_workflow.sh +39 -0
  27. package/examples/python-sdk/README.md +28 -5
  28. package/examples/python-sdk/documentation_audit_pipeline.py +83 -0
  29. package/examples/python-sdk/incident_triage_pipeline.py +170 -0
  30. package/examples/python-sdk/multi_agent_pipeline.py +95 -0
  31. package/examples/python-sdk/release_readiness_audit.py +144 -0
  32. package/hooks/secret-scrubber/hooks.json +16 -0
  33. package/hooks/secret-scrubber/scripts/scrub-secrets.sh +62 -0
  34. package/mcp/README.md +20 -0
  35. package/mcp/mcp_config.example.json +35 -0
  36. package/package.json +3 -1
  37. package/plugins/core/rules/core-practices.md +63 -4
  38. package/plugins/python-ai/rules/ai-agent-patterns.md +67 -4
  39. package/plugins/security-shield/rules/zero-trust.md +60 -4
  40. package/plugins/web-fullstack/rules/frontend-standards.md +74 -4
  41. package/rules/paradigms/security-hardened.md +53 -10
  42. package/rules/paradigms/tdd.md +65 -8
  43. package/scripts/install.ps1 +14 -0
  44. package/scripts/install.sh +15 -1
  45. package/scripts/validate.sh +103 -12
  46. package/skills/agent-evals/SKILL.md +61 -0
  47. package/skills/apache-kafka-streams/SKILL.md +152 -0
  48. package/skills/argo-workflows/SKILL.md +151 -0
  49. package/skills/axum-web-service/SKILL.md +159 -0
  50. package/skills/cilium-ebpf-networking/SKILL.md +145 -0
  51. package/skills/clickhouse-analytics/SKILL.md +128 -0
  52. package/skills/dbt-transformation/SKILL.md +179 -0
  53. package/skills/debezium-cdc/SKILL.md +166 -0
  54. package/skills/docker-compose-orchestrator/SKILL.md +85 -0
  55. package/skills/duckdb-local-olap/SKILL.md +134 -0
  56. package/skills/fastapi-production/SKILL.md +157 -0
  57. package/skills/graphql-architect/SKILL.md +78 -0
  58. package/skills/grpc-connect-rpc/SKILL.md +176 -0
  59. package/skills/langgraph-orchestrator/SKILL.md +144 -0
  60. package/skills/litellm-proxy-gateway/SKILL.md +154 -0
  61. package/skills/nats-jetstream/SKILL.md +122 -0
  62. package/skills/open-telemetry-tracing/SKILL.md +151 -0
  63. package/skills/playwright-visual-regression/SKILL.md +124 -0
  64. package/skills/redis-cache-patterns/SKILL.md +159 -0
  65. package/skills/svelte-kit-architect/SKILL.md +190 -0
  66. package/skills/temporal-workflows/SKILL.md +158 -0
  67. package/skills/trpc-react-query/SKILL.md +169 -0
  68. package/skills/turborepo-monorepo/SKILL.md +199 -0
  69. package/skills/vllm-inference/SKILL.md +144 -0
  70. package/skills/wasm-rust-optimizer/SKILL.md +130 -0
  71. package/templates/full-power/hooks.json +14 -0
  72. package/templates/full-power/mcp_config.json +43 -0
  73. package/templates/recommended/hooks.json +14 -0
  74. package/tests/cli.test.js +383 -0
@@ -45,19 +45,33 @@ function printHelp() {
45
45
  console.log(` ${GREEN}doctor${RESET} Inspect system, AGY surfaces, and configuration health`);
46
46
  console.log(` ${GREEN}install${RESET} [options] Install everything-gemini profiles into workspace or globally`);
47
47
  console.log(` ${GREEN}init${RESET} [options] Initialize everything-gemini in current workspace`);
48
+ console.log(` ${GREEN}status, check${RESET} Show active skills, subagents, and hooks in workspace`);
49
+ console.log(` ${GREEN}diff${RESET} Compare installed workspace components against master catalog`);
50
+ console.log(` ${GREEN}export${RESET} [options] Export installed configuration into a portable bundle`);
51
+ console.log(` ${GREEN}import${RESET} <file.json> Import portable agent configuration bundle into workspace`);
52
+ console.log(` ${GREEN}bundle, pack${RESET} [options] Package offline distribution bundle with manifest & installer`);
53
+ console.log(` ${GREEN}update${RESET} Sync installed skills, agents, and hooks with latest catalog`);
48
54
  console.log(` ${GREEN}list${RESET} Show all available skills, rules, hooks, and plugins`);
49
55
  console.log(` ${GREEN}new-skill${RESET} <name> Scaffold a new progressive-disclosure skill`);
50
56
  console.log(` ${GREEN}new-agent${RESET} <name> Scaffold a new scoped subagent specification`);
51
- console.log(` ${GREEN}add${RESET} <type> <name> Add a specific skill, agent, or plugin to workspace`);
52
- console.log(` ${GREEN}remove${RESET} <type> <name> Remove a specific skill, agent, or plugin from workspace`);
57
+ console.log(` ${GREEN}add${RESET} <type> <name> Add a specific skill, agent, hook, or plugin to workspace`);
58
+ console.log(` ${GREEN}remove${RESET} <type> <name> Remove a specific skill, agent, hook, or plugin from workspace`);
59
+ console.log(` ${GREEN}search, find${RESET} <query> Search skills, agents, hooks, and MCP blueprints`);
60
+ console.log(` ${GREEN}audit${RESET} [path] Comprehensive audit of frontmatter, contracts, hooks & links`);
53
61
  console.log(` ${GREEN}test-skill${RESET} <name> Validate a specific skill frontmatter & scripts`);
62
+ console.log(` ${GREEN}test-all${RESET} Benchmark & validate all 52 skills, 11 subagents & 7 hooks`);
63
+ console.log(` ${GREEN}info${RESET} <name> Display overview & runbook for a skill, agent, or hook`);
64
+ console.log(` ${GREEN}completion${RESET} [--install] Generate or install shell autocompletion script (bash/zsh)`);
54
65
  console.log(` ${GREEN}validate${RESET} Run self-test on frontmatter, JSON schemas & hooks`);
55
- console.log(` ${GREEN}help${RESET} Show this help message\n`);
56
- console.log(`${BOLD}OPTIONS for 'install':${RESET}`);
66
+ console.log(` ${GREEN}version, -v, --version${RESET} Print everything-gemini version`);
67
+ console.log(` ${GREEN}help, -h, --help${RESET} Show this help message\n`);
68
+ console.log(`${BOLD}GLOBAL & COMMAND OPTIONS:${RESET}`);
57
69
  console.log(` ${CYAN}--profile <core|developer|full>${RESET} Installation preset profile (default: developer)`);
58
- console.log(` ${CYAN}--global${RESET} Install globally into ~/.gemini/config/`);
59
- console.log(` ${CYAN}--workspace <path>${RESET} Install into custom workspace directory`);
60
- console.log(` ${CYAN}--force${RESET} Overwrite existing configuration files\n`);
70
+ console.log(` ${CYAN}--global${RESET} Target global config (~/.gemini/config/)`);
71
+ console.log(` ${CYAN}--workspace <path>${RESET} Target custom workspace directory`);
72
+ console.log(` ${CYAN}--dry-run${RESET} Preview actions without modifying files on disk`);
73
+ console.log(` ${CYAN}--json${RESET} Output machine-readable JSON (status, benchmark)`);
74
+ console.log(` ${CYAN}--force${RESET} Overwrite existing configuration files\n`);
61
75
  }
62
76
 
63
77
  function runDoctor() {
@@ -189,13 +203,29 @@ function listComponents() {
189
203
  if (item.isDirectory()) {
190
204
  findRules(path.join(dir, item.name), `${prefix}${item.name}/`);
191
205
  } else if (item.name.endsWith('.md')) {
192
- console.log(` ${BOLD}${(prefix + item.name).padEnd(32)}${RESET}`);
206
+ console.log(` ${BOLD}${(prefix + item.name).padEnd(36)}${RESET}`);
193
207
  }
194
208
  }
195
209
  }
196
210
  findRules(rulesDir);
197
211
  }
198
212
 
213
+ // Plugin Packaged Rules
214
+ if (fs.existsSync(pluginsDirForSkills)) {
215
+ const plugins = fs.readdirSync(pluginsDirForSkills, { withFileTypes: true })
216
+ .filter(d => d.isDirectory())
217
+ .map(d => d.name);
218
+ for (const plugin of plugins) {
219
+ const pRulesDir = path.join(pluginsDirForSkills, plugin, 'rules');
220
+ if (fs.existsSync(pRulesDir)) {
221
+ const pRules = fs.readdirSync(pRulesDir).filter(f => f.endsWith('.md'));
222
+ for (const r of pRules) {
223
+ console.log(` ${BOLD}${(`plugins/${plugin}/rules/${r}`).padEnd(36)}${RESET}`);
224
+ }
225
+ }
226
+ }
227
+ }
228
+
199
229
  // Hooks
200
230
  console.log(`\n${CYAN}${BOLD}🛡️ Lifecycle Hooks:${RESET}`);
201
231
  const hooksDir = path.join(REPO_ROOT, 'hooks');
@@ -242,19 +272,26 @@ function copyRecursiveSync(src, dest) {
242
272
  } else {
243
273
  fs.mkdirSync(path.dirname(dest), { recursive: true });
244
274
  fs.copyFileSync(src, dest);
275
+ if (src.endsWith('.sh') || (stats.mode && (stats.mode & 0o111))) {
276
+ try { fs.chmodSync(dest, 0o755); } catch (e) {}
277
+ }
245
278
  }
246
279
  }
247
280
 
248
- function installProfile(profile = 'developer', isGlobal = false, customTarget = null) {
281
+ function installProfile(profile = 'developer', isGlobal = false, customTarget = null, isDryRun = false) {
249
282
  printBanner();
250
283
  const targetDir = customTarget
251
284
  ? path.resolve(customTarget)
252
285
  : (isGlobal ? GLOBAL_CONFIG_DIR : AGENTS_DIR);
253
286
 
287
+ if (isDryRun) {
288
+ console.log(`${YELLOW}${BOLD}🔍 DRY RUN MODE ACTIVATED - No files will be modified on disk.${RESET}`);
289
+ }
290
+
254
291
  console.log(`${BOLD}🚀 Installing everything-gemini Profile: [${GREEN}${profile}${RESET}${BOLD}]${RESET}`);
255
292
  console.log(`Target Directory: ${CYAN}${targetDir}${RESET}\n`);
256
293
 
257
- if (!fs.existsSync(targetDir)) {
294
+ if (!isDryRun && !fs.existsSync(targetDir)) {
258
295
  fs.mkdirSync(targetDir, { recursive: true });
259
296
  }
260
297
 
@@ -262,69 +299,103 @@ function installProfile(profile = 'developer', isGlobal = false, customTarget =
262
299
  const targetSkills = path.join(targetDir, 'skills');
263
300
  const targetRules = path.join(targetDir, 'rules');
264
301
  const targetPlugins = path.join(targetDir, 'plugins');
265
- fs.mkdirSync(targetSkills, { recursive: true });
266
- fs.mkdirSync(targetRules, { recursive: true });
267
- fs.mkdirSync(targetPlugins, { recursive: true });
302
+ const targetAgents = path.join(targetDir, 'agents');
303
+ if (!isDryRun) {
304
+ fs.mkdirSync(targetSkills, { recursive: true });
305
+ fs.mkdirSync(targetRules, { recursive: true });
306
+ fs.mkdirSync(targetPlugins, { recursive: true });
307
+ }
268
308
 
269
309
  const skillsSrc = path.join(REPO_ROOT, 'skills');
270
310
  const rulesSrc = path.join(REPO_ROOT, 'rules');
271
311
  const hooksSrc = path.join(REPO_ROOT, 'hooks');
272
312
  const pluginsSrc = path.join(REPO_ROOT, 'plugins');
313
+ const agentsSrc = path.join(REPO_ROOT, 'agents');
273
314
 
274
315
  // Copy Common Base Rules
275
316
  const commonGemini = path.join(rulesSrc, 'common', 'GEMINI.md');
276
317
  const commonAgents = path.join(rulesSrc, 'common', 'AGENTS.md');
277
318
  if (fs.existsSync(commonGemini)) {
278
- fs.copyFileSync(commonGemini, path.join(targetDir, 'GEMINI.md'));
279
- console.log(` ${GREEN}✔${RESET} Installed base GEMINI.md`);
319
+ if (!isDryRun) fs.copyFileSync(commonGemini, path.join(targetDir, 'GEMINI.md'));
320
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} base GEMINI.md`);
280
321
  }
281
322
  if (fs.existsSync(commonAgents)) {
282
- fs.copyFileSync(commonAgents, path.join(targetDir, 'AGENTS.md'));
283
- console.log(` ${GREEN}✔${RESET} Installed base AGENTS.md`);
323
+ if (!isDryRun) fs.copyFileSync(commonAgents, path.join(targetDir, 'AGENTS.md'));
324
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} base AGENTS.md`);
284
325
  }
285
326
 
286
- // Determine what to copy based on profile
327
+ // 1. Core Profile
287
328
  if (profile === 'core' || profile === 'developer' || profile === 'full') {
288
- // Core Skills
289
329
  const coreSkills = ['tdd-workflow', 'repo-onboarding'];
290
330
  for (const s of coreSkills) {
291
331
  const src = path.join(skillsSrc, s);
292
332
  if (fs.existsSync(src)) {
293
- copyRecursiveSync(src, path.join(targetSkills, s));
294
- console.log(` ${GREEN}✔${RESET} Installed skill: ${s}`);
333
+ if (!isDryRun) copyRecursiveSync(src, path.join(targetSkills, s));
334
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} skill: ${s}`);
295
335
  }
296
336
  }
297
- // Core Hook (Safety Shield)
298
- const safetyHookJson = path.join(hooksSrc, 'safety-shield', 'hooks.json');
299
- if (fs.existsSync(safetyHookJson)) {
300
- copyRecursiveSync(path.join(hooksSrc, 'safety-shield'), path.join(targetDir, 'hooks', 'safety-shield'));
301
- console.log(` ${GREEN}✔${RESET} Installed safety-shield hook`);
337
+ const safetyHook = path.join(hooksSrc, 'safety-shield');
338
+ if (fs.existsSync(safetyHook)) {
339
+ if (!isDryRun) copyRecursiveSync(safetyHook, path.join(targetDir, 'hooks', 'safety-shield'));
340
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} safety-shield hook`);
302
341
  }
303
342
  }
304
343
 
344
+ // 2. Developer Profile
305
345
  if (profile === 'developer' || profile === 'full') {
306
- // Developer Skills
307
- const devSkills = ['browser-qa-tester', 'architecture-designer', 'git-craftsman', 'performance-profiler', 'fullstack-nextjs'];
346
+ const devSkills = [
347
+ 'browser-qa-tester',
348
+ 'architecture-designer',
349
+ 'git-craftsman',
350
+ 'performance-profiler',
351
+ 'fullstack-nextjs',
352
+ 'gemini-multimodal',
353
+ 'context-caching',
354
+ 'subagent-handoff',
355
+ 'security-audit',
356
+ 'continuous-learning',
357
+ 'ai-first-engineering'
358
+ ];
308
359
  for (const s of devSkills) {
309
360
  const src = path.join(skillsSrc, s);
310
361
  if (fs.existsSync(src)) {
311
- copyRecursiveSync(src, path.join(targetSkills, s));
312
- console.log(` ${GREEN}✔${RESET} Installed skill: ${s}`);
362
+ if (!isDryRun) copyRecursiveSync(src, path.join(targetSkills, s));
363
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} skill: ${s}`);
313
364
  }
314
365
  }
315
366
 
316
367
  // Developer Language Rules
317
368
  const langRules = path.join(rulesSrc, 'languages');
318
369
  if (fs.existsSync(langRules)) {
319
- copyRecursiveSync(langRules, targetRules);
320
- console.log(` ${GREEN}✔${RESET} Installed language rules (TypeScript, Python, Go)`);
370
+ if (!isDryRun) copyRecursiveSync(langRules, targetRules);
371
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} language rules (TypeScript, Python, Go)`);
321
372
  }
322
373
 
323
374
  // Auto-lint formatter hook
324
375
  const lintHook = path.join(hooksSrc, 'auto-lint-formatter');
325
376
  if (fs.existsSync(lintHook)) {
326
- copyRecursiveSync(lintHook, path.join(targetDir, 'hooks', 'auto-lint-formatter'));
327
- console.log(` ${GREEN}✔${RESET} Installed auto-lint-formatter hook`);
377
+ if (!isDryRun) copyRecursiveSync(lintHook, path.join(targetDir, 'hooks', 'auto-lint-formatter'));
378
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} auto-lint-formatter hook`);
379
+ }
380
+
381
+ // Goal-verifier hook
382
+ const goalHook = path.join(hooksSrc, 'goal-verifier');
383
+ if (fs.existsSync(goalHook)) {
384
+ if (!isDryRun) copyRecursiveSync(goalHook, path.join(targetDir, 'hooks', 'goal-verifier'));
385
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} goal-verifier hook`);
386
+ }
387
+
388
+ // Secret-scrubber hook
389
+ const scrubberHook = path.join(hooksSrc, 'secret-scrubber');
390
+ if (fs.existsSync(scrubberHook)) {
391
+ if (!isDryRun) copyRecursiveSync(scrubberHook, path.join(targetDir, 'hooks', 'secret-scrubber'));
392
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} secret-scrubber hook`);
393
+ }
394
+
395
+ // Scoped Subagents (agents/)
396
+ if (fs.existsSync(agentsSrc)) {
397
+ if (!isDryRun) copyRecursiveSync(agentsSrc, targetAgents);
398
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} 9 scoped subagents (agents/)`);
328
399
  }
329
400
 
330
401
  // Developer Plugins
@@ -332,58 +403,652 @@ function installProfile(profile = 'developer', isGlobal = false, customTarget =
332
403
  for (const p of devPlugins) {
333
404
  const src = path.join(pluginsSrc, p);
334
405
  if (fs.existsSync(src)) {
335
- copyRecursiveSync(src, path.join(targetPlugins, p));
336
- console.log(` ${GREEN}✔${RESET} Installed plugin: ${p}`);
406
+ if (!isDryRun) copyRecursiveSync(src, path.join(targetPlugins, p));
407
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} plugin: ${p}`);
337
408
  }
338
409
  }
339
410
  }
340
411
 
412
+ // 3. Full Power Profile
341
413
  if (profile === 'full') {
342
- // All Skills
343
- copyRecursiveSync(skillsSrc, targetSkills);
344
- console.log(` ${GREEN}✔${RESET} Installed entire skills library`);
414
+ if (!isDryRun) copyRecursiveSync(skillsSrc, targetSkills);
415
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} entire skills library (48 progressive skills)`);
416
+
417
+ if (!isDryRun) copyRecursiveSync(rulesSrc, targetRules);
418
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} entire rules library`);
345
419
 
346
- // All Rules
347
- copyRecursiveSync(rulesSrc, targetRules);
348
- console.log(` ${GREEN}✔${RESET} Installed entire rules library`);
420
+ if (!isDryRun) copyRecursiveSync(pluginsSrc, targetPlugins);
421
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} all modular plugins`);
349
422
 
350
- // All Plugins
351
- copyRecursiveSync(pluginsSrc, targetPlugins);
352
- console.log(` ${GREEN}✔${RESET} Installed all modular plugins`);
423
+ if (!isDryRun) copyRecursiveSync(hooksSrc, path.join(targetDir, 'hooks'));
424
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} full lifecycle hooks suite (7 hooks)`);
353
425
 
354
- // All Hooks
355
- copyRecursiveSync(hooksSrc, path.join(targetDir, 'hooks'));
356
- console.log(` ${GREEN}✔${RESET} Installed full lifecycle hooks suite`);
426
+ if (fs.existsSync(agentsSrc)) {
427
+ if (!isDryRun) copyRecursiveSync(agentsSrc, targetAgents);
428
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} 10 scoped subagents (agents/)`);
429
+ }
357
430
 
358
431
  // MCP Config Example
359
432
  const mcpExample = path.join(REPO_ROOT, 'mcp', 'mcp_config.example.json');
360
433
  if (fs.existsSync(mcpExample)) {
361
- fs.copyFileSync(mcpExample, path.join(targetDir, 'mcp_config.json'));
362
- console.log(` ${GREEN}✔${RESET} Installed mcp_config.json`);
363
- }
364
- }
365
-
366
- // Create or Merge Master hooks.json in targetDir
367
- const masterHooks = {
368
- "safety-shield": {
369
- "PreToolUse": [
370
- {
371
- "matcher": "run_command",
372
- "hooks": [
373
- {
374
- "type": "command",
375
- "command": "bash ./hooks/safety-shield/scripts/safety-gate.sh",
376
- "timeout": 15
377
- }
378
- ]
434
+ if (!isDryRun) fs.copyFileSync(mcpExample, path.join(targetDir, 'mcp_config.json'));
435
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would install' : 'Installed'} mcp_config.json`);
436
+ }
437
+ }
438
+
439
+ // Template-driven master hooks.json generation
440
+ let templateHooksPath = null;
441
+ if (profile === 'minimal' || profile === 'core') {
442
+ templateHooksPath = path.join(REPO_ROOT, 'templates', 'minimal', 'hooks.json');
443
+ } else if (profile === 'full') {
444
+ templateHooksPath = path.join(REPO_ROOT, 'templates', 'full-power', 'hooks.json');
445
+ } else {
446
+ templateHooksPath = path.join(REPO_ROOT, 'templates', 'recommended', 'hooks.json');
447
+ }
448
+
449
+ if (fs.existsSync(templateHooksPath)) {
450
+ if (!isDryRun) fs.copyFileSync(templateHooksPath, path.join(targetDir, 'hooks.json'));
451
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would generate' : 'Generated'} profile hooks.json (${profile})`);
452
+ }
453
+
454
+ if (isDryRun) {
455
+ console.log(`\n${GREEN}${BOLD}✨ Dry run preview complete! 0 files modified on disk.${RESET}\n`);
456
+ } else {
457
+ console.log(`\n${GREEN}${BOLD}✨ Installation complete! Everything Gemini is ready.${RESET}\n`);
458
+ }
459
+ }
460
+
461
+ function runStatus(isGlobal = false, customTarget = null, asJson = false) {
462
+ const targetDir = customTarget
463
+ ? path.resolve(customTarget)
464
+ : (isGlobal ? GLOBAL_CONFIG_DIR : AGENTS_DIR);
465
+
466
+ const isInitialized = fs.existsSync(targetDir);
467
+ const geminiRule = path.join(targetDir, 'GEMINI.md');
468
+ const agentsRule = path.join(targetDir, 'AGENTS.md');
469
+ const hasGemini = fs.existsSync(geminiRule);
470
+ const hasAgents = fs.existsSync(agentsRule);
471
+
472
+ // 1. Installed Skills
473
+ const skillsDir = path.join(targetDir, 'skills');
474
+ let installedSkills = [];
475
+ if (fs.existsSync(skillsDir)) {
476
+ installedSkills = fs.readdirSync(skillsDir, { withFileTypes: true })
477
+ .filter(d => d.isDirectory())
478
+ .map(d => d.name)
479
+ .sort();
480
+ }
481
+
482
+ // 2. Subagents
483
+ const agentsDir = path.join(targetDir, 'agents');
484
+ let installedAgents = [];
485
+ if (fs.existsSync(agentsDir)) {
486
+ installedAgents = fs.readdirSync(agentsDir)
487
+ .filter(f => f.endsWith('.md'))
488
+ .map(f => f.replace('.md', ''))
489
+ .sort();
490
+ }
491
+
492
+ // 3. Hooks
493
+ const hooksFile = path.join(targetDir, 'hooks.json');
494
+ let hooksSummary = {};
495
+ if (fs.existsSync(hooksFile)) {
496
+ try {
497
+ hooksSummary = JSON.parse(fs.readFileSync(hooksFile, 'utf8'));
498
+ } catch (e) {}
499
+ }
500
+
501
+ if (asJson) {
502
+ const payload = {
503
+ version: VERSION,
504
+ targetDir,
505
+ isGlobal,
506
+ isInitialized,
507
+ rules: {
508
+ gemini: hasGemini,
509
+ agents: hasAgents
510
+ },
511
+ skills: {
512
+ installedCount: installedSkills.length,
513
+ totalCatalogCount: 52,
514
+ installed: installedSkills
515
+ },
516
+ subagents: {
517
+ installedCount: installedAgents.length,
518
+ totalCatalogCount: 11,
519
+ installed: installedAgents
520
+ },
521
+ hooks: {
522
+ activeCount: Object.keys(hooksSummary).length,
523
+ active: Object.keys(hooksSummary)
524
+ }
525
+ };
526
+ console.log(JSON.stringify(payload, null, 2));
527
+ return;
528
+ }
529
+
530
+ printBanner();
531
+ console.log(`${BOLD}📊 Everything Gemini Workspace Status${RESET}`);
532
+ console.log(`Directory: ${CYAN}${targetDir}${RESET}\n`);
533
+
534
+ if (!isInitialized) {
535
+ console.log(` ${YELLOW}○ Workspace is not initialized.${RESET}`);
536
+ console.log(` Run ${GREEN}everything-gemini install${RESET} to set up.\n`);
537
+ return;
538
+ }
539
+
540
+ console.log(`${CYAN}${BOLD}📜 Base Rules:${RESET}`);
541
+ console.log(` ${hasGemini ? GREEN + '✔' : GRAY + '○'}${RESET} GEMINI.md ${hasGemini ? '(active)' : '(not installed)'}`);
542
+ console.log(` ${hasAgents ? GREEN + '✔' : GRAY + '○'}${RESET} AGENTS.md ${hasAgents ? '(active)' : '(not installed)'}`);
543
+
544
+ console.log(`\n${CYAN}${BOLD}⚡ Installed Skills (${installedSkills.length}/52):${RESET}`);
545
+ if (installedSkills.length === 0) {
546
+ console.log(` ${GRAY}(no skills installed)${RESET}`);
547
+ } else {
548
+ for (const s of installedSkills) {
549
+ console.log(` ${GREEN}✔${RESET} ${s}`);
550
+ }
551
+ }
552
+
553
+ console.log(`\n${CYAN}${BOLD}🤖 Scoped Subagents (${installedAgents.length}/11):${RESET}`);
554
+ if (installedAgents.length === 0) {
555
+ console.log(` ${GRAY}(no subagents installed)${RESET}`);
556
+ } else {
557
+ for (const a of installedAgents) {
558
+ console.log(` ${GREEN}✔${RESET} ${a}`);
559
+ }
560
+ }
561
+
562
+ console.log(`\n${CYAN}${BOLD}🛡️ Lifecycle Hooks:${RESET}`);
563
+ const hookNames = Object.keys(hooksSummary);
564
+ if (hookNames.length > 0) {
565
+ console.log(` ${GREEN}✔${RESET} hooks.json configured (${hookNames.length} hooks active):`);
566
+ for (const h of hookNames) {
567
+ const events = Object.keys(hooksSummary[h]).join(', ');
568
+ console.log(` • ${BOLD}${h}${RESET} [${GRAY}${events}${RESET}]`);
569
+ }
570
+ } else {
571
+ console.log(` ${GRAY}(no hooks.json found)${RESET}`);
572
+ }
573
+ console.log('');
574
+ }
575
+
576
+ function runUpdate(isGlobal = false, customTarget = null, isDryRun = false) {
577
+ printBanner();
578
+ const targetDir = customTarget
579
+ ? path.resolve(customTarget)
580
+ : (isGlobal ? GLOBAL_CONFIG_DIR : AGENTS_DIR);
581
+
582
+ if (isDryRun) {
583
+ console.log(`${YELLOW}${BOLD}🔍 DRY RUN MODE ACTIVATED - No files will be modified on disk.${RESET}`);
584
+ }
585
+ console.log(`${BOLD}🔄 Updating Installed Components in: ${CYAN}${targetDir}${RESET}\n`);
586
+
587
+ if (!fs.existsSync(targetDir)) {
588
+ console.log(` ${YELLOW}○ Workspace is not initialized.${RESET}`);
589
+ console.log(` Run ${GREEN}everything-gemini install${RESET} first.\n`);
590
+ return;
591
+ }
592
+
593
+ let updatedSkills = 0;
594
+ let updatedAgents = 0;
595
+ let updatedHooks = 0;
596
+
597
+ // 1. Update Existing Installed Skills
598
+ const targetSkills = path.join(targetDir, 'skills');
599
+ if (fs.existsSync(targetSkills)) {
600
+ const installed = fs.readdirSync(targetSkills, { withFileTypes: true })
601
+ .filter(d => d.isDirectory())
602
+ .map(d => d.name);
603
+ for (const s of installed) {
604
+ const src = path.join(REPO_ROOT, 'skills', s);
605
+ if (fs.existsSync(src)) {
606
+ if (!isDryRun) copyRecursiveSync(src, path.join(targetSkills, s));
607
+ updatedSkills++;
608
+ if (isDryRun) {
609
+ console.log(` ${CYAN}[DRY RUN]${RESET} Would update skill: ${s}`);
379
610
  }
380
- ]
611
+ }
381
612
  }
613
+ }
614
+
615
+ // 2. Update Existing Installed Subagents
616
+ const targetAgents = path.join(targetDir, 'agents');
617
+ if (fs.existsSync(targetAgents)) {
618
+ const installed = fs.readdirSync(targetAgents)
619
+ .filter(f => f.endsWith('.md'));
620
+ for (const a of installed) {
621
+ const src = path.join(REPO_ROOT, 'agents', a);
622
+ if (fs.existsSync(src)) {
623
+ if (!isDryRun) fs.copyFileSync(src, path.join(targetAgents, a));
624
+ updatedAgents++;
625
+ if (isDryRun) {
626
+ console.log(` ${CYAN}[DRY RUN]${RESET} Would update subagent: ${a}`);
627
+ }
628
+ }
629
+ }
630
+ }
631
+
632
+ // 3. Update Hooks Scripts
633
+ const targetHooks = path.join(targetDir, 'hooks');
634
+ if (fs.existsSync(targetHooks)) {
635
+ const installed = fs.readdirSync(targetHooks, { withFileTypes: true })
636
+ .filter(d => d.isDirectory())
637
+ .map(d => d.name);
638
+ for (const h of installed) {
639
+ const src = path.join(REPO_ROOT, 'hooks', h);
640
+ if (fs.existsSync(src)) {
641
+ if (!isDryRun) copyRecursiveSync(src, path.join(targetHooks, h));
642
+ updatedHooks++;
643
+ if (isDryRun) {
644
+ console.log(` ${CYAN}[DRY RUN]${RESET} Would refresh hook: ${h}`);
645
+ }
646
+ }
647
+ }
648
+ }
649
+
650
+ // 4. Refresh base rules if present
651
+ const rulesSrc = path.join(REPO_ROOT, 'rules', 'common');
652
+ if (fs.existsSync(path.join(targetDir, 'GEMINI.md')) && fs.existsSync(path.join(rulesSrc, 'GEMINI.md'))) {
653
+ if (!isDryRun) fs.copyFileSync(path.join(rulesSrc, 'GEMINI.md'), path.join(targetDir, 'GEMINI.md'));
654
+ if (isDryRun) console.log(` ${CYAN}[DRY RUN]${RESET} Would refresh base GEMINI.md`);
655
+ }
656
+ if (fs.existsSync(path.join(targetDir, 'AGENTS.md')) && fs.existsSync(path.join(rulesSrc, 'AGENTS.md'))) {
657
+ if (!isDryRun) fs.copyFileSync(path.join(rulesSrc, 'AGENTS.md'), path.join(targetDir, 'AGENTS.md'));
658
+ if (isDryRun) console.log(` ${CYAN}[DRY RUN]${RESET} Would refresh base AGENTS.md`);
659
+ }
660
+
661
+ if (isDryRun) {
662
+ console.log(`\n${GREEN}${BOLD}✨ Dry run preview complete! 0 files modified on disk.${RESET}\n`);
663
+ } else {
664
+ console.log(` ${GREEN}✔${RESET} Synced ${BOLD}${updatedSkills}${RESET} installed skills to latest catalog versions`);
665
+ console.log(` ${GREEN}✔${RESET} Synced ${BOLD}${updatedAgents}${RESET} subagent specifications`);
666
+ console.log(` ${GREEN}✔${RESET} Refreshed ${BOLD}${updatedHooks}${RESET} lifecycle hook scripts & verified permissions`);
667
+ console.log(` ${GREEN}✔${RESET} Refreshed base GEMINI.md & AGENTS.md rules\n`);
668
+ console.log(`${GREEN}${BOLD}✨ Update complete! Everything Gemini is up to date.${RESET}\n`);
669
+ }
670
+ }
671
+
672
+ function runDiff(isGlobal = false, customTarget = null) {
673
+ printBanner();
674
+ const targetDir = customTarget ? path.resolve(customTarget) : (isGlobal ? GLOBAL_CONFIG_DIR : AGENTS_DIR);
675
+ console.log(`${BOLD}🔍 Comparing Workspace vs. Master Everything Gemini Catalog...${RESET}`);
676
+ console.log(`Target: ${CYAN}${targetDir}${RESET}\n`);
677
+
678
+ if (!fs.existsSync(targetDir)) {
679
+ console.log(`${YELLOW}No active configuration found at ${targetDir}.${RESET}\n`);
680
+ return;
681
+ }
682
+
683
+ // Compare skills
684
+ const wsSkillsDir = path.join(targetDir, 'skills');
685
+ const catalogSkillsDir = path.join(REPO_ROOT, 'skills');
686
+ const wsSkills = fs.existsSync(wsSkillsDir) ? fs.readdirSync(wsSkillsDir).filter(s => {
687
+ try { return fs.statSync(path.join(wsSkillsDir, s)).isDirectory(); } catch (_) { return false; }
688
+ }) : [];
689
+
690
+ console.log(`${BOLD}⚡ Progressive Skills Comparison:${RESET}`);
691
+ let modifiedCount = 0;
692
+ for (const s of wsSkills) {
693
+ const wsFile = path.join(wsSkillsDir, s, 'SKILL.md');
694
+ const catFile = path.join(catalogSkillsDir, s, 'SKILL.md');
695
+ if (!fs.existsSync(catFile)) {
696
+ console.log(` ${CYAN}+ [CUSTOM/LOCAL]${RESET} ${s}`);
697
+ } else {
698
+ const wsContent = fs.existsSync(wsFile) ? fs.readFileSync(wsFile, 'utf8') : '';
699
+ const catContent = fs.readFileSync(catFile, 'utf8');
700
+ if (wsContent !== catContent) {
701
+ console.log(` ${YELLOW}* [MODIFIED]${RESET} ${s} (differs from catalog)`);
702
+ modifiedCount++;
703
+ } else {
704
+ console.log(` ${GREEN}✔ [IN-SYNC]${RESET} ${s}`);
705
+ }
706
+ }
707
+ }
708
+
709
+ // Compare agents
710
+ const wsAgentsDir = path.join(targetDir, 'agents');
711
+ const catAgentsDir = path.join(REPO_ROOT, 'agents');
712
+ const wsAgents = fs.existsSync(wsAgentsDir) ? fs.readdirSync(wsAgentsDir).filter(a => a.endsWith('.md')) : [];
713
+ console.log(`\n${BOLD}🤖 Scoped Subagents Comparison:${RESET}`);
714
+ for (const a of wsAgents) {
715
+ const wsFile = path.join(wsAgentsDir, a);
716
+ const catFile = path.join(catAgentsDir, a);
717
+ if (!fs.existsSync(catFile)) {
718
+ console.log(` ${CYAN}+ [CUSTOM/LOCAL]${RESET} ${a}`);
719
+ } else {
720
+ const wsContent = fs.readFileSync(wsFile, 'utf8');
721
+ const catContent = fs.readFileSync(catFile, 'utf8');
722
+ if (wsContent !== catContent) {
723
+ console.log(` ${YELLOW}* [MODIFIED]${RESET} ${a} (differs from catalog)`);
724
+ modifiedCount++;
725
+ } else {
726
+ console.log(` ${GREEN}✔ [IN-SYNC]${RESET} ${a}`);
727
+ }
728
+ }
729
+ }
730
+
731
+ console.log(`\n${BOLD}Diff Summary:${RESET} ${wsSkills.length} skills, ${wsAgents.length} subagents checked. ${modifiedCount === 0 ? GREEN + 'All matching components are in sync with master catalog!' + RESET : YELLOW + `${modifiedCount} modified component(s) detected.` + RESET}\n`);
732
+ }
733
+
734
+ function runExport(isGlobal = false, customTarget = null, outputPath = null) {
735
+ printBanner();
736
+ const targetDir = customTarget ? path.resolve(customTarget) : (isGlobal ? GLOBAL_CONFIG_DIR : AGENTS_DIR);
737
+ console.log(`${BOLD}📦 Exporting Agent Configuration Bundle...${RESET}`);
738
+ console.log(`Source: ${CYAN}${targetDir}${RESET}\n`);
739
+
740
+ if (!fs.existsSync(targetDir)) {
741
+ console.error(`${RED}Error: Source directory does not exist: ${targetDir}${RESET}\n`);
742
+ process.exit(1);
743
+ }
744
+
745
+ const exportData = {
746
+ generator: "everything-gemini",
747
+ version: VERSION,
748
+ exportedAt: new Date().toISOString(),
749
+ source: targetDir,
750
+ skills: [],
751
+ agents: [],
752
+ hooksConfig: null
382
753
  };
383
- fs.writeFileSync(path.join(targetDir, 'hooks.json'), JSON.stringify(masterHooks, null, 2));
384
- console.log(` ${GREEN}✔${RESET} Generated master hooks.json`);
385
754
 
386
- console.log(`\n${GREEN}${BOLD}🎉 Installation complete! Everything Gemini is active.${RESET}\n`);
755
+ const skillsDir = path.join(targetDir, 'skills');
756
+ if (fs.existsSync(skillsDir)) {
757
+ for (const s of fs.readdirSync(skillsDir)) {
758
+ const skillPath = path.join(skillsDir, s, 'SKILL.md');
759
+ if (fs.existsSync(skillPath)) {
760
+ exportData.skills.push({ name: s, content: fs.readFileSync(skillPath, 'utf8') });
761
+ }
762
+ }
763
+ }
764
+
765
+ const agentsDir = path.join(targetDir, 'agents');
766
+ if (fs.existsSync(agentsDir)) {
767
+ for (const a of fs.readdirSync(agentsDir)) {
768
+ if (a.endsWith('.md')) {
769
+ exportData.agents.push({ name: a, content: fs.readFileSync(path.join(agentsDir, a), 'utf8') });
770
+ }
771
+ }
772
+ }
773
+
774
+ const hooksFile = path.join(targetDir, 'hooks.json');
775
+ if (fs.existsSync(hooksFile)) {
776
+ try {
777
+ exportData.hooksConfig = JSON.parse(fs.readFileSync(hooksFile, 'utf8'));
778
+ } catch (_) {}
779
+ }
780
+
781
+ const outDest = outputPath ? path.resolve(outputPath) : path.join(process.cwd(), 'everything-gemini-profile.json');
782
+ fs.writeFileSync(outDest, JSON.stringify(exportData, null, 2), 'utf8');
783
+ console.log(` ${GREEN}✔${RESET} Successfully exported ${exportData.skills.length} skills, ${exportData.agents.length} subagents to:`);
784
+ console.log(` ${BOLD}${outDest}${RESET}\n`);
785
+ }
786
+
787
+ function runImport(inputFile, isGlobal = false, customTarget = null, isDryRun = false) {
788
+ printBanner();
789
+ if (!inputFile) {
790
+ console.error(`${RED}Error: Input file required. Usage: everything-gemini import <profile.json>${RESET}\n`);
791
+ process.exit(1);
792
+ }
793
+
794
+ const filePath = path.resolve(inputFile);
795
+ if (!fs.existsSync(filePath)) {
796
+ console.error(`${RED}Error: Import file does not exist: ${filePath}${RESET}\n`);
797
+ process.exit(1);
798
+ }
799
+
800
+ let bundle = null;
801
+ try {
802
+ bundle = JSON.parse(fs.readFileSync(filePath, 'utf8'));
803
+ } catch (err) {
804
+ console.error(`${RED}Error parsing JSON import bundle: ${err.message}${RESET}\n`);
805
+ process.exit(1);
806
+ }
807
+
808
+ const targetDir = customTarget ? path.resolve(customTarget) : (isGlobal ? GLOBAL_CONFIG_DIR : AGENTS_DIR);
809
+ console.log(`${BOLD}📥 Importing Agent Configuration Bundle...${RESET}`);
810
+ console.log(`Source File: ${CYAN}${filePath}${RESET}`);
811
+ console.log(`Target: ${CYAN}${targetDir}${RESET}\n`);
812
+
813
+ if (isDryRun) {
814
+ console.log(`${YELLOW}${BOLD}⚠️ DRY RUN MODE ACTIVATED. Previewing import:${RESET}\n`);
815
+ }
816
+
817
+ let importedSkills = 0;
818
+ let importedAgents = 0;
819
+
820
+ // 1. Import Skills
821
+ if (Array.isArray(bundle.skills)) {
822
+ const targetSkills = path.join(targetDir, 'skills');
823
+ for (const s of bundle.skills) {
824
+ if (s.name && s.content) {
825
+ if (!isDryRun) {
826
+ const sDir = path.join(targetSkills, s.name);
827
+ fs.mkdirSync(sDir, { recursive: true });
828
+ fs.writeFileSync(path.join(sDir, 'SKILL.md'), s.content, 'utf8');
829
+ }
830
+ importedSkills++;
831
+ if (isDryRun) {
832
+ console.log(` ${CYAN}[DRY RUN]${RESET} Would import skill: ${s.name}`);
833
+ }
834
+ }
835
+ }
836
+ }
837
+
838
+ // 2. Import Subagents
839
+ if (Array.isArray(bundle.agents)) {
840
+ const targetAgents = path.join(targetDir, 'agents');
841
+ for (const a of bundle.agents) {
842
+ if (a.name && a.content) {
843
+ if (!isDryRun) {
844
+ fs.mkdirSync(targetAgents, { recursive: true });
845
+ fs.writeFileSync(path.join(targetAgents, a.name), a.content, 'utf8');
846
+ }
847
+ importedAgents++;
848
+ if (isDryRun) {
849
+ console.log(` ${CYAN}[DRY RUN]${RESET} Would import subagent: ${a.name}`);
850
+ }
851
+ }
852
+ }
853
+ }
854
+
855
+ // 3. Import Hooks Config
856
+ if (bundle.hooksConfig && typeof bundle.hooksConfig === 'object') {
857
+ if (!isDryRun) {
858
+ fs.mkdirSync(targetDir, { recursive: true });
859
+ fs.writeFileSync(path.join(targetDir, 'hooks.json'), JSON.stringify(bundle.hooksConfig, null, 2), 'utf8');
860
+ }
861
+ console.log(` ${GREEN}✔${RESET} ${isDryRun ? '[DRY RUN] Would import' : 'Imported'} hooks.json configuration`);
862
+ }
863
+
864
+ if (isDryRun) {
865
+ console.log(`\n${GREEN}${BOLD}✨ Dry run complete! Would import ${importedSkills} skills and ${importedAgents} subagents.${RESET}\n`);
866
+ } else {
867
+ console.log(` ${GREEN}✔${RESET} Successfully imported ${BOLD}${importedSkills}${RESET} progressive skills`);
868
+ console.log(` ${GREEN}✔${RESET} Successfully imported ${BOLD}${importedAgents}${RESET} scoped subagents\n`);
869
+ console.log(`${GREEN}${BOLD}✨ Import complete! Configuration applied to ${targetDir}${RESET}\n`);
870
+ }
871
+ }
872
+
873
+ function runBundle(profile = 'all', outputDir = null, isDryRun = false, asJson = false) {
874
+ const destDir = outputDir ? path.resolve(outputDir) : path.join(process.cwd(), 'everything-gemini-bundle');
875
+ const startTime = Date.now();
876
+ const crypto = require('crypto');
877
+
878
+ const skillsToBundle = [];
879
+ const agentsToBundle = [];
880
+ const hooksToBundle = [];
881
+
882
+ const catalogSkillsDir = path.join(REPO_ROOT, 'skills');
883
+ const catalogAgentsDir = path.join(REPO_ROOT, 'agents');
884
+ const catalogHooksDir = path.join(REPO_ROOT, 'hooks');
885
+
886
+ if (fs.existsSync(catalogSkillsDir)) {
887
+ const list = fs.readdirSync(catalogSkillsDir, { withFileTypes: true })
888
+ .filter(d => d.isDirectory())
889
+ .map(d => d.name)
890
+ .sort();
891
+ skillsToBundle.push(...list);
892
+ }
893
+
894
+ const pluginSkills = [
895
+ { name: 'antigravity-sdk-orchestrator', src: path.join(REPO_ROOT, 'plugins', 'python-ai', 'skills', 'antigravity-sdk-orchestrator') },
896
+ { name: 'responsive-design', src: path.join(REPO_ROOT, 'plugins', 'web-fullstack', 'skills', 'responsive-design') }
897
+ ];
898
+
899
+ if (fs.existsSync(catalogAgentsDir)) {
900
+ const list = fs.readdirSync(catalogAgentsDir)
901
+ .filter(f => f.endsWith('.md'))
902
+ .sort();
903
+ agentsToBundle.push(...list);
904
+ }
905
+
906
+ if (fs.existsSync(catalogHooksDir)) {
907
+ const list = fs.readdirSync(catalogHooksDir, { withFileTypes: true })
908
+ .filter(d => d.isDirectory())
909
+ .map(d => d.name)
910
+ .sort();
911
+ hooksToBundle.push(...list);
912
+ }
913
+
914
+ const manifest = {
915
+ generator: "everything-gemini",
916
+ version: VERSION,
917
+ profile,
918
+ createdAt: new Date().toISOString(),
919
+ components: {
920
+ skillsCount: skillsToBundle.length + pluginSkills.length,
921
+ subagentsCount: agentsToBundle.length,
922
+ hooksCount: hooksToBundle.length,
923
+ totalCount: skillsToBundle.length + pluginSkills.length + agentsToBundle.length + hooksToBundle.length
924
+ },
925
+ skills: [...skillsToBundle, ...pluginSkills.map(p => p.name)],
926
+ subagents: agentsToBundle,
927
+ hooks: hooksToBundle,
928
+ files: []
929
+ };
930
+
931
+ if (isDryRun) {
932
+ if (asJson) {
933
+ console.log(JSON.stringify({
934
+ dryRun: true,
935
+ targetDirectory: destDir,
936
+ manifest
937
+ }, null, 2));
938
+ return;
939
+ }
940
+ printBanner();
941
+ console.log(`${YELLOW}${BOLD}🔍 DRY RUN MODE ACTIVATED - Previewing bundle contents${RESET}`);
942
+ console.log(`Target: ${CYAN}${destDir}${RESET}\n`);
943
+ console.log(` ${CYAN}⚡ Skills to bundle:${RESET} ${skillsToBundle.length + pluginSkills.length}`);
944
+ console.log(` ${CYAN}🤖 Subagents to bundle:${RESET} ${agentsToBundle.length}`);
945
+ console.log(` ${CYAN}🛡️ Hooks to bundle:${RESET} ${hooksToBundle.length}`);
946
+ console.log(` ${CYAN}📦 Total Components:${RESET} ${manifest.components.totalCount}\n`);
947
+ console.log(`${GREEN}${BOLD}✨ Dry run preview complete! 0 files written to disk.${RESET}\n`);
948
+ return;
949
+ }
950
+
951
+ fs.mkdirSync(destDir, { recursive: true });
952
+ const bundleSkillsDir = path.join(destDir, 'skills');
953
+ const bundleAgentsDir = path.join(destDir, 'agents');
954
+ const bundleHooksDir = path.join(destDir, 'hooks');
955
+ const bundleRulesDir = path.join(destDir, 'rules');
956
+ fs.mkdirSync(bundleSkillsDir, { recursive: true });
957
+ fs.mkdirSync(bundleAgentsDir, { recursive: true });
958
+ fs.mkdirSync(bundleHooksDir, { recursive: true });
959
+ fs.mkdirSync(bundleRulesDir, { recursive: true });
960
+
961
+ for (const s of skillsToBundle) {
962
+ const src = path.join(catalogSkillsDir, s);
963
+ const dest = path.join(bundleSkillsDir, s);
964
+ copyRecursiveSync(src, dest);
965
+ const skillMd = path.join(dest, 'SKILL.md');
966
+ if (fs.existsSync(skillMd)) {
967
+ const hash = crypto.createHash('sha256').update(fs.readFileSync(skillMd)).digest('hex');
968
+ manifest.files.push({ path: `skills/${s}/SKILL.md`, sha256: hash });
969
+ }
970
+ }
971
+
972
+ for (const ps of pluginSkills) {
973
+ if (fs.existsSync(ps.src)) {
974
+ const dest = path.join(bundleSkillsDir, ps.name);
975
+ copyRecursiveSync(ps.src, dest);
976
+ const skillMd = path.join(dest, 'SKILL.md');
977
+ if (fs.existsSync(skillMd)) {
978
+ const hash = crypto.createHash('sha256').update(fs.readFileSync(skillMd)).digest('hex');
979
+ manifest.files.push({ path: `skills/${ps.name}/SKILL.md`, sha256: hash });
980
+ }
981
+ }
982
+ }
983
+
984
+ for (const a of agentsToBundle) {
985
+ const src = path.join(catalogAgentsDir, a);
986
+ const dest = path.join(bundleAgentsDir, a);
987
+ fs.copyFileSync(src, dest);
988
+ const hash = crypto.createHash('sha256').update(fs.readFileSync(dest)).digest('hex');
989
+ manifest.files.push({ path: `agents/${a}`, sha256: hash });
990
+ }
991
+
992
+ for (const h of hooksToBundle) {
993
+ const src = path.join(catalogHooksDir, h);
994
+ const dest = path.join(bundleHooksDir, h);
995
+ copyRecursiveSync(src, dest);
996
+ const hookJson = path.join(dest, 'hooks.json');
997
+ if (fs.existsSync(hookJson)) {
998
+ const hash = crypto.createHash('sha256').update(fs.readFileSync(hookJson)).digest('hex');
999
+ manifest.files.push({ path: `hooks/${h}/hooks.json`, sha256: hash });
1000
+ }
1001
+ }
1002
+
1003
+ const commonRules = path.join(REPO_ROOT, 'rules', 'common');
1004
+ if (fs.existsSync(commonRules)) {
1005
+ copyRecursiveSync(commonRules, bundleRulesDir);
1006
+ if (fs.existsSync(path.join(bundleRulesDir, 'GEMINI.md'))) {
1007
+ fs.copyFileSync(path.join(bundleRulesDir, 'GEMINI.md'), path.join(destDir, 'GEMINI.md'));
1008
+ }
1009
+ if (fs.existsSync(path.join(bundleRulesDir, 'AGENTS.md'))) {
1010
+ fs.copyFileSync(path.join(bundleRulesDir, 'AGENTS.md'), path.join(destDir, 'AGENTS.md'));
1011
+ }
1012
+ }
1013
+
1014
+ const installerScript = `#!/usr/bin/env bash
1015
+ # Offline Installer for Everything Gemini Bundle
1016
+ set -e
1017
+ TARGET="\${1:-.agents}"
1018
+ mkdir -p "$TARGET/skills" "$TARGET/agents" "$TARGET/hooks"
1019
+ cp -R skills/* "$TARGET/skills/" 2>/dev/null || true
1020
+ cp -R agents/* "$TARGET/agents/" 2>/dev/null || true
1021
+ cp -R hooks/* "$TARGET/hooks/" 2>/dev/null || true
1022
+ [ -f GEMINI.md ] && cp GEMINI.md "$TARGET/GEMINI.md"
1023
+ [ -f AGENTS.md ] && cp AGENTS.md "$TARGET/AGENTS.md"
1024
+ find "$TARGET/hooks" -name "*.sh" -exec chmod +x {} + 2>/dev/null || true
1025
+ echo "✨ Offline Everything Gemini bundle installed cleanly into $TARGET"
1026
+ `.trim();
1027
+ fs.writeFileSync(path.join(destDir, 'offline-install.sh'), installerScript, { mode: 0o755 });
1028
+
1029
+ fs.writeFileSync(path.join(destDir, 'bundle-manifest.json'), JSON.stringify(manifest, null, 2), 'utf8');
1030
+
1031
+ const duration = ((Date.now() - startTime) / 1000).toFixed(2);
1032
+
1033
+ if (asJson) {
1034
+ console.log(JSON.stringify({
1035
+ targetDirectory: destDir,
1036
+ manifest,
1037
+ durationSeconds: parseFloat(duration)
1038
+ }, null, 2));
1039
+ return;
1040
+ }
1041
+
1042
+ printBanner();
1043
+ console.log(`${BOLD}📦 Everything Gemini Offline Distribution Bundle Created${RESET}`);
1044
+ console.log(`Target: ${CYAN}${destDir}${RESET}\n`);
1045
+ console.log(` ${GREEN}✔${RESET} Packaged ${BOLD}${manifest.components.skillsCount}${RESET} progressive disclosure skills`);
1046
+ console.log(` ${GREEN}✔${RESET} Packaged ${BOLD}${manifest.components.subagentsCount}${RESET} scoped subagents`);
1047
+ console.log(` ${GREEN}✔${RESET} Packaged ${BOLD}${manifest.components.hooksCount}${RESET} lifecycle safety hooks`);
1048
+ console.log(` ${GREEN}✔${RESET} Generated ${BOLD}bundle-manifest.json${RESET} with ${manifest.files.length} SHA-256 integrity digests`);
1049
+ console.log(` ${GREEN}✔${RESET} Generated executable ${BOLD}offline-install.sh${RESET}`);
1050
+ console.log(` ${GREEN}✔${RESET} Total bundle duration: ${duration}s\n`);
1051
+ console.log(`${GREEN}${BOLD}✨ Bundle packaging complete! Ready for air-gapped and CI/CD deployment.${RESET}\n`);
387
1052
  }
388
1053
 
389
1054
  function runValidate() {
@@ -506,14 +1171,17 @@ Return structured report to parent agent:
506
1171
  console.log(` 📄 ${targetFile}\n`);
507
1172
  }
508
1173
 
509
- function addComponent(type, name) {
1174
+ function addComponent(type, name, isGlobal = false, customTarget = null) {
510
1175
  if (!type || !name) {
511
- console.error(`${RED}Usage: everything-gemini add <skill|agent|plugin> <name>${RESET}`);
1176
+ console.error(`${RED}Usage: everything-gemini add <skill|agent|hook|plugin> <name> [--workspace <path>] [--global]${RESET}`);
512
1177
  process.exit(1);
513
1178
  }
514
1179
 
515
1180
  const cleanName = name.trim().toLowerCase();
516
- const targetWorkspace = path.join(WORKSPACE_DIR, '.agents');
1181
+ const targetWorkspace = customTarget
1182
+ ? path.resolve(customTarget)
1183
+ : (isGlobal ? GLOBAL_CONFIG_DIR : path.join(WORKSPACE_DIR, '.agents'));
1184
+
517
1185
  if (!fs.existsSync(targetWorkspace)) {
518
1186
  fs.mkdirSync(targetWorkspace, { recursive: true });
519
1187
  }
@@ -537,6 +1205,21 @@ function addComponent(type, name) {
537
1205
  fs.mkdirSync(destDir, { recursive: true });
538
1206
  fs.copyFileSync(src, path.join(destDir, `${cleanName}.md`));
539
1207
  console.log(`${GREEN}✔ Added agent '${cleanName}' to ${destDir}${RESET}`);
1208
+ } else if (type === 'hook') {
1209
+ const src = path.join(REPO_ROOT, 'hooks', cleanName);
1210
+ if (!fs.existsSync(src)) {
1211
+ console.error(`${RED}Hook '${cleanName}' not found in catalog.${RESET}`);
1212
+ process.exit(1);
1213
+ }
1214
+ const dest = path.join(targetWorkspace, 'hooks', cleanName);
1215
+ copyRecursiveSync(src, dest);
1216
+ const scriptsDir = path.join(dest, 'scripts');
1217
+ if (fs.existsSync(scriptsDir)) {
1218
+ fs.readdirSync(scriptsDir).forEach(file => {
1219
+ try { fs.chmodSync(path.join(scriptsDir, file), 0o755); } catch (e) {}
1220
+ });
1221
+ }
1222
+ console.log(`${GREEN}✔ Added hook '${cleanName}' to ${dest}${RESET}`);
540
1223
  } else if (type === 'plugin') {
541
1224
  const src = path.join(REPO_ROOT, 'plugins', cleanName);
542
1225
  if (!fs.existsSync(src)) {
@@ -547,19 +1230,21 @@ function addComponent(type, name) {
547
1230
  copyRecursiveSync(src, dest);
548
1231
  console.log(`${GREEN}✔ Added plugin '${cleanName}' to ${dest}${RESET}`);
549
1232
  } else {
550
- console.error(`${RED}Unknown type '${type}'. Use: skill, agent, or plugin.${RESET}`);
1233
+ console.error(`${RED}Unknown type '${type}'. Use: skill, agent, hook, or plugin.${RESET}`);
551
1234
  process.exit(1);
552
1235
  }
553
1236
  }
554
1237
 
555
- function removeComponent(type, name) {
1238
+ function removeComponent(type, name, isGlobal = false, customTarget = null) {
556
1239
  if (!type || !name) {
557
- console.error(`${RED}Usage: everything-gemini remove <skill|agent|plugin> <name>${RESET}`);
1240
+ console.error(`${RED}Usage: everything-gemini remove <skill|agent|hook|plugin> <name> [--workspace <path>] [--global]${RESET}`);
558
1241
  process.exit(1);
559
1242
  }
560
1243
 
561
1244
  const cleanName = name.trim().toLowerCase();
562
- const targetWorkspace = path.join(WORKSPACE_DIR, '.agents');
1245
+ const targetWorkspace = customTarget
1246
+ ? path.resolve(customTarget)
1247
+ : (isGlobal ? GLOBAL_CONFIG_DIR : path.join(WORKSPACE_DIR, '.agents'));
563
1248
 
564
1249
  if (type === 'skill') {
565
1250
  const dest = path.join(targetWorkspace, 'skills', cleanName);
@@ -568,7 +1253,7 @@ function removeComponent(type, name) {
568
1253
  return;
569
1254
  }
570
1255
  fs.rmSync(dest, { recursive: true, force: true });
571
- console.log(`${GREEN}✔ Removed skill '${cleanName}' from workspace.${RESET}`);
1256
+ console.log(`${GREEN}✔ Removed skill '${cleanName}' from ${dest}.${RESET}`);
572
1257
  } else if (type === 'agent') {
573
1258
  const dest = path.join(targetWorkspace, 'agents', `${cleanName}.md`);
574
1259
  if (!fs.existsSync(dest)) {
@@ -576,7 +1261,15 @@ function removeComponent(type, name) {
576
1261
  return;
577
1262
  }
578
1263
  fs.unlinkSync(dest);
579
- console.log(`${GREEN}✔ Removed agent '${cleanName}' from workspace.${RESET}`);
1264
+ console.log(`${GREEN}✔ Removed agent '${cleanName}' from ${dest}.${RESET}`);
1265
+ } else if (type === 'hook') {
1266
+ const dest = path.join(targetWorkspace, 'hooks', cleanName);
1267
+ if (!fs.existsSync(dest)) {
1268
+ console.log(`${YELLOW}Hook '${cleanName}' is not installed in ${dest}${RESET}`);
1269
+ return;
1270
+ }
1271
+ fs.rmSync(dest, { recursive: true, force: true });
1272
+ console.log(`${GREEN}✔ Removed hook '${cleanName}' from ${dest}.${RESET}`);
580
1273
  } else if (type === 'plugin') {
581
1274
  const dest = path.join(targetWorkspace, 'plugins', cleanName);
582
1275
  if (!fs.existsSync(dest)) {
@@ -584,9 +1277,9 @@ function removeComponent(type, name) {
584
1277
  return;
585
1278
  }
586
1279
  fs.rmSync(dest, { recursive: true, force: true });
587
- console.log(`${GREEN}✔ Removed plugin '${cleanName}' from workspace.${RESET}`);
1280
+ console.log(`${GREEN}✔ Removed plugin '${cleanName}' from ${dest}.${RESET}`);
588
1281
  } else {
589
- console.error(`${RED}Unknown type '${type}'. Use: skill, agent, or plugin.${RESET}`);
1282
+ console.error(`${RED}Unknown type '${type}'. Use: skill, agent, hook, or plugin.${RESET}`);
590
1283
  process.exit(1);
591
1284
  }
592
1285
  }
@@ -653,6 +1346,639 @@ function testSkill(name) {
653
1346
  console.log(`\n${GREEN}${BOLD}✨ Skill '${cleanName}' passed all validation checks!${RESET}\n`);
654
1347
  }
655
1348
 
1349
+ function searchComponents(query, asJson = false) {
1350
+ if (!query || !query.trim()) {
1351
+ console.log(`${YELLOW}Please specify a search query.${RESET}`);
1352
+ console.log(`Usage: everything-gemini search <term> [--json]\n`);
1353
+ return;
1354
+ }
1355
+ const q = query.trim().toLowerCase();
1356
+ const results = {
1357
+ skills: [],
1358
+ subagents: [],
1359
+ hooks: [],
1360
+ mcp: []
1361
+ };
1362
+
1363
+ // 1. Search Skills (core + plugins)
1364
+ const skillsDir = path.join(REPO_ROOT, 'skills');
1365
+ if (fs.existsSync(skillsDir)) {
1366
+ const skills = fs.readdirSync(skillsDir, { withFileTypes: true })
1367
+ .filter(d => d.isDirectory())
1368
+ .map(d => d.name);
1369
+ for (const skill of skills) {
1370
+ const skillMd = path.join(skillsDir, skill, 'SKILL.md');
1371
+ let desc = '';
1372
+ let fullContent = '';
1373
+ if (fs.existsSync(skillMd)) {
1374
+ fullContent = fs.readFileSync(skillMd, 'utf8');
1375
+ const match = fullContent.match(/description:\s*>?-?\s*([^\n\r]+)/);
1376
+ if (match) desc = match[1].trim();
1377
+ }
1378
+ if (skill.toLowerCase().includes(q) || desc.toLowerCase().includes(q) || fullContent.toLowerCase().includes(q)) {
1379
+ results.skills.push({ name: skill, description: desc || 'Progressive disclosure skill' });
1380
+ }
1381
+ }
1382
+ }
1383
+
1384
+ const pluginsDir = path.join(REPO_ROOT, 'plugins');
1385
+ if (fs.existsSync(pluginsDir)) {
1386
+ const plugins = fs.readdirSync(pluginsDir, { withFileTypes: true })
1387
+ .filter(d => d.isDirectory())
1388
+ .map(d => d.name);
1389
+ for (const p of plugins) {
1390
+ const pSkillsDir = path.join(pluginsDir, p, 'skills');
1391
+ if (fs.existsSync(pSkillsDir)) {
1392
+ const pSkills = fs.readdirSync(pSkillsDir, { withFileTypes: true })
1393
+ .filter(d => d.isDirectory())
1394
+ .map(d => d.name);
1395
+ for (const skill of pSkills) {
1396
+ const skillMd = path.join(pSkillsDir, skill, 'SKILL.md');
1397
+ let desc = '';
1398
+ let fullContent = '';
1399
+ if (fs.existsSync(skillMd)) {
1400
+ fullContent = fs.readFileSync(skillMd, 'utf8');
1401
+ const match = fullContent.match(/description:\s*>?-?\s*([^\n\r]+)/);
1402
+ if (match) desc = match[1].trim();
1403
+ }
1404
+ if (skill.toLowerCase().includes(q) || desc.toLowerCase().includes(q) || fullContent.toLowerCase().includes(q)) {
1405
+ results.skills.push({ name: `${skill} [${p}]`, description: desc || 'Plugin progressive skill' });
1406
+ }
1407
+ }
1408
+ }
1409
+ }
1410
+ }
1411
+
1412
+ // 2. Search Subagents
1413
+ const agentsDir = path.join(REPO_ROOT, 'agents');
1414
+ if (fs.existsSync(agentsDir)) {
1415
+ const agents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
1416
+ for (const ag of agents) {
1417
+ const name = ag.replace('.md', '');
1418
+ const content = fs.readFileSync(path.join(agentsDir, ag), 'utf8');
1419
+ const missionMatch = content.match(/## Role & Mission\s+([^\n\r]+)/);
1420
+ const mission = missionMatch ? missionMatch[1].trim() : '';
1421
+ if (name.toLowerCase().includes(q) || content.toLowerCase().includes(q)) {
1422
+ results.subagents.push({ name, description: mission || 'Scoped autonomous subagent' });
1423
+ }
1424
+ }
1425
+ }
1426
+
1427
+ // 3. Search Lifecycle Hooks
1428
+ const hooksDir = path.join(REPO_ROOT, 'hooks');
1429
+ if (fs.existsSync(hooksDir)) {
1430
+ const hooks = fs.readdirSync(hooksDir, { withFileTypes: true })
1431
+ .filter(d => d.isDirectory())
1432
+ .map(d => d.name);
1433
+ for (const h of hooks) {
1434
+ const hJson = path.join(hooksDir, h, 'hooks.json');
1435
+ let desc = 'Lifecycle safety gate';
1436
+ if (fs.existsSync(hJson)) {
1437
+ try {
1438
+ const parsed = JSON.parse(fs.readFileSync(hJson, 'utf8'));
1439
+ if (parsed.description) desc = parsed.description;
1440
+ } catch (_) {}
1441
+ }
1442
+ if (h.toLowerCase().includes(q) || desc.toLowerCase().includes(q)) {
1443
+ results.hooks.push({ name: h, description: desc });
1444
+ }
1445
+ }
1446
+ }
1447
+
1448
+ // 4. Search MCP Blueprints
1449
+ const mcpExamplePath = path.join(REPO_ROOT, 'mcp', 'mcp_config.example.json');
1450
+ if (fs.existsSync(mcpExamplePath)) {
1451
+ try {
1452
+ const mcpConfig = JSON.parse(fs.readFileSync(mcpExamplePath, 'utf8'));
1453
+ for (const [srvName, cfg] of Object.entries(mcpConfig.mcpServers || {})) {
1454
+ const cmdStr = `${srvName} ${cfg.command || ''} ${(cfg.args || []).join(' ')}`;
1455
+ if (cmdStr.toLowerCase().includes(q)) {
1456
+ results.mcp.push({ name: srvName, description: (cfg.args || []).join(' ') || cfg.command });
1457
+ }
1458
+ }
1459
+ } catch (_) {}
1460
+ }
1461
+
1462
+ const totalMatches = results.skills.length + results.subagents.length + results.hooks.length + results.mcp.length;
1463
+
1464
+ if (asJson) {
1465
+ console.log(JSON.stringify({ query, totalMatches, results }, null, 2));
1466
+ return;
1467
+ }
1468
+
1469
+ printBanner();
1470
+ console.log(`${BOLD}🔎 Search Results for: "${CYAN}${query}${RESET}${BOLD}" (${GREEN}${totalMatches} found${RESET}${BOLD})${RESET}\n`);
1471
+
1472
+ if (totalMatches === 0) {
1473
+ console.log(` ${YELLOW}○ No matching components found.${RESET}`);
1474
+ console.log(` Run ${GREEN}everything-gemini list${RESET} to browse all 48 skills, 10 subagents, and 7 hooks.\n`);
1475
+ return;
1476
+ }
1477
+
1478
+ if (results.skills.length > 0) {
1479
+ console.log(`${CYAN}${BOLD}⚡ Progressive Skills (${results.skills.length}):${RESET}`);
1480
+ for (const s of results.skills) {
1481
+ console.log(` • ${BOLD}${s.name.padEnd(28)}${RESET} ${GRAY}${s.description}${RESET}`);
1482
+ console.log(` ${GREEN}Add:${RESET} everything-gemini add skill ${s.name.split(' ')[0]}`);
1483
+ }
1484
+ console.log('');
1485
+ }
1486
+
1487
+ if (results.subagents.length > 0) {
1488
+ console.log(`${CYAN}${BOLD}🤖 Scoped Subagents (${results.subagents.length}):${RESET}`);
1489
+ for (const a of results.subagents) {
1490
+ console.log(` • ${BOLD}${a.name.padEnd(28)}${RESET} ${GRAY}${a.description}${RESET}`);
1491
+ console.log(` ${GREEN}Add:${RESET} everything-gemini add agent ${a.name}`);
1492
+ }
1493
+ console.log('');
1494
+ }
1495
+
1496
+ if (results.hooks.length > 0) {
1497
+ console.log(`${CYAN}${BOLD}🛡️ Lifecycle Hooks (${results.hooks.length}):${RESET}`);
1498
+ for (const h of results.hooks) {
1499
+ console.log(` • ${BOLD}${h.name.padEnd(28)}${RESET} ${GRAY}${h.description}${RESET}`);
1500
+ console.log(` ${GREEN}Add:${RESET} everything-gemini add hook ${h.name}`);
1501
+ }
1502
+ console.log('');
1503
+ }
1504
+
1505
+ if (results.mcp.length > 0) {
1506
+ console.log(`${CYAN}${BOLD}🌐 MCP Blueprints (${results.mcp.length}):${RESET}`);
1507
+ for (const m of results.mcp) {
1508
+ console.log(` • ${BOLD}${m.name.padEnd(28)}${RESET} ${GRAY}${m.description}${RESET}`);
1509
+ }
1510
+ console.log('');
1511
+ }
1512
+ }
1513
+
1514
+ function runAudit(targetPath = null, isGlobal = false, asJson = false) {
1515
+ const targetDir = isGlobal
1516
+ ? path.join(os.homedir(), '.gemini', 'config')
1517
+ : (targetPath ? path.resolve(targetPath) : (fs.existsSync(path.join(process.cwd(), '.agents')) ? path.join(process.cwd(), '.agents') : REPO_ROOT));
1518
+
1519
+ const isRepoAudit = (targetDir === REPO_ROOT);
1520
+ const auditReport = {
1521
+ target: targetDir,
1522
+ timestamp: new Date().toISOString(),
1523
+ isRepoCatalog: isRepoAudit,
1524
+ checks: [],
1525
+ passedCount: 0,
1526
+ warningCount: 0,
1527
+ errorCount: 0,
1528
+ valid: true,
1529
+ };
1530
+
1531
+ function addCheck(category, item, status, message, details = null) {
1532
+ if (status === 'error') auditReport.errorCount++;
1533
+ else if (status === 'warn') auditReport.warningCount++;
1534
+ else auditReport.passedCount++;
1535
+ auditReport.checks.push({ category, item, status, message, details });
1536
+ }
1537
+
1538
+ // 1. Audit Skills
1539
+ const skillsBase = isRepoAudit ? path.join(REPO_ROOT, 'skills') : path.join(targetDir, 'skills');
1540
+ if (fs.existsSync(skillsBase)) {
1541
+ const skillEntries = fs.readdirSync(skillsBase, { withFileTypes: true }).filter(d => d.isDirectory());
1542
+ for (const ent of skillEntries) {
1543
+ const skillFile = path.join(skillsBase, ent.name, 'SKILL.md');
1544
+ if (!fs.existsSync(skillFile)) {
1545
+ addCheck('skills', ent.name, 'error', 'Missing SKILL.md in directory');
1546
+ continue;
1547
+ }
1548
+ const raw = fs.readFileSync(skillFile, 'utf8');
1549
+ const lines = raw.split('\n');
1550
+ const parts = raw.split('---');
1551
+ if (parts.length < 3) {
1552
+ addCheck('skills', ent.name, 'error', 'Invalid or missing YAML frontmatter delimiters (---)');
1553
+ continue;
1554
+ }
1555
+ const frontmatter = parts[1];
1556
+ const nameMatch = frontmatter.match(/name:\s*([a-zA-Z0-9_-]+)/);
1557
+ const descMatch = frontmatter.match(/description:\s*>?-?\s*([^\n\r]+)/);
1558
+
1559
+ if (!nameMatch) {
1560
+ addCheck('skills', ent.name, 'error', "Missing 'name' field in YAML frontmatter");
1561
+ } else if (nameMatch[1].trim() !== ent.name) {
1562
+ addCheck('skills', ent.name, 'warn', `Frontmatter name '${nameMatch[1].trim()}' does not match directory '${ent.name}'`);
1563
+ }
1564
+
1565
+ if (!descMatch || !descMatch[1].trim()) {
1566
+ addCheck('skills', ent.name, 'error', "Missing 'description' trigger in YAML frontmatter");
1567
+ }
1568
+
1569
+ if (lines.length > 260) {
1570
+ addCheck('skills', ent.name, 'warn', `Runbook length exceeds 250 lines (${lines.length} lines); consider progressive disclosure sub-references`);
1571
+ } else {
1572
+ addCheck('skills', ent.name, 'pass', `Valid YAML frontmatter and runbook compliance (${lines.length} lines)`);
1573
+ }
1574
+ }
1575
+ }
1576
+
1577
+ // 2. Audit Scoped Subagents
1578
+ const agentsBase = isRepoAudit ? path.join(REPO_ROOT, 'agents') : path.join(targetDir, 'agents');
1579
+ if (fs.existsSync(agentsBase)) {
1580
+ const agentFiles = fs.readdirSync(agentsBase).filter(f => f.endsWith('.md'));
1581
+ for (const f of agentFiles) {
1582
+ const agentPath = path.join(agentsBase, f);
1583
+ const content = fs.readFileSync(agentPath, 'utf8');
1584
+ const hasRole = /#+\s*(Core Role|Role & Mission)/i.test(content);
1585
+ const hasGuardrails = /#+\s*(Execution Guardrails|Tool Permissions)/i.test(content);
1586
+ const hasProtocol = /#+\s*(Delegation Protocol|Protocol|Handoff)/i.test(content);
1587
+
1588
+ if (hasRole && hasGuardrails && hasProtocol) {
1589
+ addCheck('subagents', f, 'pass', 'Complies with Subagent Specification Contract (Role, Guardrails, Handoff)');
1590
+ } else {
1591
+ const missing = [];
1592
+ if (!hasRole) missing.push('Role & Mission');
1593
+ if (!hasGuardrails) missing.push('Guardrails / Tool Permissions');
1594
+ if (!hasProtocol) missing.push('Handoff / Protocol');
1595
+ addCheck('subagents', f, 'error', `Missing required specification sections: ${missing.join(', ')}`);
1596
+ }
1597
+ }
1598
+ }
1599
+
1600
+ // 3. Audit Lifecycle Hooks
1601
+ const hooksBase = isRepoAudit ? path.join(REPO_ROOT, 'hooks') : path.join(targetDir, 'hooks');
1602
+ if (fs.existsSync(hooksBase)) {
1603
+ const hookDirs = fs.readdirSync(hooksBase, { withFileTypes: true }).filter(d => d.isDirectory());
1604
+ for (const hd of hookDirs) {
1605
+ const scriptsDir = path.join(hooksBase, hd.name, 'scripts');
1606
+ if (fs.existsSync(scriptsDir)) {
1607
+ const scripts = fs.readdirSync(scriptsDir).filter(s => s.endsWith('.sh'));
1608
+ for (const s of scripts) {
1609
+ const sPath = path.join(scriptsDir, s);
1610
+ try {
1611
+ fs.accessSync(sPath, fs.constants.X_OK);
1612
+ addCheck('hooks', `${hd.name}/${s}`, 'pass', 'Hook script is executable (+x)');
1613
+ } catch {
1614
+ addCheck('hooks', `${hd.name}/${s}`, 'error', 'Hook script lacks executable permissions (chmod +x)');
1615
+ }
1616
+ }
1617
+ }
1618
+ }
1619
+ }
1620
+
1621
+ auditReport.valid = (auditReport.errorCount === 0);
1622
+
1623
+ if (asJson) {
1624
+ console.log(JSON.stringify(auditReport, null, 2));
1625
+ if (!auditReport.valid) process.exit(1);
1626
+ return;
1627
+ }
1628
+
1629
+ printBanner();
1630
+ console.log(`${BOLD}🛡️ Everything Gemini Ecosystem Audit Report${RESET}`);
1631
+ console.log(`Target: ${CYAN}${targetDir}${RESET} ${isRepoAudit ? `${YELLOW}(Master Repository Catalog)${RESET}` : ''}\n`);
1632
+
1633
+ const categories = ['skills', 'subagents', 'hooks'];
1634
+ for (const cat of categories) {
1635
+ const items = auditReport.checks.filter(c => c.category === cat);
1636
+ if (items.length === 0) continue;
1637
+
1638
+ const catTitle = cat === 'skills' ? '⚡ Progressive Skills' :
1639
+ cat === 'subagents' ? '🤖 Scoped Subagents' : '🛡️ Lifecycle Hooks';
1640
+ console.log(`${BOLD}${catTitle} (${items.length}):${RESET}`);
1641
+ for (const it of items) {
1642
+ const icon = it.status === 'pass' ? `${GREEN}✔${RESET}` :
1643
+ it.status === 'warn' ? `${YELLOW}▲${RESET}` : `${RED}✘${RESET}`;
1644
+ console.log(` ${icon} ${it.item.padEnd(32)} ${it.message}`);
1645
+ }
1646
+ console.log('');
1647
+ }
1648
+
1649
+ console.log(`${BOLD}✨ Audit Summary:${RESET}`);
1650
+ console.log(` Passed Checks: ${GREEN}${auditReport.passedCount}${RESET}`);
1651
+ console.log(` Warnings: ${auditReport.warningCount > 0 ? YELLOW : GREEN}${auditReport.warningCount}${RESET}`);
1652
+ console.log(` Errors: ${auditReport.errorCount > 0 ? RED : GREEN}${auditReport.errorCount}${RESET}\n`);
1653
+
1654
+ if (auditReport.valid) {
1655
+ console.log(` ${GREEN}${BOLD}✔ ALL CHECKS PASSED: Target is 100% compliant with Antigravity Progressive Disclosure standards!${RESET}\n`);
1656
+ } else {
1657
+ console.log(` ${RED}${BOLD}✘ AUDIT FAILED: ${auditReport.errorCount} blocking errors found.${RESET}\n`);
1658
+ process.exit(1);
1659
+ }
1660
+ }
1661
+
1662
+ function testAllSkills(asJson = false) {
1663
+ const startTime = Date.now();
1664
+ let skillCount = 0;
1665
+ let totalChars = 0;
1666
+ const skillsGathered = [];
1667
+
1668
+ // 1. Core Skills
1669
+ const skillsDir = path.join(REPO_ROOT, 'skills');
1670
+ const skills = fs.readdirSync(skillsDir, { withFileTypes: true })
1671
+ .filter(d => d.isDirectory())
1672
+ .map(d => d.name)
1673
+ .sort();
1674
+
1675
+ if (!asJson) {
1676
+ printBanner();
1677
+ console.log(`${BOLD}🧪 Benchmarking & Validating All Skills, Subagents & Hooks...${RESET}\n`);
1678
+ console.log(`${CYAN}${BOLD}⚡ Skills Validation (Progressive Disclosure):${RESET}`);
1679
+ }
1680
+
1681
+ for (const s of skills) {
1682
+ const md = path.join(skillsDir, s, 'SKILL.md');
1683
+ if (fs.existsSync(md)) {
1684
+ const content = fs.readFileSync(md, 'utf8');
1685
+ totalChars += content.length;
1686
+ skillCount++;
1687
+ const estTokens = Math.round(content.length / 4);
1688
+ skillsGathered.push({ name: s, plugin: null, tokens: estTokens });
1689
+ if (!asJson) {
1690
+ console.log(` ${GREEN}✔${RESET} ${s.padEnd(30)} ${GRAY}(~${estTokens} tokens)${RESET}`);
1691
+ }
1692
+ }
1693
+ }
1694
+
1695
+ // 2. Plugin Skills
1696
+ const pluginsDir = path.join(REPO_ROOT, 'plugins');
1697
+ if (fs.existsSync(pluginsDir)) {
1698
+ const plugins = fs.readdirSync(pluginsDir, { withFileTypes: true })
1699
+ .filter(d => d.isDirectory())
1700
+ .map(d => d.name)
1701
+ .sort();
1702
+ for (const p of plugins) {
1703
+ const pSkillsDir = path.join(pluginsDir, p, 'skills');
1704
+ if (fs.existsSync(pSkillsDir)) {
1705
+ const pSkills = fs.readdirSync(pSkillsDir, { withFileTypes: true })
1706
+ .filter(d => d.isDirectory())
1707
+ .map(d => d.name)
1708
+ .sort();
1709
+ for (const s of pSkills) {
1710
+ const md = path.join(pSkillsDir, s, 'SKILL.md');
1711
+ if (fs.existsSync(md)) {
1712
+ const content = fs.readFileSync(md, 'utf8');
1713
+ totalChars += content.length;
1714
+ skillCount++;
1715
+ const estTokens = Math.round(content.length / 4);
1716
+ skillsGathered.push({ name: s, plugin: p, tokens: estTokens });
1717
+ if (!asJson) {
1718
+ console.log(` ${GREEN}✔${RESET} ${(`${s} [${p}]`).padEnd(30)} ${GRAY}(~${estTokens} tokens)${RESET}`);
1719
+ }
1720
+ }
1721
+ }
1722
+ }
1723
+ }
1724
+ }
1725
+
1726
+ // 3. Subagents
1727
+ if (!asJson) console.log(`\n${CYAN}${BOLD}🤖 Scoped Subagents Validation:${RESET}`);
1728
+ const agentsDir = path.join(REPO_ROOT, 'agents');
1729
+ const agents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md')).sort().map(f => f.replace('.md', ''));
1730
+ if (!asJson) {
1731
+ for (const a of agents) {
1732
+ console.log(` ${GREEN}✔${RESET} ${a.padEnd(30)}`);
1733
+ }
1734
+ }
1735
+
1736
+ // 4. Lifecycle Hooks
1737
+ if (!asJson) console.log(`\n${CYAN}${BOLD}🛡️ Lifecycle Hooks Validation:${RESET}`);
1738
+ const hooksDir = path.join(REPO_ROOT, 'hooks');
1739
+ const hooks = fs.readdirSync(hooksDir, { withFileTypes: true })
1740
+ .filter(d => d.isDirectory())
1741
+ .map(d => d.name)
1742
+ .sort();
1743
+ if (!asJson) {
1744
+ for (const h of hooks) {
1745
+ console.log(` ${GREEN}✔${RESET} ${h.padEnd(30)}`);
1746
+ }
1747
+ }
1748
+
1749
+ const duration = ((Date.now() - startTime) / 1000).toFixed(2);
1750
+ const totalTokens = Math.round(totalChars / 4);
1751
+ const tokenSavings = Math.round(totalTokens * 0.85);
1752
+
1753
+ if (asJson) {
1754
+ console.log(JSON.stringify({
1755
+ version: VERSION,
1756
+ totalComponents: skillCount + agents.length + hooks.length,
1757
+ progressiveSkillsCount: skillCount,
1758
+ scopedAgentsCount: agents.length,
1759
+ lifecycleHooksCount: hooks.length,
1760
+ totalRunbookTokens: totalTokens,
1761
+ estimatedTokensSavedPerTurn: tokenSavings,
1762
+ latencySeconds: parseFloat(duration),
1763
+ skills: skillsGathered,
1764
+ agents,
1765
+ hooks
1766
+ }, null, 2));
1767
+ return;
1768
+ }
1769
+
1770
+ console.log(`\n${GREEN}${BOLD}✨ Benchmark Summary:${RESET}`);
1771
+ console.log(` Total Components: ${BOLD}${skillCount + agents.length + hooks.length}${RESET}`);
1772
+ console.log(` Progressive Skills: ${BOLD}${skillCount}${RESET}`);
1773
+ console.log(` Total Runbook Tokens: ${BOLD}~${totalTokens.toLocaleString()}${RESET}`);
1774
+ console.log(` Estimated Tokens Saved / Turn: ${BOLD}~${tokenSavings.toLocaleString()} tokens (>85%)${RESET}`);
1775
+ console.log(` Diagnostic Latency: ${BOLD}${duration}s${RESET}\n`);
1776
+ }
1777
+
1778
+ function printCompletion(installMode = false, isDryRun = false, customRc = null) {
1779
+ const script = `
1780
+ # Everything Gemini Bash/Zsh completion
1781
+ _everything_gemini() {
1782
+ local cur prev commands skills agents hooks plugins
1783
+ COMPREPLY=()
1784
+ cur="\${COMP_WORDS[COMP_CWORD]}"
1785
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
1786
+ commands="doctor list init install status check update new-skill new-agent add remove test-skill test-all benchmark info show completion validate version help diff export import bundle pack search find audit"
1787
+ skills="agent-evals ai-first-engineering apache-kafka-streams api-craftsman architecture-designer argo-workflows axum-web-service browser-qa-tester cilium-ebpf-networking clickhouse-analytics cloudflare-workers context-caching continuous-learning database-architect dbt-transformation debezium-cdc devops-pipeline docker-compose-orchestrator duckdb-local-olap fastapi-production fullstack-nextjs gemini-function-calling gemini-grounding gemini-multimodal git-craftsman github-ops graphql-architect grpc-connect-rpc kubernetes-operator langgraph-orchestrator litellm-proxy-gateway nats-jetstream open-telemetry-tracing performance-profiler playwright-visual-regression rag-architect redis-cache-patterns repo-onboarding root-cause-debugger security-audit stripe-integration subagent-handoff supabase-architect svelte-kit-architect tdd-workflow temporal-workflows trpc-react-query turborepo-monorepo vllm-inference wasm-rust-optimizer antigravity-sdk-orchestrator responsive-design"
1788
+ agents="architect browser-qa build-repair code-reviewer database-migrator documentation-writer incident-responder performance-tuner planner release-engineer security-auditor"
1789
+ hooks="auto-lint-formatter ephemeral-context gemini-shield goal-verifier learned-instincts safety-shield secret-scrubber"
1790
+ plugins="core python-ai security-shield web-fullstack"
1791
+
1792
+ case "\${prev}" in
1793
+ everything-gemini|eagy|egemini)
1794
+ COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
1795
+ return 0
1796
+ ;;
1797
+ add|remove)
1798
+ COMPREPLY=( $(compgen -W "skill agent hook plugin" -- "\${cur}") )
1799
+ return 0
1800
+ ;;
1801
+ skill|test-skill)
1802
+ COMPREPLY=( $(compgen -W "\${skills}" -- "\${cur}") )
1803
+ return 0
1804
+ ;;
1805
+ agent)
1806
+ COMPREPLY=( $(compgen -W "\${agents}" -- "\${cur}") )
1807
+ return 0
1808
+ ;;
1809
+ hook)
1810
+ COMPREPLY=( $(compgen -W "\${hooks}" -- "\${cur}") )
1811
+ return 0
1812
+ ;;
1813
+ plugin)
1814
+ COMPREPLY=( $(compgen -W "\${plugins}" -- "\${cur}") )
1815
+ return 0
1816
+ ;;
1817
+ info|show|search|find|audit)
1818
+ COMPREPLY=( $(compgen -W "\${skills} \${agents} \${hooks} \${plugins}" -- "\${cur}") )
1819
+ return 0
1820
+ ;;
1821
+ --profile)
1822
+ COMPREPLY=( $(compgen -W "core developer full" -- "\${cur}") )
1823
+ return 0
1824
+ ;;
1825
+ esac
1826
+ }
1827
+ complete -F _everything_gemini everything-gemini egemini eagy
1828
+ `.trim();
1829
+
1830
+ if (!installMode) {
1831
+ console.log(script);
1832
+ return;
1833
+ }
1834
+
1835
+ printBanner();
1836
+ console.log(`${BOLD}🐚 Shell Autocompletion Installer${RESET}\n`);
1837
+
1838
+ let targetRc = customRc;
1839
+ if (!targetRc) {
1840
+ const isZsh = (process.env.SHELL && process.env.SHELL.includes('zsh')) || fs.existsSync(path.join(os.homedir(), '.zshrc'));
1841
+ targetRc = isZsh ? path.join(os.homedir(), '.zshrc') : path.join(os.homedir(), '.bashrc');
1842
+ }
1843
+
1844
+ if (fs.existsSync(targetRc)) {
1845
+ const currentContent = fs.readFileSync(targetRc, 'utf8');
1846
+ if (currentContent.includes('_everything_gemini()')) {
1847
+ console.log(` ${YELLOW}ℹ${RESET} Autocompletion is already configured in ${BOLD}${targetRc}${RESET}`);
1848
+ console.log(` To reload, run: ${GREEN}source ${targetRc}${RESET}\n`);
1849
+ return;
1850
+ }
1851
+ }
1852
+
1853
+ if (isDryRun) {
1854
+ console.log(` ${CYAN}[DRY RUN]${RESET} Would append completion script to: ${BOLD}${targetRc}${RESET}\n`);
1855
+ return;
1856
+ }
1857
+
1858
+ const payload = `\n\n# Everything Gemini Autocompletion\n${script}\n`;
1859
+ fs.appendFileSync(targetRc, payload, 'utf8');
1860
+ console.log(` ${GREEN}✔${RESET} Successfully installed autocompletion into: ${BOLD}${targetRc}${RESET}`);
1861
+ console.log(`\n${GREEN}${BOLD}✨ Ready! Reload your shell with:${RESET}`);
1862
+ console.log(` ${CYAN}source ${targetRc}${RESET}\n`);
1863
+ }
1864
+
1865
+ function showComponentInfo(query1, query2) {
1866
+ let target = query1;
1867
+ let explicitType = null;
1868
+ if (['skill', 'agent', 'hook', 'plugin'].includes(query1) && query2) {
1869
+ explicitType = query1;
1870
+ target = query2;
1871
+ }
1872
+ if (!target) {
1873
+ console.error(`\n${RED}Error: Please specify a component name.${RESET}`);
1874
+ console.log(`Usage: everything-gemini info [skill|agent|hook] <name>\n`);
1875
+ process.exit(1);
1876
+ }
1877
+
1878
+ const cleanName = target.trim().toLowerCase().replace(/^(skills|agents|hooks)\//, '');
1879
+
1880
+ // 1. Check Subagents if type is agent or undefined
1881
+ if (!explicitType || explicitType === 'agent') {
1882
+ const agentMd = path.join(REPO_ROOT, 'agents', `${cleanName}.md`);
1883
+ if (fs.existsSync(agentMd)) {
1884
+ printBanner();
1885
+ console.log(`${BOLD}🤖 Subagent Specification: ${CYAN}${cleanName}${RESET}`);
1886
+ console.log(`Path: ${GRAY}${agentMd}${RESET}\n`);
1887
+ const content = fs.readFileSync(agentMd, 'utf8');
1888
+ const lines = content.split('\n').slice(0, 25);
1889
+ console.log(lines.join('\n'));
1890
+ if (content.split('\n').length > 25) {
1891
+ console.log(`\n${GRAY}... (${content.split('\n').length - 25} more lines in ${agentMd})${RESET}`);
1892
+ }
1893
+ console.log('');
1894
+ return;
1895
+ }
1896
+ }
1897
+
1898
+ // 2. Check Hooks if type is hook or undefined
1899
+ if (!explicitType || explicitType === 'hook') {
1900
+ const hookDir = path.join(REPO_ROOT, 'hooks', cleanName);
1901
+ const hookJson = path.join(hookDir, 'hooks.json');
1902
+ if (fs.existsSync(hookJson)) {
1903
+ printBanner();
1904
+ console.log(`${BOLD}🛡️ Lifecycle Hook: ${CYAN}${cleanName}${RESET}`);
1905
+ console.log(`Directory: ${GRAY}${hookDir}${RESET}\n`);
1906
+ try {
1907
+ const parsed = JSON.parse(fs.readFileSync(hookJson, 'utf8'));
1908
+ console.log(`${BOLD}Configuration (hooks.json):${RESET}`);
1909
+ console.log(JSON.stringify(parsed, null, 2));
1910
+ } catch (e) {
1911
+ console.log(fs.readFileSync(hookJson, 'utf8'));
1912
+ }
1913
+ const scriptsDir = path.join(hookDir, 'scripts');
1914
+ if (fs.existsSync(scriptsDir)) {
1915
+ const scripts = fs.readdirSync(scriptsDir);
1916
+ console.log(`\n${BOLD}Hook Scripts:${RESET}`);
1917
+ scripts.forEach(s => console.log(` 🔧 scripts/${s}`));
1918
+ }
1919
+ console.log('');
1920
+ return;
1921
+ }
1922
+ }
1923
+
1924
+ // 3. Check Skills (Core or Plugin)
1925
+ let skillDir = path.join(REPO_ROOT, 'skills', cleanName);
1926
+ let pluginName = null;
1927
+
1928
+ if (!fs.existsSync(skillDir)) {
1929
+ const pluginsDir = path.join(REPO_ROOT, 'plugins');
1930
+ if (fs.existsSync(pluginsDir)) {
1931
+ const plugins = fs.readdirSync(pluginsDir, { withFileTypes: true })
1932
+ .filter(d => d.isDirectory())
1933
+ .map(d => d.name);
1934
+ for (const p of plugins) {
1935
+ const candidate = path.join(pluginsDir, p, 'skills', cleanName);
1936
+ if (fs.existsSync(candidate)) {
1937
+ skillDir = candidate;
1938
+ pluginName = p;
1939
+ break;
1940
+ }
1941
+ }
1942
+ }
1943
+ }
1944
+
1945
+ const skillMd = path.join(skillDir, 'SKILL.md');
1946
+ if (fs.existsSync(skillMd)) {
1947
+ printBanner();
1948
+ console.log(`${BOLD}📖 Skill Overview: ${CYAN}${cleanName}${RESET}`);
1949
+ if (pluginName) {
1950
+ console.log(`Source Plugin: ${YELLOW}${pluginName}${RESET}`);
1951
+ }
1952
+ console.log(`Path: ${GRAY}${skillMd}${RESET}\n`);
1953
+
1954
+ const content = fs.readFileSync(skillMd, 'utf8');
1955
+ const parts = content.split('---');
1956
+ if (parts.length >= 3) {
1957
+ const frontmatter = parts[1];
1958
+ const descMatch = frontmatter.match(/description:\s*>?-?\s*([^\n\r]+)/);
1959
+ if (descMatch) {
1960
+ console.log(`${BOLD}🎯 Trigger Description:${RESET}`);
1961
+ console.log(` ${descMatch[1].trim()}\n`);
1962
+ }
1963
+
1964
+ const body = parts.slice(2).join('---').trim();
1965
+ const lines = body.split('\n').slice(0, 22);
1966
+ console.log(`${BOLD}📋 Playbook Preview:${RESET}`);
1967
+ console.log(lines.join('\n'));
1968
+ if (body.split('\n').length > 22) {
1969
+ console.log(`\n${GRAY}... (${body.split('\n').length - 22} more lines in ${skillMd})${RESET}`);
1970
+ }
1971
+ } else {
1972
+ console.log(content.split('\n').slice(0, 25).join('\n'));
1973
+ }
1974
+ console.log('');
1975
+ return;
1976
+ }
1977
+
1978
+ console.error(`\n${RED}Error: Component '${cleanName}' not found in catalog (checked skills, agents, and hooks).${RESET}\n`);
1979
+ process.exit(1);
1980
+ }
1981
+
656
1982
  // CLI Argument Parsing
657
1983
  const args = process.argv.slice(2);
658
1984
  const command = args[0] || 'help';
@@ -670,31 +1996,169 @@ switch (command) {
670
1996
  case 'new-agent':
671
1997
  scaffoldAgent(args[1]);
672
1998
  break;
673
- case 'add':
674
- addComponent(args[1], args[2]);
1999
+ case 'add': {
2000
+ let customTarget = null;
2001
+ let isGlobal = false;
2002
+ for (let i = 3; i < args.length; i++) {
2003
+ if (args[i] === '--global') isGlobal = true;
2004
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2005
+ }
2006
+ addComponent(args[1], args[2], isGlobal, customTarget);
675
2007
  break;
676
- case 'remove':
677
- removeComponent(args[1], args[2]);
2008
+ }
2009
+ case 'remove': {
2010
+ let customTarget = null;
2011
+ let isGlobal = false;
2012
+ for (let i = 3; i < args.length; i++) {
2013
+ if (args[i] === '--global') isGlobal = true;
2014
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2015
+ }
2016
+ removeComponent(args[1], args[2], isGlobal, customTarget);
678
2017
  break;
2018
+ }
679
2019
  case 'test-skill':
680
2020
  testSkill(args[1]);
681
2021
  break;
2022
+ case 'test-all':
2023
+ case 'test-skills':
2024
+ case 'benchmark': {
2025
+ const asJson = args.includes('--json');
2026
+ testAllSkills(asJson);
2027
+ break;
2028
+ }
2029
+ case 'completion': {
2030
+ const installMode = args.includes('--install') || args.includes('-i');
2031
+ const isDryRun = args.includes('--dry-run');
2032
+ let customRc = null;
2033
+ for (let i = 1; i < args.length; i++) {
2034
+ if (args[i] === '--rc' && args[i + 1]) customRc = args[++i];
2035
+ }
2036
+ printCompletion(installMode, isDryRun, customRc);
2037
+ break;
2038
+ }
2039
+ case 'info':
2040
+ case 'show':
2041
+ showComponentInfo(args[1], args[2]);
2042
+ break;
2043
+ case 'status':
2044
+ case 'check': {
2045
+ let isGlobal = false;
2046
+ let customTarget = null;
2047
+ let asJson = false;
2048
+ for (let i = 1; i < args.length; i++) {
2049
+ if (args[i] === '--global') isGlobal = true;
2050
+ else if (args[i] === '--json') asJson = true;
2051
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2052
+ }
2053
+ runStatus(isGlobal, customTarget, asJson);
2054
+ break;
2055
+ }
2056
+ case 'diff': {
2057
+ let isGlobal = false;
2058
+ let customTarget = null;
2059
+ for (let i = 1; i < args.length; i++) {
2060
+ if (args[i] === '--global') isGlobal = true;
2061
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2062
+ }
2063
+ runDiff(isGlobal, customTarget);
2064
+ break;
2065
+ }
2066
+ case 'export': {
2067
+ let isGlobal = false;
2068
+ let customTarget = null;
2069
+ let outputPath = null;
2070
+ for (let i = 1; i < args.length; i++) {
2071
+ if (args[i] === '--global') isGlobal = true;
2072
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2073
+ else if ((args[i] === '--output' || args[i] === '-o') && args[i + 1]) outputPath = args[++i];
2074
+ }
2075
+ runExport(isGlobal, customTarget, outputPath);
2076
+ break;
2077
+ }
2078
+ case 'import': {
2079
+ const inputFile = args[1] && !args[1].startsWith('-') ? args[1] : null;
2080
+ let isGlobal = false;
2081
+ let customTarget = null;
2082
+ let isDryRun = false;
2083
+ for (let i = 1; i < args.length; i++) {
2084
+ if (args[i] === '--global') isGlobal = true;
2085
+ else if (args[i] === '--dry-run') isDryRun = true;
2086
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2087
+ }
2088
+ runImport(inputFile, isGlobal, customTarget, isDryRun);
2089
+ break;
2090
+ }
2091
+ case 'bundle':
2092
+ case 'pack': {
2093
+ let profile = 'all';
2094
+ let outputDir = null;
2095
+ let isDryRun = false;
2096
+ let asJson = false;
2097
+ for (let i = 1; i < args.length; i++) {
2098
+ if (args[i] === '--profile' && args[i + 1]) profile = args[++i];
2099
+ else if ((args[i] === '--output' || args[i] === '-o') && args[i + 1]) outputDir = args[++i];
2100
+ else if (args[i] === '--dry-run') isDryRun = true;
2101
+ else if (args[i] === '--json') asJson = true;
2102
+ else if (!args[i].startsWith('-') && !outputDir) outputDir = args[i];
2103
+ }
2104
+ runBundle(profile, outputDir, isDryRun, asJson);
2105
+ break;
2106
+ }
2107
+ case 'update': {
2108
+ let isGlobal = false;
2109
+ let customTarget = null;
2110
+ let isDryRun = false;
2111
+ for (let i = 1; i < args.length; i++) {
2112
+ if (args[i] === '--global') isGlobal = true;
2113
+ else if (args[i] === '--dry-run') isDryRun = true;
2114
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2115
+ }
2116
+ runUpdate(isGlobal, customTarget, isDryRun);
2117
+ break;
2118
+ }
682
2119
  case 'init':
683
2120
  case 'install': {
684
2121
  let profile = 'developer';
685
2122
  let isGlobal = false;
686
2123
  let customTarget = null;
2124
+ let isDryRun = false;
687
2125
  for (let i = 1; i < args.length; i++) {
688
2126
  if (args[i] === '--profile' && args[i + 1]) profile = args[++i];
689
2127
  else if (args[i] === '--global') isGlobal = true;
2128
+ else if (args[i] === '--dry-run') isDryRun = true;
690
2129
  else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
691
2130
  }
692
- installProfile(profile, isGlobal, customTarget);
2131
+ installProfile(profile, isGlobal, customTarget, isDryRun);
693
2132
  break;
694
2133
  }
695
2134
  case 'validate':
696
2135
  runValidate();
697
2136
  break;
2137
+ case 'search':
2138
+ case 'find': {
2139
+ const asJson = args.includes('--json');
2140
+ const queryTerms = args.slice(1).filter(a => !a.startsWith('-')).join(' ');
2141
+ searchComponents(queryTerms, asJson);
2142
+ break;
2143
+ }
2144
+ case 'audit': {
2145
+ let isGlobal = false;
2146
+ let customTarget = null;
2147
+ let asJson = false;
2148
+ for (let i = 1; i < args.length; i++) {
2149
+ if (args[i] === '--global') isGlobal = true;
2150
+ else if (args[i] === '--json') asJson = true;
2151
+ else if (args[i] === '--workspace' && args[i + 1]) customTarget = args[++i];
2152
+ else if (!args[i].startsWith('-') && !customTarget) customTarget = args[i];
2153
+ }
2154
+ runAudit(customTarget, isGlobal, asJson);
2155
+ break;
2156
+ }
2157
+ case 'version':
2158
+ case '--version':
2159
+ case '-v':
2160
+ console.log(VERSION);
2161
+ break;
698
2162
  case 'help':
699
2163
  case '--help':
700
2164
  case '-h':