Repository: Pythagora-io/gpt-pilot
File: core/cli/main.py (Python)

Code before:

    if args.list:
        await list_projects(db)
        return True
    elif args.list_json:
        await list_projects_json(db)
        return True
    if args.show_config:
        show_config()
        return True
    elif args.import_v0:
        importer = LegacyDatabaseImporter(db, args.import_v0)
        await importer.import_database()
        return True

    telemetry.set("user_contact", args.email)
    if args.extension_version:
        telemetry.set("is_extension", True)
        telemetry.set("extension_version", args.extension_version)

    sm = StateManager(db, ui)
    ui_started = await ui.start()
    if not ui_started:
        return False

    if not await llm_api_check(ui):
        return False

    if args.project or args.branch or args.step:
        telemetry.set("is_continuation", True)
        # FIXME: we should send the project stage and other runtime info to the UI
        success = await load_project(sm, args.project, args.branch, args.step)
        if not success:
            return False
    elif args.delete:
        success = await delete_project(sm, args.delete)
        return success
    else:
        success = await start_new_project(sm, ui)
        if not success:
            return False

    return await run_project(sm, ui)


def run_pythagora():
    ui, db, args = init()
    if not ui or not db:
        return -1
    success = run(async_main(ui, db, args))
    return 0 if success else -1

Review comment (refactor):
I previously initialized `telemetry.start()` and then did `telemetry.send()` in `run_project()`. Because it is now needed before that, I think it makes sense to do `start()` before this line, but we don't want to run it for list/config/import/... operations, I think it makes sense to split this function into two:

1. async_main() that runs everything before this line, and then runs the second one
2. run_pythagora_session() that runs everything from this line down

Then the async main can have telemetry start, run the new function, telemetry send.

(and the start and send can be removed from run_project). This will minimize duplication and still make it start/end correctly

Lemme know if that makes sense

Code after:
        telemetry.set("is_continuation", True)
        # FIXME: we should send the project stage and other runtime info to the UI
        success = await load_project(sm, args.project, args.branch, args.step)
        if not success:
            return False
    elif args.delete:
        success = await delete_project(sm, args.delete)
        return success
    else:
        success = await start_new_project(sm, ui)
        if not success:
            return False

    return await run_project(sm, ui)


async def async_main(
    ui: UIBase,
    db: SessionManager,
    args: Namespace,
) -> bool:
    """
    Main application coroutine.

    :param ui: User interface.
    :param db: Database session manager.
    :param args: Command-line arguments.
    :return: True if the application ran successfully, False otherwise.
    """

    if args.list:
        await list_projects(db)
        return True
    elif args.list_json:
        await list_projects_json(db)
        return True
    if args.show_config:
        show_config()
        return True
    elif args.import_v0:
        importer = LegacyDatabaseImporter(db, args.import_v0)
        await importer.import_database()
        return True

    telemetry.set("user_contact", args.email)
    if args.extension_version:
        telemetry.set("is_extension", True)
        telemetry.set("extension_version", args.extension_version)

    sm = StateManager(db, ui)
    ui_started = await ui.start()