@friggframework/devtools 2.0.0--canary.400.bed3308.0 → 2.0.0--canary.404.e9d4980.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 (182) hide show
  1. package/frigg-cli/build-command/index.js +3 -18
  2. package/frigg-cli/deploy-command/index.js +3 -19
  3. package/frigg-cli/index.js +1 -73
  4. package/frigg-cli/install-command/index.js +2 -15
  5. package/frigg-cli/start-command/index.js +2 -17
  6. package/infrastructure/create-frigg-infrastructure.js +2 -2
  7. package/infrastructure/serverless-template.js +79 -529
  8. package/package.json +5 -9
  9. package/frigg-cli/.eslintrc.js +0 -141
  10. package/frigg-cli/__tests__/jest.config.js +0 -102
  11. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
  12. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
  13. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
  14. package/frigg-cli/__tests__/utils/command-tester.js +0 -170
  15. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  16. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  17. package/frigg-cli/__tests__/utils/test-setup.js +0 -286
  18. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
  19. package/frigg-cli/generate-command/azure-generator.js +0 -43
  20. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  21. package/frigg-cli/generate-command/index.js +0 -350
  22. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  23. package/frigg-cli/generate-iam-command.js +0 -115
  24. package/frigg-cli/package.json +0 -75
  25. package/frigg-cli/ui-command/index.js +0 -167
  26. package/frigg-cli/utils/app-resolver.js +0 -319
  27. package/frigg-cli/utils/backend-path.js +0 -38
  28. package/frigg-cli/utils/process-manager.js +0 -199
  29. package/frigg-cli/utils/repo-detection.js +0 -405
  30. package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +0 -245
  31. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +0 -620
  32. package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +0 -268
  33. package/infrastructure/GENERATE-IAM-DOCS.md +0 -253
  34. package/infrastructure/IAM-POLICY-TEMPLATES.md +0 -176
  35. package/infrastructure/README-TESTING.md +0 -332
  36. package/infrastructure/README.md +0 -421
  37. package/infrastructure/WEBSOCKET-CONFIGURATION.md +0 -105
  38. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +0 -391
  39. package/infrastructure/__tests__/helpers/test-utils.js +0 -277
  40. package/infrastructure/aws-discovery.js +0 -568
  41. package/infrastructure/aws-discovery.test.js +0 -373
  42. package/infrastructure/build-time-discovery.js +0 -206
  43. package/infrastructure/build-time-discovery.test.js +0 -375
  44. package/infrastructure/frigg-deployment-iam-stack.yaml +0 -393
  45. package/infrastructure/iam-generator.js +0 -810
  46. package/infrastructure/iam-generator.test.js +0 -169
  47. package/infrastructure/iam-policy-basic.json +0 -236
  48. package/infrastructure/iam-policy-full.json +0 -305
  49. package/infrastructure/integration.test.js +0 -383
  50. package/infrastructure/run-discovery.js +0 -110
  51. package/infrastructure/serverless-template.test.js +0 -553
  52. package/management-ui/.eslintrc.js +0 -22
  53. package/management-ui/README.md +0 -203
  54. package/management-ui/components.json +0 -21
  55. package/management-ui/index.html +0 -13
  56. package/management-ui/merge-conflict-cleaner.py +0 -371
  57. package/management-ui/package-lock.json +0 -10997
  58. package/management-ui/package.json +0 -76
  59. package/management-ui/postcss.config.js +0 -6
  60. package/management-ui/server/api/backend.js +0 -256
  61. package/management-ui/server/api/cli.js +0 -315
  62. package/management-ui/server/api/codegen.js +0 -663
  63. package/management-ui/server/api/connections.js +0 -857
  64. package/management-ui/server/api/discovery.js +0 -185
  65. package/management-ui/server/api/environment/index.js +0 -1
  66. package/management-ui/server/api/environment/router.js +0 -378
  67. package/management-ui/server/api/environment.js +0 -328
  68. package/management-ui/server/api/integrations.js +0 -479
  69. package/management-ui/server/api/logs.js +0 -248
  70. package/management-ui/server/api/monitoring.js +0 -282
  71. package/management-ui/server/api/open-ide.js +0 -31
  72. package/management-ui/server/api/project.js +0 -553
  73. package/management-ui/server/api/users/sessions.js +0 -371
  74. package/management-ui/server/api/users/simulation.js +0 -254
  75. package/management-ui/server/api/users.js +0 -362
  76. package/management-ui/server/api-contract.md +0 -275
  77. package/management-ui/server/index.js +0 -428
  78. package/management-ui/server/middleware/errorHandler.js +0 -70
  79. package/management-ui/server/middleware/security.js +0 -32
  80. package/management-ui/server/processManager.js +0 -296
  81. package/management-ui/server/server.js +0 -188
  82. package/management-ui/server/services/aws-monitor.js +0 -413
  83. package/management-ui/server/services/npm-registry.js +0 -347
  84. package/management-ui/server/services/template-engine.js +0 -538
  85. package/management-ui/server/utils/cliIntegration.js +0 -220
  86. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  87. package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
  88. package/management-ui/server/utils/environment/encryption.js +0 -278
  89. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  90. package/management-ui/server/utils/import-commonjs.js +0 -28
  91. package/management-ui/server/utils/response.js +0 -83
  92. package/management-ui/server/websocket/handler.js +0 -325
  93. package/management-ui/src/App.jsx +0 -51
  94. package/management-ui/src/assets/FriggLogo.svg +0 -1
  95. package/management-ui/src/components/AppRouter.jsx +0 -65
  96. package/management-ui/src/components/Button.jsx +0 -2
  97. package/management-ui/src/components/Card.jsx +0 -9
  98. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  99. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  100. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  101. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  102. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  103. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  104. package/management-ui/src/components/IntegrationCard.jsx +0 -199
  105. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
  106. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  107. package/management-ui/src/components/IntegrationStatus.jsx +0 -235
  108. package/management-ui/src/components/Layout.jsx +0 -250
  109. package/management-ui/src/components/LoadingSpinner.jsx +0 -45
  110. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  111. package/management-ui/src/components/SessionMonitor.jsx +0 -255
  112. package/management-ui/src/components/StatusBadge.jsx +0 -70
  113. package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
  114. package/management-ui/src/components/UserSimulation.jsx +0 -299
  115. package/management-ui/src/components/Welcome.jsx +0 -434
  116. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  117. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  118. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  119. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  120. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  121. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  122. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  123. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  124. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  125. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  126. package/management-ui/src/components/codegen/index.js +0 -10
  127. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  128. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  129. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  130. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  131. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  132. package/management-ui/src/components/connections/index.js +0 -5
  133. package/management-ui/src/components/index.js +0 -21
  134. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  135. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  136. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  137. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  138. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  139. package/management-ui/src/components/monitoring/index.js +0 -6
  140. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  141. package/management-ui/src/components/theme-provider.jsx +0 -52
  142. package/management-ui/src/components/theme-toggle.jsx +0 -39
  143. package/management-ui/src/components/ui/badge.tsx +0 -36
  144. package/management-ui/src/components/ui/button.test.jsx +0 -56
  145. package/management-ui/src/components/ui/button.tsx +0 -57
  146. package/management-ui/src/components/ui/card.tsx +0 -76
  147. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  148. package/management-ui/src/components/ui/select.tsx +0 -157
  149. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  150. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  151. package/management-ui/src/hooks/useSocket.jsx +0 -58
  152. package/management-ui/src/index.css +0 -194
  153. package/management-ui/src/lib/utils.ts +0 -6
  154. package/management-ui/src/main.jsx +0 -10
  155. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  156. package/management-ui/src/pages/Connections.jsx +0 -252
  157. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
  158. package/management-ui/src/pages/Dashboard.jsx +0 -311
  159. package/management-ui/src/pages/Environment.jsx +0 -314
  160. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
  161. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
  162. package/management-ui/src/pages/IntegrationTest.jsx +0 -494
  163. package/management-ui/src/pages/Integrations.jsx +0 -254
  164. package/management-ui/src/pages/Monitoring.jsx +0 -17
  165. package/management-ui/src/pages/Simulation.jsx +0 -155
  166. package/management-ui/src/pages/Users.jsx +0 -492
  167. package/management-ui/src/services/api.js +0 -41
  168. package/management-ui/src/services/apiModuleService.js +0 -193
  169. package/management-ui/src/services/websocket-handlers.js +0 -120
  170. package/management-ui/src/test/api/project.test.js +0 -273
  171. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  172. package/management-ui/src/test/mocks/server.js +0 -178
  173. package/management-ui/src/test/setup.js +0 -61
  174. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  175. package/management-ui/src/utils/repository.js +0 -98
  176. package/management-ui/src/utils/repository.test.js +0 -118
  177. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  178. package/management-ui/tailwind.config.js +0 -63
  179. package/management-ui/tsconfig.json +0 -37
  180. package/management-ui/tsconfig.node.json +0 -10
  181. package/management-ui/vite.config.js +0 -26
  182. package/management-ui/vitest.config.js +0 -38
@@ -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,13 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Frigg Management UI</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="/src/main.jsx"></script>
12
- </body>
13
- </html>
@@ -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()