cognitive-modules-cli 2.2.0 → 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 (94) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +35 -29
  4. package/dist/cli.js +572 -28
  5. package/dist/commands/add.d.ts +33 -14
  6. package/dist/commands/add.js +222 -13
  7. package/dist/commands/compose.d.ts +31 -0
  8. package/dist/commands/compose.js +185 -0
  9. package/dist/commands/index.d.ts +5 -0
  10. package/dist/commands/index.js +5 -0
  11. package/dist/commands/init.js +23 -1
  12. package/dist/commands/migrate.d.ts +30 -0
  13. package/dist/commands/migrate.js +650 -0
  14. package/dist/commands/pipe.d.ts +1 -0
  15. package/dist/commands/pipe.js +31 -11
  16. package/dist/commands/remove.js +33 -2
  17. package/dist/commands/run.d.ts +1 -0
  18. package/dist/commands/run.js +37 -27
  19. package/dist/commands/search.d.ts +28 -0
  20. package/dist/commands/search.js +143 -0
  21. package/dist/commands/test.d.ts +65 -0
  22. package/dist/commands/test.js +454 -0
  23. package/dist/commands/update.d.ts +1 -0
  24. package/dist/commands/update.js +106 -14
  25. package/dist/commands/validate.d.ts +36 -0
  26. package/dist/commands/validate.js +97 -0
  27. package/dist/errors/index.d.ts +218 -0
  28. package/dist/errors/index.js +412 -0
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +5 -1
  31. package/dist/mcp/server.js +84 -79
  32. package/dist/modules/composition.d.ts +251 -0
  33. package/dist/modules/composition.js +1330 -0
  34. package/dist/modules/index.d.ts +2 -0
  35. package/dist/modules/index.js +2 -0
  36. package/dist/modules/loader.d.ts +22 -2
  37. package/dist/modules/loader.js +171 -6
  38. package/dist/modules/runner.d.ts +422 -1
  39. package/dist/modules/runner.js +1472 -71
  40. package/dist/modules/subagent.d.ts +6 -1
  41. package/dist/modules/subagent.js +20 -13
  42. package/dist/modules/validator.d.ts +28 -0
  43. package/dist/modules/validator.js +637 -0
  44. package/dist/providers/anthropic.d.ts +15 -0
  45. package/dist/providers/anthropic.js +147 -5
  46. package/dist/providers/base.d.ts +11 -0
  47. package/dist/providers/base.js +18 -0
  48. package/dist/providers/gemini.d.ts +15 -0
  49. package/dist/providers/gemini.js +122 -5
  50. package/dist/providers/ollama.d.ts +15 -0
  51. package/dist/providers/ollama.js +111 -3
  52. package/dist/providers/openai.d.ts +11 -0
  53. package/dist/providers/openai.js +133 -0
  54. package/dist/registry/client.d.ts +204 -0
  55. package/dist/registry/client.js +356 -0
  56. package/dist/registry/index.d.ts +4 -0
  57. package/dist/registry/index.js +4 -0
  58. package/dist/server/http.js +173 -42
  59. package/dist/types.d.ts +123 -8
  60. package/dist/types.js +4 -1
  61. package/dist/version.d.ts +1 -0
  62. package/dist/version.js +4 -0
  63. package/package.json +32 -7
  64. package/src/cli.ts +0 -410
  65. package/src/commands/add.ts +0 -315
  66. package/src/commands/index.ts +0 -12
  67. package/src/commands/init.ts +0 -94
  68. package/src/commands/list.ts +0 -33
  69. package/src/commands/pipe.ts +0 -76
  70. package/src/commands/remove.ts +0 -57
  71. package/src/commands/run.ts +0 -80
  72. package/src/commands/update.ts +0 -130
  73. package/src/commands/versions.ts +0 -79
  74. package/src/index.ts +0 -55
  75. package/src/mcp/index.ts +0 -5
  76. package/src/mcp/server.ts +0 -403
  77. package/src/modules/index.ts +0 -7
  78. package/src/modules/loader.ts +0 -318
  79. package/src/modules/runner.ts +0 -495
  80. package/src/modules/subagent.ts +0 -275
  81. package/src/providers/anthropic.ts +0 -89
  82. package/src/providers/base.ts +0 -29
  83. package/src/providers/deepseek.ts +0 -83
  84. package/src/providers/gemini.ts +0 -117
  85. package/src/providers/index.ts +0 -78
  86. package/src/providers/minimax.ts +0 -81
  87. package/src/providers/moonshot.ts +0 -82
  88. package/src/providers/ollama.ts +0 -83
  89. package/src/providers/openai.ts +0 -84
  90. package/src/providers/qwen.ts +0 -82
  91. package/src/server/http.ts +0 -316
  92. package/src/server/index.ts +0 -6
  93. package/src/types.ts +0 -495
  94. 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 } 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' },
@@ -48,6 +49,18 @@ async function main() {
48
49
  // Server options
49
50
  host: { type: 'string', short: 'H' },
50
51
  port: { type: 'string', short: 'P' },
52
+ // Compose options
53
+ 'max-depth': { type: 'string', short: 'd' },
54
+ timeout: { type: 'string', short: 'T' },
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' },
51
64
  },
52
65
  allowPositionals: true,
53
66
  });
@@ -81,7 +94,12 @@ async function main() {
81
94
  verbose: values.verbose,
82
95
  });
83
96
  if (!result.success) {
84
- 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
+ }
85
103
  process.exit(1);
86
104
  }
87
105
  console.log(JSON.stringify(result.data, null, values.pretty ? 2 : 0));
@@ -140,33 +158,137 @@ async function main() {
140
158
  break;
141
159
  }
142
160
  case 'doctor': {
143
- console.log('Cognitive Runtime - Environment Check\n');
144
- console.log('Providers:');
145
- for (const p of listProviders()) {
146
- const status = p.configured ? '✓ configured' : '– not configured';
147
- 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;
148
181
  }
149
182
  console.log('');
183
+ // 3. Active provider
184
+ console.log('Active Provider:');
150
185
  try {
151
186
  const provider = getProvider();
152
- 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
+ }
153
258
  }
154
259
  catch {
155
- console.log('Active provider: none (set an API key)');
260
+ // Ignore
261
+ }
262
+ if (recommendations.length === 0) {
263
+ console.log(' ✓ All good! Your environment is properly configured.');
156
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');
157
273
  break;
158
274
  }
159
275
  case 'add': {
160
276
  const url = args[1];
161
277
  if (!url || url.startsWith('-')) {
162
- 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)');
163
283
  console.error('');
164
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');
165
287
  console.error(' cog add ziel-io/cognitive-modules -m code-simplifier');
166
288
  console.error(' cog add org/repo --module my-module --tag v1.0.0');
167
289
  process.exit(1);
168
290
  }
169
- console.log(`→ Adding module from: ${url}`);
291
+ console.log(`→ Adding module: ${url}`);
170
292
  if (values.module)
171
293
  console.log(` Module path: ${values.module}`);
172
294
  if (values.tag)
@@ -252,6 +374,47 @@ async function main() {
252
374
  }
253
375
  break;
254
376
  }
377
+ case 'compose': {
378
+ const moduleName = args[1];
379
+ if (!moduleName || moduleName.startsWith('-')) {
380
+ console.error('Usage: cog compose <module> [--args "..."] [--timeout <ms>] [--max-depth <n>]');
381
+ process.exit(1);
382
+ }
383
+ const result = await compose(moduleName, ctx, {
384
+ args: values.args,
385
+ input: values.input,
386
+ maxDepth: values['max-depth'] ? parseInt(values['max-depth'], 10) : undefined,
387
+ timeout: values.timeout ? parseInt(values.timeout, 10) : undefined,
388
+ trace: values.trace,
389
+ pretty: values.pretty,
390
+ verbose: values.verbose,
391
+ });
392
+ if (!result.success) {
393
+ if (result.data) {
394
+ console.log(JSON.stringify(result.data, null, values.pretty ? 2 : 0));
395
+ }
396
+ else {
397
+ console.error(`Error: ${result.error}`);
398
+ }
399
+ process.exit(1);
400
+ }
401
+ console.log(JSON.stringify(result.data, null, values.pretty ? 2 : 0));
402
+ break;
403
+ }
404
+ case 'compose-info': {
405
+ const moduleName = args[1];
406
+ if (!moduleName || moduleName.startsWith('-')) {
407
+ console.error('Usage: cog compose-info <module>');
408
+ process.exit(1);
409
+ }
410
+ const result = await composeInfo(moduleName, ctx);
411
+ if (!result.success) {
412
+ console.error(`Error: ${result.error}`);
413
+ process.exit(1);
414
+ }
415
+ console.log(JSON.stringify(result.data, null, 2));
416
+ break;
417
+ }
255
418
  case 'serve': {
256
419
  const { serve } = await import('./server/http.js');
257
420
  const port = values.port ? parseInt(values.port, 10) : 8000;
@@ -275,6 +438,345 @@ async function main() {
275
438
  }
276
439
  break;
277
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
+ }
278
780
  default:
279
781
  console.error(`Unknown command: ${command}`);
280
782
  console.error('Run "cog --help" for usage.');
@@ -298,17 +800,24 @@ USAGE:
298
800
  cog <command> [options]
299
801
 
300
802
  COMMANDS:
301
- run <module> Run a Cognitive Module
302
- list List available modules
303
- add <url> Add module from GitHub
304
- update <module> Update module to latest version
305
- remove <module> Remove installed module
306
- versions <url> List available versions
307
- pipe Pipe mode (stdin/stdout)
308
- init [name] Initialize project or create module
309
- serve Start HTTP API server
310
- mcp Start MCP server (for Claude Code, Cursor)
311
- doctor Check configuration
803
+ run <module> Run a Cognitive Module
804
+ test <module> Run golden tests for a module
805
+ compose <module> Execute a composed module workflow
806
+ compose-info <mod> Show composition configuration
807
+ list List available (installed) modules
808
+ add <source> Add module from Registry or GitHub
809
+ update <module> Update module to latest version
810
+ remove <module> Remove installed module
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
816
+ pipe Pipe mode (stdin/stdout)
817
+ init [name] Initialize project or create module
818
+ serve Start HTTP API server
819
+ mcp Start MCP server (for Claude Code, Cursor)
820
+ doctor Check environment and configuration
312
821
 
313
822
  OPTIONS:
314
823
  -a, --args <str> Arguments to pass to module
@@ -324,12 +833,31 @@ OPTIONS:
324
833
  --no-validate Skip schema validation
325
834
  -H, --host <host> Server host (default: 0.0.0.0)
326
835
  -P, --port <port> Server port (default: 8000)
836
+ -d, --max-depth <n> Max composition depth (default: 5)
837
+ -T, --timeout <ms> Composition timeout in milliseconds
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)
327
846
  -v, --version Show version
328
847
  -h, --help Show this help
329
848
 
330
849
  EXAMPLES:
331
- # Add modules from GitHub
332
- 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
333
861
  cog add org/repo --module my-module --tag v1.0.0
334
862
 
335
863
  # Version management
@@ -337,19 +865,35 @@ EXAMPLES:
337
865
  cog versions ziel-io/cognitive-modules
338
866
  cog remove code-simplifier
339
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
+
340
879
  # Run modules
341
880
  cog run code-reviewer --args "def foo(): pass"
342
881
  cog run code-reviewer --provider openai --model gpt-4o --args "..."
343
882
  cog list
344
883
 
884
+ # Compose modules (multi-step workflows)
885
+ cog compose code-review-pipeline --args "code to review"
886
+ cog compose smart-processor --args "input" --timeout 60000 --verbose
887
+ cog compose-info code-review-pipeline
888
+
345
889
  # Servers
346
890
  cog serve --port 8080
347
891
  cog mcp
348
892
 
349
- # Other
893
+ # Environment check
894
+ cog doctor # Full diagnostics
350
895
  echo "review this code" | cog pipe --module code-reviewer
351
896
  cog init my-module
352
- cog doctor
353
897
 
354
898
  ENVIRONMENT:
355
899
  GEMINI_API_KEY Google Gemini