devsync 0.5.5__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.
Files changed (84) hide show
  1. aiconfigkit/__init__.py +0 -0
  2. aiconfigkit/__main__.py +6 -0
  3. aiconfigkit/ai_tools/__init__.py +0 -0
  4. aiconfigkit/ai_tools/base.py +236 -0
  5. aiconfigkit/ai_tools/capability_registry.py +262 -0
  6. aiconfigkit/ai_tools/claude.py +91 -0
  7. aiconfigkit/ai_tools/claude_desktop.py +97 -0
  8. aiconfigkit/ai_tools/cline.py +92 -0
  9. aiconfigkit/ai_tools/copilot.py +92 -0
  10. aiconfigkit/ai_tools/cursor.py +109 -0
  11. aiconfigkit/ai_tools/detector.py +169 -0
  12. aiconfigkit/ai_tools/kiro.py +85 -0
  13. aiconfigkit/ai_tools/mcp_syncer.py +291 -0
  14. aiconfigkit/ai_tools/roo.py +110 -0
  15. aiconfigkit/ai_tools/translator.py +390 -0
  16. aiconfigkit/ai_tools/winsurf.py +102 -0
  17. aiconfigkit/cli/__init__.py +0 -0
  18. aiconfigkit/cli/delete.py +118 -0
  19. aiconfigkit/cli/download.py +274 -0
  20. aiconfigkit/cli/install.py +237 -0
  21. aiconfigkit/cli/install_new.py +937 -0
  22. aiconfigkit/cli/list.py +275 -0
  23. aiconfigkit/cli/main.py +454 -0
  24. aiconfigkit/cli/mcp_configure.py +232 -0
  25. aiconfigkit/cli/mcp_install.py +166 -0
  26. aiconfigkit/cli/mcp_sync.py +165 -0
  27. aiconfigkit/cli/package.py +383 -0
  28. aiconfigkit/cli/package_create.py +323 -0
  29. aiconfigkit/cli/package_install.py +472 -0
  30. aiconfigkit/cli/template.py +19 -0
  31. aiconfigkit/cli/template_backup.py +261 -0
  32. aiconfigkit/cli/template_init.py +499 -0
  33. aiconfigkit/cli/template_install.py +261 -0
  34. aiconfigkit/cli/template_list.py +172 -0
  35. aiconfigkit/cli/template_uninstall.py +146 -0
  36. aiconfigkit/cli/template_update.py +225 -0
  37. aiconfigkit/cli/template_validate.py +234 -0
  38. aiconfigkit/cli/tools.py +47 -0
  39. aiconfigkit/cli/uninstall.py +125 -0
  40. aiconfigkit/cli/update.py +309 -0
  41. aiconfigkit/core/__init__.py +0 -0
  42. aiconfigkit/core/checksum.py +211 -0
  43. aiconfigkit/core/component_detector.py +905 -0
  44. aiconfigkit/core/conflict_resolution.py +329 -0
  45. aiconfigkit/core/git_operations.py +539 -0
  46. aiconfigkit/core/mcp/__init__.py +1 -0
  47. aiconfigkit/core/mcp/credentials.py +279 -0
  48. aiconfigkit/core/mcp/manager.py +308 -0
  49. aiconfigkit/core/mcp/set_manager.py +1 -0
  50. aiconfigkit/core/mcp/validator.py +1 -0
  51. aiconfigkit/core/models.py +1661 -0
  52. aiconfigkit/core/package_creator.py +743 -0
  53. aiconfigkit/core/package_manifest.py +248 -0
  54. aiconfigkit/core/repository.py +298 -0
  55. aiconfigkit/core/secret_detector.py +438 -0
  56. aiconfigkit/core/template_manifest.py +283 -0
  57. aiconfigkit/core/version.py +201 -0
  58. aiconfigkit/storage/__init__.py +0 -0
  59. aiconfigkit/storage/library.py +429 -0
  60. aiconfigkit/storage/mcp_tracker.py +1 -0
  61. aiconfigkit/storage/package_tracker.py +234 -0
  62. aiconfigkit/storage/template_library.py +229 -0
  63. aiconfigkit/storage/template_tracker.py +296 -0
  64. aiconfigkit/storage/tracker.py +416 -0
  65. aiconfigkit/tui/__init__.py +5 -0
  66. aiconfigkit/tui/installer.py +511 -0
  67. aiconfigkit/utils/__init__.py +0 -0
  68. aiconfigkit/utils/atomic_write.py +90 -0
  69. aiconfigkit/utils/backup.py +169 -0
  70. aiconfigkit/utils/dotenv.py +128 -0
  71. aiconfigkit/utils/git_helpers.py +187 -0
  72. aiconfigkit/utils/logging.py +60 -0
  73. aiconfigkit/utils/namespace.py +134 -0
  74. aiconfigkit/utils/paths.py +205 -0
  75. aiconfigkit/utils/project.py +109 -0
  76. aiconfigkit/utils/streaming.py +216 -0
  77. aiconfigkit/utils/ui.py +194 -0
  78. aiconfigkit/utils/validation.py +187 -0
  79. devsync-0.5.5.dist-info/LICENSE +21 -0
  80. devsync-0.5.5.dist-info/METADATA +477 -0
  81. devsync-0.5.5.dist-info/RECORD +84 -0
  82. devsync-0.5.5.dist-info/WHEEL +5 -0
  83. devsync-0.5.5.dist-info/entry_points.txt +2 -0
  84. devsync-0.5.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,166 @@
1
+ """CLI command for installing MCP templates."""
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ import typer
7
+ from rich.console import Console
8
+ from rich.progress import Progress, SpinnerColumn, TextColumn
9
+
10
+ from aiconfigkit.core.mcp.manager import MCPManager
11
+ from aiconfigkit.core.models import InstallationScope
12
+
13
+ logger = logging.getLogger(__name__)
14
+ console = Console()
15
+
16
+
17
+ def mcp_install_command(
18
+ source: str = typer.Argument(..., help="Source URL or local path to MCP template repository"),
19
+ namespace: str = typer.Option(..., "--as", help="Namespace for this template (unique identifier)"),
20
+ scope: str = typer.Option("project", "--scope", help="Installation scope: project or global"),
21
+ force: bool = typer.Option(False, "--force", help="Overwrite existing template if it exists"),
22
+ json_output: bool = typer.Option(False, "--json", help="Output results as JSON"),
23
+ ) -> int:
24
+ """
25
+ Install MCP server configurations from a template repository.
26
+
27
+ This downloads and caches MCP server definitions from a Git repository or local
28
+ directory into your local library. After installation, use 'inskit mcp configure'
29
+ to set up credentials and 'inskit mcp sync' to apply to AI tools.
30
+
31
+ Examples:
32
+
33
+ # Install from GitHub repository
34
+ inskit mcp install https://github.com/company/backend-tools --as backend
35
+
36
+ # Install from local directory
37
+ inskit mcp install ./my-mcp-configs --as local-tools
38
+
39
+ # Install globally (available in all projects)
40
+ inskit mcp install https://github.com/me/personal-tools --as personal --scope global
41
+
42
+ # Force overwrite existing template
43
+ inskit mcp install https://github.com/company/backend-tools --as backend --force
44
+ """
45
+ try:
46
+ # Parse scope
47
+ try:
48
+ install_scope = InstallationScope(scope)
49
+ except ValueError:
50
+ console.print(f"[red]Error:[/red] Invalid scope '{scope}'. Must be 'project' or 'global'")
51
+ return 1
52
+
53
+ # Get library root
54
+ library_root = _get_library_root()
55
+
56
+ # Create MCP manager
57
+ manager = MCPManager(library_root)
58
+
59
+ # Install template with progress indicator
60
+ with Progress(
61
+ SpinnerColumn(),
62
+ TextColumn("[progress.description]{task.description}"),
63
+ console=console,
64
+ ) as progress:
65
+ task = progress.add_task(f"Installing MCP template '{namespace}'...", total=None)
66
+
67
+ try:
68
+ template = manager.install_template(
69
+ source=source,
70
+ namespace=namespace,
71
+ scope=install_scope,
72
+ force=force,
73
+ )
74
+ finally:
75
+ progress.remove_task(task)
76
+
77
+ # Output results
78
+ if json_output:
79
+ import json
80
+
81
+ result = {
82
+ "success": True,
83
+ "namespace": template.namespace,
84
+ "version": template.version,
85
+ "servers": len(template.servers),
86
+ "sets": len(template.sets),
87
+ "scope": install_scope.value,
88
+ }
89
+ console.print(json.dumps(result, indent=2))
90
+ else:
91
+ console.print(f"[green]✓[/green] Installed MCP template: [bold]{namespace}[/bold]")
92
+ console.print(f" Version: {template.version}")
93
+ console.print(f" Description: {template.description}")
94
+ console.print(f" Servers: {len(template.servers)}")
95
+ console.print(f" Sets: {len(template.sets)}")
96
+ console.print(f" Scope: {install_scope.value}")
97
+
98
+ # Show next steps
99
+ console.print("\n[bold]Next steps:[/bold]")
100
+
101
+ # Check which servers need configuration
102
+ servers_needing_config = [s for s in template.servers if s.get_required_env_vars()]
103
+
104
+ if servers_needing_config:
105
+ console.print(" 1. Configure credentials for servers:")
106
+ for server in servers_needing_config[:3]: # Show first 3
107
+ console.print(f" [cyan]inskit mcp configure {namespace}.{server.name}[/cyan]")
108
+ if len(servers_needing_config) > 3:
109
+ console.print(f" ... and {len(servers_needing_config) - 3} more")
110
+ else:
111
+ console.print(" 1. [dim]No credentials needed for servers[/dim]")
112
+
113
+ console.print(" 2. Sync to AI tools: [cyan]inskit mcp sync --tool all[/cyan]")
114
+
115
+ if template.sets:
116
+ set_name = template.sets[0].name
117
+ console.print(f" 3. Or activate a set: [cyan]inskit mcp activate {namespace}.{set_name}[/cyan]")
118
+
119
+ return 0
120
+
121
+ except ValueError as e:
122
+ if json_output:
123
+ import json
124
+
125
+ console.print(json.dumps({"success": False, "error": str(e)}, indent=2))
126
+ else:
127
+ console.print(f"[red]Error:[/red] {e}")
128
+ return 1
129
+
130
+ except FileNotFoundError as e:
131
+ if json_output:
132
+ import json
133
+
134
+ console.print(json.dumps({"success": False, "error": str(e)}, indent=2))
135
+ else:
136
+ console.print(f"[red]Error:[/red] {e}")
137
+ return 1
138
+
139
+ except RuntimeError as e:
140
+ if json_output:
141
+ import json
142
+
143
+ console.print(json.dumps({"success": False, "error": str(e)}, indent=2))
144
+ else:
145
+ console.print(f"[red]Error:[/red] {e}")
146
+ return 1
147
+
148
+ except Exception as e:
149
+ logger.exception("Unexpected error during MCP template installation")
150
+ if json_output:
151
+ import json
152
+
153
+ console.print(json.dumps({"success": False, "error": f"Unexpected error: {e}"}, indent=2))
154
+ else:
155
+ console.print(f"[red]Unexpected error:[/red] {e}")
156
+ return 1
157
+
158
+
159
+ def _get_library_root() -> Path:
160
+ """
161
+ Get the library root directory.
162
+
163
+ Returns:
164
+ Path to library root (~/.instructionkit/library/)
165
+ """
166
+ return Path.home() / ".instructionkit" / "library"
@@ -0,0 +1,165 @@
1
+ """CLI command for syncing MCP servers to AI tools."""
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ import typer
7
+ from rich.console import Console
8
+ from rich.table import Table
9
+
10
+ from aiconfigkit.ai_tools.mcp_syncer import MCPSyncer
11
+ from aiconfigkit.core.models import InstallationScope
12
+
13
+ logger = logging.getLogger(__name__)
14
+ console = Console()
15
+
16
+
17
+ def mcp_sync_command(
18
+ tool: str = typer.Option(
19
+ "all",
20
+ "--tool",
21
+ "-t",
22
+ help="AI tool to sync to (claude, cursor, windsurf, or all)",
23
+ ),
24
+ scope: str = typer.Option(
25
+ "project",
26
+ "--scope",
27
+ help="Scope to load configurations from (project or global)",
28
+ ),
29
+ dry_run: bool = typer.Option(
30
+ False,
31
+ "--dry-run",
32
+ help="Show what would be synced without actually syncing",
33
+ ),
34
+ no_backup: bool = typer.Option(
35
+ False,
36
+ "--no-backup",
37
+ help="Skip creating backup of config files before modifying",
38
+ ),
39
+ json_output: bool = typer.Option(
40
+ False,
41
+ "--json",
42
+ help="Output results as JSON",
43
+ ),
44
+ ) -> int:
45
+ """
46
+ Sync configured MCP servers to AI tool configuration files.
47
+
48
+ This command reads installed MCP servers from the library, resolves their
49
+ environment variables from .instructionkit/.env, and writes them to AI
50
+ tool configuration files (e.g., claude_desktop_config.json).
51
+
52
+ Examples:
53
+
54
+ # Sync to all detected AI tools
55
+ inskit mcp sync --tool all
56
+
57
+ # Sync to specific tool
58
+ inskit mcp sync --tool claude
59
+
60
+ # Dry run to see what would be synced
61
+ inskit mcp sync --tool all --dry-run
62
+
63
+ # Sync without creating backups
64
+ inskit mcp sync --tool claude --no-backup
65
+
66
+ # Sync global configurations
67
+ inskit mcp sync --scope global
68
+ """
69
+ try:
70
+ # Parse scope
71
+ try:
72
+ install_scope = InstallationScope(scope)
73
+ except ValueError:
74
+ console.print(f"[red]Error:[/red] Invalid scope '{scope}'. Must be 'project' or 'global'")
75
+ return 1
76
+
77
+ # Create syncer
78
+ syncer = MCPSyncer(
79
+ library_root=Path.home() / ".instructionkit" / "library",
80
+ project_root=Path.cwd(),
81
+ )
82
+
83
+ # Parse tool names
84
+ tool_names = [tool] if tool != "all" else ["all"]
85
+
86
+ # Show sync info
87
+ if not json_output:
88
+ console.print("\n[bold]Syncing MCP servers to AI tools[/bold]")
89
+ console.print(f"Scope: {install_scope.value}")
90
+ console.print(f"Tools: {tool}")
91
+ if dry_run:
92
+ console.print("[yellow]DRY RUN - no changes will be made[/yellow]")
93
+ console.print()
94
+
95
+ # Perform sync
96
+ result = syncer.sync_all(
97
+ tool_names=tool_names,
98
+ scope=install_scope,
99
+ create_backup=not no_backup,
100
+ dry_run=dry_run,
101
+ )
102
+
103
+ # Output results
104
+ if json_output:
105
+ import json
106
+
107
+ output = {
108
+ "success": result.success,
109
+ "synced_tools": result.synced_tools,
110
+ "skipped_tools": [{"name": name, "reason": reason} for name, reason in result.skipped_tools],
111
+ "synced_servers": result.synced_servers,
112
+ "skipped_servers": [{"name": name, "reason": reason} for name, reason in result.skipped_servers],
113
+ }
114
+ console.print(json.dumps(output, indent=2))
115
+ else:
116
+ # Show synced tools
117
+ if result.synced_tools:
118
+ console.print(f"[green]✓[/green] Synced to {len(result.synced_tools)} tool(s):")
119
+ for tool_name in result.synced_tools:
120
+ console.print(f" • {tool_name}")
121
+ else:
122
+ console.print("[yellow]⚠[/yellow] No tools were synced")
123
+
124
+ # Show skipped tools
125
+ if result.skipped_tools:
126
+ console.print(f"\n[yellow]⚠[/yellow] Skipped {len(result.skipped_tools)} tool(s):")
127
+ for tool_name, reason in result.skipped_tools:
128
+ console.print(f" • {tool_name}: {reason}")
129
+
130
+ # Show server summary
131
+ console.print("\n[bold]Server Summary:[/bold]")
132
+ console.print(f" Synced: {len(result.synced_servers)} server(s)")
133
+ if result.skipped_servers:
134
+ console.print(f" Skipped: {len(result.skipped_servers)} server(s)")
135
+
136
+ # Show skipped servers details
137
+ if result.skipped_servers:
138
+ console.print("\n[yellow]Skipped Servers:[/yellow]")
139
+ table = Table(show_header=True)
140
+ table.add_column("Server", style="cyan")
141
+ table.add_column("Reason", style="yellow")
142
+
143
+ for server_name, reason in result.skipped_servers:
144
+ table.add_row(server_name, reason)
145
+
146
+ console.print(table)
147
+
148
+ console.print(
149
+ "\n[dim]Tip: Run 'inskit mcp configure <namespace>' to configure missing credentials[/dim]"
150
+ )
151
+
152
+ if not result.success:
153
+ return 1
154
+
155
+ return 0
156
+
157
+ except Exception as e:
158
+ logger.exception("Unexpected error during MCP sync")
159
+ if json_output:
160
+ import json
161
+
162
+ console.print(json.dumps({"success": False, "error": str(e)}, indent=2))
163
+ else:
164
+ console.print(f"[red]Unexpected error:[/red] {e}")
165
+ return 1