The "Create New Invoice" button was configured all along, on the rv_screen
layout rather than the screen layout, and was being dropped twice over:
RecordViewTable fetched the rv_screen but kept only rv_template_uid and
threw away `layout`, and ScreenRenderer matched only the legacy
params.activity_id_init while current studio writes activity_uid_init.
collectStartButtons deep-walks either shape — the button nested under a
node's `config` as screen layouts do, or carrying type/params/job_template
at its own top level as rv_screens do — and accepts activity_uid_init,
activity_id_init, activity_uid and activity_id, newest key first.
RecordViewTable renders any start_state_machine buttons from its rv_screen
in the toolbar alongside the injected toolbarAction; ScreenRenderer routes
through the same helper and now skips buttons with no resolvable activity
instead of rendering a dead control.
Verified against app 169's live rv_screen config: yields exactly one button,
"Create New Invoice" -> Submit Invoice, ignoring the show_detailview_popup
entry.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>