diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 63bf463..54dc10e 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -101,13 +101,24 @@ class _HomeScreenState extends State { String _searchQuery = ''; _Project? _selectedProject; _Project? _customFolderProject; + final _pathController = TextEditingController(); + final _pathFocusNode = FocusNode(); @override void initState() { super.initState(); + final home = _getRealHome() ?? ''; + _pathController.text = '$home/.claude/projects'; _scanProjects(); } + @override + void dispose() { + _pathController.dispose(); + _pathFocusNode.dispose(); + super.dispose(); + } + /// Returns the real user home directory, even inside App Sandbox. /// In sandbox, HOME points to ~/Library/Containers//Data. String? _getRealHome() { @@ -291,6 +302,35 @@ class _HomeScreenState extends State { } } + /// Resolve a path string, expanding ~ to the home directory. + String _resolvePath(String input) { + final home = _getRealHome() ?? Platform.environment['HOME'] ?? ''; + var path = input.trim(); + if (path.startsWith('~/')) { + path = '$home${path.substring(1)}'; + } else if (path == '~') { + path = home; + } + return path; + } + + Future _scanFromPathInput() async { + final resolved = _resolvePath(_pathController.text); + final dir = Directory(resolved); + if (await dir.exists()) { + await _scanFolder(resolved); + } else { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Folder not found: $resolved'), + backgroundColor: AppColors.error, + ), + ); + } + } + } + Future _pickFolder() async { final result = await FilePicker.platform.getDirectoryPath( dialogTitle: 'Select a folder containing Claude session files', @@ -498,7 +538,54 @@ class _HomeScreenState extends State { : '${_projects.length} projects', style: const TextStyle(fontSize: 12, color: AppColors.textMuted), ), - const SizedBox(width: 12), + // Path input field + SizedBox( + width: 320, + child: TextField( + controller: _pathController, + focusNode: _pathFocusNode, + style: const TextStyle( + fontSize: 12, + color: AppColors.textPrimary, + fontFamily: 'JetBrains Mono', + ), + decoration: InputDecoration( + hintText: '~/ .claude/projects', + hintStyle: const TextStyle( + fontSize: 12, + color: AppColors.textMuted, + fontFamily: 'JetBrains Mono', + ), + isDense: true, + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 8, + ), + filled: true, + fillColor: AppColors.surface, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(6), + borderSide: const BorderSide(color: AppColors.surfaceBorder), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(6), + borderSide: const BorderSide(color: AppColors.surfaceBorder), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(6), + borderSide: const BorderSide(color: AppColors.assistant), + ), + suffixIcon: IconButton( + icon: const Icon(Icons.arrow_forward, size: 14, + color: AppColors.textMuted), + tooltip: 'Scan this folder', + onPressed: _scanFromPathInput, + ), + ), + onSubmitted: (_) => _scanFromPathInput(), + ), + ), + const SizedBox(width: 8), ElevatedButton.icon( onPressed: _loadSingleFile, icon: const Icon(Icons.insert_drive_file_outlined, size: 14), diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 85cb345..dd9ef37 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -724,6 +724,7 @@ CODE_SIGN_STYLE = Manual; "DEVELOPMENT_TEAM[sdk=macosx*]" = LD76P8L42W; ENABLE_HARDENED_RUNTIME = YES; + CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES; OTHER_CODE_SIGN_FLAGS = "--timestamp --options runtime"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements index eb4f4d2..6eace1e 100644 --- a/macos/Runner/Release.entitlements +++ b/macos/Runner/Release.entitlements @@ -2,11 +2,7 @@ - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - - com.apple.security.files.home-directory.read-only - +com.apple.security.get-task-allow +