cognitive-modules 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
cognitive/__init__.py CHANGED
@@ -9,4 +9,4 @@ Usage:
9
9
  cog doctor # Check environment setup
10
10
  """
11
11
 
12
- __version__ = "0.1.0"
12
+ __version__ = "0.5.0"
cognitive/cli.py CHANGED
@@ -1,16 +1,22 @@
1
1
  """
2
- Cognitive CLI - Main entry point for the cog command.
2
+ Cognitive CLI - Main entry point for the cogn command.
3
3
 
4
4
  Commands:
5
- cog list List installed modules
6
- cog run <module> <input> Run a module
7
- cog validate <module> Validate module structure
8
- cog install <source> Install module from git/local/registry
9
- cog uninstall <module> Remove an installed module
10
- cog init <name> Create a new module from template
11
- cog search <query> Search the public registry
12
- cog doctor Check environment setup
13
- cog info <module> Show module details
5
+ cogn list List installed modules
6
+ cogn run <module> <input> Run a module
7
+ cogn validate <module> Validate module structure
8
+ cogn add <url> --module <name> Add module from GitHub (recommended)
9
+ cogn update <module> Update module to latest version
10
+ cogn versions <url> List available versions for a repo
11
+ cogn install <source> Install module from git/local/registry
12
+ cogn remove <module> Remove an installed module
13
+ cogn uninstall <module> Remove an installed module (alias)
14
+ cogn init <name> Create a new module from template
15
+ cogn search <query> Search the public registry
16
+ cogn doctor Check environment setup
17
+ cogn info <module> Show module details
18
+ cogn serve Start HTTP API server
19
+ cogn mcp Start MCP server for Claude/Cursor
14
20
  """
15
21
 
16
22
  import json
@@ -31,6 +37,11 @@ from .registry import (
31
37
  uninstall_module,
32
38
  search_registry,
33
39
  fetch_registry,
40
+ install_from_github_url,
41
+ update_module,
42
+ get_installed_module_info,
43
+ get_module_version,
44
+ list_github_tags,
34
45
  USER_MODULES_DIR,
35
46
  )
36
47
  from .loader import load_module, detect_format
@@ -38,6 +49,7 @@ from .runner import run_module
38
49
  from .subagent import run_with_subagents
39
50
  from .validator import validate_module
40
51
  from .templates import create_module
52
+ from .migrate import migrate_module, migrate_all_modules
41
53
  from .providers import check_provider_status
42
54
 
43
55
  app = typer.Typer(
@@ -151,11 +163,19 @@ def run_cmd(
151
163
  @app.command("validate")
152
164
  def validate_cmd(
153
165
  module: str = typer.Argument(..., help="Module name or path"),
166
+ v22: bool = typer.Option(False, "--v22", help="Validate v2.2 format requirements"),
154
167
  ):
155
- """Validate a cognitive module's structure and examples."""
156
- rprint(f"[cyan]→[/cyan] Validating module: [bold]{module}[/bold]\n")
168
+ """
169
+ Validate a cognitive module's structure and examples.
157
170
 
158
- is_valid, errors, warnings = validate_module(module)
171
+ Examples:
172
+ cogn validate code-reviewer
173
+ cogn validate code-reviewer --v22 # Check v2.2 requirements
174
+ """
175
+ mode_str = " [dim](v2.2 strict)[/dim]" if v22 else ""
176
+ rprint(f"[cyan]→[/cyan] Validating module: [bold]{module}[/bold]{mode_str}\n")
177
+
178
+ is_valid, errors, warnings = validate_module(module, v22=v22)
159
179
 
160
180
  if warnings:
161
181
  rprint(f"[yellow]⚠ Warnings ({len(warnings)}):[/yellow]")
@@ -164,7 +184,10 @@ def validate_cmd(
164
184
  print()
165
185
 
166
186
  if is_valid:
167
- rprint(f"[green]✓ Module '{module}' is valid[/green]")
187
+ if v22:
188
+ rprint(f"[green]✓ Module '{module}' is valid v2.2 format[/green]")
189
+ else:
190
+ rprint(f"[green]✓ Module '{module}' is valid[/green]")
168
191
  else:
169
192
  rprint(f"[red]✗ Validation failed ({len(errors)} errors):[/red]")
170
193
  for e in errors:
@@ -172,6 +195,83 @@ def validate_cmd(
172
195
  raise typer.Exit(1)
173
196
 
174
197
 
198
+ @app.command("migrate")
199
+ def migrate_cmd(
200
+ module: Optional[str] = typer.Argument(None, help="Module name or path (omit for --all)"),
201
+ all_modules: bool = typer.Option(False, "--all", "-a", help="Migrate all installed modules"),
202
+ dry_run: bool = typer.Option(False, "--dry-run", "-n", help="Show what would be done without making changes"),
203
+ no_backup: bool = typer.Option(False, "--no-backup", help="Skip creating backup before migration"),
204
+ ):
205
+ """
206
+ Migrate modules from v1/v2.1 to v2.2 format.
207
+
208
+ Examples:
209
+ cogn migrate code-reviewer # Migrate single module
210
+ cogn migrate code-reviewer --dry-run # Preview changes
211
+ cogn migrate --all # Migrate all modules
212
+ """
213
+ if not module and not all_modules:
214
+ rprint("[red]Error: Provide module name or use --all[/red]")
215
+ raise typer.Exit(1)
216
+
217
+ if all_modules:
218
+ rprint(f"[cyan]→[/cyan] Migrating all modules to v2.2...")
219
+ if dry_run:
220
+ rprint("[dim](dry run - no changes will be made)[/dim]")
221
+ print()
222
+
223
+ results = migrate_all_modules(dry_run=dry_run, backup=not no_backup)
224
+
225
+ success_count = 0
226
+ for name, success, changes, warnings in results:
227
+ if success:
228
+ success_count += 1
229
+ rprint(f"[green]✓[/green] {name}")
230
+ for c in changes:
231
+ rprint(f" {c}")
232
+ else:
233
+ rprint(f"[red]✗[/red] {name}")
234
+ for w in warnings:
235
+ rprint(f" [yellow]{w}[/yellow]")
236
+
237
+ print()
238
+ rprint(f"[green]Migrated: {success_count}/{len(results)}[/green]")
239
+
240
+ else:
241
+ mode_str = " [dim](dry run)[/dim]" if dry_run else ""
242
+ rprint(f"[cyan]→[/cyan] Migrating module: [bold]{module}[/bold]{mode_str}\n")
243
+
244
+ success, changes, warnings = migrate_module(
245
+ module,
246
+ dry_run=dry_run,
247
+ backup=not no_backup
248
+ )
249
+
250
+ if changes:
251
+ rprint(f"[cyan]Changes:[/cyan]")
252
+ for c in changes:
253
+ rprint(f" - {c}")
254
+ print()
255
+
256
+ if warnings:
257
+ rprint(f"[yellow]⚠ Warnings:[/yellow]")
258
+ for w in warnings:
259
+ rprint(f" - {w}")
260
+ print()
261
+
262
+ if success:
263
+ if dry_run:
264
+ rprint(f"[green]✓ Migration preview complete[/green]")
265
+ rprint(f" Run without --dry-run to apply changes")
266
+ else:
267
+ rprint(f"[green]✓ Module '{module}' migrated to v2.2[/green]")
268
+ rprint(f"\nValidate with:")
269
+ rprint(f" [cyan]cogn validate {module} --v22[/cyan]")
270
+ else:
271
+ rprint(f"[red]✗ Migration failed[/red]")
272
+ raise typer.Exit(1)
273
+
274
+
175
275
  @app.command("install")
176
276
  def install_cmd(
177
277
  source: str = typer.Argument(..., help="Source: github:org/repo/path, registry:name, or local path"),
@@ -203,6 +303,185 @@ def install_cmd(
203
303
  raise typer.Exit(1)
204
304
 
205
305
 
306
+ @app.command("add")
307
+ def add_cmd(
308
+ url: str = typer.Argument(..., help="GitHub URL or org/repo shorthand"),
309
+ module: str = typer.Option(None, "--module", "-m", help="Module path within repo"),
310
+ name: Optional[str] = typer.Option(None, "--name", "-n", help="Override module name"),
311
+ branch: str = typer.Option("main", "--branch", "-b", help="Git branch"),
312
+ tag: Optional[str] = typer.Option(None, "--tag", "-t", help="Git tag/version (e.g., v1.0.0)"),
313
+ ):
314
+ """
315
+ Add a cognitive module from GitHub.
316
+
317
+ Examples:
318
+
319
+ cog add https://github.com/ziel-io/cognitive-modules --module code-simplifier
320
+
321
+ cog add ziel-io/cognitive-modules -m code-reviewer
322
+
323
+ cog add org/repo -m my-module --tag v1.0.0
324
+
325
+ cog add org/repo -m path/to/module --name my-module
326
+ """
327
+ rprint(f"[cyan]→[/cyan] Adding module from: {url}")
328
+ if module:
329
+ rprint(f" Module path: {module}")
330
+ if tag:
331
+ rprint(f" Version: {tag}")
332
+
333
+ try:
334
+ target = install_from_github_url(
335
+ url=url,
336
+ module_path=module,
337
+ name=name,
338
+ branch=branch,
339
+ tag=tag,
340
+ )
341
+
342
+ # Validate installed module
343
+ is_valid, errors, warnings = validate_module(str(target))
344
+
345
+ if not is_valid:
346
+ rprint(f"[red]✗ Installed module failed validation:[/red]")
347
+ for e in errors:
348
+ rprint(f" - {e}")
349
+ uninstall_module(target.name)
350
+ raise typer.Exit(1)
351
+
352
+ # Get version info
353
+ version = get_module_version(target)
354
+ version_str = f" v{version}" if version else ""
355
+
356
+ rprint(f"[green]✓ Added: {target.name}{version_str}[/green]")
357
+ rprint(f" Location: {target}")
358
+
359
+ if warnings:
360
+ rprint(f"[yellow] Warnings: {len(warnings)}[/yellow]")
361
+
362
+ rprint(f"\nRun with:")
363
+ rprint(f" [cyan]cog run {target.name} --args \"your input\"[/cyan]")
364
+
365
+ except Exception as e:
366
+ rprint(f"[red]✗ Failed to add module: {e}[/red]")
367
+ raise typer.Exit(1)
368
+
369
+
370
+ @app.command("remove")
371
+ def remove_cmd(
372
+ module: str = typer.Argument(..., help="Module name to remove"),
373
+ ):
374
+ """Remove an installed cognitive module (alias for uninstall)."""
375
+ uninstall_cmd(module)
376
+
377
+
378
+ @app.command("update")
379
+ def update_cmd(
380
+ module: str = typer.Argument(..., help="Module name to update"),
381
+ tag: Optional[str] = typer.Option(None, "--tag", "-t", help="Update to specific tag/version"),
382
+ ):
383
+ """
384
+ Update an installed module to the latest version.
385
+
386
+ Examples:
387
+
388
+ cog update code-simplifier
389
+
390
+ cog update code-simplifier --tag v2.0.0
391
+ """
392
+ rprint(f"[cyan]→[/cyan] Updating module: {module}")
393
+
394
+ # Check if module is installed
395
+ info = get_installed_module_info(module)
396
+ if not info:
397
+ rprint(f"[red]✗ Module not found or not installed from GitHub: {module}[/red]")
398
+ rprint(f" Only modules installed with 'cog add' can be updated.")
399
+ raise typer.Exit(1)
400
+
401
+ github_url = info.get("github_url")
402
+ if not github_url:
403
+ rprint(f"[red]✗ Module was not installed from GitHub: {module}[/red]")
404
+ raise typer.Exit(1)
405
+
406
+ # Get current version
407
+ current_path = USER_MODULES_DIR / module
408
+ old_version = get_module_version(current_path) if current_path.exists() else None
409
+
410
+ if old_version:
411
+ rprint(f" Current version: {old_version}")
412
+
413
+ try:
414
+ # Re-install from source
415
+ module_path = info.get("module_path")
416
+ branch = info.get("branch", "main")
417
+
418
+ # Use specified tag or keep using the same ref type
419
+ use_tag = tag or info.get("tag")
420
+
421
+ target = install_from_github_url(
422
+ url=github_url,
423
+ module_path=module_path,
424
+ name=module,
425
+ branch=branch if not use_tag else "main",
426
+ tag=use_tag,
427
+ )
428
+
429
+ # Get new version
430
+ new_version = get_module_version(target)
431
+
432
+ if old_version and new_version:
433
+ if old_version == new_version:
434
+ rprint(f"[green]✓ Already up to date: {module} v{new_version}[/green]")
435
+ else:
436
+ rprint(f"[green]✓ Updated: {module} v{old_version} → v{new_version}[/green]")
437
+ elif new_version:
438
+ rprint(f"[green]✓ Updated: {module} to v{new_version}[/green]")
439
+ else:
440
+ rprint(f"[green]✓ Updated: {module}[/green]")
441
+
442
+ except Exception as e:
443
+ rprint(f"[red]✗ Failed to update module: {e}[/red]")
444
+ raise typer.Exit(1)
445
+
446
+
447
+ @app.command("versions")
448
+ def versions_cmd(
449
+ url: str = typer.Argument(..., help="GitHub URL or org/repo shorthand"),
450
+ limit: int = typer.Option(10, "--limit", "-l", help="Max versions to show"),
451
+ ):
452
+ """
453
+ List available versions (tags) for a GitHub repository.
454
+
455
+ Examples:
456
+
457
+ cog versions ziel-io/cognitive-modules
458
+
459
+ cog versions https://github.com/org/repo
460
+ """
461
+ rprint(f"[cyan]→[/cyan] Fetching versions from: {url}\n")
462
+
463
+ try:
464
+ tags = list_github_tags(url, limit=limit)
465
+
466
+ if not tags:
467
+ rprint("[yellow]No tags/versions found.[/yellow]")
468
+ return
469
+
470
+ table = Table(title=f"Available Versions ({len(tags)})")
471
+ table.add_column("Version", style="cyan")
472
+ table.add_column("Install Command")
473
+
474
+ for tag in tags:
475
+ cmd = f"cog add {url} --tag {tag}"
476
+ table.add_row(tag, f"[dim]{cmd}[/dim]")
477
+
478
+ console.print(table)
479
+
480
+ except Exception as e:
481
+ rprint(f"[red]✗ Failed to fetch versions: {e}[/red]")
482
+ raise typer.Exit(1)
483
+
484
+
206
485
  @app.command("uninstall")
207
486
  def uninstall_cmd(
208
487
  module: str = typer.Argument(..., help="Module name to uninstall"),
@@ -403,6 +682,84 @@ def info_cmd(
403
682
 
404
683
  rprint(f"\n[bold]Path:[/bold] {m['path']}")
405
684
  rprint(f"[bold]Prompt size:[/bold] {len(m['prompt'])} chars")
685
+
686
+ # Show installation info if available
687
+ install_info = get_installed_module_info(meta.get('name', module))
688
+ if install_info:
689
+ rprint(f"\n[bold]Installation:[/bold]")
690
+ if install_info.get("github_url"):
691
+ rprint(f" Source: {install_info['github_url']}")
692
+ if install_info.get("tag"):
693
+ rprint(f" Tag: {install_info['tag']}")
694
+ elif install_info.get("branch"):
695
+ rprint(f" Branch: {install_info['branch']}")
696
+ if install_info.get("installed_time"):
697
+ rprint(f" Installed: {install_info['installed_time'][:10]}")
698
+ rprint(f"\n Update with: [cyan]cog update {meta.get('name', module)}[/cyan]")
699
+
700
+
701
+ @app.command("serve")
702
+ def serve_cmd(
703
+ host: str = typer.Option("0.0.0.0", "--host", "-h", help="Host to bind"),
704
+ port: int = typer.Option(8000, "--port", "-p", help="Port to bind"),
705
+ ):
706
+ """
707
+ Start HTTP API server for workflow integration.
708
+
709
+ Example:
710
+ cogn serve --port 8000
711
+
712
+ Then use:
713
+ curl -X POST http://localhost:8000/run \\
714
+ -H "Content-Type: application/json" \\
715
+ -d '{"module": "code-reviewer", "args": "your code"}'
716
+ """
717
+ try:
718
+ import uvicorn
719
+ except ImportError:
720
+ rprint("[red]Error:[/red] Server dependencies not installed.")
721
+ rprint("\nInstall with:")
722
+ rprint(" [cyan]pip install cognitive-modules[server][/cyan]")
723
+ raise typer.Exit(1)
724
+
725
+ rprint(f"[green]Starting Cognitive API server...[/green]")
726
+ rprint(f" Host: {host}")
727
+ rprint(f" Port: {port}")
728
+ rprint(f" Docs: http://{host if host != '0.0.0.0' else 'localhost'}:{port}/docs")
729
+ rprint()
730
+
731
+ uvicorn.run("cognitive.server:app", host=host, port=port, reload=False)
732
+
733
+
734
+ @app.command("mcp")
735
+ def mcp_cmd():
736
+ """
737
+ Start MCP (Model Context Protocol) server.
738
+
739
+ Enables Claude Code, Cursor, and other MCP-compatible tools to use Cognitive Modules.
740
+
741
+ Example:
742
+ cogn mcp
743
+
744
+ Configure in Claude Desktop (claude_desktop_config.json):
745
+ {
746
+ "mcpServers": {
747
+ "cognitive": {
748
+ "command": "cogn",
749
+ "args": ["mcp"]
750
+ }
751
+ }
752
+ }
753
+ """
754
+ try:
755
+ from .mcp_server import serve
756
+ except ImportError:
757
+ rprint("[red]Error:[/red] MCP dependencies not installed.")
758
+ rprint("\nInstall with:")
759
+ rprint(" [cyan]pip install cognitive-modules[mcp][/cyan]")
760
+ raise typer.Exit(1)
761
+
762
+ serve()
406
763
 
407
764
 
408
765
  @app.callback(invoke_without_command=True)