Load TaskDefinitions lazily when building taskGraph (#3562)
Previously, before the `Engine` struct is Prepared for execution, Turbo
stored a map of `core.Task` instances to look up Task
Definitions.
This change removes that behavior and instead looks up
TaskDefinitions during task graph construction. This bakes in the
assumption that there is more than one place for Tasks to be defined,
which is a pre-requisite for composable configs.
This implementation hardcodes looking up the `turbo.json` from the root
workspace, but in the future, we'll update to start looking for the TaskDefinition
in the task's workspace.