- Integrated react-markdown with GitHub Flavored Markdown support
- Added react-pdf for PDF viewing with full navigation controls
- Implemented react-syntax-highlighter for code syntax highlighting
- Added dual-pane Markdown editor with live preview capability
- Fixed PDF.js worker configuration with local fallback
- Enhanced internationalization support for all multimedia controls
- Removed unsupported download buttons from Markdown editor
- Resolved version compatibility issues between PDF API and worker
技术改进 Claude Code生成
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace basic HTML5 audio with react-h5-audio-player (49,599+ weekly downloads)
- Add comprehensive audio format support with proper MIME type mapping (MP3, WAV, FLAC, OGG, AAC, M4A)
- Implement modern music player UI with album artwork placeholder and track information display
- Add smart window sizing for audio files (600x400 standard dimensions)
- Include professional audio controls with progress bar, volume control, and download progress
- Enhance user experience with gradient backgrounds and responsive design
- Add comprehensive event handling for play, pause, metadata loading, and error states
- Integrate with existing media dimension detection system for consistent window behavior
- Maintain mobile-friendly interface with keyboard navigation support
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace ReactPlayer with native HTML5 video for better MP4 support
- Add proper MIME type mapping for all video formats (mp4, webm, mkv, avi, mov, wmv, flv)
- Implement smart window sizing based on media dimensions
- Auto-adjust window size to match image/video aspect ratio with constraints
- Add media dimension detection for images (naturalWidth/Height) and videos (videoWidth/Height)
- Center windows automatically when resizing for media content
- Apply intelligent scaling with max viewport limits (90% width, 80% height)
- Preserve minimum window sizes and add padding for UI elements
- Enhanced error handling and debug logging for video playback
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix keyboard shortcut conflicts in FileViewer.tsx (Ctrl+F, H, ?, Space, A)
- Add comprehensive i18n translations for keyboard shortcuts help panel
- Integrate react-photo-view for enhanced fullscreen image viewing
- Simplify image preview by removing complex toolbar and hover hints
- Add proper error handling and loading states for image display
- Update English and Chinese translation files with new keyboard shortcut terms
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace custom search/replace implementation with native CodeMirror extensions
- Add proper keyboard shortcut support: Ctrl+F, Ctrl+H, Ctrl+/, Ctrl+Space, etc.
- Fix browser shortcut conflicts by preventing defaults only when editor is focused
- Integrate autocompletion and comment toggle functionality
- Fix file name truncation in file manager grid to use text wrapping
- Add comprehensive keyboard shortcuts help panel for users
- Update i18n translations for editor buttons (Download, Replace, Replace All)
- Unify text and code file editing under single CodeMirror instance
- Add proper SSH HMAC algorithms for better compatibility
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root Cause Analysis:
- Generic error handling in main-axios.ts was stripping fileNotFound data from 404 responses
- Windows were being created before error detection, showing empty editors with "File is empty"
- Error message translation was not properly detecting various file-not-found scenarios
Core Fixes:
1. **Preserve 404 Error Data:** Modified readSSHFile to preserve fileNotFound information
- Create custom error object for 404 responses
- Set isFileNotFound flag to bypass generic error handling
- Maintain original response data for proper error detection
2. **Enhanced Error Detection:** Improved FileWindow error detection logic
- Check for custom isFileNotFound flag
- Detect multiple error message patterns: "File not found", "Resource not found"
- Handle both backend-specific and generic error formats
3. **Prevent Empty Windows:** Auto-close window when file cleanup occurs
- Call closeWindow(windowId) immediately after cleanup
- Return early to prevent showing empty editor
- Show only the cleanup notification toast
Behavior Changes:
- **Before:** Opens empty editor + shows "Server error occurred" + displays "File is empty"
- **After:** Shows "File removed from recent/pinned lists" + closes window immediately
- **Result:** Clean, user-friendly experience with automatic cleanup
Technical Details:
- Enhanced readSSHFile error handling for 404 status codes
- Improved error pattern matching for various "not found" scenarios
- Window lifecycle management during error states
- Preserved backward compatibility for other error types
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
File Cleanup Implementation:
- Detect file-not-found errors when opening files from recent/pinned lists
- Automatically remove missing files from both recent and pinned file lists
- Refresh sidebar to reflect updated lists immediately after cleanup
- Prevent error dialogs from appearing when files are successfully cleaned up
Backend Improvements:
- Enhanced SSH file manager to return proper 404 status for missing files
- Added fileNotFound flag in error responses for better error detection
- Improved error categorization for file access failures
Frontend Error Handling:
- Added onFileNotFound callback prop to FileWindow component
- Implemented handleFileNotFound function in FileManagerModern
- Enhanced error detection logic to catch various "file not found" scenarios
- Better error messages with internationalization support
Translation Additions:
- fileNotFoundAndRemoved: Notify user when file is cleaned up
- failedToLoadFile: Generic file loading error message
- serverErrorOccurred: Server error fallback message
- Chinese translations for all new error messages
Technical Details:
- Uses existing removeRecentFile and removePinnedFile API calls
- Triggers sidebar refresh via setSidebarRefreshTrigger
- Maintains backward compatibility with existing error handling
- Preserves error logging for debugging purposes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Security Fixes:
- Configure Express trust proxy to properly detect client IPs behind nginx reverse proxy
- Remove deprecated isLocalhost() function that was vulnerable to IP spoofing
- Ensure /ssh/db/host/internal endpoint uses secure token-based authentication only
Internationalization Improvements:
- Replace hardcoded English strings with proper i18n keys in admin settings
- Complete SSH configuration documentation translation (sshpass, server config)
- Add missing translation keys for Debian/Ubuntu, macOS, Windows installation methods
- Fix Chinese translation key mismatches for SSH server configuration options
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit enhances the user experience by standardizing all text editing
components to use CodeMirror, providing consistent functionality across the
entire application.
**Text Editor Unification**:
- Replaced all textarea elements with CodeMirror editors
- Unified syntax highlighting and line numbering across all text inputs
- Consistent oneDark theme implementation throughout the application
**Fixed Components**:
- FileViewer: Enhanced file editing with syntax highlighting for all file types
- CredentialEditor: Improved SSH key editing experience with code editor features
- HostManagerEditor: Better SSH private key input with proper formatting
- FileManagerGrid: Fixed new file/folder creation in empty directories
**Key Technical Improvements**:
- Fixed oneDark theme import path from @uiw/codemirror-themes to @codemirror/theme-one-dark
- Enhanced createIntent rendering logic to work properly in empty directories
- Added automatic createIntent cleanup when navigating between directories
- Configured consistent basicSetup options across all editors
**User Experience Enhancements**:
- Professional code editing interface for all text inputs
- Line numbers and syntax highlighting for better readability
- Consistent keyboard shortcuts and editing behavior
- Improved accessibility and user interaction patterns
Users now enjoy a unified, professional editing experience whether working with
code files, configuration files, or SSH credentials. The interface is consistent,
feature-rich, and optimized for developer workflows.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix missing i18n for terminal.terminalWithPath translation key
- Update keyboard shortcuts: remove Ctrl+T conflicts, change refresh to Ctrl+Y, rename shortcut to F6
- Remove click-to-rename functionality to prevent accidental renaming
- Fix drag preview z-index and positioning issues during file operations
- Remove false download trigger when dragging files to original position
- Fix 'Must be handling a user gesture' error in drag-to-desktop functionality
- Remove useless minimize button from file editor and diff viewer windows
- Improve context menu z-index hierarchy for better layering
- Add comprehensive drag state management and visual feedback
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed SSH sessions being automatically removed after a few minutes of
inactivity, causing connection errors when users return to the interface.
## Problems Identified:
### 1. Aggressive Session Timeout
**Issue**: Sessions were cleaned up after only 10 minutes of inactivity
- Too short for typical user workflows
- No warning or graceful handling when timeout occurs
- Users would get connection errors without explanation
### 2. No Session Keepalive Mechanism
**Issue**: No frontend keepalive to maintain active sessions
- Sessions would timeout even if user was actively viewing files
- No periodic communication to extend session lifetime
- No way to detect session expiration proactively
### 3. Server-side SSH Configuration
**Issue**: While SSH had keepalive settings, they weren't sufficient
- keepaliveInterval: 30000ms (30s)
- keepaliveCountMax: 3
- But no application-level session management
## Technical Solution:
### **Extended Session Timeout**
```typescript
// Increased from 10 minutes to 30 minutes
session.timeout = setTimeout(() => {
fileLogger.info(`Cleaning up inactive SSH session: ${sessionId}`);
cleanupSession(sessionId);
}, 30 * 60 * 1000); // 30 minutes
```
### **Backend Keepalive Endpoint**
```typescript
// New endpoint: POST /ssh/file_manager/ssh/keepalive
app.post("/ssh/file_manager/ssh/keepalive", (req, res) => {
const session = sshSessions[sessionId];
session.lastActive = Date.now();
scheduleSessionCleanup(sessionId); // Reset timeout
res.json({ status: "success", connected: true });
});
```
### **Frontend Automatic Keepalive**
```typescript
// Send keepalive every 5 minutes
keepaliveTimerRef.current = setInterval(async () => {
if (sshSessionId) {
await keepSSHAlive(sshSessionId);
}
}, 5 * 60 * 1000);
```
## Session Management Flow:
**Before (Problematic):**
1. User connects → 10-minute countdown starts
2. User leaves browser open but inactive
3. Session times out after 10 minutes
4. User returns → "SSH session not found" error
5. User forced to reconnect manually
**After (Fixed):**
1. User connects → 30-minute countdown starts
2. Frontend sends keepalive every 5 minutes automatically
3. Each keepalive resets the 30-minute timeout
4. Session stays alive as long as browser tab is open
5. Graceful handling if keepalive fails
## Benefits:
✅ **Extended Session Lifetime**: 30 minutes vs 10 minutes base timeout
✅ **Automatic Session Maintenance**: Keepalive every 5 minutes
✅ **Transparent to User**: No manual intervention required
✅ **Robust Error Handling**: Graceful degradation if keepalive fails
✅ **Resource Efficient**: Only active sessions consume resources
✅ **Better User Experience**: No unexpected disconnections
Sessions now persist for the entire duration users have the file
manager open, eliminating frustrating timeout errors.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed race conditions and loading problems when users click folders
or navigation buttons too quickly.
## Problems Identified:
### 1. Race Conditions in Path Changes
**Issue**: Fast clicking folders/back button caused multiple simultaneous requests
- useEffect triggered on every currentPath change
- No debouncing for path changes (only for manual refresh)
- Multiple loadDirectory() calls executed concurrently
- Later responses could overwrite earlier ones
### 2. Concurrent Request Conflicts
**Issue**: loadDirectory() had basic isLoading check but insufficient protection
- Multiple requests could run if timing was right
- No tracking of which request was current
- Stale responses could update UI incorrectly
### 3. Missing Request Cancellation
**Issue**: No way to cancel outdated requests when user navigates rapidly
- Old requests would complete and show wrong directory
- Confusing UI state when mixed responses arrived
## Technical Solution:
### **Path Change Debouncing**
```typescript
// Added 150ms debounce specifically for path changes
const debouncedLoadDirectory = useCallback((path: string) => {
if (pathChangeTimerRef.current) {
clearTimeout(pathChangeTimerRef.current);
}
pathChangeTimerRef.current = setTimeout(() => {
if (path !== lastPathChangeRef.current && sshSessionId) {
loadDirectory(path);
}
}, 150);
}, [sshSessionId, loadDirectory]);
```
### **Request Race Condition Protection**
```typescript
// Track current loading path for proper cancellation
const currentLoadingPathRef = useRef<string>("");
// Enhanced concurrent request prevention
if (isLoading && currentLoadingPathRef.current !== path) {
console.log("Directory loading already in progress, skipping:", path);
return;
}
```
### **Stale Response Handling**
```typescript
// Check if response is still relevant before updating UI
if (currentLoadingPathRef.current !== path) {
console.log("Directory load canceled, newer request in progress:", path);
return; // Discard stale response
}
```
## Flow Improvements:
**Before (Problematic):**
1. User clicks folder A → currentPath changes → useEffect → loadDirectory(A)
2. User quickly clicks folder B → currentPath changes → useEffect → loadDirectory(B)
3. Both requests run concurrently
4. Response A or B arrives randomly, wrong folder might show
**After (Fixed):**
1. User clicks folder A → currentPath changes → debouncedLoadDirectory(A)
2. User quickly clicks folder B → currentPath changes → cancels A timer → debouncedLoadDirectory(B)
3. Only request B executes after 150ms
4. If A somehow runs, its response is discarded as stale
## User Experience:
✅ Rapid folder navigation works smoothly
✅ Back button rapid clicking handled properly
✅ No more loading wrong directories
✅ Proper loading states maintained
✅ No duplicate API requests
✅ Responsive feel with 150ms debounce (fast enough to feel instant)
The file manager now handles rapid user interactions gracefully without
race conditions or loading the wrong directory content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the brief jarring flash between SSH connection and file list display:
## Problem
During file manager connection process:
1. SSH connection completes → setIsLoading(false)
2. Brief empty/intermediate state displayed (jarring flash)
3. useEffect triggers → setIsLoading(true) again
4. Directory loads → setIsLoading(false)
5. Files finally displayed
This created a jarring user experience with double loading states.
## Root Cause
- initializeSSHConnection() only handled SSH connection
- File directory loading was handled separately in useEffect
- Gap between connection completion and directory loading caused UI flash
## Solution
**Unified Connection + Directory Loading:**
- Modified initializeSSHConnection() to load initial directory immediately after SSH connection
- Added initialLoadDoneRef to prevent duplicate loading in useEffect
- Loading state now remains true until both connection AND directory are ready
**Technical Changes:**
- SSH connection + initial directory load happen atomically
- useEffect skips initial load, only handles path changes
- No more intermediate states or double loading indicators
## Flow Now:
1. setIsLoading(true) → "Connecting..."
2. SSH connection establishes
3. Initial directory loads immediately
4. setIsLoading(false) → Files displayed seamlessly
**User Experience:**
✅ Smooth single loading state until everything is ready
✅ No jarring flashes or intermediate states
✅ Immediate file display after connection
✅ Maintains proper loading states for path changes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed "ReferenceError: t is not defined" when creating new files/folders:
Problem:
- CreateIntentGridItem and CreateIntentListItem components used t() function
- But neither component had useTranslation hook imported
- Caused runtime error when trying to create new files or folders
Solution:
- Added const { t } = useTranslation(); to both components
- Fixed hardcoded English text in CreateIntentListItem placeholder
- Now uses proper i18n translation keys for all UI text
Changes:
- CreateIntentGridItem: Added useTranslation hook
- CreateIntentListItem: Added useTranslation hook + fixed placeholder text
- Both components now properly use t('fileManager.folderName') and t('fileManager.fileName')
Now file/folder creation works without console errors and supports i18n.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: Duplicate handleFileOpen function definitions caused symlinks
to be treated as regular files instead of navigating to their targets.
Problem:
- Line 575: Correct implementation with symlink handling
- Line 1401: Incorrect duplicate that overrode the correct function
- Double-clicking symlinks opened them as files instead of following links
Solution:
- Removed duplicate handleFileOpen function (lines 1401-1436)
- Preserved correct implementation with symlink navigation logic
- Added recordRecentFile call for consistency
Now symlinks properly:
- Navigate to target directories when they point to folders
- Open target files when they point to files
- Use identifySSHSymlink backend API for resolution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed WebSocket connection issue where SSH terminals couldn't connect
despite correct credentials. Root cause was port mismatch - terminals
were trying to connect to port 8081 while SSH service runs on 8082.
Changes:
- Desktop Terminal: Updated WebSocket URL to use port 8082
- Mobile Terminal: Updated WebSocket URL to use port 8082
- File Manager continues using port 8081 for HTTP API (unchanged)
This ensures all SSH terminal connections route to the correct service port.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major architectural improvements:
- Auto-generate SSL certificates on first startup with OpenSSL
- Dual HTTP (8081) + HTTPS (8443) backend API servers
- Frontend auto-detects protocol and uses appropriate API endpoint
- Fix database ORM initialization race condition with getDb() pattern
- WebSocket authentication with JWT verification during handshake
- Zero-config .env file generation for production deployment
- Docker and nginx configurations for container deployment
Technical fixes:
- Eliminate module initialization race conditions in database access
- Replace direct db imports with safer getDb() function calls
- Automatic HTTPS frontend development server (npm run dev:https)
- SSL certificate generation with termix.crt/termix.key
- Cross-platform environment variable support with cross-env
This enables seamless HTTP→HTTPS upgrade with zero manual configuration.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Core changes:
- Remove file/database fallback storage complexity
- Enforce JWT_SECRET and DATABASE_KEY as environment variables only
- Auto-generate keys on first startup with clear user guidance
- Eliminate circular dependencies and storage layer abstractions
Security improvements:
- Single source of truth for secrets (environment variables)
- No persistent storage of secrets in files or database
- Clear deployment guidance for production environments
- Simplified attack surface by removing storage complexity
WebSocket authentication:
- Implement JWT authentication for WebSocket handshake
- Add connection limits and user tracking
- Update frontend to pass JWT tokens in WebSocket URLs
- Configure Nginx for authenticated WebSocket proxy
Additional fixes:
- Replace CORS wildcard with specific origins
- Remove password logging security vulnerability
- Streamline encryption architecture following Linus principles
- FileManagerModern.tsx: Translate all Chinese comments to English, replace hardcoded text with i18n
- TerminalWindow.tsx: Complete translation and add i18n support
- DiffWindow.tsx: Complete translation and add i18n support
- FileManagerOperations.tsx: Complete translation
- Fix missed comment in FileManagerGrid.tsx
All File Manager components now have clean English comments and proper internationalization.
Follow Linus principles: simple, direct, no unnecessary complexity.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Complete translation of FileWindow.tsx comments and hardcoded text
- Complete translation of DraggableWindow.tsx hardcoded text
- Complete translation of FileManagerSidebar.tsx comments
- Complete translation of FileManagerGrid.tsx comments and UI text
- Complete translation of DiffViewer.tsx hardcoded text with proper i18n
- Partial translation of FileManagerModern.tsx comments (major sections done)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Following Linus principle: "功能不完整就不应该暴露给用户"
BEFORE: F2 key only printed console.log - useless UI control
AFTER: F2 properly triggers onStartEdit for file rename
This was a classic "half-baked" feature that frustrated users.
F2 is a standard Windows/Linux file manager shortcut.
Note: Could not locate "Straight button" mentioned in issue.
Searched all UI controls, sorting, layout functions - not found.
May have been removed or misnamed.
The core F2 rename issue is now resolved.
Following "good taste" principles to separate create intent from actual files:
DATA STRUCTURE REDESIGN:
- Add CreateIntent interface to separate intent from reality
- Replace mixed virtual/real file handling with pure separation
- Remove isCreatingNewFile state that caused confusion
ELIMINATE SPECIAL CASES:
- Cancel operation now has zero side effects (was creating default files)
- Remove complex conditional logic in handleCancelEdit
- Separate handleConfirmCreate from handleRenameConfirm responsibilities
SIMPLIFY USER FLOW:
- Create intent → Show UI → Confirm → Create file
- Cancel intent → Clean state → No side effects
- No more "NewFolder" + "UserName" duplicate creation
UI COMPONENTS:
- Add CreateIntentGridItem and CreateIntentListItem
- Render create intent separately from real files
- Focus/select input automatically with ESC/Enter handling
Resolves: Users reporting duplicate files on creation
Core fix: Eliminates the "special case" of cancel-creates-file
Result: Predictable, elegant file creation flow
Following Linus's "good taste" principles to eliminate race conditions:
- Add request ID tracking to prevent concurrent request conflicts
- Simplify loadDirectory function by removing complex reconnection logic
- Add reconnection lock to prevent concurrent SSH reconnections
- Implement 500ms refresh debouncing to prevent spam clicking
- Separate concerns: connection management vs file operations
Eliminates "special cases" that caused random state corruption.
The data structure now properly tracks request lifecycle.
Resolves file folder refresh showing stale content issue.
This commit eliminates the confusing requirePassword field that was causing
authentication issues where users couldn't disable password requirements.
Changes:
- Remove requirePassword field from database schema and migrations
- Simplify SSH authentication logic by removing special case branches
- Update frontend to remove requirePassword UI controls
- Clean up translation files to remove unused strings
- Support standard SSH empty password authentication
The new design follows the principle of "good taste" - password field itself
now expresses the requirement: null/empty = no password auth, value = use password.
Fixes the issue where setting requirePassword=false didn't work as expected.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Correct uploadSSHFile parameter order and types in FileManagerModern.tsx:
* Pass directory path instead of full file path
* Extract file.name instead of passing File object
* Read file content using FileReader API
* Support both text and binary files with proper encoding
- Apply same fixes to FileManagerOperations.tsx upload functionality
- Add intelligent file type detection:
* Text files read as UTF-8 strings
* Binary files read as ArrayBuffer and converted to base64
* Support common text file extensions and MIME types
- Include hostId parameter in uploadSSHFile calls for proper authentication
This resolves the "File path, name, and content are required" error
by ensuring all required parameters are correctly provided to the API.
- Add 18 new translation keys for file manager sidebar and context menu operations
- Replace hardcoded Chinese text with t() function calls in FileManagerSidebar.tsx:
* Toast messages for remove/unpin/clear operations
* Context menu items for recent files, pinned files, and shortcuts
- Replace hardcoded Chinese text with t() function calls in FileManagerContextMenu.tsx:
* Pin/unpin file menu items
* Add to shortcuts menu item
* Save to system menu items with dynamic count support
- Add bilingual support for all new strings (English and Chinese)
- Improve consistency with existing i18n patterns
- Add right-click menu for Recent items: remove single item or clear all
- Add right-click menu for Pinned items: unpin functionality
- Add right-click menu for Shortcut items: remove shortcut functionality
- Implement menu close on outside click and ESC key
- Optimize data refresh mechanism: auto-reload sidebar data after operations
- Add success/failure toast notifications for user feedback
Major improvements:
- Remove separate view/edit modes - editing state can view content too
- Expand text editing support to ALL file types except media/binary files
- Add realistic undo functionality for copy/cut operations
- Implement moveSSHItem API for proper cross-directory file moves
- Add file existence checks to prevent copy failures
- Enhanced error logging with full command and path information
Key changes:
- FileWindow: Expand editable file types to exclude only media extensions
- FileViewer: Remove view mode toggle, direct editing interface
- Backend: Add moveItem API endpoint for cut operations
- Backend: Add file existence verification before copy operations
- Frontend: Complete undo system for copy (delete copied files) and cut (move back to original location)
File type handling:
- Media files (jpg, mp3, mp4, etc.) → Display only
- All other files → Direct text editing (js, py, txt, config files, unknown extensions)
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>