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,92 @@
1
+ """Cline AI tool integration."""
2
+
3
+ from pathlib import Path
4
+
5
+ from aiconfigkit.ai_tools.base import AITool
6
+ from aiconfigkit.core.models import AIToolType
7
+ from aiconfigkit.utils.paths import get_cline_config_dir
8
+
9
+
10
+ class ClineTool(AITool):
11
+ """Integration for Cline AI coding tool (VS Code extension).
12
+
13
+ Cline uses .clinerules/ directory at the project root for AI instructions.
14
+ Files are .md (Markdown) and are read recursively. Optional YAML frontmatter
15
+ with `paths:` field enables conditional rule activation based on file globs.
16
+
17
+ Detection is based on the VS Code extension saoudrizwan.claude-dev
18
+ globalStorage directory.
19
+ """
20
+
21
+ @property
22
+ def tool_type(self) -> AIToolType:
23
+ """Return the AI tool type identifier."""
24
+ return AIToolType.CLINE
25
+
26
+ @property
27
+ def tool_name(self) -> str:
28
+ """Return human-readable tool name."""
29
+ return "Cline"
30
+
31
+ def is_installed(self) -> bool:
32
+ """
33
+ Check if Cline is installed on the system.
34
+
35
+ Checks for existence of the Cline VS Code extension globalStorage directory
36
+ (saoudrizwan.claude-dev).
37
+
38
+ Returns:
39
+ True if Cline is detected
40
+ """
41
+ try:
42
+ config_dir = get_cline_config_dir()
43
+ return config_dir.exists()
44
+ except Exception:
45
+ return False
46
+
47
+ def get_instructions_directory(self) -> Path:
48
+ """
49
+ Get the directory where Cline instructions should be installed.
50
+
51
+ Note: Cline global rules live in ~/Documents/Cline/Rules/ but this
52
+ is non-standard. This tool only supports project-level installations.
53
+
54
+ Returns:
55
+ Path to Cline instructions directory
56
+
57
+ Raises:
58
+ NotImplementedError: Global installation not supported for Cline
59
+ """
60
+ raise NotImplementedError(
61
+ f"{self.tool_name} global installation is not supported. "
62
+ "Please use project-level installation instead (--scope project)."
63
+ )
64
+
65
+ def get_instruction_file_extension(self) -> str:
66
+ """
67
+ Get the file extension for Cline instructions.
68
+
69
+ Cline uses markdown (.md) files in the .clinerules/ directory.
70
+
71
+ Returns:
72
+ File extension including the dot
73
+ """
74
+ return ".md"
75
+
76
+ def get_project_instructions_directory(self, project_root: Path) -> Path:
77
+ """
78
+ Get the directory for project-specific Cline instructions.
79
+
80
+ Cline stores project-specific rules in .clinerules/ directory at the
81
+ project root. It reads .md files recursively from this directory.
82
+ Numeric prefixes (e.g., 01-coding-standards.md) control load order.
83
+
84
+ Args:
85
+ project_root: Path to the project root directory
86
+
87
+ Returns:
88
+ Path to project instructions directory (.clinerules/)
89
+ """
90
+ instructions_dir = project_root / ".clinerules"
91
+ instructions_dir.mkdir(parents=True, exist_ok=True)
92
+ return instructions_dir
@@ -0,0 +1,92 @@
1
+ """GitHub Copilot AI tool integration."""
2
+
3
+ from pathlib import Path
4
+
5
+ from aiconfigkit.ai_tools.base import AITool
6
+ from aiconfigkit.core.models import AIToolType
7
+ from aiconfigkit.utils.paths import get_copilot_config_dir
8
+
9
+
10
+ class CopilotTool(AITool):
11
+ """Integration for GitHub Copilot (VS Code extension)."""
12
+
13
+ @property
14
+ def tool_type(self) -> AIToolType:
15
+ """Return the AI tool type identifier."""
16
+ return AIToolType.COPILOT
17
+
18
+ @property
19
+ def tool_name(self) -> str:
20
+ """Return human-readable tool name."""
21
+ return "GitHub Copilot"
22
+
23
+ def is_installed(self) -> bool:
24
+ """
25
+ Check if GitHub Copilot is installed on the system.
26
+
27
+ Checks for existence of VS Code and Copilot extension directory.
28
+
29
+ Returns:
30
+ True if Copilot is detected
31
+ """
32
+ try:
33
+ config_dir = get_copilot_config_dir()
34
+ # Check if the Copilot extension directory exists
35
+ # VS Code structure: .../Code/User/globalStorage/github.copilot
36
+ return config_dir.parent.exists()
37
+ except Exception:
38
+ return False
39
+
40
+ def get_instructions_directory(self) -> Path:
41
+ """
42
+ Get the directory where Copilot instructions should be installed.
43
+
44
+ Note: GitHub Copilot uses .github/copilot-instructions.md as a single file
45
+ for project-level instructions. Global instructions are not officially supported.
46
+ This tool currently only supports project-level installations.
47
+
48
+ Returns:
49
+ Path to Copilot instructions directory
50
+
51
+ Raises:
52
+ NotImplementedError: Global installation not supported for GitHub Copilot
53
+ """
54
+ raise NotImplementedError(
55
+ f"{self.tool_name} global installation is not supported. "
56
+ "GitHub Copilot uses project-level instructions only. "
57
+ "Please use project-level installation instead (--scope project)."
58
+ )
59
+
60
+ def get_instruction_file_extension(self) -> str:
61
+ """
62
+ Get the file extension for Copilot instructions.
63
+
64
+ GitHub Copilot requires path-specific instructions to end with
65
+ .instructions.md per official documentation:
66
+ https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions
67
+
68
+ Returns:
69
+ File extension including the dot
70
+ """
71
+ return ".instructions.md"
72
+
73
+ def get_project_instructions_directory(self, project_root: Path) -> Path:
74
+ """
75
+ Get the directory for project-specific Copilot instructions.
76
+
77
+ GitHub Copilot stores project-specific instructions in .github/instructions/
78
+ directory in the project root. It supports multiple .md files in this directory.
79
+
80
+ Reference:
81
+ - Path-specific: .github/instructions/*.instructions.md (multiple files)
82
+ - Alternative: .github/copilot-instructions.md (single file, not used by this tool)
83
+
84
+ Args:
85
+ project_root: Path to the project root directory
86
+
87
+ Returns:
88
+ Path to project instructions directory (.github/instructions/)
89
+ """
90
+ instructions_dir = project_root / ".github" / "instructions"
91
+ instructions_dir.mkdir(parents=True, exist_ok=True)
92
+ return instructions_dir
@@ -0,0 +1,109 @@
1
+ """Cursor AI tool integration."""
2
+
3
+ from pathlib import Path
4
+
5
+ from aiconfigkit.ai_tools.base import AITool
6
+ from aiconfigkit.core.models import AIToolType
7
+ from aiconfigkit.utils.paths import get_cursor_config_dir, get_cursor_mcp_config_path
8
+
9
+
10
+ class CursorTool(AITool):
11
+ """Integration for Cursor AI coding tool."""
12
+
13
+ @property
14
+ def tool_type(self) -> AIToolType:
15
+ """Return the AI tool type identifier."""
16
+ return AIToolType.CURSOR
17
+
18
+ @property
19
+ def tool_name(self) -> str:
20
+ """Return human-readable tool name."""
21
+ return "Cursor"
22
+
23
+ def is_installed(self) -> bool:
24
+ """
25
+ Check if Cursor is installed on the system.
26
+
27
+ Checks for existence of Cursor configuration directory.
28
+
29
+ Returns:
30
+ True if Cursor is detected
31
+ """
32
+ try:
33
+ config_dir = get_cursor_config_dir()
34
+ # Check if parent directory exists (not necessarily the full path)
35
+ # Cursor config dir structure: .../Cursor/User/globalStorage
36
+ cursor_base = config_dir.parent.parent
37
+ return cursor_base.exists()
38
+ except Exception:
39
+ return False
40
+
41
+ def get_instructions_directory(self) -> Path:
42
+ """
43
+ Get the directory where Cursor instructions should be installed.
44
+
45
+ Note: Cursor uses .cursorrules as a single file for global rules.
46
+ This tool currently only supports project-level installations.
47
+
48
+ Returns:
49
+ Path to Cursor instructions directory
50
+
51
+ Raises:
52
+ NotImplementedError: Global installation not supported for Cursor
53
+ """
54
+ raise NotImplementedError(
55
+ f"{self.tool_name} global installation is not supported. "
56
+ "Cursor uses a single .cursorrules file for global rules. "
57
+ "Please use project-level installation instead (--scope project)."
58
+ )
59
+
60
+ def get_instruction_file_extension(self) -> str:
61
+ """
62
+ Get the file extension for Cursor instructions.
63
+
64
+ Cursor uses .mdc files (markdown with metadata) for rules.
65
+
66
+ Returns:
67
+ File extension including the dot
68
+ """
69
+ return ".mdc"
70
+
71
+ def get_project_instructions_directory(self, project_root: Path) -> Path:
72
+ """
73
+ Get the directory for project-specific Cursor instructions.
74
+
75
+ Cursor stores project-specific rules in .cursor/rules/ directory
76
+ in the project root. It supports multiple .mdc files in this directory.
77
+
78
+ Reference:
79
+ - Recommended: .cursor/rules/*.mdc (multiple files with metadata)
80
+ - Alternative: .cursorrules (single file, not used by this tool)
81
+
82
+ .mdc files can include metadata like:
83
+ ---
84
+ description: Rule description
85
+ globs: ["src/**/*.tsx"]
86
+ alwaysApply: true
87
+ ---
88
+
89
+ Args:
90
+ project_root: Path to the project root directory
91
+
92
+ Returns:
93
+ Path to project instructions directory (.cursor/rules/)
94
+ """
95
+ instructions_dir = project_root / ".cursor" / "rules"
96
+ instructions_dir.mkdir(parents=True, exist_ok=True)
97
+ return instructions_dir
98
+
99
+ def get_mcp_config_path(self) -> Path:
100
+ """
101
+ Get the path to the Cursor MCP configuration file.
102
+
103
+ Note: Cursor doesn't natively support MCP yet, but we provide this
104
+ for future compatibility.
105
+
106
+ Returns:
107
+ Path to MCP configuration file
108
+ """
109
+ return get_cursor_mcp_config_path()
@@ -0,0 +1,169 @@
1
+ """AI tool detection and auto-discovery."""
2
+
3
+ from typing import Optional
4
+
5
+ from aiconfigkit.ai_tools.base import AITool
6
+ from aiconfigkit.ai_tools.claude import ClaudeTool
7
+ from aiconfigkit.ai_tools.cline import ClineTool
8
+ from aiconfigkit.ai_tools.copilot import CopilotTool
9
+ from aiconfigkit.ai_tools.cursor import CursorTool
10
+ from aiconfigkit.ai_tools.kiro import KiroTool
11
+ from aiconfigkit.ai_tools.roo import RooTool
12
+ from aiconfigkit.ai_tools.winsurf import WinsurfTool
13
+ from aiconfigkit.core.models import AIToolType
14
+
15
+
16
+ class AIToolDetector:
17
+ """Detect and manage AI coding tools."""
18
+
19
+ def __init__(self) -> None:
20
+ """Initialize detector with all supported tools."""
21
+ self.tools: dict[AIToolType, AITool] = {
22
+ AIToolType.CURSOR: CursorTool(),
23
+ AIToolType.COPILOT: CopilotTool(),
24
+ AIToolType.WINSURF: WinsurfTool(),
25
+ AIToolType.CLAUDE: ClaudeTool(),
26
+ AIToolType.KIRO: KiroTool(),
27
+ AIToolType.CLINE: ClineTool(),
28
+ AIToolType.ROO: RooTool(),
29
+ }
30
+
31
+ def detect_installed_tools(self) -> list[AITool]:
32
+ """
33
+ Detect all installed AI coding tools.
34
+
35
+ Returns:
36
+ List of installed AITool instances
37
+ """
38
+ installed = []
39
+ for tool in self.tools.values():
40
+ if tool.is_installed():
41
+ installed.append(tool)
42
+ return installed
43
+
44
+ def get_tool_by_name(self, name: str) -> Optional[AITool]:
45
+ """
46
+ Get AI tool instance by name.
47
+
48
+ Args:
49
+ name: Tool name (cursor, copilot, winsurf, claude)
50
+
51
+ Returns:
52
+ AITool instance or None if not found
53
+ """
54
+ try:
55
+ tool_type = AIToolType(name.lower())
56
+ return self.tools.get(tool_type)
57
+ except ValueError:
58
+ return None
59
+
60
+ def get_tool_by_type(self, tool_type: AIToolType) -> Optional[AITool]:
61
+ """
62
+ Get AI tool instance by type.
63
+
64
+ Args:
65
+ tool_type: AIToolType enum value
66
+
67
+ Returns:
68
+ AITool instance
69
+ """
70
+ return self.tools.get(tool_type)
71
+
72
+ def get_primary_tool(self) -> Optional[AITool]:
73
+ """
74
+ Get the primary (first detected) AI tool.
75
+
76
+ Priority order: Cursor, Copilot, Winsurf, Claude Code
77
+
78
+ Returns:
79
+ First installed AITool or None if none installed
80
+ """
81
+ # Check in priority order
82
+ priority = [
83
+ AIToolType.CURSOR,
84
+ AIToolType.COPILOT,
85
+ AIToolType.WINSURF,
86
+ AIToolType.CLAUDE,
87
+ AIToolType.KIRO,
88
+ AIToolType.CLINE,
89
+ AIToolType.ROO,
90
+ ]
91
+
92
+ for tool_type in priority:
93
+ tool = self.tools[tool_type]
94
+ if tool.is_installed():
95
+ return tool
96
+
97
+ return None
98
+
99
+ def is_any_tool_installed(self) -> bool:
100
+ """
101
+ Check if any AI coding tool is installed.
102
+
103
+ Returns:
104
+ True if at least one tool is detected
105
+ """
106
+ return len(self.detect_installed_tools()) > 0
107
+
108
+ def get_tool_names(self) -> list[str]:
109
+ """
110
+ Get list of all supported tool names.
111
+
112
+ Returns:
113
+ List of tool name strings
114
+ """
115
+ return [tool_type.value for tool_type in self.tools.keys()]
116
+
117
+ def validate_tool_name(self, name: str) -> bool:
118
+ """
119
+ Validate if tool name is supported.
120
+
121
+ Args:
122
+ name: Tool name to validate
123
+
124
+ Returns:
125
+ True if tool is supported
126
+ """
127
+ return name.lower() in self.get_tool_names()
128
+
129
+ def get_detection_summary(self) -> dict[str, bool]:
130
+ """
131
+ Get detection summary for all tools.
132
+
133
+ Returns:
134
+ Dictionary mapping tool names to installation status
135
+ """
136
+ return {tool_type.value: tool.is_installed() for tool_type, tool in self.tools.items()}
137
+
138
+ def format_detection_summary(self) -> str:
139
+ """
140
+ Format detection summary as human-readable string.
141
+
142
+ Returns:
143
+ Formatted summary string
144
+ """
145
+ summary = self.get_detection_summary()
146
+ lines = ["AI Coding Tools Detection:"]
147
+
148
+ for tool_name, is_installed in summary.items():
149
+ status = "✓ Installed" if is_installed else "✗ Not found"
150
+ lines.append(f" {tool_name.capitalize()}: {status}")
151
+
152
+ return "\n".join(lines)
153
+
154
+
155
+ # Singleton instance for convenience
156
+ _detector_instance: Optional[AIToolDetector] = None
157
+
158
+
159
+ def get_detector() -> AIToolDetector:
160
+ """
161
+ Get singleton AIToolDetector instance.
162
+
163
+ Returns:
164
+ AIToolDetector instance
165
+ """
166
+ global _detector_instance
167
+ if _detector_instance is None:
168
+ _detector_instance = AIToolDetector()
169
+ return _detector_instance
@@ -0,0 +1,85 @@
1
+ """Kiro AI tool integration."""
2
+
3
+ from pathlib import Path
4
+
5
+ from aiconfigkit.ai_tools.base import AITool
6
+ from aiconfigkit.core.models import AIToolType
7
+ from aiconfigkit.utils.paths import get_kiro_config_dir
8
+
9
+
10
+ class KiroTool(AITool):
11
+ """Integration for Kiro AI coding tool."""
12
+
13
+ @property
14
+ def tool_type(self) -> AIToolType:
15
+ """Return the AI tool type identifier."""
16
+ return AIToolType.KIRO
17
+
18
+ @property
19
+ def tool_name(self) -> str:
20
+ """Return human-readable tool name."""
21
+ return "Kiro"
22
+
23
+ def is_installed(self) -> bool:
24
+ """
25
+ Check if Kiro is installed on the system.
26
+
27
+ Checks for existence of Kiro configuration directory.
28
+
29
+ Returns:
30
+ True if Kiro is detected
31
+ """
32
+ try:
33
+ config_dir = get_kiro_config_dir()
34
+ # Check if parent directory exists
35
+ # Kiro config dir structure: .../Kiro/User/globalStorage
36
+ kiro_base = config_dir.parent.parent
37
+ return kiro_base.exists()
38
+ except Exception:
39
+ return False
40
+
41
+ def get_instructions_directory(self) -> Path:
42
+ """
43
+ Get the directory where Kiro instructions should be installed.
44
+
45
+ Note: Kiro uses ~/.kiro/steering/ for global steering files.
46
+ This tool currently only supports project-level installations.
47
+
48
+ Returns:
49
+ Path to Kiro instructions directory
50
+
51
+ Raises:
52
+ NotImplementedError: Global installation not supported for Kiro
53
+ """
54
+ raise NotImplementedError(
55
+ f"{self.tool_name} global installation is not supported. "
56
+ "Please use project-level installation instead (--scope project)."
57
+ )
58
+
59
+ def get_instruction_file_extension(self) -> str:
60
+ """
61
+ Get the file extension for Kiro instructions.
62
+
63
+ Kiro uses markdown (.md) files for steering.
64
+
65
+ Returns:
66
+ File extension including the dot
67
+ """
68
+ return ".md"
69
+
70
+ def get_project_instructions_directory(self, project_root: Path) -> Path:
71
+ """
72
+ Get the directory for project-specific Kiro instructions.
73
+
74
+ Kiro stores project-specific steering files in .kiro/steering/ directory
75
+ in the project root. It supports multiple .md files in this directory.
76
+
77
+ Args:
78
+ project_root: Path to the project root directory
79
+
80
+ Returns:
81
+ Path to project instructions directory (.kiro/steering/)
82
+ """
83
+ instructions_dir = project_root / ".kiro" / "steering"
84
+ instructions_dir.mkdir(parents=True, exist_ok=True)
85
+ return instructions_dir