Skip to content

Add a state-driven commit flow API for non-interactive commit clients #2011

@ongchi

Description

@ongchi

Description

cz commit currently assumes an interactive terminal flow: it asks all questions through questionary, renders the commit message, and immediately runs git commit.

This works well for humans in a TTY, but it is hard to integrate with LLM-based tools, editor integrations, or other non-interactive clients that need to:

  • answer one question at a time
  • inspect validation errors
  • revise earlier answers
  • finalize the real commit only after the full flow is accepted

I would like Commitizen to expose a state-driven commit flow API that separates question flow from the final commit execution.

Possible Solution

Add an optional session-based flow interface for commit adapters.

Example shape:

session = cz.start_commit_flow()

question = session.next_question()
result = session.submit_answer(question.name, answer)

if result.status == "invalid":
...
elif result.status == "next_question":
...
elif result.status == "complete":
message = session.render_message()
session.finalize_commit()

This would allow a client to drive the commit flow step by step without relying on an interactive TTY.

The existing cz commit command could continue to work as it does today by driving this API internally.

A narrow first implementation for cz_conventional_commits would probably be enough to validate the design before extending it to cz_customize or third-party plugins.

Additional context

Today, commitizen/commands/commit.py gets a flat list from self.cz.questions(), passes it directly to questionary.prompt(...), then calls self.cz.message(answers) and performs the commit.

The built-in flows are mostly linear already, so this proposal is less about adding complex branching and more about exposing the commit flow as a session/state protocol for external clients.

Main tradeoff: this would add API surface and require a compatibility story for existing adapters and plugins.

Related issues

None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions