Knob class

One knob an entry point's main takes, annotated.

The signature is the declaration; this only annotates it. main's parameter list already says what exists, with what type and what default, and it cannot be wrong about its own function — so nothing here repeats any of that. Only name appears twice, and it is the join key.

// tool/flutterware.dart — declared once, shared by being a variable
final devKnobs = [
  Knob('serverPort',
      from: ValueSource.script('tool/local_env.dart', args: ['port'])),
  Knob('apiHost', from: ValueSource.hostAddresses),
];

Entrypoint('lib/main.dart', name: 'App', knobs: devKnobs),
Entrypoint('lib/main_staging.dart', name: 'Staging', knobs: devKnobs),
// lib/main.dart — just the socket
void main({int serverPort = 8086, String apiHost = 'localhost'}) => …

Sharing across entry points needs no API: tool/flutterware.dart is Dart, so a variable does it. A per-package list was proposed and rejected for exactly that reason.

Changing a knob's value rewrites the generated wrapper and hot restarts — 262ms on desktop, 3s on an Android emulator, against a rebuild.

The word is back because the cost is. This was LaunchKnob, renamed to DartDefine on the grounds that a preview's knob costs a frame while a define costs a rebuild, so one word for both would hide the difference. The mechanism underneath has changed: a restart is not a frame, but it is the same order of thing, and a value read off a parameter list is what KnobDescriptor already models for previews and devbar variables. One vocabulary, one wire shape.

Constructors

Knob(String name, {String? label, String? description, List<String> options = const [], ValueSource? from, bool required = false})
const

Properties

description → String?
final
from → ValueSource?
A value the tool works out for itself, rather than one to type.
final
hashCode → int
The hash code for this object.
no setterinherited
label → String?
What a human sees; name when absent.
final
name → String
The parameter's name, exactly — serverPort. A knob naming a parameter main does not take is reported rather than silently ignored: the control would appear and do nothing, which looks like a broken feature.
final
options → List<String>
Values worth offering for a knob whose type cannot enumerate itself.
final
required → bool
Whether a launch that sets no value for this knob is refused.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toJson() → Map<String, Object?>
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited