269b2c4d97
Add a sink func(v any) field so MarteController's event stream can be routed somewhere other than the browser WebSocket hub. NewMarteController now sets sink to broadcast through the hub as before; a new NewHeadlessMarteController(sink) constructor builds an instance with hub == nil for the upcoming debugclient E2E tool. Direct m.hub.* calls (SetSourceState/UpdateConfigForSource/PushDataForSource) are now guarded with nil checks so a headless controller doesn't panic.