code-quality batch (T-112)
test / unit + widget + golden + a11y (push) Failing after 31s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m7s

Seven small consultant findings, one commit:

1. TreeSitterLib stores last dlopen error + path in static fields
   instead of swallowing them. Callers that observe a null instance
   can now read the diagnostic.

2. Drop the Cmsghdr alias in libc.dart — back-compat shim with no
   callers; CLAUDE.md forbids those in a solo repo.

3. Drop EditorController._events field + the unused_field
   suppression. The constructor still subscribes via `events.on<...>`
   for _eventSub; the field itself was speculative retention.

4. Replace inline hex / errno literals in native_pty.dart with
   PosixErrno.{eintr,ebadf,epipe} and new libc.{pollin, pollAnyErr,
   sighup, sigkill, sigwinch}. PosixErrno gains eintr.

5. ExtensionManager records activate/deactivate exceptions in a
   `_failed` map exposed as `failedExtensions` + `didFail(id)`.
   Listeners are notified on entry/exit; cleared on a clean
   activate. UI surfaces the degraded state instead of pretending
   everything is fine.

6. file_tree_view imports FileEntry via the clide.dart barrel
   instead of `package:clide/src/files/listing.dart` directly — the
   leak the consultant flagged (barrel already re-exports it).

7. test_app branch in main.dart wrapped in `if (kDebugMode)` so
   release tree-shaker elides the test harness from shipping
   binaries. Source import stays; tree-shake handles the rest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-17 22:11:23 +02:00
co-authored by Claude Opus 4.7
parent b66e8f6cc0
commit d4f8f89016
11 changed files with 98 additions and 27 deletions
+1
View File
@@ -15,6 +15,7 @@ abstract class PosixErrno {
static const int eperm = 1;
static const int enoent = 2;
static const int esrch = 3;
static const int eintr = 4;
static const int eio = 5;
static const int ebadf = 9;
static const int eagain = 11;
+13 -3
View File
@@ -47,6 +47,19 @@ const int fSetFl = 4;
final int tiocswinsz = Platform.isMacOS ? 0x80087467 : 0x5414;
// poll() event bits (POSIX — same numeric values on Linux + macOS).
const int pollin = 0x0001;
const int pollerr = 0x0008;
const int pollhup = 0x0010;
const int pollnval = 0x0020;
const int pollAnyErr = pollerr | pollhup | pollnval;
// Signal numbers used from the PTY layer (POSIX standard; identical
// across Linux + macOS for the entries we touch).
const int sighup = 1;
const int sigkill = 9;
const int sigwinch = 28;
// ---------------------------------------------------------------------------
// Typedefs
// ---------------------------------------------------------------------------
@@ -198,9 +211,6 @@ final class CmsghdrDarwin extends ffi.Struct {
external int cmsg_type;
}
// Alias for backward compatibility — callers use Cmsghdr.
typedef Cmsghdr = CmsghdrLinux;
/// POSIX `struct winsize` for `TIOCSWINSZ`.
final class Winsize extends ffi.Struct {
@ffi.Uint16()
+11 -10
View File
@@ -25,6 +25,7 @@ import 'dart:typed_data';
import 'package:ffi/ffi.dart';
import 'errors.dart';
import '../ipc/errno_mapping.dart' show PosixErrno;
import 'ffi/libc.dart' as libc;
// -- structs ----------------------------------------------------------------
@@ -107,7 +108,6 @@ final int _kSpawnSetsid = Platform.isMacOS ? 0x400 : 0x80;
// platform layout (glibc posix_spawnattr_t is 336 B; macOS even smaller).
const int _kSpawnStructBytes = 8192;
const _kSighup = 1;
const _kWnohang = 1;
// -- NativePty --------------------------------------------------------------
@@ -343,14 +343,16 @@ class NativePty {
final buf = malloc<ffi.Uint8>(65536);
final pfd = calloc<_Pollfd>();
pfd.ref.fd = fd;
pfd.ref.events = 0x0001; // POLLIN
pfd.ref.events = libc.pollin;
try {
while (true) {
final ready = poll(pfd, 1, 100);
if (ready < 0) break;
if (ready == 0) continue;
if (pfd.ref.revents & 0x0038 != 0 && pfd.ref.revents & 0x0001 == 0) {
// Slave closed (POLLHUP / POLLERR / POLLNVAL) with no buffered
// bytes left to read — caller loop exits and we send EOF.
if (pfd.ref.revents & libc.pollAnyErr != 0 && pfd.ref.revents & libc.pollin == 0) {
break;
}
final n = rd(fd, buf.cast(), 65536);
@@ -383,8 +385,8 @@ class NativePty {
);
if (n < 0) {
final err = libc.errno;
if (err == 4 /* EINTR */) continue;
if (err == 9 /* EBADF */ || err == 32 /* EPIPE */) _dead = true;
if (err == PosixErrno.eintr) continue;
if (err == PosixErrno.ebadf || err == PosixErrno.epipe) _dead = true;
throw PtyException('write', 'write to PTY failed', errno: err);
}
if (n == 0) break;
@@ -405,17 +407,16 @@ class NativePty {
..ref.wsCol = cols;
final rc = _ioctl(_fd, _kTiocsWinsz, ws);
calloc.free(ws);
if (rc < 0 && libc.errno == 9 /* EBADF */) {
if (rc < 0 && libc.errno == PosixErrno.ebadf) {
_dead = true;
return;
}
// Explicitly signal the child to re-query its terminal size.
// SIGWINCH = 28 on both macOS and Linux.
_nativeKill(pid, 28);
_nativeKill(pid, libc.sigwinch);
}
/// Send a signal to the child.
bool kill([int signal = _kSighup]) {
bool kill([int signal = libc.sighup]) {
if (_dead) return false;
return _nativeKill(pid, signal) == 0;
}
@@ -444,7 +445,7 @@ class NativePty {
// otherwise close() racing with start() leaves an orphan isolate.
await _readerReady;
_nativeKill(pid, _kSighup);
_nativeKill(pid, libc.sighup);
_nativeKill(pid, 9);
// Wait for the isolate to send `null` (EOF) — confirms it has