@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.
- package/frigg-cli/build-command/index.js +2 -15
- package/frigg-cli/deploy-command/index.js +2 -15
- package/frigg-cli/index.js +4 -66
- package/frigg-cli/install-command/index.js +2 -15
- package/frigg-cli/start-command/index.js +2 -17
- package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +19 -43
- package/infrastructure/IAM-POLICY-TEMPLATES.md +1 -1
- package/infrastructure/frigg-deployment-iam-stack.yaml +2 -16
- package/infrastructure/iam-generator.js +6 -129
- package/infrastructure/iam-policy-basic.json +5 -29
- package/infrastructure/iam-policy-full.json +5 -28
- package/infrastructure/serverless-template.js +3 -190
- package/infrastructure/serverless-template.test.js +0 -12
- package/management-ui/dist/assets/index-CbM64Oba.js +1221 -0
- package/management-ui/dist/assets/index-CkvseXTC.css +1 -0
- package/management-ui/{index.html → dist/index.html} +2 -1
- package/package.json +5 -5
- package/frigg-cli/.eslintrc.js +0 -141
- package/frigg-cli/__tests__/jest.config.js +0 -102
- package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
- package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
- package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
- package/frigg-cli/__tests__/utils/command-tester.js +0 -170
- package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
- package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
- package/frigg-cli/__tests__/utils/test-setup.js +0 -286
- package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
- package/frigg-cli/generate-command/azure-generator.js +0 -43
- package/frigg-cli/generate-command/gcp-generator.js +0 -47
- package/frigg-cli/generate-command/index.js +0 -350
- package/frigg-cli/generate-command/terraform-generator.js +0 -555
- package/frigg-cli/package.json +0 -75
- package/frigg-cli/ui-command/index.js +0 -167
- package/frigg-cli/utils/app-resolver.js +0 -319
- package/frigg-cli/utils/backend-path.js +0 -38
- package/frigg-cli/utils/process-manager.js +0 -199
- package/frigg-cli/utils/repo-detection.js +0 -405
- package/management-ui/.eslintrc.js +0 -22
- package/management-ui/README.md +0 -203
- package/management-ui/components.json +0 -21
- package/management-ui/merge-conflict-cleaner.py +0 -371
- package/management-ui/package-lock.json +0 -10997
- package/management-ui/package.json +0 -76
- package/management-ui/postcss.config.js +0 -6
- package/management-ui/server/api/backend.js +0 -256
- package/management-ui/server/api/cli.js +0 -315
- package/management-ui/server/api/codegen.js +0 -663
- package/management-ui/server/api/connections.js +0 -857
- package/management-ui/server/api/discovery.js +0 -185
- package/management-ui/server/api/environment/index.js +0 -1
- package/management-ui/server/api/environment/router.js +0 -378
- package/management-ui/server/api/environment.js +0 -328
- package/management-ui/server/api/integrations.js +0 -479
- package/management-ui/server/api/logs.js +0 -248
- package/management-ui/server/api/monitoring.js +0 -282
- package/management-ui/server/api/open-ide.js +0 -31
- package/management-ui/server/api/project.js +0 -553
- package/management-ui/server/api/users/sessions.js +0 -371
- package/management-ui/server/api/users/simulation.js +0 -254
- package/management-ui/server/api/users.js +0 -362
- package/management-ui/server/api-contract.md +0 -275
- package/management-ui/server/index.js +0 -428
- package/management-ui/server/middleware/errorHandler.js +0 -70
- package/management-ui/server/middleware/security.js +0 -32
- package/management-ui/server/processManager.js +0 -296
- package/management-ui/server/server.js +0 -188
- package/management-ui/server/services/aws-monitor.js +0 -413
- package/management-ui/server/services/npm-registry.js +0 -347
- package/management-ui/server/services/template-engine.js +0 -538
- package/management-ui/server/utils/cliIntegration.js +0 -220
- package/management-ui/server/utils/environment/auditLogger.js +0 -471
- package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
- package/management-ui/server/utils/environment/encryption.js +0 -278
- package/management-ui/server/utils/environment/envFileManager.js +0 -286
- package/management-ui/server/utils/import-commonjs.js +0 -28
- package/management-ui/server/utils/response.js +0 -83
- package/management-ui/server/websocket/handler.js +0 -325
- package/management-ui/src/App.jsx +0 -51
- package/management-ui/src/components/AppRouter.jsx +0 -65
- package/management-ui/src/components/Button.jsx +0 -2
- package/management-ui/src/components/Card.jsx +0 -9
- package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
- package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
- package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
- package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
- package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
- package/management-ui/src/components/ErrorBoundary.jsx +0 -73
- package/management-ui/src/components/IntegrationCard.jsx +0 -199
- package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
- package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
- package/management-ui/src/components/IntegrationStatus.jsx +0 -235
- package/management-ui/src/components/Layout.jsx +0 -250
- package/management-ui/src/components/LoadingSpinner.jsx +0 -45
- package/management-ui/src/components/RepositoryPicker.jsx +0 -248
- package/management-ui/src/components/SessionMonitor.jsx +0 -255
- package/management-ui/src/components/StatusBadge.jsx +0 -70
- package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
- package/management-ui/src/components/UserSimulation.jsx +0 -299
- package/management-ui/src/components/Welcome.jsx +0 -434
- package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
- package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
- package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
- package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
- package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
- package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
- package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
- package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
- package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
- package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
- package/management-ui/src/components/codegen/index.js +0 -10
- package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
- package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
- package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
- package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
- package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
- package/management-ui/src/components/connections/index.js +0 -5
- package/management-ui/src/components/index.js +0 -21
- package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
- package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
- package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
- package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
- package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
- package/management-ui/src/components/monitoring/index.js +0 -6
- package/management-ui/src/components/monitoring/monitoring.css +0 -218
- package/management-ui/src/components/theme-provider.jsx +0 -52
- package/management-ui/src/components/theme-toggle.jsx +0 -39
- package/management-ui/src/components/ui/badge.tsx +0 -36
- package/management-ui/src/components/ui/button.test.jsx +0 -56
- package/management-ui/src/components/ui/button.tsx +0 -57
- package/management-ui/src/components/ui/card.tsx +0 -76
- package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
- package/management-ui/src/components/ui/select.tsx +0 -157
- package/management-ui/src/components/ui/skeleton.jsx +0 -15
- package/management-ui/src/hooks/useFrigg.jsx +0 -387
- package/management-ui/src/hooks/useSocket.jsx +0 -58
- package/management-ui/src/index.css +0 -194
- package/management-ui/src/lib/utils.ts +0 -6
- package/management-ui/src/main.jsx +0 -10
- package/management-ui/src/pages/CodeGeneration.jsx +0 -14
- package/management-ui/src/pages/Connections.jsx +0 -252
- package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
- package/management-ui/src/pages/Dashboard.jsx +0 -311
- package/management-ui/src/pages/Environment.jsx +0 -314
- package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
- package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
- package/management-ui/src/pages/IntegrationTest.jsx +0 -494
- package/management-ui/src/pages/Integrations.jsx +0 -254
- package/management-ui/src/pages/Monitoring.jsx +0 -17
- package/management-ui/src/pages/Simulation.jsx +0 -155
- package/management-ui/src/pages/Users.jsx +0 -492
- package/management-ui/src/services/api.js +0 -41
- package/management-ui/src/services/apiModuleService.js +0 -193
- package/management-ui/src/services/websocket-handlers.js +0 -120
- package/management-ui/src/test/api/project.test.js +0 -273
- package/management-ui/src/test/components/Welcome.test.jsx +0 -378
- package/management-ui/src/test/mocks/server.js +0 -178
- package/management-ui/src/test/setup.js +0 -61
- package/management-ui/src/test/utils/test-utils.jsx +0 -134
- package/management-ui/src/utils/repository.js +0 -98
- package/management-ui/src/utils/repository.test.js +0 -118
- package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
- package/management-ui/tailwind.config.js +0 -63
- package/management-ui/tsconfig.json +0 -37
- package/management-ui/tsconfig.node.json +0 -10
- package/management-ui/vite.config.js +0 -26
- package/management-ui/vitest.config.js +0 -38
- /package/management-ui/{src/assets/FriggLogo.svg → dist/assets/FriggLogo-B7Xx8ZW1.svg} +0 -0
package/management-ui/README.md
DELETED
|
@@ -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()
|