contextos-agents 2.1.0 → 2.2.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 (192) hide show
  1. package/.agents/adapters/aider/export.js +2 -2
  2. package/.agents/adapters/claude/export.js +53 -2
  3. package/.agents/adapters/drift-detector.js +6 -3
  4. package/.agents/adapters/pure-compiler.js +18 -6
  5. package/.agents/ctx.js +13 -8
  6. package/.agents/plugins.js +347 -26
  7. package/.agents/profiles.js +32 -11
  8. package/README.md +38 -3
  9. package/bin/commands/hook.js +50 -12
  10. package/bin/commands/scan.js +10 -3
  11. package/bin/index.js +165 -53
  12. package/bin/lib/git-snapshot.js +70 -43
  13. package/bin/lib/scan.js +108 -27
  14. package/bin/lib/ui.js +140 -0
  15. package/catalog/skills/adapters/EXAMPLES.md +19 -0
  16. package/catalog/skills/adapters/SKILL.md +101 -0
  17. package/catalog/skills/adapters/TROUBLESHOOTING.md +7 -0
  18. package/catalog/skills/adapters/VALIDATION.json +12 -0
  19. package/catalog/skills/adapters/skill.yaml +13 -0
  20. package/catalog/skills/api-design/EXAMPLES.md +91 -0
  21. package/catalog/skills/api-design/SKILL.md +63 -0
  22. package/catalog/skills/api-design/TROUBLESHOOTING.md +54 -0
  23. package/catalog/skills/api-design/VALIDATION.json +11 -0
  24. package/catalog/skills/api-design/skill.yaml +14 -0
  25. package/catalog/skills/architecture-diagrams/SKILL.md +108 -0
  26. package/catalog/skills/architecture-diagrams/VALIDATION.json +12 -0
  27. package/catalog/skills/architecture-diagrams/skill.yaml +9 -0
  28. package/catalog/skills/brutalist-design/EXAMPLES.md +59 -0
  29. package/catalog/skills/brutalist-design/SKILL.md +150 -0
  30. package/catalog/skills/brutalist-design/VALIDATION.json +12 -0
  31. package/catalog/skills/brutalist-design/skill.yaml +10 -0
  32. package/catalog/skills/ci-cd/EXAMPLES.md +79 -0
  33. package/catalog/skills/ci-cd/SKILL.md +69 -0
  34. package/catalog/skills/ci-cd/TROUBLESHOOTING.md +52 -0
  35. package/catalog/skills/ci-cd/VALIDATION.json +11 -0
  36. package/catalog/skills/ci-cd/skill.yaml +13 -0
  37. package/catalog/skills/database/EXAMPLES.md +74 -0
  38. package/catalog/skills/database/SKILL.md +101 -0
  39. package/catalog/skills/database/TROUBLESHOOTING.md +18 -0
  40. package/catalog/skills/database/VALIDATION.json +11 -0
  41. package/catalog/skills/database/skill.yaml +14 -0
  42. package/catalog/skills/ddd/EXAMPLES.md +42 -0
  43. package/catalog/skills/ddd/SKILL.md +247 -0
  44. package/catalog/skills/ddd/TROUBLESHOOTING.md +19 -0
  45. package/catalog/skills/ddd/VALIDATION.json +12 -0
  46. package/catalog/skills/ddd/skill.yaml +14 -0
  47. package/catalog/skills/decisions/EXAMPLES.md +35 -0
  48. package/catalog/skills/decisions/SKILL.md +90 -0
  49. package/catalog/skills/decisions/TROUBLESHOOTING.md +13 -0
  50. package/catalog/skills/decisions/VALIDATION.json +12 -0
  51. package/catalog/skills/decisions/skill.yaml +13 -0
  52. package/catalog/skills/docker/EXAMPLES.md +56 -0
  53. package/catalog/skills/docker/SKILL.md +169 -0
  54. package/catalog/skills/docker/TROUBLESHOOTING.md +18 -0
  55. package/catalog/skills/docker/VALIDATION.json +11 -0
  56. package/catalog/skills/docker/skill.yaml +13 -0
  57. package/catalog/skills/fastapi/EXAMPLES.md +36 -0
  58. package/catalog/skills/fastapi/SKILL.md +171 -0
  59. package/catalog/skills/fastapi/TROUBLESHOOTING.md +19 -0
  60. package/catalog/skills/fastapi/VALIDATION.json +12 -0
  61. package/catalog/skills/fastapi/skill.yaml +14 -0
  62. package/catalog/skills/generators/EXAMPLES.md +19 -0
  63. package/catalog/skills/generators/SKILL.md +110 -0
  64. package/catalog/skills/generators/TROUBLESHOOTING.md +7 -0
  65. package/catalog/skills/generators/VALIDATION.json +12 -0
  66. package/catalog/skills/generators/skill.yaml +22 -0
  67. package/catalog/skills/generators/templates/API.md +77 -0
  68. package/catalog/skills/generators/templates/ARCHITECTURE.md +70 -0
  69. package/catalog/skills/generators/templates/DATABASE.md +42 -0
  70. package/catalog/skills/generators/templates/DECISION.md +46 -0
  71. package/catalog/skills/generators/templates/PRD.md +67 -0
  72. package/catalog/skills/generators/templates/PROJECT_GRAPH.md +56 -0
  73. package/catalog/skills/generators/templates/ROADMAP.md +51 -0
  74. package/catalog/skills/generators/templates/TASKS.md +43 -0
  75. package/catalog/skills/generators/templates/UI.md +73 -0
  76. package/catalog/skills/graphify/EXAMPLES.md +73 -0
  77. package/catalog/skills/graphify/SKILL.md +130 -0
  78. package/catalog/skills/graphify/VALIDATION.json +12 -0
  79. package/catalog/skills/graphify/skill.yaml +13 -0
  80. package/catalog/skills/impeccable-design/EXAMPLES.md +26 -0
  81. package/catalog/skills/impeccable-design/SKILL.md +201 -0
  82. package/catalog/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
  83. package/catalog/skills/impeccable-design/VALIDATION.json +12 -0
  84. package/catalog/skills/impeccable-design/skill.yaml +15 -0
  85. package/catalog/skills/interview-me/SKILL.md +97 -0
  86. package/catalog/skills/interview-me/VALIDATION.json +12 -0
  87. package/catalog/skills/interview-me/skill.yaml +9 -0
  88. package/catalog/skills/microservices/EXAMPLES.md +38 -0
  89. package/catalog/skills/microservices/SKILL.md +164 -0
  90. package/catalog/skills/microservices/TROUBLESHOOTING.md +19 -0
  91. package/catalog/skills/microservices/VALIDATION.json +12 -0
  92. package/catalog/skills/microservices/skill.yaml +14 -0
  93. package/catalog/skills/minimalist-design/EXAMPLES.md +58 -0
  94. package/catalog/skills/minimalist-design/SKILL.md +113 -0
  95. package/catalog/skills/minimalist-design/VALIDATION.json +12 -0
  96. package/catalog/skills/minimalist-design/skill.yaml +10 -0
  97. package/catalog/skills/nestjs/EXAMPLES.md +40 -0
  98. package/catalog/skills/nestjs/SKILL.md +139 -0
  99. package/catalog/skills/nestjs/TROUBLESHOOTING.md +19 -0
  100. package/catalog/skills/nestjs/VALIDATION.json +12 -0
  101. package/catalog/skills/nestjs/skill.yaml +14 -0
  102. package/catalog/skills/nextjs/EXAMPLES.md +40 -0
  103. package/catalog/skills/nextjs/SKILL.md +163 -0
  104. package/catalog/skills/nextjs/TROUBLESHOOTING.md +19 -0
  105. package/catalog/skills/nextjs/VALIDATION.json +12 -0
  106. package/catalog/skills/nextjs/skill.yaml +14 -0
  107. package/catalog/skills/node/EXAMPLES.md +80 -0
  108. package/catalog/skills/node/SKILL.md +128 -0
  109. package/catalog/skills/node/TROUBLESHOOTING.md +19 -0
  110. package/catalog/skills/node/VALIDATION.json +12 -0
  111. package/catalog/skills/node/skill.yaml +14 -0
  112. package/catalog/skills/performance/EXAMPLES.md +30 -0
  113. package/catalog/skills/performance/SKILL.md +75 -0
  114. package/catalog/skills/performance/TROUBLESHOOTING.md +19 -0
  115. package/catalog/skills/performance/VALIDATION.json +12 -0
  116. package/catalog/skills/performance/skill.yaml +14 -0
  117. package/catalog/skills/react/EXAMPLES.md +79 -0
  118. package/catalog/skills/react/SKILL.md +132 -0
  119. package/catalog/skills/react/TROUBLESHOOTING.md +19 -0
  120. package/catalog/skills/react/VALIDATION.json +12 -0
  121. package/catalog/skills/react/skill.yaml +14 -0
  122. package/catalog/skills/react-best-practices/SKILL.md +158 -0
  123. package/catalog/skills/react-best-practices/VALIDATION.json +12 -0
  124. package/catalog/skills/react-best-practices/skill.yaml +13 -0
  125. package/catalog/skills/redesign-audit/SKILL.md +117 -0
  126. package/catalog/skills/redesign-audit/VALIDATION.json +12 -0
  127. package/catalog/skills/redesign-audit/skill.yaml +9 -0
  128. package/catalog/skills/security-audit/EXAMPLES.md +79 -0
  129. package/catalog/skills/security-audit/SKILL.md +91 -0
  130. package/catalog/skills/security-audit/TROUBLESHOOTING.md +46 -0
  131. package/catalog/skills/security-audit/VALIDATION.json +11 -0
  132. package/catalog/skills/security-audit/skill.yaml +14 -0
  133. package/catalog/skills/soft-design/EXAMPLES.md +51 -0
  134. package/catalog/skills/soft-design/SKILL.md +108 -0
  135. package/catalog/skills/soft-design/VALIDATION.json +12 -0
  136. package/catalog/skills/soft-design/skill.yaml +10 -0
  137. package/catalog/skills/state-management/EXAMPLES.md +56 -0
  138. package/catalog/skills/state-management/SKILL.md +168 -0
  139. package/catalog/skills/state-management/TROUBLESHOOTING.md +18 -0
  140. package/catalog/skills/state-management/VALIDATION.json +11 -0
  141. package/catalog/skills/state-management/skill.yaml +14 -0
  142. package/catalog/skills/subagent-orchestrator/SKILL.md +117 -0
  143. package/catalog/skills/subagent-orchestrator/VALIDATION.json +12 -0
  144. package/catalog/skills/subagent-orchestrator/skill.yaml +9 -0
  145. package/catalog/skills/system-design/EXAMPLES.md +75 -0
  146. package/catalog/skills/system-design/SKILL.md +419 -0
  147. package/catalog/skills/system-design/TROUBLESHOOTING.md +19 -0
  148. package/catalog/skills/system-design/VALIDATION.json +12 -0
  149. package/catalog/skills/system-design/skill.yaml +14 -0
  150. package/catalog/skills/terraform/EXAMPLES.md +74 -0
  151. package/catalog/skills/terraform/SKILL.md +55 -0
  152. package/catalog/skills/terraform/TROUBLESHOOTING.md +53 -0
  153. package/catalog/skills/terraform/VALIDATION.json +11 -0
  154. package/catalog/skills/terraform/skill.yaml +14 -0
  155. package/catalog/skills/testing/EXAMPLES.md +122 -0
  156. package/catalog/skills/testing/SKILL.md +70 -0
  157. package/catalog/skills/testing/TROUBLESHOOTING.md +18 -0
  158. package/catalog/skills/testing/VALIDATION.json +11 -0
  159. package/catalog/skills/testing/skill.yaml +14 -0
  160. package/catalog/skills/typescript/EXAMPLES.md +64 -0
  161. package/catalog/skills/typescript/SKILL.md +112 -0
  162. package/catalog/skills/typescript/TROUBLESHOOTING.md +19 -0
  163. package/catalog/skills/typescript/VALIDATION.json +12 -0
  164. package/catalog/skills/typescript/skill.yaml +14 -0
  165. package/catalog/skills/ui-design/EXAMPLES.md +21 -0
  166. package/catalog/skills/ui-design/SKILL.md +124 -0
  167. package/catalog/skills/ui-design/TROUBLESHOOTING.md +19 -0
  168. package/catalog/skills/ui-design/VALIDATION.json +12 -0
  169. package/catalog/skills/ui-design/skill.yaml +16 -0
  170. package/catalog/skills/ui-ux-pro/EXAMPLES.md +62 -0
  171. package/catalog/skills/ui-ux-pro/SKILL.md +418 -0
  172. package/catalog/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
  173. package/catalog/skills/ui-ux-pro/VALIDATION.json +12 -0
  174. package/catalog/skills/ui-ux-pro/skill.yaml +14 -0
  175. package/catalog/skills/ux-design/EXAMPLES.md +36 -0
  176. package/catalog/skills/ux-design/SKILL.md +116 -0
  177. package/catalog/skills/ux-design/TROUBLESHOOTING.md +19 -0
  178. package/catalog/skills/ux-design/VALIDATION.json +12 -0
  179. package/catalog/skills/ux-design/skill.yaml +16 -0
  180. package/catalog/skills/vercel-optimize/SKILL.md +83 -0
  181. package/catalog/skills/vercel-optimize/VALIDATION.json +12 -0
  182. package/catalog/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
  183. package/catalog/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
  184. package/catalog/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
  185. package/catalog/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
  186. package/catalog/skills/vercel-optimize/skill.yaml +15 -0
  187. package/catalog/skills/web-accessibility/EXAMPLES.md +39 -0
  188. package/catalog/skills/web-accessibility/SKILL.md +151 -0
  189. package/catalog/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
  190. package/catalog/skills/web-accessibility/VALIDATION.json +12 -0
  191. package/catalog/skills/web-accessibility/skill.yaml +14 -0
  192. package/package.json +3 -2
@@ -90,8 +90,8 @@ function render(context) {
90
90
  }
91
91
 
92
92
  aiderConfContent = yamlProv + '\n' + YAML.stringify(parsed);
93
- } catch {
94
- aiderConfContent = yamlProv + '\nread:\n - CONVENTIONS.md\n';
93
+ } catch (err) {
94
+ throw new Error(`Failed to parse existing .aider.conf.yml: ${err.message}. Aborting to protect existing configuration from data loss.`);
95
95
  }
96
96
  } else {
97
97
  aiderConfContent = [
@@ -9,13 +9,15 @@ const { collectSkillDirectories, readMeaningfulMarkdown } = require('../shared.j
9
9
  const { registerAdapter, applyArtifacts } = require('../pure-compiler.js');
10
10
 
11
11
  const GENERATOR_ID = 'claude@2';
12
+ const CLAUDE_START_MARKER = '<!-- CONTEXTOS:START -->';
13
+ const CLAUDE_END_MARKER = '<!-- CONTEXTOS:END -->';
12
14
 
13
15
  function describe() {
14
16
  return {
15
17
  name: 'claude',
16
18
  version: '2.0.0',
17
- description: 'Compiles clean markdown skills for Claude Code CLI',
18
- targetPattern: '.agents/generated/claude/skills/**/SKILL.md',
19
+ description: 'Compiles clean markdown skills for Claude Code CLI and manages CLAUDE.md entrypoint',
20
+ targetPattern: '{CLAUDE.md,.agents/generated/claude/skills/**/SKILL.md}',
19
21
  };
20
22
  }
21
23
 
@@ -53,6 +55,50 @@ function renderClaudeSkill(skillDir, context) {
53
55
  };
54
56
  }
55
57
 
58
+ function renderClaudeRootIndex(skills, context) {
59
+ const projectRoot = context?.projectRoot || '.';
60
+ const claudePath = path.join(projectRoot, 'CLAUDE.md');
61
+ let existingContent = '';
62
+ if (fs.existsSync(claudePath)) {
63
+ try {
64
+ existingContent = fs.readFileSync(claudePath, 'utf8');
65
+ } catch {}
66
+ }
67
+
68
+ const skillEntries = skills.map(skillDir => {
69
+ const name = path.basename(skillDir);
70
+ return `- [${name}](.agents/generated/claude/skills/${name}/SKILL.md)`;
71
+ }).join('\n');
72
+
73
+ const managedBlock = `${CLAUDE_START_MARKER}
74
+ <!-- Do not edit this section directly. Synchronized by ContextOS. -->
75
+ # ContextOS Agent Governance
76
+
77
+ The following skills are managed by ContextOS:
78
+ ${skillEntries}
79
+ ${CLAUDE_END_MARKER}`;
80
+
81
+ let finalContent;
82
+ if (existingContent.includes(CLAUDE_START_MARKER)) {
83
+ const regex = new RegExp(`${CLAUDE_START_MARKER}[\\s\\S]*?${CLAUDE_END_MARKER}`);
84
+ finalContent = existingContent.replace(regex, managedBlock);
85
+ } else if (existingContent.trim()) {
86
+ finalContent = `${existingContent.trimEnd()}\n\n${managedBlock}\n`;
87
+ } else {
88
+ finalContent = `${managedBlock}\n`;
89
+ }
90
+
91
+ return {
92
+ path: 'CLAUDE.md',
93
+ content: finalContent.replace(/\r\n/g, '\n'),
94
+ mediaType: 'text/markdown',
95
+ kind: 'generated-adapter',
96
+ generator: GENERATOR_ID,
97
+ sourceSkillIds: skills.map(s => path.basename(s)),
98
+ inputsHash: context?.sourceGraphHash || 'none',
99
+ };
100
+ }
101
+
56
102
  function render(context) {
57
103
  const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
58
104
  const artifacts = [];
@@ -62,6 +108,11 @@ function render(context) {
62
108
  if (art) artifacts.push(art);
63
109
  }
64
110
 
111
+ if (skills.length > 0) {
112
+ const rootIndex = renderClaudeRootIndex(skills, context);
113
+ if (rootIndex) artifacts.push(rootIndex);
114
+ }
115
+
65
116
  return artifacts;
66
117
  }
67
118
 
@@ -170,10 +170,13 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
170
170
  } else {
171
171
  const diskContent = fs.readFileSync(fullPath, 'utf8');
172
172
  const diskSemanticHash = computeSemanticHash(diskContent);
173
+ const lockRecord = lockfile?.managedFiles?.[art.path];
173
174
 
174
- // Check if disk matches projected render
175
- if (diskSemanticHash !== projectedSemanticHash) {
176
- const lockRecord = lockfile?.managedFiles?.[art.path];
175
+ // Check if disk matches projected render and recorded lockfile
176
+ const matchesProjection = diskSemanticHash === projectedSemanticHash;
177
+ const matchesLock = lockRecord ? diskSemanticHash === lockRecord.semanticTextSha256 : matchesProjection;
178
+
179
+ if (!matchesProjection || !matchesLock) {
177
180
  if (lockRecord && lockRecord.semanticTextSha256 !== diskSemanticHash) {
178
181
  findings[DRIFT_STATES.MODIFIED_MANAGED_OUTPUT].push({
179
182
  path: art.path,
@@ -86,11 +86,22 @@ function loadCompilerContext(projectRoot, options = {}) {
86
86
 
87
87
  // 2. Profile v2
88
88
  let profile = null;
89
- try {
90
- const profiles = require('../profiles.js');
91
- profile = options.profile ? profiles.getProfile(options.profile, absRoot) : profiles.getActiveProfile(absRoot);
92
- } catch {
93
- profile = null;
89
+ const profiles = require('../profiles.js');
90
+ if (options.profile) {
91
+ try {
92
+ profile = profiles.getProfile(options.profile, absRoot);
93
+ } catch (err) {
94
+ throw new Error(`Failed to load profile '${options.profile}': ${err.message}`);
95
+ }
96
+ if (!profile) {
97
+ throw new Error(`Profile '${options.profile}' was specified but does not exist.`);
98
+ }
99
+ } else {
100
+ try {
101
+ profile = profiles.getActiveProfile(absRoot);
102
+ } catch {
103
+ profile = null;
104
+ }
94
105
  }
95
106
 
96
107
  // 3. Workspace Graph
@@ -172,9 +183,10 @@ function listAdapters() {
172
183
  */
173
184
  function renderAdapters(projectRoot, adapterNames = 'all', options = {}) {
174
185
  const context = loadCompilerContext(projectRoot, options);
175
- const targets = adapterNames === 'all'
186
+ const rawTargets = adapterNames === 'all'
176
187
  ? listAdapters()
177
188
  : (Array.isArray(adapterNames) ? adapterNames : [adapterNames]);
189
+ const targets = rawTargets.flatMap(a => (typeof a === 'string' && a.includes(',') ? a.split(',').map(s => s.trim()).filter(Boolean) : a));
178
190
 
179
191
  const allArtifacts = [];
180
192
  const pathToArtifact = new Map();
package/.agents/ctx.js CHANGED
@@ -55,10 +55,13 @@ function printHelp() {
55
55
  console.log(' watch Start continuous file watcher and auto-sync daemon');
56
56
  console.log(' init Show initialization guide');
57
57
  console.log(' install-skill <ref> Alias for skill add (install a plugin)');
58
- console.log(' skill add <ref> Install a plugin skill (GitHub or npm)');
58
+ console.log(' skill add <ref|--all> Install a plugin skill or all catalog skills (--all)');
59
59
  console.log(' skill remove <name> Uninstall a plugin skill');
60
- console.log(' skill list List installed skills (builtin + plugins)');
60
+ console.log(' skill list [--available] List installed skills (and available catalog skills)');
61
61
  console.log(' skill search [query] Search the community skill registry');
62
+ console.log(' skill override <name> Create editable project copy of an upstream skill');
63
+ console.log(' skill diff <name> Show differences between local override and upstream');
64
+ console.log(' skill eject <name> Eject upstream skill to standalone project skill');
62
65
  console.log('');
63
66
  console.log('Plugin ref formats:');
64
67
  console.log(' username/repo GitHub repo root SKILL.md');
@@ -253,8 +256,8 @@ if (command === 'export') {
253
256
  : (args.find(a => a.startsWith('--scope=')) || '').split('=')[1] || null;
254
257
 
255
258
  if (subcommand === 'list') {
256
- const list = profiles.listProfiles();
257
- const active = profiles.getActiveProfile();
259
+ const list = profiles.listProfiles(process.cwd());
260
+ const active = profiles.getActiveProfile(process.cwd());
258
261
  if (asJson) {
259
262
  console.log(JSON.stringify({ active, profiles: list }, null, 2));
260
263
  } else {
@@ -285,7 +288,7 @@ if (command === 'export') {
285
288
  console.error('[ERROR] Usage: node ctx.js profile show <name> [--json]');
286
289
  process.exit(1);
287
290
  }
288
- const profile = profiles.getProfile(name);
291
+ const profile = profiles.getProfile(name, process.cwd());
289
292
  if (!profile) {
290
293
  console.error(`[ERROR] Profile '${name}' not found.`);
291
294
  process.exit(1);
@@ -306,7 +309,7 @@ if (command === 'export') {
306
309
  process.exit(1);
307
310
  }
308
311
  try {
309
- const explanation = profiles.explainProfile(name);
312
+ const explanation = profiles.explainProfile(name, process.cwd());
310
313
  if (asJson) {
311
314
  console.log(JSON.stringify(explanation, null, 2));
312
315
  } else {
@@ -634,15 +637,17 @@ if (command === 'export') {
634
637
  }
635
638
 
636
639
  if (subcommand === 'add') {
640
+ const isAll = args.includes('--all') || ref === '--all' || ref === 'all';
637
641
  const forceUnsafe = args.includes('--force-unsafe-prompts') || args.includes('--force-unsafe');
638
- plugins.add(ref, { dryRun, checksum, forceUnsafe }).catch(err => {
642
+ plugins.add(isAll ? '--all' : ref, { dryRun, checksum, forceUnsafe, all: isAll }).catch(err => {
639
643
  console.error(`[ERROR] ${err.message}`);
640
644
  process.exit(1);
641
645
  });
642
646
  } else if (subcommand === 'remove') {
643
647
  plugins.remove(ref);
644
648
  } else if (subcommand === 'list') {
645
- plugins.list();
649
+ const available = args.includes('--available') || args.includes('-a') || args.includes('--all');
650
+ plugins.list({ available });
646
651
  } else if (subcommand === 'search') {
647
652
  const query = args.slice(2).join(' ');
648
653
  plugins.search(query).catch(err => {