server library

Live inspection for Dart servers.

The server side is FlutterwareServer — four primitives (event, span/spanSync, handle) plus zone correlation and a typed self-description (ServerInfo, published with FlutterwareServer.info), inert in release builds and on machines without flutterware. Adapters for shelf, SQL drivers and package:logging are snippets you copy, written over these primitives; fixtures/probe_app/bin/example_server.dart in flutterware's repository has them.

The attacher side — scanServerHandles, attachToServer, ServerAttachClient — is what the GUI, fw and MCP read a live server with. It is exported here too because it is the same protocol, and a pure-Dart tool wanting to observe a server needs nothing else.

Classes

FlutterwareServer
The primitives a Dart server reports through.
ServerAttachClient
The attacher's half of the protocol — what the GUI core, fw and MCP use to read a live server.
ServerConnection
One thing the server talks to, named by its connection string.
ServerHandle
The published announcement: one JSON file per live server process.
ServerHello
What the server answered meta/attach with.
ServerInfo
A server's self-description, published with FlutterwareServer.info.
ServerInspector
The machinery behind FlutterwareServer, constructible directly so tests can point it at a temp dir instead of faking the gates.
One page worth surfacing, rendered as a clickable link.

Constants

infoChannel → const String
The channel ServerInfo travels on.

Functions

attachToServer(ServerHandle handle, {Duration timeout = const Duration(seconds: 2), void onFailure(Object error, {required bool deleted})?}) → Future<ServerAttachClient?>
ServerAttachClient.connect with attachToLiveSession's cleanup rule: a handle whose socket nobody is listening on is deleted on the way past, and null comes back instead of an error. This is what keeps the published list truthful — dead servers disappear the first time anything tries to reach them.
deleteServerHandle(ServerHandle handle) → void
Deletes a handle's files — used after a failed connect, the same "on the way past" cleanup attachToLiveSession does.
existingRunDir() → String?
~/.flutterware/run if it exists, else null — never created here.
isSecretLikeKey(String key) → bool
Whether a config key looks like it names a secret — masked in displays, revealable with a click. Deliberately eager: masking a harmless value costs one click, showing a secret on a screen share costs more.
maskDsn(String dsn) → String
dsn with its password-shaped parts replaced for display: the userinfo password of a URL (postgres://app:secret@…) and password=/pwd= key-value segments (ADO-style strings). Copy still copies the real value — this guards screenshots and screen shares, not the developer's own machine.
normalizeSql(String sql) → String
Reduces a SQL statement to its shape, so queries differing only in their literals group together.
resolveLinkUrl(String url, {String? baseUrl}) → String?
ServerLink.url made absolute, or null when it cannot be — a relative link with no baseUrl to resolve against, or text that does not parse. The panel shows null as plain text instead of a dead link.
scanServerHandles(String runDir, {String? underRoot}) → List<ServerHandle>
The srv-*.json handles in runDir, newest first, optionally filtered to servers whose project root sits inside underRoot.

Typedefs

ServerCommandHandler = InspectorCommandHandler
What a command handler receives and returns. A returned map becomes the response payload as-is; anything else is wrapped as {"value": …}.
ServerEvent = InspectorEvent
One event received from an inspected server — replayed from its ring or live off its tail.
ServerRequestException = InspectorRequestException
The server-facing spelling of InspectorRequestException.