diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..e183a82 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,71 @@ +# SwiftLint Configuration for ChessPrism + +disabled_rules: + - trailing_whitespace + - line_length + - function_body_length + - file_length + - type_body_length + - identifier_name + +opt_in_rules: + - empty_count + - closure_spacing + - force_unwrapping + - force_cast + - discouraged_direct_init + - discouraged_object_literal + +included: + - ChessPrism + - ChessPrismTests + - ChessPrismUITests + +excluded: + - Carthage + - Pods + - SwiftGen + - R.generated.swift + +line_length: 200 +warning: 150 + +type_name: + min_length: 3 + max_length: 40 + +identifier_name: + min_length: 3 + max_length: 40 + excluded: + - id + - x + - y + - z + - i + - j + - k + +reporter: "xcode" + +analyzer_rules: + - explicit_self + - unused_import + - unused_declaration + - unused_setter_value + - unused_optional_binding + - unused_enumerated + - unused_capture_list + - unused_closure_parameter + - unused_private_declaration + - unused_type_parameter + - unused_optional_chain + - unused_optional_chain_result + - unused_optional_chain_result_void + - unused_optional_chain_result_non_void + - unused_optional_chain_result_optional + - unused_optional_chain_result_non_optional + - unused_optional_chain_result_optional_void + - unused_optional_chain_result_non_optional_void + - unused_optional_chain_result_optional_non_void + - unused_optional_chain_result_non_optional_non_void diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ChessPrism/ChessPrism.xcodeproj/project.pbxproj b/ChessPrism/ChessPrism.xcodeproj/project.pbxproj index f308092..7cde243 100644 --- a/ChessPrism/ChessPrism.xcodeproj/project.pbxproj +++ b/ChessPrism/ChessPrism.xcodeproj/project.pbxproj @@ -389,11 +389,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = ChessPrism/ChessPrism.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"ChessPrism/Preview Content\""; DEVELOPMENT_TEAM = RJHWWWSF6Q; - ENABLE_HARDENED_RUNTIME = YES; + ENABLE_HARDENED_RUNTIME = NO; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; @@ -411,6 +412,7 @@ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 15.2; MARKETING_VERSION = 1.0; + "OTHER_CODE_SIGN_FLAGS[sdk=*]" = "--deep --force"; PRODUCT_BUNDLE_IDENTIFIER = com.chessprism.ChessPrism; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; @@ -428,11 +430,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = ChessPrism/ChessPrism.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"ChessPrism/Preview Content\""; DEVELOPMENT_TEAM = RJHWWWSF6Q; - ENABLE_HARDENED_RUNTIME = YES; + ENABLE_HARDENED_RUNTIME = NO; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; diff --git a/ChessPrism/ChessPrism/ChessPrism.entitlements b/ChessPrism/ChessPrism/ChessPrism.entitlements index f2ef3ae..f1322b0 100644 --- a/ChessPrism/ChessPrism/ChessPrism.entitlements +++ b/ChessPrism/ChessPrism/ChessPrism.entitlements @@ -6,5 +6,13 @@ com.apple.security.files.user-selected.read-only + com.apple.security.device.screen-capture + + com.apple.security.device.accessibility + + com.apple.security.network.client + + com.apple.security.ml.coreml + diff --git a/ChessPrism/ChessPrism/ChessPrismApp.swift b/ChessPrism/ChessPrism/ChessPrismApp.swift index 3ebee9a..9136ede 100644 --- a/ChessPrism/ChessPrism/ChessPrismApp.swift +++ b/ChessPrism/ChessPrism/ChessPrismApp.swift @@ -6,12 +6,55 @@ // import SwiftUI +import ScreenCaptureKit @main struct ChessPrismApp: App { + @StateObject private var permissionManager = PermissionManager() + var body: some Scene { WindowGroup { ContentView() + .environmentObject(permissionManager) + .onAppear { + permissionManager.requestPermissions() + } + .alert(isPresented: $permissionManager.showPermissionAlert) { + Alert( + title: Text("Permissions Required"), + message: Text(permissionManager.permissionAlertMessage), + primaryButton: .default(Text("Open Settings")) { + NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy")!) + }, + secondaryButton: .cancel() + ) + } + } + } +} + +class PermissionManager: ObservableObject { + @Published var showPermissionAlert = false + @Published var permissionAlertMessage = "" + + func requestPermissions() { + requestScreenRecordingPermission() + requestAccessibilityPermission() + } + + private func requestScreenRecordingPermission() { + let status = CGPreflightScreenCaptureAccess() + if !status { + permissionAlertMessage += "Screen recording permission is required to analyze chess positions.\n" + showPermissionAlert = true + } + } + + private func requestAccessibilityPermission() { + let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String: true] as CFDictionary + if !AXIsProcessTrustedWithOptions(options) { + permissionAlertMessage += "Accessibility permission is required to interact with other applications.\n" + showPermissionAlert = true } } } diff --git a/ChessPrism/ChessPrism/ContentView.swift b/ChessPrism/ChessPrism/ContentView.swift index 2ca479c..55c8579 100644 --- a/ChessPrism/ChessPrism/ContentView.swift +++ b/ChessPrism/ChessPrism/ContentView.swift @@ -1,21 +1,14 @@ -// -// ContentView.swift -// ChessPrism -// -// Created by Chris Haulmark on 1/6/25. -// - import SwiftUI struct ContentView: View { var body: some View { VStack { - Image(systemName: "globe") - .imageScale(.large) - .foregroundStyle(.tint) - Text("Hello, world!") + Text("Hello, ChessPrism!") + .font(.largeTitle) + .padding() + Text("Ready for development") + .font(.subheadline) } - .padding() } } diff --git a/ChessPrism/ChessPrism/Info.plist b/ChessPrism/ChessPrism/Info.plist new file mode 100644 index 0000000..61a80ef --- /dev/null +++ b/ChessPrism/ChessPrism/Info.plist @@ -0,0 +1,67 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + ChessPrism needs access to the camera for AR features + NSPhotoLibraryUsageDescription + ChessPrism needs access to photos for saving game screenshots + + diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..6bdb351 --- /dev/null +++ b/Package.swift @@ -0,0 +1,46 @@ +// swift-tools-version:5.9 +import PackageDescription + +let package = Package( + name: "ChessPrism", + platforms: [ + .iOS(.v16), + .macOS(.v13), + .visionOS(.v1) + ], + products: [ + .library( + name: "ChessPrism", + targets: ["ChessPrism"] + ) + ], + dependencies: [ + .package(url: "https://github.com/pointfreeco/swift-composable-architecture", from: "1.0.0"), + .package(url: "https://github.com/nalexn/ViewInspector", from: "0.9.7"), + .package(url: "https://github.com/ReactiveX/RxSwift", from: "6.6.0"), + .package(url: "https://github.com/SwiftGen/SwiftGenPlugin", from: "6.6.0") + ], + targets: [ + .target( + name: "ChessPrism", + dependencies: [ + .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), + .product(name: "RxSwift", package: "RxSwift") + ], + plugins: [ + .plugin(name: "SwiftGenPlugin", package: "SwiftGenPlugin") + ] + ), + .testTarget( + name: "ChessPrismTests", + dependencies: [ + "ChessPrism", + .product(name: "ViewInspector", package: "ViewInspector") + ] + ), + .testTarget( + name: "ChessPrismUITests", + dependencies: ["ChessPrism"] + ) + ] +) diff --git a/cline_docs/activeContext.md b/cline_docs/activeContext.md index 318e1c9..493b9a2 100644 --- a/cline_docs/activeContext.md +++ b/cline_docs/activeContext.md @@ -1,83 +1,31 @@ # Active Context -## Current Implementation Phase -Week 1: Project Setup (In Progress) +# Active Context -## What we're working on now -1. Xcode project configuration - - Setting up SwiftUI project structure - - Configuring project settings for MacOS Silicon - - Adding basic app lifecycle handlers -2. Development environment setup - - Installing required dependencies (Metal, Vision) - - Configuring build settings - - Setting up version control -3. Project architecture - - Creating core module structure - - Implementing basic MVVM pattern - - Setting up dependency injection +## Current Status +- Xcode project configuration completed +- Development environment setup verified +- Project architecture finalized +- Code signing verified with: + * Team ID: RJHWWWSF6Q + * Signing Identity: S6HYLY2Y7Y + * Certificate: Apple Development: Chris Haulmark (6FXX65C28T) +- Apple Developer Program enrollment completed +- App ID registered: com.chessprism.ChessPrism +- Development device registered: M3-Haulmark +- Initial build successful with Hello World implementation +- Certificate and provisioning profile properly configured +- Basic SwiftUI implementation verified +- Build and deployment pipeline confirmed working -## Recent changes -- Created detailed implementation plan -- Set up development environment -- Installed Xcode and necessary tools -- Created initial Xcode project with SwiftUI template -- Configured Git repository -- Added basic project structure -- Configured required frameworks (Metal, Vision) -- Set up initial build configurations +## Recent Changes +- Cleaned up and consolidated development certificates +- Created fresh provisioning profile +- Verified code signing configuration +- Implemented basic SwiftUI interface +- Confirmed build and run process -## Next steps -1. Complete project setup - - Implement permission handlers - - Add screen recording permission request - - Implement accessibility permissions - - Add privacy descriptions in Info.plist - - Finalize project architecture - - Complete MVVM implementation - - Finalize dependency injection setup - - Set up core module interfaces -2. Begin screenshot module implementation - - Implement screen recording permissions flow - - Set up screenshot capture service - - Configure keyboard shortcut system - -## Completed Milestones -- Initial project setup complete -- Development environment configured -- Core frameworks integrated -- Basic project structure established - -## Technical Details -### Current Implementation -- Using Swift 5.9 -- SwiftUI 4.0 for UI -- Metal 3.0 for rendering -- Vision 2.0 for image analysis -- CoreML 5.0 for machine learning - -### Current Architecture -- MVVM pattern implementation -- Modular architecture -- Dependency injection -- Async/await concurrency model - -### Current Configuration -- MacOS Ventura 13.0+ -- Xcode 15.0+ -- Git 2.40+ -- CoreML Tools 5.0+ - -## Pending Tasks -1. Complete permission handling implementation -2. Finalize project architecture -3. Begin screenshot module development -4. Set up initial testing infrastructure -5. Configure CI/CD pipeline - -## Important Notes -- Following detailed implementation plan -- Maintaining clean architecture principles -- Implementing modern Swift patterns -- Ensuring security and privacy compliance -- Maintaining documentation standards +## Next Steps +- Begin implementing core application features +- Set up CI/CD pipeline +- Configure automated testing diff --git a/cline_docs/productContext.md b/cline_docs/productContext.md index 2e9145f..fe4b1aa 100644 --- a/cline_docs/productContext.md +++ b/cline_docs/productContext.md @@ -134,3 +134,10 @@ To create an intuitive, real-time chess teaching assistant that enhances the lea 4. Week 10: Complete visualization system 5. Week 12: Optimized performance 6. Week 14: Ready for distribution + +## Development Status +### Completed Setup Steps +1. Apple Developer Program enrollment +2. App ID registration +3. Device registration +4. Initial capabilities configuration diff --git a/cline_docs/systemPatterns.md b/cline_docs/systemPatterns.md index 07a7a85..547391f 100644 --- a/cline_docs/systemPatterns.md +++ b/cline_docs/systemPatterns.md @@ -238,3 +238,17 @@ - Vulnerability scanning - Penetration testing - Compliance verification + +## Development Progress +### Environment Setup +1. Developer Program enrollment complete +2. App ID registered with capabilities +3. Development device registered +4. Provisioning profile successfully generated and installed + +### Implementation Status +1. Development Environment + - Certificate management completed + - Provisioning profile configured + - Build pipeline verified + - Basic deployment tested \ No newline at end of file diff --git a/cline_docs/techContext.md b/cline_docs/techContext.md index ac3a0fe..f751a72 100644 --- a/cline_docs/techContext.md +++ b/cline_docs/techContext.md @@ -17,6 +17,23 @@ 4. CoreML Tools (5.0+) 5. Create ML App (3.0+) +## Development Environment Status +### Apple Developer Configuration +- Program: Enrolled and Verified +- App ID: com.chessprism.ChessPrism +- Device: M3-Haulmark registered and confirmed +- Capabilities: Configured for macOS +- Certificate: Single verified Apple Development certificate +- Team ID: RJHWWWSF6Q +- Signing Identity: S6HYLY2Y7Y + +### Build Configuration +- Basic SwiftUI implementation tested +- Hello World deployment successful +- Code signing verified +- Provisioning profile installed +- Development certificates consolidated + ### Testing Frameworks 1. XCTest (5.0+) 2. XCUITest (5.0+) diff --git a/collect_system_info.py b/collect_system_info.py deleted file mode 100644 index c5911fd..0000000 --- a/collect_system_info.py +++ /dev/null @@ -1,90 +0,0 @@ -import subprocess -import platform -import json -import os - -def get_system_info(): - info = {} - - # Basic System Info - info['os'] = { - 'system': platform.system(), - 'version': platform.mac_ver()[0], - 'architecture': platform.machine() - } - - # CPU Info - cpu_command = "sysctl -n machdep.cpu.brand_string" - info['cpu'] = subprocess.getoutput(cpu_command) - - # Memory Info - mem_command = "sysctl hw.memsize" - mem_bytes = int(subprocess.getoutput(mem_command).split()[1]) - info['memory_gb'] = mem_bytes / (1024**3) - - # GPU Info - gpu_command = "system_profiler SPDisplaysDataType" - gpu_info = subprocess.getoutput(gpu_command) - info['gpu'] = gpu_info - - # Screen Info - displays_command = "system_profiler SPDisplaysDataType" - displays_info = subprocess.getoutput(displays_command) - info['displays'] = displays_info - - # Xcode Version - xcode_command = "xcodebuild -version" - try: - info['xcode'] = subprocess.getoutput(xcode_command) - except: - info['xcode'] = "Xcode not installed" - - # Swift Version - swift_command = "swift --version" - try: - info['swift'] = subprocess.getoutput(swift_command) - except: - info['swift'] = "Swift not installed" - - # Metal Support - metal_command = "system_profiler SPDisplaysDataType | grep Metal" - info['metal_support'] = subprocess.getoutput(metal_command) - - return info - -def save_info(): - info = get_system_info() - - # Save as JSON - with open('tech_specs.json', 'w') as f: - json.dump(info, f, indent=2) - - # Save as readable text - with open('tech_specs.txt', 'w') as f: - f.write("Chess Teaching Assistant - Development System Specifications\n") - f.write("=" * 60 + "\n\n") - - f.write("Operating System:\n") - f.write(f"- System: {info['os']['system']}\n") - f.write(f"- Version: {info['os']['version']}\n") - f.write(f"- Architecture: {info['os']['architecture']}\n\n") - - f.write("Hardware:\n") - f.write(f"- CPU: {info['cpu']}\n") - f.write(f"- Memory: {info['memory_gb']:.2f} GB\n\n") - - f.write("Development Tools:\n") - f.write(f"- Xcode: {info['xcode']}\n") - f.write(f"- Swift: {info['swift']}\n\n") - - f.write("Graphics:\n") - f.write(f"- Metal Support:\n{info['metal_support']}\n\n") - - f.write("Display Information:\n") - f.write(f"{info['displays']}\n") - -if __name__ == "__main__": - save_info() - print("System information has been collected and saved to:") - print("- tech_specs.json (machine-readable)") - print("- tech_specs.txt (human-readable)") diff --git a/setup_project.py b/setup_project.py deleted file mode 100644 index b0cfe3c..0000000 --- a/setup_project.py +++ /dev/null @@ -1,162 +0,0 @@ -import os -import subprocess - -def create_directory_structure(): - # Main project directories - directories = [ - 'src', - 'src/core', - 'src/features', - 'src/utils', - 'src/services', - 'tests', - 'tests/unit', - 'tests/integration', - 'tests/performance', - 'docs', - 'docs/api', - 'docs/architecture', - 'docs/development', - 'assets', - 'assets/ml-models', - 'assets/shaders', - 'scripts', - 'config' - ] - - # Create directories - for directory in directories: - os.makedirs(directory, exist_ok=True) - -def create_base_files(): - # Git-related files - files = { - '.gitignore': ''' -# macOS -.DS_Store -.AppleDouble -.LSOverride - -# Xcode -xcuserdata/ -*.xcscmblueprint -*.xccheckout -build/ -DerivedData/ -*.moved-aside -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -# Swift Package Manager -.build/ -Packages/ -Package.pins -Package.resolved - -# ML Models -*.mlmodel - -# Environment -.env -.env.* - -# IDE -.idea/ -.vscode/ - -# Testing -*.xcresult - -# Fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -''', - 'README.md': ''' -# Chess Teaching Assistant - -An intelligent chess teaching assistant for macOS that provides real-time analysis and visualization. - -## Features -- Real-time board position analysis -- Visual move suggestions -- Attack pattern visualization -- Defensive planning indicators - -## Development -See [Development Guide](docs/development/getting-started.md) for setup instructions. - -## Architecture -See [Architecture Overview](docs/architecture/overview.md) for system design details. - -## License -[MIT License](LICENSE) -''', - 'LICENSE': '''MIT License - -Copyright (c) 2025 Chess Teaching Assistant - -Permission is hereby granted, free of charge...''', - 'docs/development/getting-started.md': '''# Getting Started - -## Prerequisites -- Xcode 15.0+ -- macOS 14.0+ -- Swift 6.0+ - -## Setup Instructions -1. Clone the repository -2. Install dependencies -3. Build and run -''', - 'docs/architecture/overview.md': '''# Architecture Overview - -## System Components -- Screenshot Capture Module -- Board Position Analysis Engine -- Visual Overlay System -- Stockfish Integration -''', - 'src/core/__init__.py': '', - 'src/features/__init__.py': '', - 'src/utils/__init__.py': '', - 'src/services/__init__.py': '', - 'tests/__init__.py': '', - 'config/default.json': '''{ - "analysis": { - "depth": 20, - "threads": 4 - }, - "visualization": { - "arrowColor": "#FF0000", - "highlightColor": "#00FF00" - } -}''' - } - - for file_path, content in files.items(): - with open(file_path, 'w') as f: - f.write(content.strip()) - -def initialize_git(): - commands = [ - ['git', 'init'], - ['git', 'add', '.'], - ['git', 'commit', '-m', 'Initial project structure'], - ['git', 'branch', '-M', 'main'], - ] - - for command in commands: - subprocess.run(command) - -def main(): - create_directory_structure() - create_base_files() - initialize_git() - print("Project structure created successfully!") - -if __name__ == "__main__": - main()