Complete three overdue cleanups discovered during macOS health check: D-56 daemon dissolution: delete bin/clide.dart, DaemonServer, and orphaned tests (test/cli/, subprocess_test, in_process_test). Update stale "clide --daemon" references in i18n catalogs, error messages, editor_commands, CI scripts, and decision records. ptyc retirement: delete ptyc/ source tree, PtySession, scm_rights. Remove from Toolchain resolution, ToolCheck gate, backend serialization, testmode harness, Makefile, CI, and sandbox entitlements. PTY spawning uses NativePty (Dart FFI forkpty) since the terminal was absorbed in-tree. D-5 amended. Golden tests: wire the existing but never-applied clideGoldenConfig via flutter_test_config.dart. Disable CI goldens (Skia anti-aliasing differs between macOS/Linux even with Ahem). Keep platform-keyed goldens only — goldens/linux/ and goldens/macos/ each run on their own OS. Test suite: 826 pass, 0 fail on macOS (was 829 pass, 11 fail). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
43 lines
1.1 KiB
Dart
43 lines
1.1 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');
|
|
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;
|
|
}
|
|
}
|