docs(workflow): add comprehensive git workflow standards #1

Merged
chaulmark merged 9 commits from develop into main 2025-01-06 17:06:02 +00:00
7 changed files with 254 additions and 86 deletions
Showing only changes of commit 4b8935afd1 - Show all commits

View file

@ -89,11 +89,26 @@ struct ContentView: View {
var body: some View { var body: some View {
VStack { VStack {
// Capture status indicator // Status and Scan controls
CaptureStatusButton( HStack {
isCapturing: viewModel.isCapturing, CaptureStatusButton(
isBoardDetected: viewModel.isBoardDetected isCapturing: viewModel.isCapturing,
) isBoardDetected: viewModel.isBoardDetected
)
Button(action: {
Task {
await viewModel.takeSnapshot()
}
}) {
Text("Scan")
.foregroundColor(.white)
.padding(.horizontal, 20)
.padding(.vertical, 10)
}
.buttonStyle(.borderedProminent)
.disabled(!viewModel.isCapturing || !viewModel.isBoardDetected)
}
.onAppear { .onAppear {
// Start monitoring for chess boards when view appears // Start monitoring for chess boards when view appears
viewModel.startMonitoring() viewModel.startMonitoring()
@ -142,6 +157,22 @@ struct ContentView: View {
Text("No board detected") Text("No board detected")
.foregroundColor(.gray) .foregroundColor(.gray)
} }
if viewModel.snapshotTaken {
Divider()
.padding(.vertical)
Text("Latest Snapshot")
if let snapshot = viewModel.latestSnapshot {
Image(nsImage: snapshot)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 400)
.padding()
.background(Color.black.opacity(0.1))
.cornerRadius(8)
}
}
} }
} }
.padding() .padding()

View file

@ -23,8 +23,16 @@ class ScreenCapture: NSObject, SCStreamOutput {
private var activeStream: SCStream? private var activeStream: SCStream?
private var lastCapturedImage: NSImage? private var lastCapturedImage: NSImage?
private var excludeCursor: Bool = false
func startCapture() async throws { func startCapture(excludeCursor: Bool = false) async throws {
// Always stop any existing capture before starting a new one
if activeStream != nil {
try await stopCapture()
}
self.excludeCursor = excludeCursor
guard #available(macOS 12.3, *) else { return } guard #available(macOS 12.3, *) else { return }
let content = try await SCShareableContent.current let content = try await SCShareableContent.current
@ -43,6 +51,9 @@ class ScreenCapture: NSObject, SCStreamOutput {
let config = SCStreamConfiguration() let config = SCStreamConfiguration()
config.width = Int(window.frame.width) config.width = Int(window.frame.width)
config.height = Int(window.frame.height) config.height = Int(window.frame.height)
config.minimumFrameInterval = CMTime(value: 1, timescale: 30) // 30 FPS
config.queueDepth = 5 // Buffer up to 5 frames
config.showsCursor = !excludeCursor // Set cursor visibility
let stream = SCStream(filter: filter, configuration: config, delegate: nil) let stream = SCStream(filter: filter, configuration: config, delegate: nil)
try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: DispatchQueue.global(qos: .userInitiated)) try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: DispatchQueue.global(qos: .userInitiated))
@ -53,9 +64,11 @@ class ScreenCapture: NSObject, SCStreamOutput {
} }
func stopCapture() async throws { func stopCapture() async throws {
guard let stream = activeStream else { return } if let stream = activeStream {
try await stream.stopCapture() try await stream.stopCapture()
activeStream = nil activeStream = nil
lastCapturedImage = nil
}
} }
func getCurrentImage() -> NSImage? { func getCurrentImage() -> NSImage? {

View file

@ -11,8 +11,11 @@ class ScreenCaptureViewModel: ObservableObject {
@Published var isCapturing = false @Published var isCapturing = false
@Published var isBoardDetected = false @Published var isBoardDetected = false
@Published var isAutoCapturing = true // Default to auto-capture mode @Published var isAutoCapturing = true // Default to auto-capture mode
@Published var snapshotTaken = false // Track if snapshot was taken
@Published var latestSnapshot: NSImage? // Make snapshot accessible to view
private let screenCapture = ScreenCapture() private let captureManager = ScreenCapture() // For actual capture
private let monitorManager = ScreenCapture() // For monitoring
private let boardDetector = BoardDetector() private let boardDetector = BoardDetector()
private var captureTask: Task<Void, Never>? private var captureTask: Task<Void, Never>?
private var monitorTask: Task<Void, Never>? private var monitorTask: Task<Void, Never>?
@ -21,11 +24,13 @@ class ScreenCaptureViewModel: ObservableObject {
private var context: CIContext { ScreenCaptureViewModel.shared } private var context: CIContext { ScreenCaptureViewModel.shared }
private var detectedBoardRect: CGRect? private var detectedBoardRect: CGRect?
private var isMonitoring = false
enum CaptureError: LocalizedError { enum CaptureError: LocalizedError {
case chessWindowNotFound case chessWindowNotFound
case boardDetectionFailed case boardDetectionFailed
case noBoardDetected case noBoardDetected
case snapshotFailed
var errorDescription: String? { var errorDescription: String? {
switch self { switch self {
@ -35,92 +40,135 @@ class ScreenCaptureViewModel: ObservableObject {
return "Failed to detect chess board" return "Failed to detect chess board"
case .noBoardDetected: case .noBoardDetected:
return "No chess board detected" return "No chess board detected"
case .snapshotFailed:
return "Failed to take snapshot"
} }
} }
} }
func takeSnapshot() async {
// Stop current capture
try? await captureManager.stopCapture()
// Start new capture without cursor
do {
try await captureManager.startCapture(excludeCursor: true)
// Wait a brief moment for the capture to stabilize
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds
if let currentImage = captureManager.getCurrentImage() {
// Process the image to get the cropped board
try await processImage(currentImage)
// Store the cropped board as snapshot
if let boardImage = croppedBoardImage {
latestSnapshot = boardImage
snapshotTaken = true
} else {
captureError = .snapshotFailed
}
} else {
captureError = .snapshotFailed
}
// Restart normal capture
try await captureManager.startCapture(excludeCursor: false)
} catch {
captureError = .snapshotFailed
// Ensure we restart normal capture even if snapshot fails
try? await captureManager.startCapture(excludeCursor: false)
}
}
func startMonitoring() { func startMonitoring() {
guard monitorTask == nil else { return } guard !isMonitoring else { return }
isMonitoring = true
monitorTask = Task { monitorTask = Task {
do { monitorLoop: while !Task.isCancelled {
// Start continuous monitoring do {
try await screenCapture.startCapture() // Start monitoring capture
try await monitorManager.startCapture()
monitorLoop: while !Task.isCancelled {
do { while !Task.isCancelled {
if let image = screenCapture.getCurrentImage(), if let image = monitorManager.getCurrentImage(),
let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) { let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) {
// Check for board // Check for board
let ciImage = CIImage(cgImage: cgImage) let ciImage = CIImage(cgImage: cgImage)
if boardDetector.detectBoard(in: ciImage) != nil { if boardDetector.detectBoard(in: ciImage) != nil {
// Board detected, start capture if not already capturing // Board detected, start capture if not already capturing
if !isCapturing { if !isCapturing {
startCapture() await startCapture()
} }
} }
} }
try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
} catch is CancellationError { }
break monitorLoop } catch {
} catch { print("Monitor error: \(error)")
// Just log the error and continue monitoring // If there's an error, wait briefly and try again
print("Monitor error: \(error)") if !Task.isCancelled {
try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 second
continue monitorLoop
} }
} }
try? await screenCapture.stopCapture()
} catch {
print("Monitor setup error: \(error)")
} }
isMonitoring = false
try? await monitorManager.stopCapture()
} }
} }
func stopMonitoring() { func stopMonitoring() {
monitorTask?.cancel() monitorTask?.cancel()
monitorTask = nil monitorTask = nil
isMonitoring = false
stopCapture() stopCapture()
Task {
try? await monitorManager.stopCapture()
}
} }
func startCapture() { func startCapture() async {
guard !isCapturing else { return } guard !isCapturing else { return }
isCapturing = true isCapturing = true
captureError = nil captureError = nil
snapshotTaken = false
latestSnapshot = nil
do {
try await captureManager.startCapture()
} catch {
handleCaptureError(error)
isCapturing = false
return
}
captureTask = Task { captureTask = Task {
do { captureLoop: while !Task.isCancelled {
// Start continuous capture do {
try await screenCapture.startCapture() if let image = captureManager.getCurrentImage() {
try await processImage(image)
captureLoop: while !Task.isCancelled { }
do { try await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds
if let image = screenCapture.getCurrentImage() { } catch is CancellationError {
try await processImage(image) break captureLoop
} } catch {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds // Just update the error state but continue capturing
} catch is CancellationError { if !Task.isCancelled {
break captureLoop handleCaptureError(error)
} catch { if isAutoCapturing && error as? CaptureError == .noBoardDetected {
// Just update the error state but continue capturing // In auto-capture mode, stop capture but keep monitoring
if !Task.isCancelled { stopCapture()
handleCaptureError(error) break captureLoop
if isAutoCapturing && error as? CaptureError == .noBoardDetected {
// In auto-capture mode, stop capture but keep monitoring
stopCapture()
break captureLoop
}
} }
} }
} }
}
// Clean up
try? await screenCapture.stopCapture() if isCapturing {
if isCapturing {
isCapturing = false
}
} catch {
handleCaptureError(error)
isCapturing = false isCapturing = false
} }
} }
@ -132,6 +180,13 @@ class ScreenCaptureViewModel: ObservableObject {
isCapturing = false isCapturing = false
captureError = nil captureError = nil
isBoardDetected = false isBoardDetected = false
snapshotTaken = false
latestSnapshot = nil
// Clean up capture session
Task {
try? await captureManager.stopCapture()
}
} }
private func processImage(_ image: NSImage) async throws { private func processImage(_ image: NSImage) async throws {

View file

@ -10,23 +10,43 @@
- Automatic board detection and capture implemented - Automatic board detection and capture implemented
- Visual capture status indicator added - Visual capture status indicator added
- Continuous board monitoring system implemented - Continuous board monitoring system implemented
- Auto-capture on game start/stop working successfully
- Manual snapshot system implemented with Scan button
- Snapshot preview display added below Chessboard Preview
- Cursor-free snapshot capture implemented
## Recent Changes ## Recent Changes
1. Implemented Continuous Board Monitoring: 1. Enhanced Manual Snapshot System:
- New cursor-free capture:
* Temporarily disables cursor during snapshot
* Ensures clean board capture without mouse pointer
* Automatically restores cursor after snapshot
- Improved snapshot process:
* Stops current capture
* Takes cursor-free snapshot
* Processes board detection
* Restores normal capture
* Handles errors gracefully
- Snapshot visualization:
* Added preview area below Chessboard Preview
* Shows latest snapshot with visual feedback
* Clear indication when snapshot is taken
2. Implemented Continuous Board Monitoring:
- Added separate monitoring and capture tasks: - Added separate monitoring and capture tasks:
* Monitor constantly checks for chess boards (0.5s interval) * Monitor constantly checks for chess boards (0.5s interval)
* Capture processes frames when active (0.1s interval) * Capture processes frames when active (0.1s interval)
- Auto-capture behavior: - Auto-capture behavior working as expected:
* Starts monitoring when app launches * Starts monitoring when app launches
* Automatically starts capture when board appears * Automatically starts capture when board appears
* Stops capture (but keeps monitoring) when board disappears * Stops capture but continues monitoring when board disappears
* Resumes capture when new board is detected * Successfully resumes capture when new game starts
- Fixed image conversion pipeline: - Performance characteristics:
* Proper NSImage → CGImage → CIImage conversion * ~40% CPU usage during operation
* Efficient resource management * Stable memory management
* Clean error handling * Responsive to game state changes
2. Enhanced Status Indication: 3. Enhanced Status Indication:
- Visual status indicator shows capture state: - Visual status indicator shows capture state:
* Green: Actively capturing board * Green: Actively capturing board
* Yellow: Waiting for board * Yellow: Waiting for board
@ -34,7 +54,7 @@
- Clear error messages for different states - Clear error messages for different states
- Automatic status updates based on board detection - Automatic status updates based on board detection
3. Resource Management Optimization: 4. Resource Management:
- Implemented shared CIContext pattern: - Implemented shared CIContext pattern:
* Prevents command queue exhaustion * Prevents command queue exhaustion
* Reduces Metal resource usage * Reduces Metal resource usage
@ -42,22 +62,13 @@
- Proper cleanup on task completion - Proper cleanup on task completion
- Efficient resource utilization - Efficient resource utilization
4. Improved Window Detection: 5. Improved Window Detection:
- Using SCShareableContent for window access - Using SCShareableContent for window access
- Precise window identification: - Precise window identification:
* Exact bundle ID matching (com.chess.iphone) * Exact bundle ID matching (com.chess.iphone)
* Window visibility verification (isOnScreen) * Window visibility verification (isOnScreen)
* Size validation (width > 100 && height > 100) * Size validation (width > 100 && height > 100)
5. Enhanced Capture System:
- Continuous capture implementation:
* Single persistent capture stream
* Smooth frame processing (no flickering)
* Efficient resource usage
- Proper frame dimensions from window
- Clean task cancellation handling
- Main thread safety for UI updates
6. Error Handling: 6. Error Handling:
- Improved error resilience: - Improved error resilience:
* Continues monitoring even if capture stops * Continues monitoring even if capture stops
@ -69,16 +80,17 @@
- Thread-safe state updates - Thread-safe state updates
## Current Focus ## Current Focus
1. Board Detection: 1. Board Recognition:
- Implement chess board recognition - Process snapshot images
- Handle different board themes - Implement piece detection
- Process captured frames efficiently - Extract board state
## Next Steps ## Next Steps
1. Implement board detection: 1. Implement board recognition:
- Pattern recognition for chess pieces - Process snapshot images
- Board coordinate mapping - Detect chess pieces
- Position validation - Map board coordinates
- Validate positions
2. Add position analysis 2. Add position analysis
3. Create move detection system 3. Create move detection system
4. Implement visual overlay 4. Implement visual overlay

View file

@ -15,11 +15,13 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Recognizes board coordinates and boundaries - Recognizes board coordinates and boundaries
- Handles various board themes and orientations - Handles various board themes and orientations
- Maintains accuracy during game play - Maintains accuracy during game play
- Provides clean board snapshots for analysis
### Real-time Processing ### Real-time Processing
- Captures and processes screen content in real-time - Captures and processes screen content in real-time
- Provides immediate feedback and analysis - Provides immediate feedback and analysis
- Maintains performance during long sessions - Maintains performance during long sessions
- Supports manual snapshot capture for detailed analysis
## User Experience Goals ## User Experience Goals
@ -28,11 +30,14 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Works with Chess.com desktop app - Works with Chess.com desktop app
- Minimal setup requirements - Minimal setup requirements
- Automatic board detection and tracking - Automatic board detection and tracking
- Clean snapshot capture without cursor interference
2. Intuitive Interface 2. Intuitive Interface
- Clear visualization of analysis - Clear visualization of analysis
- Easy-to-understand suggestions - Easy-to-understand suggestions
- Minimal user intervention required - Minimal user intervention required
- Visual feedback for capture states
- Manual snapshot control
### Reliable Detection ### Reliable Detection
1. Board Recognition 1. Board Recognition
@ -41,6 +46,7 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
* Coordinate-based fallback for reliability * Coordinate-based fallback for reliability
- Proper coordinate system handling - Proper coordinate system handling
- Consistent board capture across sessions - Consistent board capture across sessions
- High-quality snapshots for analysis
2. Position Analysis 2. Position Analysis
- Accurate piece recognition (planned) - Accurate piece recognition (planned)
@ -59,11 +65,13 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Understanding position evaluation - Understanding position evaluation
- Learning from mistakes - Learning from mistakes
- Exploring alternative moves - Exploring alternative moves
- Analyzing specific positions via snapshots
2. Analysis 2. Analysis
- Real-time position assessment - Real-time position assessment
- Move validation - Move validation
- Strategic planning - Strategic planning
- Detailed position study
## Product Requirements ## Product Requirements
@ -73,6 +81,7 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Full board capture - Full board capture
- Support for Chess.com desktop app - Support for Chess.com desktop app
- Reliable coordinate transformations - Reliable coordinate transformations
- Clean snapshot capability
2. Position Analysis (Planned) 2. Position Analysis (Planned)
- Real-time evaluation - Real-time evaluation
@ -83,22 +92,27 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Analysis overlay - Analysis overlay
- Control panel - Control panel
- Settings management - Settings management
- Snapshot controls
- Visual status indicators
### Quality Standards ### Quality Standards
1. Accuracy 1. Accuracy
- Reliable board detection - Reliable board detection
- Complete board capture - Complete board capture
- Precise coordinate handling - Precise coordinate handling
- Clean snapshots without artifacts
2. Performance 2. Performance
- Real-time processing - Real-time processing
- Minimal resource usage - Minimal resource usage
- Stable operation - Stable operation
- Efficient snapshot handling
3. Usability 3. Usability
- Intuitive controls - Intuitive controls
- Clear feedback - Clear feedback
- Minimal setup - Minimal setup
- Simple snapshot workflow
## Success Metrics ## Success Metrics
@ -107,12 +121,14 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Full board capture success rate - Full board capture success rate
- Processing speed per frame - Processing speed per frame
- Error recovery rate - Error recovery rate
- Snapshot quality assessment
### User Metrics ### User Metrics
- Setup success rate - Setup success rate
- Analysis accuracy - Analysis accuracy
- User engagement time - User engagement time
- Feature utilization - Feature utilization
- Snapshot usage patterns
## Current Challenges ## Current Challenges
@ -127,12 +143,14 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Full board capture - Full board capture
- Consistent positioning - Consistent positioning
- Reliable boundaries - Reliable boundaries
- Clean snapshots
### Next Steps ### Next Steps
1. Refine board detection 1. Refine board detection
- Improve coordinate handling - Improve coordinate handling
- Ensure full board capture - Ensure full board capture
- Validate transformations - Validate transformations
- Optimize snapshot quality
2. Move to position analysis 2. Move to position analysis
- Piece recognition - Piece recognition
@ -146,16 +164,19 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Deep position evaluation - Deep position evaluation
- Opening recognition - Opening recognition
- Endgame tablebases - Endgame tablebases
- Position comparison from snapshots
2. Learning Tools 2. Learning Tools
- Mistake analysis - Mistake analysis
- Improvement suggestions - Improvement suggestions
- Progress tracking - Progress tracking
- Position database from snapshots
3. Customization 3. Customization
- Analysis depth control - Analysis depth control
- Visual preference settings - Visual preference settings
- Platform-specific optimizations - Platform-specific optimizations
- Snapshot management options
## Product Roadmap ## Product Roadmap
@ -163,13 +184,16 @@ ChessPrism is an advanced chess analysis tool that enhances the online chess exp
- Core board detection system - Core board detection system
- Coordinate system handling - Coordinate system handling
- Basic user interface - Basic user interface
- Manual snapshot system
### Next Phase ### Next Phase
- Position analysis - Position analysis
- Move suggestion system - Move suggestion system
- Visual overlay implementation - Visual overlay implementation
- Enhanced snapshot analysis
### Future Phase ### Future Phase
- Advanced analysis features - Advanced analysis features
- Learning tools integration - Learning tools integration
- Customization options - Customization options
- Snapshot database and comparison tools

View file

@ -24,12 +24,35 @@
- Window-specific capture setup - Window-specific capture setup
- Frame dimension matching - Frame dimension matching
- Proper delegate handling - Proper delegate handling
- Cursor visibility control:
* Configurable cursor display
* Clean snapshot support
* State preservation
2. Frame Processing 2. Frame Processing
- Main thread safety for UI updates - Main thread safety for UI updates
- Efficient image conversion pipeline - Efficient image conversion pipeline
- Resource cleanup - Resource cleanup
### Snapshot System Pattern
1. Cursor-Free Capture
- Temporary capture session:
* Disables cursor visibility
* Takes clean snapshot
* Restores normal capture
- Error handling:
* Session cleanup
* State recovery
* Capture restoration
2. Process Flow
- Stop current capture
- Start cursor-free capture
- Wait for stabilization
- Take snapshot
- Process image
- Restore normal capture
### Error Handling Pattern ### Error Handling Pattern
1. Task Management 1. Task Management
- Proper cancellation points - Proper cancellation points
@ -89,6 +112,7 @@
- Handles capture session lifecycle and cleanup - Handles capture session lifecycle and cleanup
- Manages permissions and error handling - Manages permissions and error handling
- Optimized resource usage - Optimized resource usage
- Configurable cursor visibility
### Board Detection System ### Board Detection System
Two implemented approaches: Two implemented approaches:

View file

@ -25,11 +25,13 @@
* iOS app window capture support * iOS app window capture support
* Real-time frame capture * Real-time frame capture
* Proper error handling * Proper error handling
* Configurable cursor visibility
- Key components: - Key components:
* SCShareableContent: Window and display access * SCShareableContent: Window and display access
* SCContentFilter: Window-specific capture * SCContentFilter: Window-specific capture
* SCStream: Frame capture management * SCStream: Frame capture management
* SCStreamOutput: Frame processing * SCStreamOutput: Frame processing
* SCStreamConfiguration: Capture settings including cursor control
### Vision Framework (Planned) ### Vision Framework (Planned)
- Will be used for board and coordinate detection - Will be used for board and coordinate detection
@ -89,6 +91,10 @@
- Frame dimension matching - Frame dimension matching
- Proper delegate handling - Proper delegate handling
- Resource cleanup - Resource cleanup
- Cursor visibility control:
* Configurable via SCStreamConfiguration
* State preservation between captures
* Clean snapshot support
3. Performance 3. Performance
- Main thread safety for UI updates - Main thread safety for UI updates
@ -155,18 +161,21 @@
- Error handling - Error handling
- State management - State management
- Resource management - Resource management
- Cursor control functionality
### Integration Tests ### Integration Tests
- End-to-end workflows - End-to-end workflows
- Component interaction - Component interaction
- Event propagation - Event propagation
- Resource sharing - Resource sharing
- Snapshot system
### UI Tests ### UI Tests
- User interaction flows - User interaction flows
- Error state handling - Error state handling
- Visual feedback - Visual feedback
- Performance monitoring - Performance monitoring
- Snapshot visualization
## Documentation Requirements ## Documentation Requirements