The approach I like the most is to first design a CLI that has the functionality you need. Then move that functionality to a lib and have the CLI now be a frontend for the lib. Then make a GUI frontend too.

Allows for a GUI for tasks that need that better context or hand holding. But then the CLI is there when there is a workflow the GUI doesn't support comes up. Bonus of scripting being possible with the CLI too.

Challenges this approach has is that you have to have a test suite that exercises both workflows or due diligence to make sure they both work as development continues.

Also not all programs can be done acceptably with a CLI. Real time 3d games are an easy example of a GUI only task.