@friggframework/devtools 2.0.0--canary.400.bed3308.0 → 2.0.0--canary.400.545e7a8.0

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 (167) hide show
  1. package/frigg-cli/build-command/index.js +2 -15
  2. package/frigg-cli/deploy-command/index.js +2 -15
  3. package/frigg-cli/index.js +4 -66
  4. package/frigg-cli/install-command/index.js +2 -15
  5. package/frigg-cli/start-command/index.js +2 -17
  6. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +19 -43
  7. package/infrastructure/IAM-POLICY-TEMPLATES.md +1 -1
  8. package/infrastructure/frigg-deployment-iam-stack.yaml +2 -16
  9. package/infrastructure/iam-generator.js +6 -129
  10. package/infrastructure/iam-policy-basic.json +5 -29
  11. package/infrastructure/iam-policy-full.json +5 -28
  12. package/infrastructure/serverless-template.js +3 -190
  13. package/infrastructure/serverless-template.test.js +0 -12
  14. package/management-ui/dist/assets/index-CbM64Oba.js +1221 -0
  15. package/management-ui/dist/assets/index-CkvseXTC.css +1 -0
  16. package/management-ui/{index.html → dist/index.html} +2 -1
  17. package/package.json +5 -5
  18. package/frigg-cli/.eslintrc.js +0 -141
  19. package/frigg-cli/__tests__/jest.config.js +0 -102
  20. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
  21. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
  22. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
  23. package/frigg-cli/__tests__/utils/command-tester.js +0 -170
  24. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  25. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  26. package/frigg-cli/__tests__/utils/test-setup.js +0 -286
  27. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
  28. package/frigg-cli/generate-command/azure-generator.js +0 -43
  29. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  30. package/frigg-cli/generate-command/index.js +0 -350
  31. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  32. package/frigg-cli/package.json +0 -75
  33. package/frigg-cli/ui-command/index.js +0 -167
  34. package/frigg-cli/utils/app-resolver.js +0 -319
  35. package/frigg-cli/utils/backend-path.js +0 -38
  36. package/frigg-cli/utils/process-manager.js +0 -199
  37. package/frigg-cli/utils/repo-detection.js +0 -405
  38. package/management-ui/.eslintrc.js +0 -22
  39. package/management-ui/README.md +0 -203
  40. package/management-ui/components.json +0 -21
  41. package/management-ui/merge-conflict-cleaner.py +0 -371
  42. package/management-ui/package-lock.json +0 -10997
  43. package/management-ui/package.json +0 -76
  44. package/management-ui/postcss.config.js +0 -6
  45. package/management-ui/server/api/backend.js +0 -256
  46. package/management-ui/server/api/cli.js +0 -315
  47. package/management-ui/server/api/codegen.js +0 -663
  48. package/management-ui/server/api/connections.js +0 -857
  49. package/management-ui/server/api/discovery.js +0 -185
  50. package/management-ui/server/api/environment/index.js +0 -1
  51. package/management-ui/server/api/environment/router.js +0 -378
  52. package/management-ui/server/api/environment.js +0 -328
  53. package/management-ui/server/api/integrations.js +0 -479
  54. package/management-ui/server/api/logs.js +0 -248
  55. package/management-ui/server/api/monitoring.js +0 -282
  56. package/management-ui/server/api/open-ide.js +0 -31
  57. package/management-ui/server/api/project.js +0 -553
  58. package/management-ui/server/api/users/sessions.js +0 -371
  59. package/management-ui/server/api/users/simulation.js +0 -254
  60. package/management-ui/server/api/users.js +0 -362
  61. package/management-ui/server/api-contract.md +0 -275
  62. package/management-ui/server/index.js +0 -428
  63. package/management-ui/server/middleware/errorHandler.js +0 -70
  64. package/management-ui/server/middleware/security.js +0 -32
  65. package/management-ui/server/processManager.js +0 -296
  66. package/management-ui/server/server.js +0 -188
  67. package/management-ui/server/services/aws-monitor.js +0 -413
  68. package/management-ui/server/services/npm-registry.js +0 -347
  69. package/management-ui/server/services/template-engine.js +0 -538
  70. package/management-ui/server/utils/cliIntegration.js +0 -220
  71. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  72. package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
  73. package/management-ui/server/utils/environment/encryption.js +0 -278
  74. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  75. package/management-ui/server/utils/import-commonjs.js +0 -28
  76. package/management-ui/server/utils/response.js +0 -83
  77. package/management-ui/server/websocket/handler.js +0 -325
  78. package/management-ui/src/App.jsx +0 -51
  79. package/management-ui/src/components/AppRouter.jsx +0 -65
  80. package/management-ui/src/components/Button.jsx +0 -2
  81. package/management-ui/src/components/Card.jsx +0 -9
  82. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  83. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  84. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  85. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  86. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  87. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  88. package/management-ui/src/components/IntegrationCard.jsx +0 -199
  89. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
  90. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  91. package/management-ui/src/components/IntegrationStatus.jsx +0 -235
  92. package/management-ui/src/components/Layout.jsx +0 -250
  93. package/management-ui/src/components/LoadingSpinner.jsx +0 -45
  94. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  95. package/management-ui/src/components/SessionMonitor.jsx +0 -255
  96. package/management-ui/src/components/StatusBadge.jsx +0 -70
  97. package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
  98. package/management-ui/src/components/UserSimulation.jsx +0 -299
  99. package/management-ui/src/components/Welcome.jsx +0 -434
  100. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  101. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  102. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  103. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  104. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  105. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  106. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  107. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  108. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  109. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  110. package/management-ui/src/components/codegen/index.js +0 -10
  111. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  112. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  113. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  114. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  115. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  116. package/management-ui/src/components/connections/index.js +0 -5
  117. package/management-ui/src/components/index.js +0 -21
  118. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  119. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  120. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  121. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  122. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  123. package/management-ui/src/components/monitoring/index.js +0 -6
  124. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  125. package/management-ui/src/components/theme-provider.jsx +0 -52
  126. package/management-ui/src/components/theme-toggle.jsx +0 -39
  127. package/management-ui/src/components/ui/badge.tsx +0 -36
  128. package/management-ui/src/components/ui/button.test.jsx +0 -56
  129. package/management-ui/src/components/ui/button.tsx +0 -57
  130. package/management-ui/src/components/ui/card.tsx +0 -76
  131. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  132. package/management-ui/src/components/ui/select.tsx +0 -157
  133. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  134. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  135. package/management-ui/src/hooks/useSocket.jsx +0 -58
  136. package/management-ui/src/index.css +0 -194
  137. package/management-ui/src/lib/utils.ts +0 -6
  138. package/management-ui/src/main.jsx +0 -10
  139. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  140. package/management-ui/src/pages/Connections.jsx +0 -252
  141. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
  142. package/management-ui/src/pages/Dashboard.jsx +0 -311
  143. package/management-ui/src/pages/Environment.jsx +0 -314
  144. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
  145. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
  146. package/management-ui/src/pages/IntegrationTest.jsx +0 -494
  147. package/management-ui/src/pages/Integrations.jsx +0 -254
  148. package/management-ui/src/pages/Monitoring.jsx +0 -17
  149. package/management-ui/src/pages/Simulation.jsx +0 -155
  150. package/management-ui/src/pages/Users.jsx +0 -492
  151. package/management-ui/src/services/api.js +0 -41
  152. package/management-ui/src/services/apiModuleService.js +0 -193
  153. package/management-ui/src/services/websocket-handlers.js +0 -120
  154. package/management-ui/src/test/api/project.test.js +0 -273
  155. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  156. package/management-ui/src/test/mocks/server.js +0 -178
  157. package/management-ui/src/test/setup.js +0 -61
  158. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  159. package/management-ui/src/utils/repository.js +0 -98
  160. package/management-ui/src/utils/repository.test.js +0 -118
  161. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  162. package/management-ui/tailwind.config.js +0 -63
  163. package/management-ui/tsconfig.json +0 -37
  164. package/management-ui/tsconfig.node.json +0 -10
  165. package/management-ui/vite.config.js +0 -26
  166. package/management-ui/vitest.config.js +0 -38
  167. /package/management-ui/{src/assets/FriggLogo.svg → dist/assets/FriggLogo-B7Xx8ZW1.svg} +0 -0
@@ -1,203 +0,0 @@
1
- # Frigg Management UI
2
-
3
- A modern React-based management interface for Frigg development environment. Built with Vite, React, and Tailwind CSS, this application provides developers with a comprehensive dashboard to manage integrations, users, connections, and environment variables.
4
-
5
- ## Features
6
-
7
- - **Dashboard**: Server control, metrics, and activity monitoring
8
- - **Integration Discovery**: Browse, install, and manage Frigg integrations
9
- - **Environment Management**: Configure environment variables and settings
10
- - **User Management**: Create and manage test users
11
- - **Connection Management**: Monitor and manage integration connections
12
- - **Real-time Updates**: WebSocket-based live updates
13
- - **Responsive Design**: Mobile-friendly interface
14
- - **Error Boundaries**: Robust error handling
15
-
16
- ## Tech Stack
17
-
18
- - **React 18.3**: Modern React with hooks and functional components
19
- - **Vite**: Fast development and build tooling
20
- - **React Router**: Client-side routing
21
- - **Tailwind CSS**: Utility-first CSS framework
22
- - **Lucide React**: Modern icon library
23
- - **Socket.io**: Real-time communication
24
- - **Axios**: HTTP client
25
- - **@friggframework/ui**: Shared UI components
26
-
27
- ## Getting Started
28
-
29
- ### Prerequisites
30
-
31
- - Node.js 16+ and npm
32
- - Running Frigg backend server
33
-
34
- ### Installation
35
-
36
- ```bash
37
- # Install dependencies
38
- npm install
39
-
40
- # Start development server (frontend only)
41
- npm run dev
42
-
43
- # Start both frontend and backend
44
- npm run dev:server
45
-
46
- # Build for production
47
- npm run build
48
- ```
49
-
50
- ### Available Scripts
51
-
52
- - `npm run dev` - Start Vite development server
53
- - `npm run dev:server` - Start both frontend and backend concurrently
54
- - `npm run build` - Build for production
55
- - `npm run preview` - Preview production build
56
- - `npm run server` - Start backend server only
57
- - `npm run server:dev` - Start backend server with nodemon
58
- - `npm run lint` - Run ESLint
59
- - `npm run lint:fix` - Fix ESLint issues
60
- - `npm run typecheck` - Run TypeScript type checking
61
-
62
- ## Project Structure
63
-
64
- ```
65
- src/
66
- ├── components/ # Reusable UI components
67
- │ ├── Button.jsx # Custom button component
68
- │ ├── Card.jsx # Card container components
69
- │ ├── ErrorBoundary.jsx
70
- │ ├── IntegrationCard.jsx
71
- │ ├── Layout.jsx # Main layout component
72
- │ ├── LoadingSpinner.jsx
73
- │ ├── StatusBadge.jsx
74
- │ └── index.js # Component exports
75
- ├── hooks/ # React hooks
76
- │ ├── useFrigg.jsx # Main Frigg state management
77
- │ └── useSocket.jsx # WebSocket connection
78
- ├── pages/ # Page components
79
- │ ├── Dashboard.jsx # Main dashboard
80
- │ ├── Integrations.jsx
81
- │ ├── Environment.jsx
82
- │ ├── Users.jsx
83
- │ └── Connections.jsx
84
- ├── services/ # API services
85
- │ └── api.js # Axios configuration
86
- ├── utils/ # Utility functions
87
- │ └── cn.js # Class name utility
88
- ├── App.jsx # Root component
89
- ├── main.jsx # Application entry point
90
- └── index.css # Global styles
91
-
92
- server/
93
- ├── api/ # Backend API routes
94
- ├── middleware/ # Express middleware
95
- ├── utils/ # Server utilities
96
- ├── websocket/ # WebSocket handlers
97
- └── index.js # Server entry point
98
- ```
99
-
100
- ## Component Architecture
101
-
102
- ### Layout Components
103
- - **Layout**: Main application layout with responsive sidebar
104
- - **ErrorBoundary**: Catches and displays errors gracefully
105
-
106
- ### UI Components
107
- - **Button**: Customizable button with variants and sizes
108
- - **Card**: Container components for content sections
109
- - **StatusBadge**: Displays server status with color coding
110
- - **LoadingSpinner**: Loading indicators
111
- - **IntegrationCard**: Rich integration display component
112
-
113
- ### State Management
114
- - **useFrigg**: Central state management for Frigg data
115
- - **useSocket**: WebSocket connection and real-time updates
116
-
117
- ## API Integration
118
-
119
- The management UI communicates with the Frigg backend through:
120
-
121
- 1. **REST API**: Standard CRUD operations
122
- 2. **WebSocket**: Real-time updates and notifications
123
-
124
- ### API Endpoints
125
-
126
- - `GET /api/frigg/status` - Server status
127
- - `POST /api/frigg/start` - Start Frigg server
128
- - `POST /api/frigg/stop` - Stop Frigg server
129
- - `GET /api/integrations` - List integrations
130
- - `POST /api/integrations/install` - Install integration
131
- - `GET /api/environment` - Environment variables
132
- - `PUT /api/environment` - Update environment variables
133
- - `GET /api/users` - List test users
134
- - `POST /api/users` - Create test user
135
- - `GET /api/connections` - List connections
136
-
137
- ## Styling
138
-
139
- This project uses Tailwind CSS for styling with:
140
-
141
- - **Design System**: Consistent spacing, colors, and typography
142
- - **Responsive Design**: Mobile-first approach
143
- - **Component Variants**: Button and component style variants
144
- - **Dark Mode Ready**: CSS custom properties for theming
145
-
146
- ### Custom Utilities
147
-
148
- - `cn()`: Utility for combining Tailwind classes with conditional logic
149
-
150
- ## Error Handling
151
-
152
- - **Error Boundaries**: React error boundaries catch component errors
153
- - **API Error Handling**: Axios interceptors handle API errors
154
- - **Loading States**: Loading spinners and disabled states
155
- - **Validation**: Form validation and user feedback
156
-
157
- ## Development
158
-
159
- ### Code Style
160
-
161
- - **ESLint**: Linting with React and React Hooks rules
162
- - **Prettier**: Code formatting (recommended)
163
- - **TypeScript Ready**: Prepared for TypeScript migration
164
-
165
- ### Best Practices
166
-
167
- - Functional components with hooks
168
- - Component composition over inheritance
169
- - Separation of concerns (UI, state, logic)
170
- - Error boundaries for robustness
171
- - Loading states for better UX
172
- - Responsive design principles
173
-
174
- ## Building and Deployment
175
-
176
- ```bash
177
- # Build for production
178
- npm run build
179
-
180
- # Preview production build
181
- npm run preview
182
- ```
183
-
184
- The build output will be in the `dist/` directory and can be served by any static file server.
185
-
186
- ## Environment Variables
187
-
188
- The application automatically detects the environment:
189
-
190
- - **Development**: API calls to `http://localhost:3001`
191
- - **Production**: API calls to the same origin
192
-
193
- ## Contributing
194
-
195
- 1. Follow the existing code style and patterns
196
- 2. Add error handling for new features
197
- 3. Include loading states for async operations
198
- 4. Write tests for new components (when testing is set up)
199
- 5. Update documentation for significant changes
200
-
201
- ## License
202
-
203
- This project is part of the Frigg Framework and follows the same licensing terms.
@@ -1,21 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "new-york",
4
- "rsc": false,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "tailwind.config.js",
8
- "css": "src/index.css",
9
- "baseColor": "neutral",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "aliases": {
14
- "components": "@/components",
15
- "utils": "@/lib/utils",
16
- "ui": "@/components/ui",
17
- "lib": "@/lib",
18
- "hooks": "@/hooks"
19
- },
20
- "iconLibrary": "lucide"
21
- }
@@ -1,371 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Merge Conflict Cleaner Script
4
-
5
- This script automatically cleans up merge conflicts by:
6
- 1. Removing duplicate imports
7
- 2. Keeping the most complete version of duplicated code blocks
8
- 3. Ensuring proper syntax after cleanup
9
- 4. Preserving functionality while removing conflicts
10
-
11
- Focus on these key patterns:
12
- - Import dedupe and consolidation
13
- - Taking the most complete version of components
14
- - Preserving industrial design system elements
15
- - Keeping proper React patterns
16
- """
17
-
18
- import os
19
- import re
20
- import sys
21
- from pathlib import Path
22
- from typing import List, Dict, Set, Tuple
23
- import logging
24
-
25
- # Configure logging
26
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
27
- logger = logging.getLogger(__name__)
28
-
29
- class MergeConflictCleaner:
30
- def __init__(self, base_path: str):
31
- self.base_path = Path(base_path)
32
- self.files_processed = 0
33
- self.conflicts_resolved = 0
34
- self.errors = []
35
-
36
- def find_conflict_files(self) -> List[Path]:
37
- """Find all files with merge conflict markers"""
38
- conflict_files = []
39
-
40
- for file_path in self.base_path.rglob('*.jsx'):
41
- if self._has_conflicts(file_path):
42
- conflict_files.append(file_path)
43
-
44
- for file_path in self.base_path.rglob('*.js'):
45
- if self._has_conflicts(file_path):
46
- conflict_files.append(file_path)
47
-
48
- for file_path in self.base_path.rglob('*.css'):
49
- if self._has_conflicts(file_path):
50
- conflict_files.append(file_path)
51
-
52
- return conflict_files
53
-
54
- def _has_conflicts(self, file_path: Path) -> bool:
55
- """Check if file has merge conflict markers"""
56
- try:
57
- with open(file_path, 'r', encoding='utf-8') as f:
58
- content = f.read()
59
- return any(marker in content for marker in ['<<<<<<<', '=======', '>>>>>>>'])
60
- except Exception as e:
61
- logger.error(f"Error reading {file_path}: {e}")
62
- return False
63
-
64
- def clean_file(self, file_path: Path) -> bool:
65
- """Clean merge conflicts in a single file"""
66
- try:
67
- with open(file_path, 'r', encoding='utf-8') as f:
68
- content = f.read()
69
-
70
- logger.info(f"Processing {file_path}")
71
-
72
- # Parse and resolve conflicts
73
- cleaned_content = self._resolve_conflicts(content, file_path)
74
-
75
- # Write cleaned content back
76
- with open(file_path, 'w', encoding='utf-8') as f:
77
- f.write(cleaned_content)
78
-
79
- self.files_processed += 1
80
- return True
81
-
82
- except Exception as e:
83
- error_msg = f"Error processing {file_path}: {e}"
84
- logger.error(error_msg)
85
- self.errors.append(error_msg)
86
- return False
87
-
88
- def _resolve_conflicts(self, content: str, file_path: Path) -> str:
89
- """Resolve merge conflicts in content"""
90
- lines = content.split('\n')
91
- cleaned_lines = []
92
- i = 0
93
-
94
- while i < len(lines):
95
- line = lines[i]
96
-
97
- # Check for conflict start
98
- if line.startswith('<<<<<<<'):
99
- conflict_resolved = self._resolve_conflict_block(lines, i, file_path)
100
- if conflict_resolved:
101
- resolved_lines, skip_count = conflict_resolved
102
- cleaned_lines.extend(resolved_lines)
103
- i += skip_count
104
- self.conflicts_resolved += 1
105
- else:
106
- # If we can't resolve, keep the line as is
107
- cleaned_lines.append(line)
108
- i += 1
109
- else:
110
- cleaned_lines.append(line)
111
- i += 1
112
-
113
- return '\n'.join(cleaned_lines)
114
-
115
- def _resolve_conflict_block(self, lines: List[str], start_idx: int, file_path: Path) -> Tuple[List[str], int]:
116
- """Resolve a single conflict block"""
117
- # Find the boundaries of the conflict
118
- head_start = start_idx
119
- separator_idx = -1
120
- end_idx = -1
121
-
122
- for i in range(start_idx + 1, len(lines)):
123
- if lines[i].startswith('======='):
124
- separator_idx = i
125
- elif lines[i].startswith('>>>>>>>'):
126
- end_idx = i
127
- break
128
-
129
- if separator_idx == -1 or end_idx == -1:
130
- logger.warning(f"Malformed conflict block at line {start_idx + 1} in {file_path}")
131
- return None
132
-
133
- # Extract the two versions
134
- head_version = lines[head_start + 1:separator_idx]
135
- incoming_version = lines[separator_idx + 1:end_idx]
136
-
137
- # Resolve based on file-specific logic
138
- resolved_lines = self._choose_best_version(head_version, incoming_version, file_path)
139
-
140
- # Return resolved lines and number of lines to skip
141
- return resolved_lines, end_idx - start_idx + 1
142
-
143
- def _choose_best_version(self, head_version: List[str], incoming_version: List[str], file_path: Path) -> List[str]:
144
- """Choose the best version based on content analysis"""
145
-
146
- # Handle imports specially
147
- if self._is_import_block(head_version) or self._is_import_block(incoming_version):
148
- return self._merge_imports(head_version, incoming_version)
149
-
150
- # Handle export statements
151
- if self._is_export_block(head_version) or self._is_export_block(incoming_version):
152
- return self._merge_exports(head_version, incoming_version)
153
-
154
- # For Layout.jsx and similar component files, prefer the more complete version
155
- if 'Layout.jsx' in str(file_path):
156
- return self._resolve_layout_conflicts(head_version, incoming_version)
157
-
158
- # For Button.jsx, prefer the shadcn re-export version
159
- if 'Button.jsx' in str(file_path):
160
- return self._resolve_button_conflicts(head_version, incoming_version)
161
-
162
- # General heuristic: prefer the version with more content
163
- if len(''.join(head_version).strip()) > len(''.join(incoming_version).strip()):
164
- return head_version
165
- else:
166
- return incoming_version
167
-
168
- def _is_import_block(self, lines: List[str]) -> bool:
169
- """Check if this is an import block"""
170
- content = ''.join(lines).strip()
171
- return content.startswith('import') or 'import' in content
172
-
173
- def _is_export_block(self, lines: List[str]) -> bool:
174
- """Check if this is an export block"""
175
- content = ''.join(lines).strip()
176
- return content.startswith('export') or 'export' in content
177
-
178
- def _merge_imports(self, head_version: List[str], incoming_version: List[str]) -> List[str]:
179
- """Merge and deduplicate imports"""
180
- all_imports = set()
181
- import_lines = []
182
-
183
- # Process both versions
184
- for version in [head_version, incoming_version]:
185
- for line in version:
186
- line = line.strip()
187
- if line and not line.startswith('//'):
188
- # Extract import statements
189
- if line.startswith('import'):
190
- if line not in all_imports:
191
- all_imports.add(line)
192
- import_lines.append(line)
193
- elif 'import' in line and '{' in line:
194
- # Handle multi-line imports
195
- if line not in all_imports:
196
- all_imports.add(line)
197
- import_lines.append(line)
198
-
199
- # Sort imports for consistency
200
- import_lines.sort()
201
- return import_lines
202
-
203
- def _merge_exports(self, head_version: List[str], incoming_version: List[str]) -> List[str]:
204
- """Merge exports, preferring named exports"""
205
- for version in [head_version, incoming_version]:
206
- for line in version:
207
- if 'export {' in line:
208
- return version
209
-
210
- # If no named exports, prefer the version with more content
211
- if len(''.join(head_version).strip()) > len(''.join(incoming_version).strip()):
212
- return head_version
213
- else:
214
- return incoming_version
215
-
216
- def _resolve_layout_conflicts(self, head_version: List[str], incoming_version: List[str]) -> List[str]:
217
- """Resolve Layout.jsx specific conflicts"""
218
- # Look for industrial design elements
219
- head_content = ''.join(head_version)
220
- incoming_content = ''.join(incoming_version)
221
-
222
- # Prefer version with industrial design elements
223
- industrial_keywords = ['industrial', 'FriggLogo', 'ThemeToggle', 'RepositoryPicker']
224
-
225
- head_score = sum(1 for keyword in industrial_keywords if keyword in head_content)
226
- incoming_score = sum(1 for keyword in industrial_keywords if keyword in incoming_content)
227
-
228
- if head_score > incoming_score:
229
- return head_version
230
- elif incoming_score > head_score:
231
- return incoming_version
232
- else:
233
- # If equal, prefer the longer version
234
- return head_version if len(head_content) > len(incoming_content) else incoming_version
235
-
236
- def _resolve_button_conflicts(self, head_version: List[str], incoming_version: List[str]) -> List[str]:
237
- """Resolve Button.jsx conflicts - prefer shadcn re-export"""
238
- head_content = ''.join(head_version)
239
- incoming_content = ''.join(incoming_version)
240
-
241
- # Prefer the shadcn re-export version
242
- if 'ui/button' in head_content:
243
- return head_version
244
- elif 'ui/button' in incoming_content:
245
- return incoming_version
246
- else:
247
- # If neither has shadcn, prefer the more complete implementation
248
- return head_version if len(head_content) > len(incoming_content) else incoming_version
249
-
250
- def verify_syntax(self, file_path: Path) -> bool:
251
- """Basic syntax verification for JS/JSX files"""
252
- try:
253
- with open(file_path, 'r', encoding='utf-8') as f:
254
- content = f.read()
255
-
256
- # Basic checks
257
- if file_path.suffix in ['.jsx', '.js']:
258
- # Check for unbalanced braces
259
- open_braces = content.count('{')
260
- close_braces = content.count('}')
261
- if open_braces != close_braces:
262
- logger.warning(f"Unbalanced braces in {file_path}")
263
- return False
264
-
265
- # Check for unbalanced parentheses
266
- open_parens = content.count('(')
267
- close_parens = content.count(')')
268
- if open_parens != close_parens:
269
- logger.warning(f"Unbalanced parentheses in {file_path}")
270
- return False
271
-
272
- # Check for remaining conflict markers
273
- if any(marker in content for marker in ['<<<<<<<', '=======', '>>>>>>>']):
274
- logger.warning(f"Remaining conflict markers in {file_path}")
275
- return False
276
-
277
- return True
278
-
279
- except Exception as e:
280
- logger.error(f"Error verifying syntax for {file_path}: {e}")
281
- return False
282
-
283
- def run(self) -> Dict[str, any]:
284
- """Run the merge conflict cleaner"""
285
- logger.info(f"Starting merge conflict cleanup in {self.base_path}")
286
-
287
- # Find all files with conflicts
288
- conflict_files = self.find_conflict_files()
289
-
290
- if not conflict_files:
291
- logger.info("No merge conflicts found!")
292
- return {
293
- 'files_processed': 0,
294
- 'conflicts_resolved': 0,
295
- 'errors': [],
296
- 'success': True
297
- }
298
-
299
- logger.info(f"Found {len(conflict_files)} files with merge conflicts")
300
-
301
- # Process each file
302
- successful_files = []
303
- failed_files = []
304
-
305
- for file_path in conflict_files:
306
- if self.clean_file(file_path):
307
- if self.verify_syntax(file_path):
308
- successful_files.append(file_path)
309
- logger.info(f"✓ Successfully cleaned {file_path}")
310
- else:
311
- failed_files.append(file_path)
312
- logger.error(f"✗ Syntax issues after cleaning {file_path}")
313
- else:
314
- failed_files.append(file_path)
315
- logger.error(f"✗ Failed to clean {file_path}")
316
-
317
- # Summary
318
- logger.info(f"Cleanup complete!")
319
- logger.info(f"Files processed: {self.files_processed}")
320
- logger.info(f"Conflicts resolved: {self.conflicts_resolved}")
321
- logger.info(f"Successful: {len(successful_files)}")
322
- logger.info(f"Failed: {len(failed_files)}")
323
-
324
- if failed_files:
325
- logger.error("Failed files:")
326
- for file_path in failed_files:
327
- logger.error(f" - {file_path}")
328
-
329
- if self.errors:
330
- logger.error("Errors encountered:")
331
- for error in self.errors:
332
- logger.error(f" - {error}")
333
-
334
- return {
335
- 'files_processed': self.files_processed,
336
- 'conflicts_resolved': self.conflicts_resolved,
337
- 'successful_files': successful_files,
338
- 'failed_files': failed_files,
339
- 'errors': self.errors,
340
- 'success': len(failed_files) == 0
341
- }
342
-
343
- def main():
344
- """Main entry point"""
345
- if len(sys.argv) != 2:
346
- print("Usage: python merge-conflict-cleaner.py <path-to-src-directory>")
347
- sys.exit(1)
348
-
349
- src_path = sys.argv[1]
350
-
351
- if not os.path.exists(src_path):
352
- print(f"Error: Path {src_path} does not exist")
353
- sys.exit(1)
354
-
355
- cleaner = MergeConflictCleaner(src_path)
356
- result = cleaner.run()
357
-
358
- if result['success']:
359
- print(f"\n✓ All merge conflicts resolved successfully!")
360
- print(f" Files processed: {result['files_processed']}")
361
- print(f" Conflicts resolved: {result['conflicts_resolved']}")
362
- sys.exit(0)
363
- else:
364
- print(f"\n✗ Some issues occurred during cleanup")
365
- print(f" Files processed: {result['files_processed']}")
366
- print(f" Conflicts resolved: {result['conflicts_resolved']}")
367
- print(f" Errors: {len(result['errors'])}")
368
- sys.exit(1)
369
-
370
- if __name__ == "__main__":
371
- main()