cognitive-modules-cli 2.2.1 → 2.2.5

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 (95) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +35 -29
  4. package/dist/cli.js +513 -22
  5. package/dist/commands/add.d.ts +33 -14
  6. package/dist/commands/add.js +222 -13
  7. package/dist/commands/compose.js +60 -23
  8. package/dist/commands/index.d.ts +4 -0
  9. package/dist/commands/index.js +4 -0
  10. package/dist/commands/init.js +23 -1
  11. package/dist/commands/migrate.d.ts +30 -0
  12. package/dist/commands/migrate.js +650 -0
  13. package/dist/commands/pipe.d.ts +1 -0
  14. package/dist/commands/pipe.js +31 -11
  15. package/dist/commands/remove.js +33 -2
  16. package/dist/commands/run.d.ts +1 -0
  17. package/dist/commands/run.js +37 -27
  18. package/dist/commands/search.d.ts +28 -0
  19. package/dist/commands/search.js +143 -0
  20. package/dist/commands/test.d.ts +65 -0
  21. package/dist/commands/test.js +454 -0
  22. package/dist/commands/update.d.ts +1 -0
  23. package/dist/commands/update.js +106 -14
  24. package/dist/commands/validate.d.ts +36 -0
  25. package/dist/commands/validate.js +97 -0
  26. package/dist/errors/index.d.ts +218 -0
  27. package/dist/errors/index.js +412 -0
  28. package/dist/mcp/server.js +84 -79
  29. package/dist/modules/composition.js +97 -32
  30. package/dist/modules/loader.js +4 -2
  31. package/dist/modules/runner.d.ts +65 -0
  32. package/dist/modules/runner.js +293 -49
  33. package/dist/modules/subagent.d.ts +6 -1
  34. package/dist/modules/subagent.js +18 -13
  35. package/dist/modules/validator.js +14 -6
  36. package/dist/providers/anthropic.d.ts +15 -0
  37. package/dist/providers/anthropic.js +147 -5
  38. package/dist/providers/base.d.ts +11 -0
  39. package/dist/providers/base.js +18 -0
  40. package/dist/providers/gemini.d.ts +15 -0
  41. package/dist/providers/gemini.js +122 -5
  42. package/dist/providers/ollama.d.ts +15 -0
  43. package/dist/providers/ollama.js +111 -3
  44. package/dist/providers/openai.d.ts +11 -0
  45. package/dist/providers/openai.js +133 -0
  46. package/dist/registry/client.d.ts +204 -0
  47. package/dist/registry/client.js +356 -0
  48. package/dist/registry/index.d.ts +4 -0
  49. package/dist/registry/index.js +4 -0
  50. package/dist/server/http.js +173 -42
  51. package/dist/types.d.ts +32 -1
  52. package/dist/types.js +4 -1
  53. package/dist/version.d.ts +1 -0
  54. package/dist/version.js +4 -0
  55. package/package.json +31 -7
  56. package/dist/modules/composition.test.d.ts +0 -11
  57. package/dist/modules/composition.test.js +0 -450
  58. package/dist/modules/policy.test.d.ts +0 -10
  59. package/dist/modules/policy.test.js +0 -369
  60. package/src/cli.ts +0 -471
  61. package/src/commands/add.ts +0 -315
  62. package/src/commands/compose.ts +0 -185
  63. package/src/commands/index.ts +0 -13
  64. package/src/commands/init.ts +0 -94
  65. package/src/commands/list.ts +0 -33
  66. package/src/commands/pipe.ts +0 -76
  67. package/src/commands/remove.ts +0 -57
  68. package/src/commands/run.ts +0 -80
  69. package/src/commands/update.ts +0 -130
  70. package/src/commands/versions.ts +0 -79
  71. package/src/index.ts +0 -90
  72. package/src/mcp/index.ts +0 -5
  73. package/src/mcp/server.ts +0 -403
  74. package/src/modules/composition.test.ts +0 -558
  75. package/src/modules/composition.ts +0 -1674
  76. package/src/modules/index.ts +0 -9
  77. package/src/modules/loader.ts +0 -508
  78. package/src/modules/policy.test.ts +0 -455
  79. package/src/modules/runner.ts +0 -1983
  80. package/src/modules/subagent.ts +0 -277
  81. package/src/modules/validator.ts +0 -700
  82. package/src/providers/anthropic.ts +0 -89
  83. package/src/providers/base.ts +0 -29
  84. package/src/providers/deepseek.ts +0 -83
  85. package/src/providers/gemini.ts +0 -117
  86. package/src/providers/index.ts +0 -78
  87. package/src/providers/minimax.ts +0 -81
  88. package/src/providers/moonshot.ts +0 -82
  89. package/src/providers/ollama.ts +0 -83
  90. package/src/providers/openai.ts +0 -84
  91. package/src/providers/qwen.ts +0 -82
  92. package/src/server/http.ts +0 -316
  93. package/src/server/index.ts +0 -6
  94. package/src/types.ts +0 -599
  95. package/tsconfig.json +0 -17
package/dist/cli.js CHANGED
@@ -15,8 +15,9 @@
15
15
  */
16
16
  import { parseArgs } from 'node:util';
17
17
  import { getProvider, listProviders } from './providers/index.js';
18
- import { run, list, pipe, init, add, update, remove, versions, compose, composeInfo } from './commands/index.js';
19
- const VERSION = '1.3.0';
18
+ import { run, list, pipe, init, add, update, remove, versions, compose, composeInfo, validate, validateAll, migrate, migrateAll, test, testAll, search, listCategories, info } from './commands/index.js';
19
+ import { listModules, getDefaultSearchPaths } from './modules/loader.js';
20
+ import { VERSION } from './version.js';
20
21
  async function main() {
21
22
  const args = process.argv.slice(2);
22
23
  const command = args[0];
@@ -29,7 +30,7 @@ async function main() {
29
30
  process.exit(0);
30
31
  }
31
32
  // Parse common options
32
- const { values } = parseArgs({
33
+ const { values, positionals } = parseArgs({
33
34
  args: args.slice(1),
34
35
  options: {
35
36
  args: { type: 'string', short: 'a' },
@@ -52,6 +53,14 @@ async function main() {
52
53
  'max-depth': { type: 'string', short: 'd' },
53
54
  timeout: { type: 'string', short: 'T' },
54
55
  trace: { type: 'boolean', default: false },
56
+ // Validate/migrate options
57
+ v22: { type: 'boolean', default: false },
58
+ 'dry-run': { type: 'boolean', default: false },
59
+ 'no-backup': { type: 'boolean', default: false },
60
+ all: { type: 'boolean', default: false },
61
+ format: { type: 'string', short: 'f' },
62
+ // Search options
63
+ category: { type: 'string', short: 'c' },
55
64
  },
56
65
  allowPositionals: true,
57
66
  });
@@ -85,7 +94,12 @@ async function main() {
85
94
  verbose: values.verbose,
86
95
  });
87
96
  if (!result.success) {
88
- console.error(`Error: ${result.error}`);
97
+ if (result.data) {
98
+ console.log(JSON.stringify(result.data, null, values.pretty ? 2 : 0));
99
+ }
100
+ else {
101
+ console.error(`Error: ${result.error}`);
102
+ }
89
103
  process.exit(1);
90
104
  }
91
105
  console.log(JSON.stringify(result.data, null, values.pretty ? 2 : 0));
@@ -144,33 +158,137 @@ async function main() {
144
158
  break;
145
159
  }
146
160
  case 'doctor': {
147
- console.log('Cognitive Runtime - Environment Check\n');
148
- console.log('Providers:');
149
- for (const p of listProviders()) {
150
- const status = p.configured ? '✓ configured' : '– not configured';
151
- console.log(` ${p.name}: ${status} (${p.model})`);
161
+ console.log('═══════════════════════════════════════════════════════════');
162
+ console.log(`Cognitive Runtime v${VERSION} - Environment Diagnostics`);
163
+ console.log('═══════════════════════════════════════════════════════════\n');
164
+ // 1. Version info
165
+ console.log('Version Information:');
166
+ console.log(` Runtime: v${VERSION}`);
167
+ console.log(` Spec: v2.2`);
168
+ console.log('');
169
+ // 2. Provider configuration
170
+ console.log('LLM Providers:');
171
+ const providers = listProviders();
172
+ let hasConfiguredProvider = false;
173
+ for (const p of providers) {
174
+ const status = p.configured ? '✓' : '–';
175
+ const apiKeyStatus = p.configured ? 'API key set' : 'not configured';
176
+ console.log(` ${status} ${p.name}`);
177
+ console.log(` Model: ${p.model}`);
178
+ console.log(` Status: ${apiKeyStatus}`);
179
+ if (p.configured)
180
+ hasConfiguredProvider = true;
152
181
  }
153
182
  console.log('');
183
+ // 3. Active provider
184
+ console.log('Active Provider:');
154
185
  try {
155
186
  const provider = getProvider();
156
- console.log(`Active provider: ${provider.name}`);
187
+ console.log(` ${provider.name} (ready to use)`);
188
+ }
189
+ catch {
190
+ console.log(' ✗ None configured');
191
+ console.log(' → Set one of: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, etc.');
192
+ }
193
+ console.log('');
194
+ // 4. Module scan
195
+ console.log('Module Search Paths:');
196
+ const searchPaths = getDefaultSearchPaths(ctx.cwd);
197
+ for (const p of searchPaths) {
198
+ console.log(` • ${p}`);
199
+ }
200
+ console.log('');
201
+ // 5. Installed modules
202
+ console.log('Installed Modules:');
203
+ try {
204
+ const modules = await listModules(searchPaths);
205
+ if (modules.length === 0) {
206
+ console.log(' – No modules found');
207
+ console.log(' → Use `cog add <repo> -m <module>` to install modules');
208
+ }
209
+ else {
210
+ let v22Count = 0;
211
+ let legacyCount = 0;
212
+ for (const m of modules) {
213
+ const isV22 = m.tier !== undefined || m.formatVersion === 'v2.2';
214
+ if (isV22)
215
+ v22Count++;
216
+ else
217
+ legacyCount++;
218
+ const versionBadge = isV22 ? '[v2.2]' : '[legacy]';
219
+ const tierBadge = m.tier ? `tier:${m.tier}` : '';
220
+ console.log(` ✓ ${m.name} ${versionBadge} ${tierBadge}`);
221
+ console.log(` ${m.responsibility || 'No description'}`);
222
+ }
223
+ console.log('');
224
+ console.log(` Total: ${modules.length} modules (${v22Count} v2.2, ${legacyCount} legacy)`);
225
+ if (legacyCount > 0) {
226
+ console.log('');
227
+ console.log(' ⚠ Legacy modules detected');
228
+ console.log(' → Use `cog migrate --all` to upgrade to v2.2');
229
+ }
230
+ }
231
+ }
232
+ catch (e) {
233
+ console.log(` ✗ Error scanning modules: ${e instanceof Error ? e.message : e}`);
234
+ }
235
+ console.log('');
236
+ // 6. Recommendations
237
+ console.log('Recommendations:');
238
+ const recommendations = [];
239
+ if (!hasConfiguredProvider) {
240
+ recommendations.push('Configure at least one LLM provider (e.g., OPENAI_API_KEY)');
241
+ }
242
+ try {
243
+ const modules = await listModules(searchPaths);
244
+ if (modules.length === 0) {
245
+ recommendations.push('Install some modules with `cog add`');
246
+ }
247
+ // Check for modules without tests
248
+ let modulesWithoutTests = 0;
249
+ for (const m of modules) {
250
+ const testsConfig = m.tests;
251
+ if (!testsConfig || testsConfig.length === 0) {
252
+ modulesWithoutTests++;
253
+ }
254
+ }
255
+ if (modulesWithoutTests > 0) {
256
+ recommendations.push(`${modulesWithoutTests} module(s) have no tests - consider adding golden tests`);
257
+ }
157
258
  }
158
259
  catch {
159
- console.log('Active provider: none (set an API key)');
260
+ // Ignore
160
261
  }
262
+ if (recommendations.length === 0) {
263
+ console.log(' ✓ All good! Your environment is properly configured.');
264
+ }
265
+ else {
266
+ for (const rec of recommendations) {
267
+ console.log(` → ${rec}`);
268
+ }
269
+ }
270
+ console.log('');
271
+ console.log('───────────────────────────────────────────────────────────');
272
+ console.log('For more help: cog --help');
161
273
  break;
162
274
  }
163
275
  case 'add': {
164
276
  const url = args[1];
165
277
  if (!url || url.startsWith('-')) {
166
- console.error('Usage: cog add <url> [--module <name>] [--tag <version>]');
278
+ console.error('Usage: cog add <source> [--module <name>] [--tag <version>]');
279
+ console.error('');
280
+ console.error('Source can be:');
281
+ console.error(' - GitHub: org/repo (e.g., ziel-io/cognitive-modules)');
282
+ console.error(' - Registry: module-name[@version] (e.g., code-simplifier)');
167
283
  console.error('');
168
284
  console.error('Examples:');
285
+ console.error(' cog add code-simplifier # From registry');
286
+ console.error(' cog add code-reviewer@1.2.0 # Specific version');
169
287
  console.error(' cog add ziel-io/cognitive-modules -m code-simplifier');
170
288
  console.error(' cog add org/repo --module my-module --tag v1.0.0');
171
289
  process.exit(1);
172
290
  }
173
- console.log(`→ Adding module from: ${url}`);
291
+ console.log(`→ Adding module: ${url}`);
174
292
  if (values.module)
175
293
  console.log(` Module path: ${values.module}`);
176
294
  if (values.tag)
@@ -272,9 +390,11 @@ async function main() {
272
390
  verbose: values.verbose,
273
391
  });
274
392
  if (!result.success) {
275
- console.error(`Error: ${result.error}`);
276
393
  if (result.data) {
277
- console.error('Partial results:', JSON.stringify(result.data, null, 2));
394
+ console.log(JSON.stringify(result.data, null, values.pretty ? 2 : 0));
395
+ }
396
+ else {
397
+ console.error(`Error: ${result.error}`);
278
398
  }
279
399
  process.exit(1);
280
400
  }
@@ -318,6 +438,345 @@ async function main() {
318
438
  }
319
439
  break;
320
440
  }
441
+ case 'validate': {
442
+ const target = args[1];
443
+ if (values.all) {
444
+ // Validate all modules
445
+ console.log('→ Validating all modules...\n');
446
+ const result = await validateAll(ctx, {
447
+ v22: values.v22,
448
+ format: values.format || 'text',
449
+ });
450
+ const data = result.data;
451
+ if (values.format === 'json') {
452
+ console.log(JSON.stringify(data, null, 2));
453
+ }
454
+ else {
455
+ console.log(`Total: ${data.total}, Valid: ${data.valid}, Invalid: ${data.invalid}\n`);
456
+ for (const r of data.results) {
457
+ const status = r.valid ? '✓' : '✗';
458
+ console.log(`${status} ${r.moduleName || 'unknown'}`);
459
+ for (const err of r.errors) {
460
+ console.log(` Error: ${err}`);
461
+ }
462
+ for (const warn of r.warnings) {
463
+ console.log(` Warning: ${warn}`);
464
+ }
465
+ }
466
+ }
467
+ process.exit(result.success ? 0 : 1);
468
+ }
469
+ if (!target || target.startsWith('-')) {
470
+ console.error('Usage: cog validate <module> [--v22] [--all]');
471
+ process.exit(1);
472
+ }
473
+ console.log(`→ Validating module: ${target}`);
474
+ if (values.v22)
475
+ console.log(' Using strict v2.2 validation');
476
+ console.log('');
477
+ const result = await validate(target, ctx, {
478
+ v22: values.v22,
479
+ format: values.format || 'text',
480
+ });
481
+ const data = result.data;
482
+ if (values.format === 'json') {
483
+ console.log(JSON.stringify(data, null, 2));
484
+ }
485
+ else {
486
+ if (data.valid) {
487
+ console.log('✓ Module is valid');
488
+ }
489
+ else {
490
+ console.log('✗ Validation failed');
491
+ console.log('');
492
+ for (const err of data.errors) {
493
+ console.log(` Error: ${err}`);
494
+ }
495
+ }
496
+ if (data.warnings.length > 0) {
497
+ console.log('');
498
+ console.log('Warnings:');
499
+ for (const warn of data.warnings) {
500
+ console.log(` ${warn}`);
501
+ }
502
+ }
503
+ }
504
+ process.exit(result.success ? 0 : 1);
505
+ }
506
+ case 'migrate': {
507
+ const target = args[1];
508
+ const dryRun = values['dry-run'];
509
+ const backup = !values['no-backup'];
510
+ if (values.all) {
511
+ // Migrate all modules
512
+ console.log('→ Migrating all modules to v2.2...');
513
+ if (dryRun)
514
+ console.log(' (Dry run - no changes will be made)');
515
+ console.log('');
516
+ const result = await migrateAll(ctx, { dryRun, backup });
517
+ const data = result.data;
518
+ console.log(`Total: ${data.total}, Migrated: ${data.migrated}, Skipped: ${data.skipped}, Failed: ${data.failed}\n`);
519
+ for (const r of data.results) {
520
+ const status = r.success ? (r.changes.length > 0 ? '✓' : '–') : '✗';
521
+ console.log(`${status} ${r.moduleName}`);
522
+ for (const change of r.changes) {
523
+ console.log(` ${change}`);
524
+ }
525
+ for (const warn of r.warnings) {
526
+ console.log(` Warning: ${warn}`);
527
+ }
528
+ }
529
+ process.exit(result.success ? 0 : 1);
530
+ }
531
+ if (!target || target.startsWith('-')) {
532
+ console.error('Usage: cog migrate <module> [--dry-run] [--no-backup] [--all]');
533
+ process.exit(1);
534
+ }
535
+ console.log(`→ Migrating module to v2.2: ${target}`);
536
+ if (dryRun)
537
+ console.log(' (Dry run - no changes will be made)');
538
+ console.log('');
539
+ const result = await migrate(target, ctx, { dryRun, backup });
540
+ const data = result.data;
541
+ if (data.success) {
542
+ if (data.changes.length > 0) {
543
+ console.log('✓ Migration completed');
544
+ console.log('');
545
+ for (const change of data.changes) {
546
+ console.log(` ${change}`);
547
+ }
548
+ }
549
+ else {
550
+ console.log('– No changes needed');
551
+ }
552
+ }
553
+ else {
554
+ console.log('✗ Migration failed');
555
+ }
556
+ if (data.warnings.length > 0) {
557
+ console.log('');
558
+ console.log('Warnings:');
559
+ for (const warn of data.warnings) {
560
+ console.log(` ${warn}`);
561
+ }
562
+ }
563
+ process.exit(result.success ? 0 : 1);
564
+ }
565
+ case 'test': {
566
+ const target = args[1];
567
+ if (values.all) {
568
+ // Test all modules
569
+ console.log('→ Running tests for all modules...\n');
570
+ const result = await testAll(ctx, {
571
+ verbose: values.verbose,
572
+ timeout: values.timeout ? parseInt(values.timeout, 10) : undefined,
573
+ });
574
+ const data = result.data;
575
+ // Summary
576
+ console.log('═══════════════════════════════════════════════════════════');
577
+ console.log('Test Summary');
578
+ console.log('═══════════════════════════════════════════════════════════');
579
+ console.log(`Total: ${data.total}, Passed: ${data.passed}, Failed: ${data.failed}, Skipped: ${data.skipped}`);
580
+ console.log(`Duration: ${data.duration_ms}ms\n`);
581
+ // Per-module results
582
+ for (const m of data.modules) {
583
+ if (m.total === 0) {
584
+ console.log(`– ${m.moduleName}: no tests`);
585
+ continue;
586
+ }
587
+ const status = m.failed === 0 ? '✓' : '✗';
588
+ console.log(`${status} ${m.moduleName}: ${m.passed}/${m.total} passed`);
589
+ for (const r of m.results) {
590
+ if (!r.passed) {
591
+ console.log(` ✗ ${r.name}: ${r.error}`);
592
+ }
593
+ }
594
+ }
595
+ process.exit(result.success ? 0 : 1);
596
+ }
597
+ if (!target || target.startsWith('-')) {
598
+ console.error('Usage: cog test <module> [--all] [--verbose] [--timeout <ms>]');
599
+ process.exit(1);
600
+ }
601
+ console.log(`→ Running tests for module: ${target}\n`);
602
+ const result = await test(target, ctx, {
603
+ verbose: values.verbose,
604
+ timeout: values.timeout ? parseInt(values.timeout, 10) : undefined,
605
+ });
606
+ if (!result.success && !result.data) {
607
+ console.error(`✗ ${result.error}`);
608
+ process.exit(1);
609
+ }
610
+ const data = result.data;
611
+ if (data.total === 0) {
612
+ console.log('– No tests found for this module');
613
+ console.log('');
614
+ console.log('To add tests, create a tests/ directory with:');
615
+ console.log(' - tests/case1.input.json');
616
+ console.log(' - tests/case1.expected.json');
617
+ console.log('');
618
+ console.log('Or define in module.yaml:');
619
+ console.log(' tests:');
620
+ console.log(' - tests/case1.input.json -> tests/case1.expected.json');
621
+ process.exit(0);
622
+ }
623
+ // Results
624
+ console.log(`Module: ${data.moduleName}`);
625
+ console.log(`Total: ${data.total}, Passed: ${data.passed}, Failed: ${data.failed}`);
626
+ console.log(`Duration: ${data.duration_ms}ms\n`);
627
+ for (const r of data.results) {
628
+ const status = r.passed ? '✓' : '✗';
629
+ console.log(`${status} ${r.name} (${r.duration_ms}ms)`);
630
+ if (!r.passed) {
631
+ if (r.error) {
632
+ console.log(` Error: ${r.error}`);
633
+ }
634
+ if (r.diff && r.diff.length > 0) {
635
+ console.log(' Differences:');
636
+ for (const d of r.diff.slice(0, 5)) {
637
+ console.log(` ${d.field}:`);
638
+ console.log(` expected: ${JSON.stringify(d.expected)}`);
639
+ console.log(` actual: ${JSON.stringify(d.actual)}`);
640
+ }
641
+ if (r.diff.length > 5) {
642
+ console.log(` ... and ${r.diff.length - 5} more`);
643
+ }
644
+ }
645
+ }
646
+ }
647
+ process.exit(result.success ? 0 : 1);
648
+ }
649
+ case 'search': {
650
+ // Use positionals for query (excludes options)
651
+ const query = positionals.join(' ');
652
+ const limit = values.limit ? parseInt(values.limit, 10) : 20;
653
+ const category = values.category;
654
+ const result = await search(query, ctx, { limit, category });
655
+ if (!result.success) {
656
+ console.error(`✗ ${result.error}`);
657
+ process.exit(1);
658
+ }
659
+ const data = result.data;
660
+ if (data.results.length === 0) {
661
+ if (query) {
662
+ console.log(`No modules found for: "${query}"`);
663
+ }
664
+ else {
665
+ console.log('No modules available in registry.');
666
+ }
667
+ console.log('');
668
+ console.log('Try:');
669
+ console.log(' cog search code review');
670
+ console.log(' cog search task management');
671
+ }
672
+ else {
673
+ if (query) {
674
+ console.log(`Search results for "${query}" (${data.total} total):\n`);
675
+ }
676
+ else {
677
+ console.log(`Available modules (${data.total} total):\n`);
678
+ }
679
+ for (const mod of data.results) {
680
+ console.log(` ${mod.name} (v${mod.version})`);
681
+ console.log(` ${mod.description}`);
682
+ if (mod.keywords.length > 0) {
683
+ console.log(` Tags: ${mod.keywords.join(', ')}`);
684
+ }
685
+ console.log('');
686
+ }
687
+ console.log('Install with:');
688
+ console.log(` cog add <module-name>`);
689
+ }
690
+ break;
691
+ }
692
+ case 'registry': {
693
+ // positionals[0] is the subcommand, positionals[1] is the argument
694
+ const subCommand = positionals[0];
695
+ if (!subCommand || subCommand === 'list') {
696
+ // List all modules
697
+ const result = await search('', ctx, {});
698
+ if (!result.success) {
699
+ console.error(`✗ ${result.error}`);
700
+ process.exit(1);
701
+ }
702
+ const data = result.data;
703
+ console.log(`Registry modules (${data.total} total):\n`);
704
+ for (const mod of data.results) {
705
+ console.log(` ${mod.name} (v${mod.version})`);
706
+ console.log(` ${mod.description}`);
707
+ console.log('');
708
+ }
709
+ }
710
+ else if (subCommand === 'categories') {
711
+ const result = await listCategories(ctx, {});
712
+ if (!result.success) {
713
+ console.error(`✗ ${result.error}`);
714
+ process.exit(1);
715
+ }
716
+ const data = result.data;
717
+ console.log('Registry categories:\n');
718
+ for (const cat of data.categories) {
719
+ console.log(` ${cat.key} - ${cat.name} (${cat.moduleCount} modules)`);
720
+ console.log(` ${cat.description}`);
721
+ console.log('');
722
+ }
723
+ }
724
+ else if (subCommand === 'info') {
725
+ // positionals[1] is the module name (positionals[0] is 'info')
726
+ const moduleName = positionals[1];
727
+ if (!moduleName) {
728
+ console.error('Usage: cog registry info <module>');
729
+ process.exit(1);
730
+ }
731
+ const result = await info(moduleName, ctx, {});
732
+ if (!result.success) {
733
+ console.error(`✗ ${result.error}`);
734
+ process.exit(1);
735
+ }
736
+ const data = result.data;
737
+ const mod = data.module;
738
+ console.log(`Module: ${mod.name}\n`);
739
+ console.log(` Version: ${mod.version}`);
740
+ console.log(` Description: ${mod.description}`);
741
+ console.log(` Author: ${mod.author}`);
742
+ console.log(` Source: ${mod.source}`);
743
+ if (mod.tier)
744
+ console.log(` Tier: ${mod.tier}`);
745
+ if (mod.license)
746
+ console.log(` License: ${mod.license}`);
747
+ if (mod.repository)
748
+ console.log(` Repository: ${mod.repository}`);
749
+ if (mod.keywords.length > 0)
750
+ console.log(` Keywords: ${mod.keywords.join(', ')}`);
751
+ if (mod.conformance_level)
752
+ console.log(` Conformance Level: ${mod.conformance_level}`);
753
+ if (mod.verified !== undefined)
754
+ console.log(` Verified: ${mod.verified ? 'Yes' : 'No'}`);
755
+ if (mod.deprecated)
756
+ console.log(` DEPRECATED: This module is deprecated`);
757
+ console.log('');
758
+ console.log('Install with:');
759
+ console.log(` cog add ${mod.name}`);
760
+ }
761
+ else if (subCommand === 'refresh') {
762
+ // Force refresh the registry cache
763
+ const { RegistryClient } = await import('./registry/client.js');
764
+ const client = new RegistryClient();
765
+ await client.fetchRegistry(true);
766
+ console.log('✓ Registry cache refreshed');
767
+ }
768
+ else {
769
+ console.error(`Unknown registry subcommand: ${subCommand}`);
770
+ console.error('');
771
+ console.error('Usage:');
772
+ console.error(' cog registry list List all modules');
773
+ console.error(' cog registry categories List categories');
774
+ console.error(' cog registry info <mod> Show module details');
775
+ console.error(' cog registry refresh Refresh cache');
776
+ process.exit(1);
777
+ }
778
+ break;
779
+ }
321
780
  default:
322
781
  console.error(`Unknown command: ${command}`);
323
782
  console.error('Run "cog --help" for usage.');
@@ -342,18 +801,23 @@ USAGE:
342
801
 
343
802
  COMMANDS:
344
803
  run <module> Run a Cognitive Module
804
+ test <module> Run golden tests for a module
345
805
  compose <module> Execute a composed module workflow
346
806
  compose-info <mod> Show composition configuration
347
- list List available modules
348
- add <url> Add module from GitHub
807
+ list List available (installed) modules
808
+ add <source> Add module from Registry or GitHub
349
809
  update <module> Update module to latest version
350
810
  remove <module> Remove installed module
351
811
  versions <url> List available versions
812
+ search [query] Search modules in registry
813
+ registry <cmd> Registry commands (list, categories, info, refresh)
814
+ validate <module> Validate module structure
815
+ migrate <module> Migrate module to v2.2 format
352
816
  pipe Pipe mode (stdin/stdout)
353
817
  init [name] Initialize project or create module
354
818
  serve Start HTTP API server
355
819
  mcp Start MCP server (for Claude Code, Cursor)
356
- doctor Check configuration
820
+ doctor Check environment and configuration
357
821
 
358
822
  OPTIONS:
359
823
  -a, --args <str> Arguments to pass to module
@@ -372,12 +836,28 @@ OPTIONS:
372
836
  -d, --max-depth <n> Max composition depth (default: 5)
373
837
  -T, --timeout <ms> Composition timeout in milliseconds
374
838
  --trace Include execution trace (for compose)
839
+ --v22 Use strict v2.2 validation (for validate)
840
+ --dry-run Show what would be done without changes (for migrate)
841
+ --no-backup Skip backup before migration (for migrate)
842
+ --all Process all modules (for validate/migrate)
843
+ -f, --format <fmt> Output format: text or json (for validate)
844
+ -c, --category <cat> Filter by category (for search)
845
+ -l, --limit <n> Limit results (for search, versions)
375
846
  -v, --version Show version
376
847
  -h, --help Show this help
377
848
 
378
849
  EXAMPLES:
379
- # Add modules from GitHub
380
- npx cognitive-modules-cli add ziel-io/cognitive-modules -m code-simplifier
850
+ # Search and discover modules
851
+ cog search code review # Search by keywords
852
+ cog search # List all available modules
853
+ cog search --category code-quality # Search within category
854
+ cog registry categories # View module categories
855
+ cog registry info code-simplifier # Module details
856
+
857
+ # Add modules from registry or GitHub
858
+ cog add code-simplifier # From registry
859
+ cog add code-reviewer@1.2.0 # Specific version from registry
860
+ cog add ziel-io/cognitive-modules -m code-simplifier # From GitHub
381
861
  cog add org/repo --module my-module --tag v1.0.0
382
862
 
383
863
  # Version management
@@ -385,6 +865,17 @@ EXAMPLES:
385
865
  cog versions ziel-io/cognitive-modules
386
866
  cog remove code-simplifier
387
867
 
868
+ # Validation, testing, and migration
869
+ cog validate code-reviewer
870
+ cog validate code-reviewer --v22
871
+ cog validate --all
872
+ cog test code-simplifier # Run golden tests
873
+ cog test code-simplifier --verbose # With detailed output
874
+ cog test --all # Test all modules
875
+ cog migrate code-reviewer --dry-run
876
+ cog migrate code-reviewer
877
+ cog migrate --all --no-backup
878
+
388
879
  # Run modules
389
880
  cog run code-reviewer --args "def foo(): pass"
390
881
  cog run code-reviewer --provider openai --model gpt-4o --args "..."
@@ -399,10 +890,10 @@ EXAMPLES:
399
890
  cog serve --port 8080
400
891
  cog mcp
401
892
 
402
- # Other
893
+ # Environment check
894
+ cog doctor # Full diagnostics
403
895
  echo "review this code" | cog pipe --module code-reviewer
404
896
  cog init my-module
405
- cog doctor
406
897
 
407
898
  ENVIRONMENT:
408
899
  GEMINI_API_KEY Google Gemini