mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-15 21:03:47 +00:00
Compare commits
114 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5cd9de9ac5 | |||
| d85fb26a5d | |||
| 7756dc6a4c | |||
| ff76137339 | |||
| 61db35daad | |||
| 26c1cacc9d | |||
| 8dddbaa86d | |||
| d46fafb421 | |||
| 25178928a0 | |||
| 2fe9c0f854 | |||
| 2f68dc018e | |||
| 8b8e77214c | |||
| 89589dcf9f | |||
| 250ad975d4 | |||
| b649e73c80 | |||
| 839e36adb9 | |||
| f02c0c3163 | |||
| 83c41751ea | |||
| 8058ffd217 | |||
| a3db62b0f8 | |||
| dc43bf1329 | |||
| 0a7b1b2bd0 | |||
| 94e6617638 | |||
| 76995dbc1b | |||
| be6cda7d8a | |||
| 9130eb68a8 | |||
| 200428498f | |||
| f60c9c72aa | |||
| 487919cedc | |||
| b046aedcee | |||
| 0c5216933a | |||
| 191dc8ba24 | |||
| d88c890ba7 | |||
| a34c60947d | |||
| 56fddb6fcb | |||
| b9bd00f86e | |||
| d1ae7f659d | |||
| b127c5ff4f | |||
| 75a87400eb | |||
| d4dccdb574 | |||
| a34421f5b2 | |||
| 7a5cf94d45 | |||
| 134f58b38b | |||
| 84dcda9363 | |||
| d81cf20f5e | |||
| 86fd8574f1 | |||
| 6e175e2b36 | |||
| c7fba8dbb1 | |||
| 0c2ac176a7 | |||
| 59a38dad0a | |||
| 6ac536ebad | |||
| 12418eb5b2 | |||
| e364e9b38e | |||
| 402f9fa909 | |||
| 5ac25e2a26 | |||
| 5fbac89e67 | |||
| f2fb938e5f | |||
| cef420d1d8 | |||
| 94f69cee3f | |||
| 23e72aedfd | |||
| 7957ed06e4 | |||
| 5f1a2d9a17 | |||
| dbe12ce681 | |||
| d66efdb74f | |||
| c3d1855c65 | |||
| 4f4e5296a4 | |||
| 61da21c507 | |||
| 347e8c40df | |||
| f0ae53c41b | |||
| 53f9e888df | |||
| c1d06028c3 | |||
| fa64e98ef9 | |||
| 2df2c4e73d | |||
| 7d904c4a2c | |||
| cf945e3665 | |||
| 880907cc93 | |||
| 22162e5b9b | |||
| 981705e81d | |||
| 5445cb2b78 | |||
| 2667af9437 | |||
| 58947f4455 | |||
| b7f52d4d73 | |||
| b854a4956c | |||
| 07367b24b6 | |||
| 1b076cc612 | |||
| 81d1db09e4 | |||
| f62bb7f773 | |||
| 0906ddfe6e | |||
| 96864dbeb4 | |||
| 3a663f1b47 | |||
| b9d5965aa6 | |||
| 47f8d3f23b | |||
| c71b8b4211 | |||
| 07a8fc3e50 | |||
| c90c45ec61 | |||
| 4e93ac7d88 | |||
| 9ce69a80d7 | |||
| 602f21b475 | |||
| 3b347f7ae5 | |||
| 1f83fb68f0 | |||
| a2481362a2 | |||
| f49c32d26f | |||
| 18e3f7c6fc | |||
| 6e5b34f878 | |||
| b0880129ad | |||
| b27916852f | |||
| 7b577cb343 | |||
| fc7731041e | |||
| 7dc1de913f | |||
| 30b07ba8f2 | |||
| c69e03d783 | |||
| 2ff31f5a82 | |||
| 08f9143993 | |||
| d0b139e388 |
@@ -0,0 +1,578 @@
|
||||
language: "en"
|
||||
early_access: false
|
||||
reviews:
|
||||
request_changes_workflow: false
|
||||
high_level_summary: true
|
||||
poem: false
|
||||
review_status: true
|
||||
collapse_walkthrough: false
|
||||
path_filters:
|
||||
- "!**/.xml"
|
||||
- "!**/__generated__/**"
|
||||
- "!**/generated/**"
|
||||
- "!**/*.json"
|
||||
- "!**/*.svg"
|
||||
- "!**/*.png"
|
||||
- "!**/*.jpg"
|
||||
- "!**/*.gif"
|
||||
- "!**/*.lock"
|
||||
- "!**/node_modules/**"
|
||||
- "!**/dist/**"
|
||||
- "!**/public/locales/**"
|
||||
- "!**/repo-images/**"
|
||||
path_instructions:
|
||||
- path: "**/*.{ts,tsx}"
|
||||
instructions: |
|
||||
Review TypeScript and React code for Termix server management platform. Key considerations:
|
||||
|
||||
**Architecture & Patterns:**
|
||||
- Follow the established multi-port backend architecture (SSH: 8081, Tunnel: 8083, File Manager: 8084, Stats: 8085)
|
||||
- Use proper separation between Desktop and Mobile UI components
|
||||
- Maintain consistent state management patterns with React hooks and context
|
||||
- Follow the established tab-based navigation system
|
||||
|
||||
**Database & Backend:**
|
||||
- Use Drizzle ORM with SQLite for database operations
|
||||
- Implement proper JWT authentication middleware patterns
|
||||
- Follow the established API error handling patterns in main-axios.ts
|
||||
- Use proper logging with the structured logger system (apiLogger, authLogger, sshLogger, etc.)
|
||||
- Maintain proper input validation and sanitization
|
||||
|
||||
**UI/UX Guidelines:**
|
||||
- Use Shadcn/UI components with Tailwind CSS for consistent styling
|
||||
- Follow the established theme system with dark/light mode support
|
||||
- Use proper responsive design patterns for Desktop/Mobile views
|
||||
- Implement proper loading states and error handling
|
||||
- Use the established confirmation patterns with useConfirmation hook
|
||||
- Use CSS variables and classes from index.css instead of hardcoding colors
|
||||
- Follow the established color token system (--primary, --secondary, --background, etc.)
|
||||
- Use proper Tailwind CSS classes instead of inline styles
|
||||
- Implement proper focus states and accessibility indicators
|
||||
|
||||
**SSH & Security:**
|
||||
- Implement proper SSH connection management with session handling
|
||||
- Use secure credential storage and management patterns
|
||||
- Follow the established authentication flow (password, key, credential-based)
|
||||
- Implement proper file operation security and validation
|
||||
|
||||
**Code Quality:**
|
||||
- Use proper TypeScript types from the centralized types/index.ts
|
||||
- Follow the established API patterns in main-axios.ts
|
||||
- Implement proper error boundaries and fallback UI
|
||||
- Use proper React patterns (hooks, context, refs)
|
||||
- Maintain consistent naming conventions and file organization
|
||||
- All API interactions should go through main-axios.ts functions, not direct axios calls
|
||||
- Use proper component interaction patterns through props and callbacks
|
||||
- Follow the established state management patterns with useState and useEffect
|
||||
- Use proper event handling and form submission patterns
|
||||
|
||||
**Bug Detection & Fixes:**
|
||||
- Identify and fix memory leaks in useEffect cleanup functions
|
||||
- Fix missing dependency arrays in useEffect hooks
|
||||
- Resolve infinite re-render loops caused by object/array dependencies
|
||||
- Fix race conditions in async operations and API calls
|
||||
- Identify and fix potential null/undefined access errors
|
||||
- Fix improper state updates that cause stale closures
|
||||
- Resolve event handler memory leaks and proper cleanup
|
||||
- Fix improper error handling that could crash the application
|
||||
- Identify and fix accessibility issues and keyboard navigation problems
|
||||
- Fix responsive design issues and mobile compatibility problems
|
||||
- Resolve TypeScript type errors and missing type definitions
|
||||
- Fix improper form validation and submission handling
|
||||
- Identify and fix performance issues and unnecessary re-renders
|
||||
- Fix improper API error handling and user feedback
|
||||
- Resolve authentication state inconsistencies and token management issues
|
||||
|
||||
**Internationalization:**
|
||||
- Use the i18next translation system with proper t() function calls
|
||||
- Support both English and Chinese locales
|
||||
- Use proper translation keys and fallbacks
|
||||
|
||||
**Performance:**
|
||||
- Implement proper cleanup in useEffect hooks
|
||||
- Use proper memoization where appropriate
|
||||
- Follow the established polling and refresh patterns
|
||||
- Implement proper connection pooling and resource management
|
||||
|
||||
**Specific to Termix:**
|
||||
- Maintain compatibility with Electron and web versions
|
||||
- Follow the established terminal integration patterns with xterm.js
|
||||
- Use proper file manager operations and SSH session management
|
||||
- Implement proper tunnel management and status tracking
|
||||
- Follow the established alert and notification system patterns
|
||||
|
||||
Highlight any deviations from these patterns and suggest improvements for maintainability, security, and user experience.
|
||||
|
||||
**General Bug Detection & Fixes:**
|
||||
- Identify and fix common React bugs (missing keys, improper state updates, memory leaks)
|
||||
- Fix TypeScript errors and type safety issues
|
||||
- Resolve accessibility violations and keyboard navigation problems
|
||||
- Fix responsive design issues and mobile compatibility problems
|
||||
- Identify and fix performance bottlenecks and unnecessary re-renders
|
||||
- Fix improper error handling that could crash the application
|
||||
- Resolve security vulnerabilities and improper data handling
|
||||
- Fix improper form validation and user input handling
|
||||
- Identify and fix race conditions and async operation issues
|
||||
- Fix improper cleanup and resource management
|
||||
- Resolve improper authentication and authorization issues
|
||||
- Fix improper API error handling and user feedback
|
||||
- Identify and fix potential null/undefined access errors
|
||||
- Fix improper event handling and memory leaks
|
||||
- Resolve improper state management and data flow issues
|
||||
|
||||
- path: "**/backend/**/*.{ts,js}"
|
||||
instructions: |
|
||||
Review backend code for Termix server management platform. Key considerations:
|
||||
|
||||
**Backend Architecture:**
|
||||
- Follow the multi-port microservice architecture (SSH: 8081, Tunnel: 8083, File Manager: 8084, Stats: 8085)
|
||||
- Use Express.js with proper middleware patterns
|
||||
- Implement proper CORS and security headers
|
||||
- Use proper request/response logging with structured logging
|
||||
|
||||
**Database Operations:**
|
||||
- Use Drizzle ORM with proper schema definitions
|
||||
- Implement proper database migrations and schema updates
|
||||
- Use proper transaction handling for critical operations
|
||||
- Follow the established database connection patterns
|
||||
|
||||
**Authentication & Security:**
|
||||
- Implement proper JWT token validation and refresh
|
||||
- Use bcryptjs for password hashing with proper salt rounds
|
||||
- Implement proper input validation and sanitization
|
||||
- Use proper CORS configuration for security
|
||||
- Implement proper rate limiting and security headers
|
||||
|
||||
**SSH Operations:**
|
||||
- Use ssh2 library with proper connection management
|
||||
- Implement proper SSH key handling and validation
|
||||
- Use proper session management and cleanup
|
||||
- Implement proper error handling for SSH operations
|
||||
- Use proper file operation security and validation
|
||||
|
||||
**API Design:**
|
||||
- Follow RESTful API patterns with proper HTTP status codes
|
||||
- Implement proper error response formatting
|
||||
- Use proper request/response validation
|
||||
- Implement proper API versioning and backward compatibility
|
||||
- All API routes should be defined in main-axios.ts, not scattered across components
|
||||
- Use the established multi-port API architecture (SSH: 8081, Tunnel: 8083, File Manager: 8084, Stats: 8085)
|
||||
- Follow the established error handling patterns with handleApiError function
|
||||
- Use proper structured logging with service-specific loggers (apiLogger, authLogger, sshLogger, etc.)
|
||||
|
||||
**Logging & Monitoring:**
|
||||
- Use the structured logging system with proper context
|
||||
- Implement proper error tracking and reporting
|
||||
- Use proper performance monitoring and metrics
|
||||
- Implement proper health checks and status endpoints
|
||||
|
||||
Highlight any security vulnerabilities, performance issues, or architectural deviations.
|
||||
|
||||
- path: "**/components/**/*.{ts,tsx}"
|
||||
instructions: |
|
||||
Review UI components for Termix server management platform. Key considerations:
|
||||
|
||||
**Component Design:**
|
||||
- Use Shadcn/UI components as the foundation
|
||||
- Implement proper component composition and reusability
|
||||
- Use proper TypeScript interfaces and prop types
|
||||
- Follow the established component naming conventions
|
||||
|
||||
**Styling & Theming:**
|
||||
- Use Tailwind CSS with proper responsive design
|
||||
- Implement proper dark/light theme support
|
||||
- Use proper color tokens and design system consistency
|
||||
- Implement proper accessibility features (ARIA labels, keyboard navigation)
|
||||
- Use CSS variables from index.css instead of hardcoding colors (--primary, --secondary, --background, etc.)
|
||||
- Follow the established color scheme and design tokens
|
||||
- Use proper Tailwind CSS utility classes instead of custom CSS
|
||||
- Implement proper focus states and hover effects
|
||||
|
||||
**State Management:**
|
||||
- Use proper React hooks and context patterns
|
||||
- Implement proper state lifting and prop drilling avoidance
|
||||
- Use proper memoization with useMemo and useCallback
|
||||
- Implement proper cleanup in useEffect hooks
|
||||
|
||||
**Form Handling:**
|
||||
- Use react-hook-form with proper validation
|
||||
- Implement proper form state management
|
||||
- Use proper error handling and user feedback
|
||||
- Implement proper accessibility for form elements
|
||||
|
||||
**SSH Integration:**
|
||||
- Implement proper SSH connection status indicators
|
||||
- Use proper terminal integration with xterm.js
|
||||
- Implement proper file manager operations
|
||||
- Use proper tunnel status and management UI
|
||||
|
||||
Highlight any UI/UX issues, accessibility problems, or performance concerns.
|
||||
|
||||
- path: "**/types/**/*.{ts,js}"
|
||||
instructions: |
|
||||
Review type definitions for Termix server management platform. Key considerations:
|
||||
|
||||
**Type Design:**
|
||||
- Use proper TypeScript interfaces and type definitions
|
||||
- Implement proper type safety and validation
|
||||
- Use proper generic types and utility types
|
||||
- Follow the established type naming conventions
|
||||
|
||||
**API Types:**
|
||||
- Define proper request/response types for all API endpoints
|
||||
- Use proper error types and status codes
|
||||
- Implement proper validation types and schemas
|
||||
- Use proper pagination and filtering types
|
||||
|
||||
**SSH Types:**
|
||||
- Define proper SSH connection and configuration types
|
||||
- Use proper tunnel and credential types
|
||||
- Implement proper file operation types
|
||||
- Use proper authentication and security types
|
||||
|
||||
**Type Safety:**
|
||||
- Ensure proper type coverage and completeness
|
||||
- Use proper strict type checking
|
||||
- Implement proper type narrowing and guards
|
||||
- Use proper type assertions and casting
|
||||
|
||||
Highlight any type safety issues, missing types, or type inconsistencies.
|
||||
|
||||
- path: "**/hooks/**/*.{ts,tsx}"
|
||||
instructions: |
|
||||
Review custom hooks for Termix server management platform. Key considerations:
|
||||
|
||||
**Hook Design:**
|
||||
- Use proper React hooks patterns and conventions
|
||||
- Implement proper hook composition and reusability
|
||||
- Use proper TypeScript types for hook parameters and return values
|
||||
- Follow the established hook naming conventions
|
||||
|
||||
**State Management:**
|
||||
- Implement proper state management with useState and useReducer
|
||||
- Use proper context and provider patterns
|
||||
- Implement proper state persistence and synchronization
|
||||
- Use proper state cleanup and memory management
|
||||
|
||||
**Side Effects:**
|
||||
- Use proper useEffect patterns with proper dependencies
|
||||
- Implement proper cleanup functions and resource management
|
||||
- Use proper async operations and error handling
|
||||
- Implement proper polling and refresh patterns
|
||||
|
||||
**Performance:**
|
||||
- Use proper memoization with useMemo and useCallback
|
||||
- Implement proper debouncing and throttling
|
||||
- Use proper lazy loading and code splitting
|
||||
- Implement proper optimization patterns
|
||||
|
||||
**SSH Integration:**
|
||||
- Implement proper SSH connection management hooks
|
||||
- Use proper terminal integration hooks
|
||||
- Implement proper file manager operation hooks
|
||||
- Use proper tunnel management hooks
|
||||
|
||||
**Hook-Specific Bug Detection:**
|
||||
- Fix missing cleanup functions in useEffect hooks that cause memory leaks
|
||||
- Resolve infinite loops caused by incorrect dependency arrays
|
||||
- Fix stale closure issues in event handlers and async operations
|
||||
- Identify and fix improper state updates that cause unnecessary re-renders
|
||||
- Fix race conditions in async hooks and API calls
|
||||
- Resolve improper ref usage and null reference errors
|
||||
- Fix improper context usage and provider nesting issues
|
||||
- Identify and fix custom hook dependency issues
|
||||
- Resolve improper memoization that causes stale data
|
||||
- Fix improper error handling in custom hooks
|
||||
|
||||
Highlight any hook design issues, performance problems, or reusability concerns.
|
||||
|
||||
- path: "**/lib/**/*.{ts,js}"
|
||||
instructions: |
|
||||
Review utility libraries and helper functions for Termix server management platform. Key considerations:
|
||||
|
||||
**Utility Functions:**
|
||||
- Implement proper utility functions with clear purposes
|
||||
- Use proper TypeScript types and JSDoc documentation
|
||||
- Implement proper error handling and validation
|
||||
- Follow the established utility naming conventions
|
||||
|
||||
**Logging System:**
|
||||
- Use proper structured logging with context and metadata
|
||||
- Implement proper log levels and filtering
|
||||
- Use proper log formatting and output
|
||||
- Implement proper log rotation and cleanup
|
||||
|
||||
**API Utilities:**
|
||||
- Implement proper API client configuration and management
|
||||
- Use proper request/response interceptors
|
||||
- Implement proper error handling and retry logic
|
||||
- Use proper authentication and authorization handling
|
||||
- All API functions should be centralized in main-axios.ts
|
||||
- Use proper service-specific API instances (sshHostApi, tunnelApi, fileManagerApi, statsApi, authApi)
|
||||
- Follow the established error handling patterns with handleApiError function
|
||||
- Use proper structured logging with service-specific loggers
|
||||
|
||||
**Security Utilities:**
|
||||
- Implement proper input validation and sanitization
|
||||
- Use proper encryption and decryption functions
|
||||
- Implement proper secure random generation
|
||||
- Use proper security headers and CORS handling
|
||||
|
||||
**SSH Utilities:**
|
||||
- Implement proper SSH connection utilities
|
||||
- Use proper SSH key handling and validation
|
||||
- Implement proper SSH command execution
|
||||
- Use proper SSH file operation utilities
|
||||
|
||||
**Utility Bug Detection:**
|
||||
- Fix improper error handling in utility functions that could crash the application
|
||||
- Resolve null/undefined access errors in utility functions
|
||||
- Fix improper input validation that could cause security vulnerabilities
|
||||
- Identify and fix memory leaks in utility functions
|
||||
- Fix improper async/await usage and promise handling
|
||||
- Resolve improper type checking and validation errors
|
||||
- Fix improper logging that could expose sensitive information
|
||||
- Identify and fix performance bottlenecks in utility functions
|
||||
- Fix improper data transformation and serialization issues
|
||||
- Resolve improper configuration and environment variable handling
|
||||
|
||||
Highlight any utility design issues, performance problems, or security concerns.
|
||||
|
||||
- path: "**/main-axios.ts"
|
||||
instructions: |
|
||||
Review main-axios.ts API client configuration for Termix server management platform. Key considerations:
|
||||
|
||||
**API Client Architecture:**
|
||||
- Maintain the multi-port API architecture (SSH: 8081, Tunnel: 8083, File Manager: 8084, Stats: 8085)
|
||||
- Use proper service-specific API instances (sshHostApi, tunnelApi, fileManagerApi, statsApi, authApi)
|
||||
- Implement proper API instance creation with createApiInstance function
|
||||
- Use proper base URL configuration for different environments (dev, production, Electron)
|
||||
|
||||
**Error Handling:**
|
||||
- Use the centralized handleApiError function for consistent error handling
|
||||
- Implement proper error classification (auth, network, validation, server errors)
|
||||
- Use proper error logging with service-specific loggers
|
||||
- Implement proper error response formatting and user-friendly messages
|
||||
|
||||
**Request/Response Interceptors:**
|
||||
- Implement proper JWT token handling in request interceptors
|
||||
- Use proper request timing and performance logging
|
||||
- Implement proper response logging and error tracking
|
||||
- Use proper authentication token refresh and cleanup
|
||||
|
||||
**API Function Organization:**
|
||||
- Group API functions by service (SSH Host Management, Tunnel Management, File Manager, etc.)
|
||||
- Use proper TypeScript types for all API functions
|
||||
- Implement proper parameter validation and sanitization
|
||||
- Use proper return type definitions and error handling
|
||||
|
||||
**Authentication:**
|
||||
- Implement proper JWT token management and refresh
|
||||
- Use proper cookie handling for web and Electron environments
|
||||
- Implement proper authentication state management
|
||||
- Use proper token expiration and cleanup
|
||||
|
||||
**Logging:**
|
||||
- Use proper structured logging with context and metadata
|
||||
- Implement proper request/response logging with performance metrics
|
||||
- Use proper error logging with appropriate log levels
|
||||
- Implement proper service-specific logger selection
|
||||
|
||||
**Performance:**
|
||||
- Implement proper request timeout and retry logic
|
||||
- Use proper connection pooling and resource management
|
||||
- Implement proper request deduplication and caching
|
||||
- Use proper performance monitoring and metrics
|
||||
|
||||
**Security:**
|
||||
- Implement proper input validation and sanitization
|
||||
- Use proper CORS and security header handling
|
||||
- Implement proper authentication and authorization
|
||||
- Use proper secure communication and data handling
|
||||
|
||||
**API Bug Detection:**
|
||||
- Fix improper error handling that could expose sensitive information
|
||||
- Resolve race conditions in concurrent API calls
|
||||
- Fix improper token management and authentication state issues
|
||||
- Identify and fix memory leaks in API interceptors
|
||||
- Fix improper request/response validation that could cause crashes
|
||||
- Resolve improper timeout handling and retry logic
|
||||
- Fix improper error response formatting and user feedback
|
||||
- Identify and fix performance issues in API calls
|
||||
- Fix improper request deduplication and caching issues
|
||||
- Resolve improper authentication token refresh and cleanup
|
||||
- Fix improper CORS and security header configuration
|
||||
- Identify and fix potential security vulnerabilities in API handling
|
||||
|
||||
Highlight any API design issues, error handling problems, or security concerns.
|
||||
|
||||
- path: "**/electron/**/*.{ts,js,cjs}"
|
||||
instructions: |
|
||||
Review Electron application code for Termix server management platform. Key considerations:
|
||||
|
||||
**Electron Architecture:**
|
||||
- Use proper Electron main and renderer process separation
|
||||
- Implement proper IPC (Inter-Process Communication) patterns
|
||||
- Use proper security and sandboxing configurations
|
||||
- Follow the established Electron best practices
|
||||
|
||||
**Security:**
|
||||
- Implement proper security policies and configurations
|
||||
- Use proper context isolation and node integration
|
||||
- Implement proper CSP and security headers
|
||||
- Use proper authentication and authorization handling
|
||||
|
||||
**Performance:**
|
||||
- Implement proper memory management and cleanup
|
||||
- Use proper resource optimization and caching
|
||||
- Implement proper background processing and threading
|
||||
- Use proper performance monitoring and profiling
|
||||
|
||||
**Electron Bug Detection:**
|
||||
- Fix improper IPC communication that could cause crashes
|
||||
- Resolve memory leaks in Electron main and renderer processes
|
||||
- Fix improper window management and lifecycle issues
|
||||
- Identify and fix security vulnerabilities in Electron configuration
|
||||
- Fix improper context isolation and node integration issues
|
||||
- Resolve improper event handling and cleanup in Electron
|
||||
- Fix improper file system access and permission issues
|
||||
- Identify and fix performance issues in Electron processes
|
||||
- Fix improper auto-updater and version management
|
||||
- Resolve improper tray and menu functionality issues
|
||||
- Fix improper security policies and CSP configuration
|
||||
- Identify and fix potential security vulnerabilities in Electron setup
|
||||
|
||||
Highlight any Electron-specific issues, security vulnerabilities, or performance problems.
|
||||
|
||||
- path: "**/docker/**/*"
|
||||
instructions: |
|
||||
Review Docker configuration files for Termix server management platform. Key considerations:
|
||||
|
||||
**Dockerfile Design:**
|
||||
- Use proper multi-stage builds for optimization
|
||||
- Implement proper layer caching and optimization
|
||||
- Use proper security and minimal base images
|
||||
- Follow the established Docker best practices
|
||||
|
||||
**Security:**
|
||||
- Implement proper user and permission management
|
||||
- Use proper security scanning and vulnerability assessment
|
||||
- Implement proper secrets and credential management
|
||||
- Use proper network security and isolation
|
||||
|
||||
**Performance:**
|
||||
- Implement proper resource optimization and allocation
|
||||
- Use proper caching and build optimization
|
||||
- Implement proper monitoring and logging
|
||||
- Use proper health checks and status monitoring
|
||||
|
||||
**Docker Bug Detection:**
|
||||
- Fix improper multi-stage build optimization that causes large images
|
||||
- Resolve security vulnerabilities in base images and dependencies
|
||||
- Fix improper volume and data persistence configuration
|
||||
- Identify and fix resource limit and constraint issues
|
||||
- Fix improper networking and port configuration
|
||||
- Resolve improper environment variable and secret management
|
||||
- Fix improper health check and status monitoring configuration
|
||||
- Identify and fix performance issues in container startup
|
||||
- Fix improper logging and monitoring configuration
|
||||
- Resolve improper backup and recovery procedures
|
||||
- Fix improper scaling and load balancing configuration
|
||||
- Identify and fix potential security vulnerabilities in Docker setup
|
||||
|
||||
Highlight any Docker configuration issues, security vulnerabilities, or performance problems.
|
||||
|
||||
- path: "**/*.md"
|
||||
instructions: |
|
||||
Review documentation files for Termix server management platform. Key considerations:
|
||||
|
||||
**Documentation Quality:**
|
||||
- Ensure proper grammar, spelling, and clarity
|
||||
- Use proper formatting and structure
|
||||
- Implement proper code examples and snippets
|
||||
- Follow the established documentation standards
|
||||
|
||||
**Content Accuracy:**
|
||||
- Ensure proper technical accuracy and completeness
|
||||
- Use proper up-to-date information and examples
|
||||
- Implement proper cross-references and links
|
||||
- Use proper version and compatibility information
|
||||
|
||||
**User Experience:**
|
||||
- Ensure proper user-friendly language and explanations
|
||||
- Use proper step-by-step instructions and guides
|
||||
- Implement proper troubleshooting and FAQ sections
|
||||
- Use proper visual aids and diagrams where appropriate
|
||||
|
||||
Highlight any documentation issues, inaccuracies, or missing information.
|
||||
|
||||
- path: "**/index.css"
|
||||
instructions: |
|
||||
Review index.css styling configuration for Termix server management platform. Key considerations:
|
||||
|
||||
**CSS Variable System:**
|
||||
- Define proper CSS custom properties for colors, spacing, and typography
|
||||
- Use consistent naming conventions for CSS variables (--primary, --secondary, --background, etc.)
|
||||
- Implement proper dark/light theme variable definitions
|
||||
- Use proper semantic color naming (--destructive, --muted, --accent, etc.)
|
||||
|
||||
**Design System:**
|
||||
- Follow the established design token system
|
||||
- Use proper color palette definitions with proper contrast ratios
|
||||
- Implement proper typography scale and font family definitions
|
||||
- Use proper spacing and sizing scale definitions
|
||||
|
||||
**Theme Support:**
|
||||
- Implement proper dark and light theme variable definitions
|
||||
- Use proper CSS custom property fallbacks
|
||||
- Implement proper theme switching support
|
||||
- Use proper color scheme media queries
|
||||
|
||||
**Component Styling:**
|
||||
- Define proper base styles for common components
|
||||
- Use proper utility classes and helper styles
|
||||
- Implement proper responsive design utilities
|
||||
- Use proper accessibility-focused styling
|
||||
|
||||
**Color Management:**
|
||||
- Avoid hardcoded color values, use CSS variables instead
|
||||
- Implement proper color contrast and accessibility
|
||||
- Use proper semantic color definitions
|
||||
- Implement proper color state variations (hover, focus, active)
|
||||
|
||||
**Typography:**
|
||||
- Define proper font family and weight definitions
|
||||
- Use proper line height and letter spacing
|
||||
- Implement proper text size and hierarchy
|
||||
- Use proper font loading and fallback strategies
|
||||
|
||||
**Layout Utilities:**
|
||||
- Define proper spacing and margin utilities
|
||||
- Use proper flexbox and grid utilities
|
||||
- Implement proper responsive breakpoint utilities
|
||||
- Use proper container and layout helpers
|
||||
|
||||
**Accessibility:**
|
||||
- Implement proper focus indicators and states
|
||||
- Use proper color contrast ratios
|
||||
- Implement proper reduced motion support
|
||||
- Use proper screen reader friendly styling
|
||||
|
||||
**Performance:**
|
||||
- Use efficient CSS selectors and properties
|
||||
- Implement proper CSS organization and structure
|
||||
- Use proper CSS custom property optimization
|
||||
- Implement proper critical CSS and loading strategies
|
||||
|
||||
Highlight any styling issues, accessibility problems, or design system inconsistencies.
|
||||
auto_review:
|
||||
enabled: true
|
||||
ignore_title_keywords:
|
||||
- "WIP"
|
||||
- "DO NOT MERGE"
|
||||
- "DRAFT"
|
||||
- "EXPERIMENTAL"
|
||||
- "TEST"
|
||||
drafts: false
|
||||
chat:
|
||||
auto_reply: true
|
||||
@@ -0,0 +1 @@
|
||||
github: [LukeGus]
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help Termix improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots/Logs**
|
||||
If applicable, add screenshots or console/Docker logs to help explain your problem.
|
||||
|
||||
**Environment (please complete the following information):**
|
||||
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 1.6.0]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for Termix
|
||||
title: "[FEATURE]"
|
||||
labels: enhancement
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,40 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
dev-patch-updates:
|
||||
dependency-type: "development"
|
||||
update-types:
|
||||
- "patch"
|
||||
dev-minor-updates:
|
||||
dependency-type: "development"
|
||||
update-types:
|
||||
- "minor"
|
||||
prod-patch-updates:
|
||||
dependency-type: "production"
|
||||
update-types:
|
||||
- "patch"
|
||||
prod-minor-updates:
|
||||
dependency-type: "production"
|
||||
update-types:
|
||||
- "minor"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/docker"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
patch-updates:
|
||||
update-types:
|
||||
- "patch"
|
||||
minor-updates:
|
||||
update-types:
|
||||
- "minor"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -4,6 +4,9 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- development
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- ".gitignore"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
@@ -16,27 +19,45 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
node-version: '18'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install Dependencies and Build Frontend
|
||||
run: |
|
||||
cd src
|
||||
npm ci
|
||||
npm run build
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
driver-opts: |
|
||||
image=moby/buildkit:master
|
||||
network=host
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Cache npm dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.npm
|
||||
node_modules
|
||||
*/*/node_modules
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.ref_name }}-${{ hashFiles('docker/Dockerfile') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-${{ github.ref_name }}-
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -45,29 +66,42 @@ jobs:
|
||||
- name: Determine Docker image tag
|
||||
run: |
|
||||
echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
|
||||
if [ "${{ github.event.inputs.tag_name }}" == "" ]; then
|
||||
IMAGE_TAG="${{ github.ref_name }}-development-latest"
|
||||
else
|
||||
if [ "${{ github.event.inputs.tag_name }}" != "" ]; then
|
||||
IMAGE_TAG="${{ github.event.inputs.tag_name }}"
|
||||
elif [ "${{ github.ref }}" == "refs/heads/main" ]; then
|
||||
IMAGE_TAG="latest"
|
||||
elif [ "${{ github.ref }}" == "refs/heads/development" ]; then
|
||||
IMAGE_TAG="development-latest"
|
||||
else
|
||||
IMAGE_TAG="${{ github.ref_name }}"
|
||||
fi
|
||||
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
|
||||
|
||||
- name: Build and Push Multi-Arch Docker Image
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ghcr.io/${{ env.REPO_OWNER }}/termix:${{ env.IMAGE_TAG }}
|
||||
labels: org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
labels: |
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||
build-args: |
|
||||
BUILDKIT_INLINE_CACHE=1
|
||||
BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
|
||||
outputs: type=registry,compression=zstd,compression-level=19
|
||||
|
||||
- name: Notify via ntfy
|
||||
- name: Move cache
|
||||
run: |
|
||||
curl -d "Docker image build and push completed successfully for tag: ${{ env.IMAGE_TAG }}" \
|
||||
https://ntfy.karmaa.site/termix-build
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
|
||||
- name: Delete all untagged image versions
|
||||
if: success()
|
||||
uses: quartx-analytics/ghcr-cleaner@v1
|
||||
with:
|
||||
owner-type: user
|
||||
@@ -76,6 +110,7 @@ jobs:
|
||||
delete-untagged: true
|
||||
|
||||
- name: Cleanup Docker Images Locally
|
||||
if: always()
|
||||
run: |
|
||||
docker image prune -af
|
||||
docker system prune -af --volumes
|
||||
docker system prune -af --volumes
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
name: Build Electron App
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- development
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- '.gitignore'
|
||||
- 'docker/**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_type:
|
||||
description: "Build type to run"
|
||||
required: true
|
||||
default: "all"
|
||||
type: choice
|
||||
options:
|
||||
- all
|
||||
- windows
|
||||
- linux
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
if: github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'windows' || github.event.inputs.build_type == ''
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Windows Portable
|
||||
run: npm run build:win-portable
|
||||
|
||||
- name: Build Windows Installer
|
||||
run: npm run build:win-installer
|
||||
|
||||
- name: Create Windows Portable zip
|
||||
run: |
|
||||
Compress-Archive -Path "release/win-unpacked/*" -DestinationPath "Termix-Windows-Portable.zip"
|
||||
|
||||
- name: Upload Windows Portable Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Termix-Windows-Portable
|
||||
path: Termix-Windows-Portable.zip
|
||||
retention-days: 30
|
||||
|
||||
- name: Upload Windows Installer Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Termix-Windows-Installer
|
||||
path: release/*.exe
|
||||
retention-days: 30
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'linux' || github.event.inputs.build_type == ''
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Linux Portable
|
||||
run: npm run build:linux-portable
|
||||
|
||||
- name: Create Linux Portable zip
|
||||
run: |
|
||||
cd release/linux-unpacked
|
||||
zip -r ../../Termix-Linux-Portable.zip *
|
||||
cd ../..
|
||||
|
||||
- name: Upload Linux Portable Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Termix-Linux-Portable
|
||||
path: Termix-Linux-Portable.zip
|
||||
retention-days: 30
|
||||
+3
-140
@@ -22,143 +22,6 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
.bash_history
|
||||
.bashrc
|
||||
.init_done
|
||||
.profile
|
||||
.sudo_as_admin_successful
|
||||
.wget-hsts
|
||||
.git-credentials
|
||||
.docker/
|
||||
.bash_logout
|
||||
|
||||
# VSCode Files
|
||||
.vscode-server/
|
||||
|
||||
# Configs
|
||||
.config/
|
||||
|
||||
# .dotnet
|
||||
.dotnet/
|
||||
|
||||
# .local
|
||||
.local/
|
||||
/docker/docker-compose.yml
|
||||
/src/data/
|
||||
/docker/mongodb/
|
||||
/docker/docker-compose.yml
|
||||
/db/
|
||||
/release/
|
||||
/.claude/
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ignore artifacts:
|
||||
build
|
||||
coverage
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
\_# Contributing
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Node.js](https://nodejs.org/en/download/) (built with v24)
|
||||
- [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
```sh
|
||||
git clone https://github.com/LukeGus/Termix
|
||||
```
|
||||
2. Install the dependencies:
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
## Running the development server
|
||||
|
||||
Run the following commands:
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
npm run dev:backend
|
||||
```
|
||||
|
||||
a
|
||||
This will start the backend and the frontend Vite server. You can access Termix by going to `http://localhost:5174/`.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. **Fork the repository**: Click the "Fork" button at the top right of
|
||||
the [repository page](https://github.com/LukeGus/Termix).
|
||||
2. **Create a new branch**:
|
||||
```sh
|
||||
git checkout -b feature/my-new-feature
|
||||
```
|
||||
3. **Make your changes**: Implement your feature, fix, or improvement.
|
||||
4. **Commit your changes**:
|
||||
```sh
|
||||
git commit -m "Feature request my new feature"
|
||||
```
|
||||
5. **Push to your fork**:
|
||||
```sh
|
||||
git push origin feature/my-feature-request
|
||||
```
|
||||
6. **Open a pull request**: Go to the original repository and create a PR with a clear description.
|
||||
|
||||
## 📝 Guidelines
|
||||
|
||||
- Follow the existing code style. Use Tailwind CSS with shadcn components.
|
||||
- Use the below color scheme with the respective CSS variable placed in the `className` of a div/component.
|
||||
- Place all API routes in the `main-axios.ts` file. Updating the `openapi.json` is unneeded.
|
||||
- Include meaningful commit messages.
|
||||
- Link related issues when applicable.
|
||||
- `MobileApp.tsx` renders when the users screen width is less than 768px, otherwise it loads the usual `DesktopApp.tsx`.
|
||||
|
||||
## Color Scheme
|
||||
|
||||
### Background Colors
|
||||
|
||||
| CSS Variable | Color Value | Usage | Description |
|
||||
| ----------------------------- | ----------- | --------------------------- | ---------------------------------------- |
|
||||
| `--color-dark-bg` | `#18181b` | Main dark background | Primary dark background color |
|
||||
| `--color-dark-bg-darker` | `#0e0e10` | Darker backgrounds | Darker variant for panels and containers |
|
||||
| `--color-dark-bg-darkest` | `#09090b` | Darkest backgrounds | Darkest background (terminal) |
|
||||
| `--color-dark-bg-light` | `#141416` | Light dark backgrounds | Lighter variant of dark background |
|
||||
| `--color-dark-bg-very-light` | `#101014` | Very light dark backgrounds | Very light variant of dark background |
|
||||
| `--color-dark-bg-panel` | `#1b1b1e` | Panel backgrounds | Background for panels and cards |
|
||||
| `--color-dark-bg-panel-hover` | `#232327` | Panel hover states | Background for panels on hover |
|
||||
|
||||
### Element-Specific Backgrounds
|
||||
|
||||
| CSS Variable | Color Value | Usage | Description |
|
||||
| ------------------------ | ----------- | ------------------ | --------------------------------------------- |
|
||||
| `--color-dark-bg-input` | `#222225` | Input fields | Background for input fields and form elements |
|
||||
| `--color-dark-bg-button` | `#23232a` | Button backgrounds | Background for buttons and clickable elements |
|
||||
| `--color-dark-bg-active` | `#1d1d1f` | Active states | Background for active/selected elements |
|
||||
| `--color-dark-bg-header` | `#131316` | Header backgrounds | Background for headers and navigation bars |
|
||||
|
||||
### Border Colors
|
||||
|
||||
| CSS Variable | Color Value | Usage | Description |
|
||||
| ---------------------------- | ----------- | --------------- | ---------------------------------------- |
|
||||
| `--color-dark-border` | `#303032` | Default borders | Standard border color |
|
||||
| `--color-dark-border-active` | `#2d2d30` | Active borders | Border color for active elements |
|
||||
| `--color-dark-border-hover` | `#434345` | Hover borders | Border color on hover states |
|
||||
| `--color-dark-border-light` | `#5a5a5d` | Light borders | Lighter border color for subtle elements |
|
||||
| `--color-dark-border-medium` | `#373739` | Medium borders | Medium weight border color |
|
||||
| `--color-dark-border-panel` | `#222224` | Panel borders | Border color for panels and cards |
|
||||
|
||||
### Interactive States
|
||||
|
||||
| CSS Variable | Color Value | Usage | Description |
|
||||
| ------------------------ | ----------- | ----------------- | --------------------------------------------- |
|
||||
| `--color-dark-hover` | `#2d2d30` | Hover states | Background color for hover effects |
|
||||
| `--color-dark-active` | `#2a2a2c` | Active states | Background color for active elements |
|
||||
| `--color-dark-pressed` | `#1a1a1c` | Pressed states | Background color for pressed/clicked elements |
|
||||
| `--color-dark-hover-alt` | `#2a2a2d` | Alternative hover | Alternative hover state color |
|
||||
|
||||
## Support
|
||||
|
||||
If you need help with Termix, you can join the [Discord](https://discord.gg/jVQGdvHDrf) server and visit the support
|
||||
channel. You can also open an issue or open a pull request on the [GitHub](https://github.com/LukeGus/Termix/issues)
|
||||
repo.
|
||||
@@ -1,21 +1,13 @@
|
||||
MIT License
|
||||
Copyright 2025 Luke Gustafson
|
||||
|
||||
Copyright (c) 2025 Luke Gustafson
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
# 仓库统计
|
||||
|
||||
<p align="center">
|
||||
<a href="README.md"><img src="https://flagcdn.com/us.svg" alt="English" width="24" height="16"> 英文</a> |
|
||||
<img src="https://flagcdn.com/cn.svg" alt="中文" width="24" height="16"> 中文
|
||||
</p>
|
||||
|
||||

|
||||

|
||||

|
||||
<a href="https://discord.gg/jVQGdvHDrf"><img alt="Discord" src="https://img.shields.io/discord/1347374268253470720"></a>
|
||||
|
||||
#### 核心技术
|
||||
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
|
||||
<br />
|
||||
<p align="center">
|
||||
<a href="https://github.com/LukeGus/Termix">
|
||||
<img alt="Termix Banner" src=./repo-images/HeaderImage.png style="width: auto; height: auto;"> </a>
|
||||
</p>
|
||||
|
||||
如果你愿意,可以在这里支持这个项目!\
|
||||
[](https://github.com/sponsors/LukeGus)
|
||||
|
||||
# 概览
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/LukeGus/Termix">
|
||||
<img alt="Termix Banner" src=./public/icon.svg style="width: 250px; height: 250px;"> </a>
|
||||
</p>
|
||||
|
||||
Termix 是一个开源、永久免费、自托管的一体化服务器管理平台。它提供了一个基于网页的解决方案,通过一个直观的界面管理你的服务器和基础设施。Termix
|
||||
提供 SSH 终端访问、SSH 隧道功能以及远程文件编辑,还会陆续添加更多工具。
|
||||
|
||||
# 功能
|
||||
|
||||
- **SSH 终端访问** - 功能完整的终端,支持分屏(最多 4 个面板)和标签系统
|
||||
- **SSH 隧道管理** - 创建和管理 SSH 隧道,支持自动重连和健康监控
|
||||
- **远程文件编辑器** - 直接在远程服务器编辑文件,支持语法高亮和文件管理功能(上传、删除、重命名等)
|
||||
- **SSH 主机管理器** - 保存、组织和管理 SSH 连接,支持标签和文件夹
|
||||
- **服务器统计** - 查看任意 SSH 服务器的 CPU、内存和硬盘使用情况
|
||||
- **用户认证** - 安全的用户管理,支持管理员控制、OIDC 和双因素认证(TOTP)
|
||||
- **现代化界面** - 使用 React、Tailwind CSS 和 Shadcn 构建的简洁界面
|
||||
- **语言支持** - 内置中英文支持
|
||||
|
||||
# 计划功能
|
||||
|
||||
- **增强管理员控制** - 提供更精细的用户和管理员权限控制、共享主机等功能
|
||||
- **主题定制** - 修改所有工具的主题风格
|
||||
- **增强终端支持** - 添加更多终端协议,如 VNC 和 RDP(有类似 Apache Guacamole 的 RDP 集成经验者请通过创建 issue 联系我)
|
||||
- **移动端支持** - 支持移动应用或 Termix 网站移动版,让你在手机上管理服务器
|
||||
|
||||
# 安装
|
||||
|
||||
访问 Termix [文档](https://docs.termix.site/install) 获取安装信息。或者可以参考以下示例 docker-compose 文件:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
termix:
|
||||
image: ghcr.io/lukegus/termix:latest
|
||||
container_name: termix
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- termix-data:/app/data
|
||||
environment:
|
||||
PORT: "8080"
|
||||
|
||||
volumes:
|
||||
termix-data:
|
||||
driver: local
|
||||
```
|
||||
|
||||
# 支持
|
||||
|
||||
如果你需要 Termix 的帮助,可以加入 [Discord](https://discord.gg/jVQGdvHDrf)
|
||||
服务器并访问支持频道。你也可以在 [GitHub](https://github.com/LukeGus/Termix/issues) 仓库提交 issue 或 pull request。
|
||||
|
||||
# 展示
|
||||
|
||||
<p align="center">
|
||||
<img src="./repo-images/Image 1.png" width="400" alt="Termix Demo 1"/>
|
||||
<img src="./repo-images/Image 2.png" width="400" alt="Termix Demo 2"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="./repo-images/Image 3.png" width="250" alt="Termix Demo 3"/>
|
||||
<img src="./repo-images/Image 4.png" width="250" alt="Termix Demo 4"/>
|
||||
<img src="./repo-images/Image 5.png" width="250" alt="Termix Demo 5"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<video src="https://github.com/user-attachments/assets/f9caa061-10dc-4173-ae7d-c6d42f05cf56" width="800" controls>
|
||||
你的浏览器不支持 video 标签。
|
||||
</video>
|
||||
</p>
|
||||
|
||||
# 许可证
|
||||
|
||||
根据 Apache 2.0 许可证发布。更多信息请参见 LICENSE。
|
||||
@@ -1,62 +1,117 @@
|
||||
# Repo Stats
|
||||
|
||||
<p align="center">
|
||||
<img src="https://flagcdn.com/us.svg" alt="English" width="24" height="16"> English |
|
||||
<a href="README-CN.md"><img src="https://flagcdn.com/cn.svg" alt="中文" width="24" height="16"> 中文</a>
|
||||
</p>
|
||||
|
||||

|
||||

|
||||

|
||||
<a href="https://discord.gg/jVQGdvHDrf"><img alt="Discord" src="https://img.shields.io/discord/1347374268253470720"></a>
|
||||
|
||||
#### Top Technologies
|
||||
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
|
||||
[](#)
|
||||
[](#)
|
||||
|
||||
<br />
|
||||
<p align="center">
|
||||
<a href="https://github.com/LukeGus/Termix">
|
||||
<img alt="Termix Banner" src=./repo-images/TermixLogo.png style="width: 125px; height: auto;"> </a>
|
||||
<img alt="Termix Banner" src=./repo-images/HeaderImage.png style="width: auto; height: auto;"> </a>
|
||||
</p>
|
||||
|
||||
If you would like, you can support the project here!\
|
||||
[](https://paypal.me/LukeGustafson803)
|
||||
[](https://github.com/sponsors/LukeGus)
|
||||
|
||||
# Overview
|
||||
Termix is an open-source forever free self-hosted SSH (other protocols planned, see [Planned Features](#planned-features)) server management panel inspired by [Nexterm](https://github.com/gnmyt/Nexterm). Its purpose is to provide an all-in-one docker-hosted web solution to manage your servers in one easy place. I'm using this project to help me learn [React](https://github.com/facebook/react), [Vite](https://github.com/vitejs/vite-plugin-react), and [Docker](https://www.docker.com) but also because I could never settle on a server management software that I enjoyed to use.
|
||||
|
||||
> [!WARNING]
|
||||
> This app is in the VERY early stages of development. Expect bugs, data loss, and unexplainable issues! For that reason, I recommend you securely tunnel your connection to Termix through a VPN.
|
||||
<p align="center">
|
||||
<a href="https://github.com/LukeGus/Termix">
|
||||
<img alt="Termix Banner" src=./public/icon.svg style="width: 250px; height: 250px;"> </a>
|
||||
</p>
|
||||
|
||||
Termix is an open-source, forever-free, self-hosted all-in-one server management platform. It provides a web-based
|
||||
solution for managing your servers and infrastructure through a single, intuitive interface. Termix offers SSH terminal
|
||||
access, SSH tunneling capabilities, and remote file editing, with many more tools to come.
|
||||
|
||||
# Features
|
||||
- SSH
|
||||
- Split Screen (Up to 4) & Tab System
|
||||
- User Authentication
|
||||
- Save Hosts (and easily view, connect, and manage them)
|
||||
|
||||
- **SSH Terminal Access** - Full-featured terminal with split-screen support (up to 4 panels) and tab system
|
||||
- **SSH Tunnel Management** - Create and manage SSH tunnels with automatic reconnection and health monitoring
|
||||
- **Remote File Editor** - Edit files directly on remote servers with syntax highlighting, file management features (
|
||||
uploading, removing, renaming, deleting files)
|
||||
- **SSH Host Manager** - Save, organize, and manage your SSH connections with tags and folders
|
||||
- **Server Stats** - View CPU, memory, and HDD usage on any SSH server
|
||||
- **User Authentication** - Secure user management with admin controls and OIDC and 2FA (TOTP) support
|
||||
- **Modern UI** - Clean desktop/mobile friendly (in progress) interface built with React, Tailwind CSS, and Shadcn
|
||||
- **Languages** - Built-in support for English and Chinese
|
||||
- **Improved Platform Support** - Now includes an installable Electron app (in progress) for desktop, with a dedicated
|
||||
mobile app also planned.
|
||||
|
||||
# Planned Features
|
||||
- VNC
|
||||
- RDP
|
||||
- SFTP (build in file transfer)
|
||||
- ChatGPT/Ollama Integration (for commands)
|
||||
- Apps (like notes, AI, etc)
|
||||
- Terminal Themes
|
||||
- User Management (roles, permissions, etc.)
|
||||
- SSH Tunneling
|
||||
- More Authentication Methods
|
||||
- More Security Features (like 2FA, etc.)
|
||||
|
||||
See [Projects](https://github.com/users/LukeGus/projects/3). If you are looking to contribute,
|
||||
see [Contributing](https://github.com/LukeGus/Termix/blob/main/CONTRIBUTING.md),
|
||||
|
||||
# Installation
|
||||
Visit the Termix [Wiki](https://github.com/LukeGus/Termix/wiki) for information on how to install Termix. You can also use these links to go directly to guide. [Docker](https://github.com/LukeGus/Termix/wiki/Docker) or [Manual](https://github.com/LukeGus/Termix/wiki/Manual).
|
||||
|
||||
Visit the Termix [Docs](https://docs.termix.site/install) for more information on how to install Termix. Otherwise, view
|
||||
a sample docker-compose file here:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
termix:
|
||||
image: ghcr.io/lukegus/termix:latest
|
||||
container_name: termix
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- termix-data:/app/data
|
||||
environment:
|
||||
PORT: "8080"
|
||||
|
||||
volumes:
|
||||
termix-data:
|
||||
driver: local
|
||||
```
|
||||
|
||||
Pre-built binaries are now available for download, including a Windows installer/portable app and a Linux portable app (
|
||||
built with Electron). See [Docs](http://localhost:5174/install#pre-built-binaries) for details. A native iOS/Android app
|
||||
is planned.
|
||||
|
||||
# Support
|
||||
If you need help with Termix, you can join the [Discord](https://discord.gg/jVQGdvHDrf) server and visit the support channel. You can also open an issue or open a pull request on the [GitHub](https://github.com/LukeGus/Termix/issues) repo. If you would like to support me financially, you can on [Paypal](https://paypal.me/LukeGustafson803).
|
||||
|
||||
If you need help with Termix, you can join the [Discord](https://discord.gg/jVQGdvHDrf) server and visit the support
|
||||
channel. You can also open an issue or open a pull request on the [GitHub](https://github.com/LukeGus/Termix/issues)
|
||||
repo.
|
||||
|
||||
# Show-off
|
||||
|
||||

|
||||

|
||||
<p align="center">
|
||||
<img src="./repo-images/Image 1.png" width="400" alt="Termix Demo 1"/>
|
||||
<img src="./repo-images/Image 2.png" width="400" alt="Termix Demo 2"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="./repo-images/Image 3.png" width="250" alt="Termix Demo 3"/>
|
||||
<img src="./repo-images/Image 4.png" width="250" alt="Termix Demo 4"/>
|
||||
<img src="./repo-images/Image 5.png" width="250" alt="Termix Demo 5"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<video src="https://github.com/user-attachments/assets/f9caa061-10dc-4173-ae7d-c6d42f05cf56" width="800" controls>
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</p>
|
||||
|
||||
# License
|
||||
Distributed under the MIT license. See LICENSE for more information.
|
||||
|
||||
Distributed under the Apache License Version 2.0. See LICENSE for more information.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": false,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/index.css",
|
||||
"baseColor": "zinc",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"iconLibrary": "lucide"
|
||||
}
|
||||
+78
-41
@@ -1,61 +1,98 @@
|
||||
# Stage 1: Build frontend
|
||||
FROM --platform=$BUILDPLATFORM node:18 AS frontend-builder
|
||||
# Stage 1: Install dependencies and build frontend
|
||||
FROM node:24-alpine AS deps
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache python3 make g++
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
ENV npm_config_target_platform=linux
|
||||
ENV npm_config_target_arch=x64
|
||||
ENV npm_config_target_libc=glibc
|
||||
|
||||
RUN npm ci --force --ignore-scripts && \
|
||||
npm cache clean --force
|
||||
|
||||
# Stage 2: Build frontend
|
||||
FROM deps AS frontend-builder
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Build backend
|
||||
FROM --platform=$BUILDPLATFORM node:18 AS backend-builder
|
||||
# Stage 3: Build backend TypeScript
|
||||
FROM deps AS backend-builder
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
ENV npm_config_target_platform=linux
|
||||
ENV npm_config_target_arch=x64
|
||||
ENV npm_config_target_libc=glibc
|
||||
|
||||
RUN npm rebuild better-sqlite3 --force
|
||||
|
||||
RUN npm run build:backend
|
||||
|
||||
# Stage 4: Production dependencies
|
||||
FROM node:24-alpine AS production-deps
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY src/backend/ ./src/backend/
|
||||
|
||||
# Stage 3: Final production image
|
||||
FROM mongo:5
|
||||
# Install Node.js
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
nginx \
|
||||
python3 \
|
||||
build-essential \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y nodejs \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ENV npm_config_target_platform=linux
|
||||
ENV npm_config_target_arch=x64
|
||||
ENV npm_config_target_libc=glibc
|
||||
|
||||
RUN npm ci --only=production --ignore-scripts --force && \
|
||||
npm cache clean --force
|
||||
|
||||
# Stage 5: Build native modules
|
||||
FROM node:24-alpine AS native-builder
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache python3 make g++
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
ENV npm_config_target_platform=linux
|
||||
ENV npm_config_target_arch=x64
|
||||
ENV npm_config_target_libc=glibc
|
||||
|
||||
# Install native modules and compile them properly
|
||||
RUN npm ci --only=production --force && \
|
||||
npm rebuild better-sqlite3 bcryptjs --force && \
|
||||
npm cache clean --force
|
||||
|
||||
# Stage 6: Final image
|
||||
FROM node:24-alpine
|
||||
ENV DATA_DIR=/app/data \
|
||||
PORT=8080 \
|
||||
NODE_ENV=production
|
||||
|
||||
RUN apk add --no-cache nginx gettext su-exec && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R node:node /app/data
|
||||
|
||||
# Configure nginx
|
||||
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY --from=frontend-builder /app/dist /usr/share/nginx/html
|
||||
COPY --from=frontend-builder /app/src/locales /usr/share/nginx/html/locales
|
||||
RUN chown -R nginx:nginx /usr/share/nginx/html
|
||||
|
||||
# Setup backend
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install --omit=dev
|
||||
COPY --from=backend-builder /app/src/backend ./src/backend
|
||||
|
||||
# Create directories for MongoDB and nginx
|
||||
RUN mkdir -p /data/db && \
|
||||
mkdir -p /var/log/nginx && \
|
||||
mkdir -p /var/lib/nginx && \
|
||||
mkdir -p /var/log/mongodb && \
|
||||
chown -R mongodb:mongodb /data/db /var/log/mongodb && \
|
||||
chown -R www-data:www-data /var/log/nginx /var/lib/nginx
|
||||
COPY --from=native-builder /app/node_modules /app/node_modules
|
||||
COPY --from=backend-builder /app/dist/backend ./dist/backend
|
||||
|
||||
# Set environment variables
|
||||
ENV MONGO_URL=mongodb://localhost:27017/termix \
|
||||
MONGODB_DATA_DIR=/data/db \
|
||||
MONGODB_LOG_DIR=/var/log/mongodb
|
||||
COPY package.json ./
|
||||
COPY .env ./.env
|
||||
RUN chown -R node:node /app
|
||||
|
||||
# Create volume for MongoDB data
|
||||
VOLUME ["/data/db"]
|
||||
VOLUME ["/app/data"]
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 8080 8081 8082 27017
|
||||
EXPOSE ${PORT} 8081 8082 8083 8084 8085
|
||||
|
||||
# Use a entrypoint script to run all services
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
CMD ["/entrypoint.sh"]
|
||||
CMD ["/entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
services:
|
||||
termix:
|
||||
image: ghcr.io/lukegus/termix:latest
|
||||
container_name: termix
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- termix-data:/app/data
|
||||
environment:
|
||||
PORT: "8080"
|
||||
|
||||
volumes:
|
||||
termix-data:
|
||||
driver: local
|
||||
+18
-21
@@ -1,32 +1,29 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Start MongoDB
|
||||
echo "Starting MongoDB..."
|
||||
mongod --fork --dbpath $MONGODB_DATA_DIR --logpath $MONGODB_LOG_DIR/mongodb.log
|
||||
export PORT=${PORT:-8080}
|
||||
echo "Configuring web UI to run on port: $PORT"
|
||||
|
||||
# Wait for MongoDB to be ready
|
||||
echo "Waiting for MongoDB to start..."
|
||||
until mongosh --eval "print(\"waited for connection\")" > /dev/null 2>&1; do
|
||||
sleep 0.5
|
||||
done
|
||||
echo "MongoDB has started"
|
||||
envsubst '${PORT}' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf.tmp
|
||||
mv /etc/nginx/nginx.conf.tmp /etc/nginx/nginx.conf
|
||||
|
||||
mkdir -p /app/data
|
||||
chown -R node:node /app/data
|
||||
chmod 755 /app/data
|
||||
|
||||
# Start nginx
|
||||
echo "Starting nginx..."
|
||||
nginx
|
||||
|
||||
# Change to app directory
|
||||
echo "Starting backend services..."
|
||||
cd /app
|
||||
export NODE_ENV=production
|
||||
|
||||
# Start the SSH service
|
||||
echo "Starting SSH service..."
|
||||
node src/backend/ssh.cjs &
|
||||
if command -v su-exec > /dev/null 2>&1; then
|
||||
su-exec node node dist/backend/backend/starter.js
|
||||
else
|
||||
su -s /bin/sh node -c "node dist/backend/backend/starter.js"
|
||||
fi
|
||||
|
||||
# Start the database service
|
||||
echo "Starting database service..."
|
||||
node src/backend/database.cjs &
|
||||
echo "All services started"
|
||||
|
||||
# Keep the container running and show MongoDB logs
|
||||
echo "All services started. Tailing MongoDB logs..."
|
||||
tail -f $MONGODB_LOG_DIR/mongodb.log
|
||||
tail -f /dev/null
|
||||
+138
-21
@@ -3,54 +3,171 @@ events {
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
listen ${PORT};
|
||||
server_name localhost;
|
||||
|
||||
# Serve the React app
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
# Proxy SSH socket requests
|
||||
location /ssh.io/ {
|
||||
location ~ ^/users(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Proxy MongoDB socket requests
|
||||
location /database.io/ {
|
||||
proxy_pass http://127.0.0.1:8082;
|
||||
location ~ ^/version(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ~ ^/releases(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ~ ^/alerts(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ~ ^/credentials(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ssh/ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ssh/websocket/ {
|
||||
proxy_pass http://127.0.0.1:8082/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_connect_timeout 75s;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Error pages
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location /ssh/tunnel/ {
|
||||
proxy_pass http://127.0.0.1:8083;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ssh/file_manager/recent {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ssh/file_manager/pinned {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ssh/file_manager/shortcuts {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ssh/file_manager/ssh/ {
|
||||
proxy_pass http://127.0.0.1:8084;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ~ ^/status(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8085;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ~ ^/metrics(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8085;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"appId": "com.termix.app",
|
||||
"productName": "Termix",
|
||||
"directories": {
|
||||
"output": "release"
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"electron/**/*",
|
||||
"public/**/*",
|
||||
"!**/node_modules/**/*",
|
||||
"!src/**/*",
|
||||
"!*.md",
|
||||
"!tsconfig*.json",
|
||||
"!vite.config.ts",
|
||||
"!eslint.config.js"
|
||||
],
|
||||
"asarUnpack": ["node_modules/node-fetch/**/*"],
|
||||
"extraMetadata": {
|
||||
"main": "electron/main.cjs"
|
||||
},
|
||||
"buildDependenciesFromSource": false,
|
||||
"nodeGypRebuild": false,
|
||||
"npmRebuild": false,
|
||||
"win": {
|
||||
"target": "nsis",
|
||||
"icon": "public/icon.ico",
|
||||
"executableName": "Termix"
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": false,
|
||||
"allowToChangeInstallationDirectory": true,
|
||||
"artifactName": "${productName}-Setup-${version}.${ext}",
|
||||
"createDesktopShortcut": true,
|
||||
"createStartMenuShortcut": true,
|
||||
"shortcutName": "Termix",
|
||||
"uninstallDisplayName": "Termix"
|
||||
},
|
||||
"linux": {
|
||||
"target": "AppImage",
|
||||
"icon": "public/icon.png",
|
||||
"category": "Development"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
const { app, BrowserWindow, shell, ipcMain } = require("electron");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
let mainWindow = null;
|
||||
|
||||
const isDev = process.env.NODE_ENV === "development" || !app.isPackaged;
|
||||
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
console.log("Another instance is already running, quitting...");
|
||||
app.quit();
|
||||
process.exit(0);
|
||||
} else {
|
||||
app.on("second-instance", (event, commandLine, workingDirectory) => {
|
||||
console.log("Second instance detected, focusing existing window...");
|
||||
if (mainWindow) {
|
||||
if (mainWindow.isMinimized()) mainWindow.restore();
|
||||
mainWindow.focus();
|
||||
mainWindow.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
minWidth: 800,
|
||||
minHeight: 600,
|
||||
title: "Termix",
|
||||
icon: isDev
|
||||
? path.join(__dirname, "..", "public", "icon.png")
|
||||
: path.join(process.resourcesPath, "public", "icon.png"),
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
webSecurity: !isDev,
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
},
|
||||
show: false,
|
||||
});
|
||||
|
||||
if (process.platform !== "darwin") {
|
||||
mainWindow.setMenuBarVisibility(false);
|
||||
}
|
||||
|
||||
if (isDev) {
|
||||
mainWindow.loadURL("http://localhost:5173");
|
||||
mainWindow.webContents.openDevTools();
|
||||
} else {
|
||||
const indexPath = path.join(__dirname, "..", "dist", "index.html");
|
||||
console.log("Loading frontend from:", indexPath);
|
||||
mainWindow.loadFile(indexPath);
|
||||
}
|
||||
|
||||
mainWindow.once("ready-to-show", () => {
|
||||
console.log("Window ready to show");
|
||||
mainWindow.show();
|
||||
});
|
||||
|
||||
mainWindow.webContents.on(
|
||||
"did-fail-load",
|
||||
(event, errorCode, errorDescription, validatedURL) => {
|
||||
console.error(
|
||||
"Failed to load:",
|
||||
errorCode,
|
||||
errorDescription,
|
||||
validatedURL,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
mainWindow.webContents.on("did-finish-load", () => {
|
||||
console.log("Frontend loaded successfully");
|
||||
});
|
||||
|
||||
mainWindow.on("close", (event) => {
|
||||
if (process.platform === "darwin") {
|
||||
event.preventDefault();
|
||||
mainWindow.hide();
|
||||
}
|
||||
});
|
||||
|
||||
mainWindow.on("closed", () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
shell.openExternal(url);
|
||||
return { action: "deny" };
|
||||
});
|
||||
}
|
||||
|
||||
ipcMain.handle("get-app-version", () => {
|
||||
return app.getVersion();
|
||||
});
|
||||
|
||||
ipcMain.handle("get-platform", () => {
|
||||
return process.platform;
|
||||
});
|
||||
|
||||
ipcMain.handle("get-server-config", () => {
|
||||
try {
|
||||
const userDataPath = app.getPath("userData");
|
||||
const configPath = path.join(userDataPath, "server-config.json");
|
||||
|
||||
if (fs.existsSync(configPath)) {
|
||||
const configData = fs.readFileSync(configPath, "utf8");
|
||||
return JSON.parse(configData);
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error("Error reading server config:", error);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle("save-server-config", (event, config) => {
|
||||
try {
|
||||
const userDataPath = app.getPath("userData");
|
||||
const configPath = path.join(userDataPath, "server-config.json");
|
||||
|
||||
if (!fs.existsSync(userDataPath)) {
|
||||
fs.mkdirSync(userDataPath, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Error saving server config:", error);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle("test-server-connection", async (event, serverUrl) => {
|
||||
try {
|
||||
let fetch;
|
||||
try {
|
||||
fetch = globalThis.fetch || require("node:fetch");
|
||||
} catch (e) {
|
||||
const https = require("https");
|
||||
const http = require("http");
|
||||
const { URL } = require("url");
|
||||
|
||||
fetch = (url, options = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const urlObj = new URL(url);
|
||||
const isHttps = urlObj.protocol === "https:";
|
||||
const client = isHttps ? https : http;
|
||||
|
||||
const req = client.request(
|
||||
url,
|
||||
{
|
||||
method: options.method || "GET",
|
||||
headers: options.headers || {},
|
||||
timeout: options.timeout || 5000,
|
||||
},
|
||||
(res) => {
|
||||
let data = "";
|
||||
res.on("data", (chunk) => (data += chunk));
|
||||
res.on("end", () => {
|
||||
resolve({
|
||||
ok: res.statusCode >= 200 && res.statusCode < 300,
|
||||
status: res.statusCode,
|
||||
text: () => Promise.resolve(data),
|
||||
json: () => Promise.resolve(JSON.parse(data)),
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
req.on("error", reject);
|
||||
req.on("timeout", () => {
|
||||
req.destroy();
|
||||
reject(new Error("Request timeout"));
|
||||
});
|
||||
|
||||
if (options.body) {
|
||||
req.write(options.body);
|
||||
}
|
||||
req.end();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const normalizedServerUrl = serverUrl.replace(/\/$/, "");
|
||||
|
||||
const healthUrl = `${normalizedServerUrl}/health`;
|
||||
|
||||
try {
|
||||
const response = await fetch(healthUrl, {
|
||||
method: "GET",
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.text();
|
||||
|
||||
if (
|
||||
data.includes("<html") ||
|
||||
data.includes("<!DOCTYPE") ||
|
||||
data.includes("<head>") ||
|
||||
data.includes("<body>")
|
||||
) {
|
||||
console.log(
|
||||
"Health endpoint returned HTML instead of JSON - not a Termix server",
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
"Server returned HTML instead of JSON. This does not appear to be a Termix server.",
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const healthData = JSON.parse(data);
|
||||
if (
|
||||
healthData &&
|
||||
(healthData.status === "ok" ||
|
||||
healthData.status === "healthy" ||
|
||||
healthData.healthy === true ||
|
||||
healthData.database === "connected")
|
||||
) {
|
||||
return {
|
||||
success: true,
|
||||
status: response.status,
|
||||
testedUrl: healthUrl,
|
||||
};
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.log("Health endpoint did not return valid JSON");
|
||||
}
|
||||
}
|
||||
} catch (urlError) {
|
||||
console.error("Health check failed:", urlError);
|
||||
}
|
||||
|
||||
try {
|
||||
const versionUrl = `${normalizedServerUrl}/version`;
|
||||
const response = await fetch(versionUrl, {
|
||||
method: "GET",
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.text();
|
||||
|
||||
if (
|
||||
data.includes("<html") ||
|
||||
data.includes("<!DOCTYPE") ||
|
||||
data.includes("<head>") ||
|
||||
data.includes("<body>")
|
||||
) {
|
||||
console.log(
|
||||
"Version endpoint returned HTML instead of JSON - not a Termix server",
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
"Server returned HTML instead of JSON. This does not appear to be a Termix server.",
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const versionData = JSON.parse(data);
|
||||
if (
|
||||
versionData &&
|
||||
(versionData.status === "up_to_date" ||
|
||||
versionData.status === "requires_update" ||
|
||||
(versionData.localVersion &&
|
||||
versionData.version &&
|
||||
versionData.latest_release))
|
||||
) {
|
||||
return {
|
||||
success: true,
|
||||
status: response.status,
|
||||
testedUrl: versionUrl,
|
||||
warning:
|
||||
"Health endpoint not available, but server appears to be running",
|
||||
};
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.log("Version endpoint did not return valid JSON");
|
||||
}
|
||||
}
|
||||
} catch (versionError) {
|
||||
console.error("Version check failed:", versionError);
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
"Server is not responding or does not appear to be a valid Termix server. Please ensure the server is running and accessible.",
|
||||
};
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
});
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow();
|
||||
console.log("Termix started successfully");
|
||||
});
|
||||
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
} else if (mainWindow) {
|
||||
mainWindow.show();
|
||||
}
|
||||
});
|
||||
|
||||
app.on("before-quit", () => {
|
||||
console.log("App is quitting...");
|
||||
});
|
||||
|
||||
app.on("will-quit", () => {
|
||||
console.log("App will quit...");
|
||||
});
|
||||
|
||||
process.on("uncaughtException", (error) => {
|
||||
console.error("Uncaught Exception:", error);
|
||||
});
|
||||
|
||||
process.on("unhandledRejection", (reason, promise) => {
|
||||
console.error("Unhandled Rejection at:", promise, "reason:", reason);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
const { contextBridge, ipcRenderer } = require("electron");
|
||||
|
||||
contextBridge.exposeInMainWorld("electronAPI", {
|
||||
getAppVersion: () => ipcRenderer.invoke("get-app-version"),
|
||||
getPlatform: () => ipcRenderer.invoke("get-platform"),
|
||||
|
||||
getServerConfig: () => ipcRenderer.invoke("get-server-config"),
|
||||
saveServerConfig: (config) =>
|
||||
ipcRenderer.invoke("save-server-config", config),
|
||||
testServerConnection: (serverUrl) =>
|
||||
ipcRenderer.invoke("test-server-connection", serverUrl),
|
||||
|
||||
showSaveDialog: (options) => ipcRenderer.invoke("show-save-dialog", options),
|
||||
showOpenDialog: (options) => ipcRenderer.invoke("show-open-dialog", options),
|
||||
|
||||
onUpdateAvailable: (callback) => ipcRenderer.on("update-available", callback),
|
||||
onUpdateDownloaded: (callback) =>
|
||||
ipcRenderer.on("update-downloaded", callback),
|
||||
|
||||
removeAllListeners: (channel) => ipcRenderer.removeAllListeners(channel),
|
||||
isElectron: true,
|
||||
isDev: process.env.NODE_ENV === "development",
|
||||
|
||||
invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),
|
||||
});
|
||||
|
||||
window.IS_ELECTRON = true;
|
||||
|
||||
console.log("electronAPI exposed to window");
|
||||
+16
-31
@@ -1,38 +1,23 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import react from 'eslint-plugin-react'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
import reactHooks from "eslint-plugin-react-hooks";
|
||||
import reactRefresh from "eslint-plugin-react-refresh";
|
||||
import tseslint from "typescript-eslint";
|
||||
import { globalIgnores } from "eslint/config";
|
||||
|
||||
export default [
|
||||
{ ignores: ['dist'] },
|
||||
export default tseslint.config([
|
||||
globalIgnores(["dist"]),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
files: ["**/*.{ts,tsx}"],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
tseslint.configs.recommended,
|
||||
reactHooks.configs["recommended-latest"],
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
settings: { react: { version: '18.3' } },
|
||||
plugins: {
|
||||
react,
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...js.configs.recommended.rules,
|
||||
...react.configs.recommended.rules,
|
||||
...react.configs['jsx-runtime'].rules,
|
||||
...reactHooks.configs.recommended.rules,
|
||||
'react/jsx-no-target-blank': 'off',
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
]);
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+2305
File diff suppressed because it is too large
Load Diff
Generated
+12625
-4854
File diff suppressed because it is too large
Load Diff
+109
-43
@@ -1,60 +1,126 @@
|
||||
{
|
||||
"name": "termix",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "1.6.0",
|
||||
"description": "A web-based server management platform with SSH terminal, tunneling, and file editing capabilities",
|
||||
"author": "Karmaa",
|
||||
"main": "electron/main.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"clean": "npx prettier . --write",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"build": "vite build && tsc -p tsconfig.node.json",
|
||||
"build:backend": "tsc -p tsconfig.node.json",
|
||||
"dev:backend": "tsc -p tsconfig.node.json && node ./dist/backend/backend/starter.js",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"electron": "electron .",
|
||||
"electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:5173 && electron .\"",
|
||||
"build:win-portable": "npm run build && electron-builder --win --dir",
|
||||
"build:win-installer": "npm run build && electron-builder --win --publish=never",
|
||||
"build:linux-portable": "npm run build && electron-builder --linux --dir"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@fontsource/inter": "^5.1.1",
|
||||
"@mui/icons-material": "^6.4.7",
|
||||
"@mui/joy": "^5.0.0-beta.51",
|
||||
"@tailwindcss/vite": "^4.0.8",
|
||||
"@tiptap/extension-link": "^2.11.5",
|
||||
"@tiptap/pm": "^2.11.5",
|
||||
"@tiptap/react": "^2.11.5",
|
||||
"@tiptap/starter-kit": "^2.11.5",
|
||||
"@hookform/resolvers": "^5.1.1",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-checkbox": "^1.3.2",
|
||||
"@radix-ui/react-collapsible": "^1.1.11",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.15",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
"@radix-ui/react-popover": "^1.1.14",
|
||||
"@radix-ui/react-progress": "^1.1.7",
|
||||
"@radix-ui/react-scroll-area": "^1.2.9",
|
||||
"@radix-ui/react-select": "^2.2.5",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@radix-ui/react-slider": "^1.3.5",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-switch": "^1.2.5",
|
||||
"@radix-ui/react-tabs": "^1.1.12",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/multer": "^2.0.0",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/speakeasy": "^2.0.10",
|
||||
"@uiw/codemirror-extensions-hyper-link": "^4.24.1",
|
||||
"@uiw/codemirror-extensions-langs": "^4.24.1",
|
||||
"@uiw/codemirror-themes": "^4.24.1",
|
||||
"@uiw/react-codemirror": "^4.24.1",
|
||||
"@xterm/addon-attach": "^0.11.0",
|
||||
"@xterm/addon-clipboard": "^0.1.0",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/addon-search": "^0.15.0",
|
||||
"@xterm/addon-unicode11": "^0.8.0",
|
||||
"@xterm/addon-web-links": "^0.11.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"axios": "^1.10.0",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"better-sqlite3": "^12.2.0",
|
||||
"chalk": "^4.1.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"crypto": "^1.0.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"dotenv": "^16.4.7",
|
||||
"embla-carousel-react": "^7.1.0",
|
||||
"express": "^4.21.2",
|
||||
"is-stream": "^4.0.1",
|
||||
"make-dir": "^5.0.0",
|
||||
"mongoose": "^8.12.1",
|
||||
"node-ssh": "^13.2.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"recharts": "^2.15.1",
|
||||
"sb-promise-queue": "^2.1.1",
|
||||
"sb-scandir": "^3.1.0",
|
||||
"shell-escape": "^0.2.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"dotenv": "^17.2.0",
|
||||
"drizzle-orm": "^0.44.3",
|
||||
"express": "^5.1.0",
|
||||
"i18next": "^25.4.2",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"i18next-http-backend": "^3.0.2",
|
||||
"jose": "^5.2.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lucide-react": "^0.525.0",
|
||||
"multer": "^2.0.2",
|
||||
"nanoid": "^5.1.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"node-fetch": "^3.3.2",
|
||||
"qrcode": "^1.5.4",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-hook-form": "^7.60.0",
|
||||
"react-i18next": "^15.7.3",
|
||||
"react-resizable-panels": "^3.0.3",
|
||||
"react-simple-keyboard": "^3.8.120",
|
||||
"react-xtermjs": "^1.0.10",
|
||||
"sonner": "^2.0.7",
|
||||
"speakeasy": "^2.0.0",
|
||||
"ssh2": "^1.16.0",
|
||||
"tailwindcss": "^4.0.8"
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"validator": "^13.15.15",
|
||||
"ws": "^8.18.3",
|
||||
"zod": "^4.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.17.0",
|
||||
"@types/react": "^18.3.18",
|
||||
"@types/react-dom": "^18.3.5",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.16",
|
||||
"globals": "^15.14.0",
|
||||
"vite": "^6.0.5"
|
||||
"@eslint/js": "^9.34.0",
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"@types/cors": "^2.8.19",
|
||||
"@types/express": "^5.0.3",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/ssh2": "^1.15.5",
|
||||
"@types/ws": "^8.18.1",
|
||||
"@vitejs/plugin-react-swc": "^3.10.2",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"concurrently": "^9.2.1",
|
||||
"electron": "^38.0.0",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-icon-builder": "^2.0.1",
|
||||
"electron-packager": "^17.1.2",
|
||||
"eslint": "^9.34.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"globals": "^16.3.0",
|
||||
"prettier": "3.6.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"tw-animate-css": "^1.3.5",
|
||||
"typescript": "~5.9.2",
|
||||
"typescript-eslint": "^8.40.0",
|
||||
"vite": "^7.1.5",
|
||||
"wait-on": "^8.0.4"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 168 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user