Toolchain centralizes binary resolution — replaces five ad-hoc mechanisms (expandedPath, _resolveGit, _resolve, _resolvePtyc, _existsOnPath). Resolves via Future.delayed after runApp to avoid blocking the merged UI/platform thread on macOS. GitClient wraps all git operations with a typed API. Every subprocess call goes through _run() using toolchain.git + toolchain.gitEnv. Replaces free functions in operations.dart. Native directory picker: NSOpenPanel on macOS (method channel in AppDelegate), GtkFileChooserDialog on Linux. Falls back to text-input dialog on web or MissingPluginException. Shows "No git repo found" dialog when the selected directory is not a git repository. PqlClient and pane commands updated to use Toolchain. ToolCheck replaced by Toolchain.missing/allOk. All IPC handlers now catch GitException to prevent unhandled exceptions on the merged thread. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
51 lines
1.5 KiB
Dart
51 lines
1.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import '../../src/pty/env.dart';
|
|
|
|
class ToolCheck extends ChangeNotifier {
|
|
bool ptycOk = false;
|
|
bool pqlOk = false;
|
|
bool tmuxOk = false;
|
|
bool gitOk = false;
|
|
bool checked = false;
|
|
|
|
bool get allOk => ptycOk && pqlOk && tmuxOk && gitOk;
|
|
|
|
List<String> get errors => [
|
|
if (!ptycOk) 'ptyc not found',
|
|
if (!pqlOk) 'pql not found',
|
|
if (!tmuxOk) 'tmux not found',
|
|
if (!gitOk) 'git not found',
|
|
];
|
|
|
|
/// Workspace root, set by the app at boot. Falls back to cwd.
|
|
static String? workspaceRoot;
|
|
|
|
Future<void> check() async {
|
|
final root = workspaceRoot ?? Directory.current.path;
|
|
ptycOk = File('$root/native/linux-x64/ptyc').existsSync() ||
|
|
File('$root/native/macos-arm64/ptyc').existsSync() ||
|
|
File('$root/native/macos-x64/ptyc').existsSync() ||
|
|
File('$root/ptyc/bin/ptyc').existsSync() ||
|
|
_existsOnPath('ptyc');
|
|
pqlOk = _existsOnPath('pql');
|
|
tmuxOk = _existsOnPath('tmux');
|
|
gitOk = _existsOnPath('git');
|
|
checked = true;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// Check if [name] exists as an executable in any PATH directory.
|
|
/// Uses direct file-existence checks — works inside a macOS sandbox
|
|
/// without needing to exec `which`.
|
|
static bool _existsOnPath(String name) {
|
|
for (final dir in expandedPath.split(':')) {
|
|
if (dir.isEmpty) continue;
|
|
if (File('$dir/$name').existsSync()) return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|