stdio 0.4.0 copy "stdio: ^0.4.0" to clipboard
stdio: ^0.4.0 copied to clipboard

File-descriptor-level (dup2) capture and redirection of stdout/stderr, including native/FFI and child-process output invisible to Dart streams. POSIX only.

example/main.dart

// The three entry points of package:stdio.
//
// Run: dart run example/main.dart
// (Everything here uses Dart writes for simplicity — the whole point of the
// package is that native/FFI `write(1|2)` and child-process output are
// captured exactly the same way.)
import 'dart:io';

import 'package:stdio/stdio.dart';

Future<void> main() async {
  // ── 1. Scoped: capture exactly one body, get the transcript + its value ──
  final cap = await Stdio.capture<int>(() {
    print('hello from stdout');
    stderr.writeln('and from stderr');
    return 6 * 7; // whatever the body returns comes back on `.value`
  });
  print('captured ${cap.lines.length} lines (body returned ${cap.value})');
  print('stdout side: ${cap.out}');
  print('stderr side: ${cap.err}');

  // ── 2. Session: live streams + history + the real terminal ───────────────
  final capture = await Stdio.start(
    classify: (l) => l.text.startsWith('[db]') ? 'db' : null,
  );
  final seen = <String>[];
  capture.output.listen(
      (l) => seen.add('${l.stream.name}${l.source == null ? '' : '/${l.source}'}: ${l.text}'));

  print('[db] opened');            // tagged 'db' by the classifier
  stderr.writeln('plain stderr');  // untagged

  // The saved terminal writes THROUGH the capture, to the real screen:
  capture.terminal.writeln('(this line skips the capture entirely)');

  final result = await capture.stop(); // restore fd 1/2 + full transcript
  print('live listener saw: $seen');
  print('history kept ${result.lines.length} lines');

  // ── 3. Redirect: no capture — point fd 1/2 at a file and walk away ───────
  final log = File('${Directory.systemTemp.path}/stdio_example.log');
  final redirect = await Stdio.redirectToFile(log);
  print('this goes to the file, not the screen');
  stderr.writeln('this too, in exact write order');
  await stdout.flush();
  await redirect.stop();
  print('log file contents:\n${log.readAsStringSync()}');
  log.deleteSync();
}
0
likes
160
points
2.63k
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

File-descriptor-level (dup2) capture and redirection of stdout/stderr, including native/FFI and child-process output invisible to Dart streams. POSIX only.

Repository (GitHub)
View/report issues

Topics

#cli #terminal #io #logging #ffi

License

MIT (license)

Dependencies

ffi

More

Packages that depend on stdio