Bring the runtime up on Windows without disturbing the POSIX paths. PTY: introduce a platform-neutral PtySession contract with a factory that picks NativePty (posix_openpt/posix_spawn) or the new WindowsPty (ConPTY via CreatePseudoConsole). The pane registry programs against the interface; NativePty now implements it. IPC: the per-workspace AF_UNIX socket lives under %LOCALAPPDATA% and is hashed from a canonical workspace key (backslash + ASCII-folded case) so the Dart server and the C client agree despite NTFS case- insensitivity. The C client grows a Win32 shim (winsock afunix); chmod is a no-op on Windows where the per-user ACL is the gate. Toolchain: PATH probing splits on ';' and tries PATHEXT extensions; the shell defaults to PowerShell (pwsh, then powershell); tmux is treated as optional since it has no Windows build; dugite falls back to PATH git for now. Build: add `make build-windows`, a clide-cli MSVC build wrapped by ci/build_cli_windows.sh, and a ConPTY smoke-test suite that self- skips off-platform. Co-Authored-By: Claude <noreply@anthropic.com>
48 lines
1.4 KiB
Dart
48 lines
1.4 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import '../../src/pty/env.dart';
|
|
|
|
class ToolCheck extends ChangeNotifier {
|
|
bool pqlOk = false;
|
|
bool tmuxOk = false;
|
|
bool gitOk = false;
|
|
bool checked = false;
|
|
|
|
bool get allOk => pqlOk && tmuxOk && gitOk;
|
|
|
|
List<String> get errors => [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 {
|
|
pqlOk = _existsOnPath('pql');
|
|
// tmux has no Windows build; absence there is the documented
|
|
// no-tmux mode, not a failed check.
|
|
tmuxOk = Platform.isWindows || _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) {
|
|
final sep = Platform.isWindows ? ';' : ':';
|
|
for (final dir in expandedPath.split(sep)) {
|
|
if (dir.isEmpty) continue;
|
|
if (Platform.isWindows) {
|
|
for (final ext in const ['.exe', '.bat', '.cmd', '.com', '']) {
|
|
if (File('$dir\\$name$ext').existsSync()) return true;
|
|
}
|
|
} else {
|
|
if (File('$dir/$name').existsSync()) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|