Skip to content

Conversation

@KRRT7
Copy link
Collaborator

@KRRT7 KRRT7 commented Dec 21, 2025

PR Type

Enhancement, Other


Description

  • Replace Inquirer with Textual prompts

  • Add themed prompt wrapper module

  • Update CLI flows to new API

  • Adjust dependencies and mypy config


Diagram Walkthrough

flowchart LR
  Inquirer["inquirer-based prompts"] -- replaced by --> ThemedPrompts["themed_prompts (inquirer-textual)"]
  ThemedPrompts -- used in --> CmdInit["cmd_init.py flows"]
  PyProject["pyproject.toml deps"] -- add/remove --> InquirerTextual["inquirer-textual"], RemoveInquirer["remove inquirer"]
  MypyCfg["mypy overrides"] -- cleanup --> RemoveInquirer
Loading

File Walkthrough

Relevant files
Enhancement
cli_common.py
Remove legacy inquirer helpers from CLI common                     

codeflash/cli_cmds/cli_common.py

  • Remove inquirer utilities and wrapping helpers
  • Keep only exit helper and console usage
+0/-82   
cmd_init.py
Port init workflow to inquirer-textual prompts                     

codeflash/cli_cmds/cmd_init.py

  • Replace inquirer prompts with themed_prompts APIs
  • Add Choice usage for formatter selection
  • Add path existence checks for text inputs
  • Remove custom inquirer theme and wrappers
+74/-156
themed_prompts.py
Add themed prompt wrapper around inquirer-textual               

codeflash/cli_cmds/themed_prompts.py

  • Introduce CodeflashThemedApp with custom CSS/theme
  • Provide select, confirm, text, checkbox helpers
  • Wrap inquirer-textual widgets with inline app
+94/-0   
Dependencies
pyproject.toml
Update dependencies and mypy config for new prompts           

pyproject.toml

  • Remove inquirer dependency
  • Add inquirer-textual dependency
  • Update mypy ignore list to drop inquirer
+2/-2     

@KRRT7 KRRT7 requested a review from misrasaurabh1 December 21, 2025 05:15
@github-actions github-actions bot changed the title no more inquirer no more inquirer Dec 21, 2025
@github-actions
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Type Handling

In multiple prompt flows, the returned value may be a Choice or a raw string. Ensure consistent handling and typing (especially when accessing .value or .value.data) to avoid runtime errors if the prompt returns unexpected types.

formatter_choices = [
    Choice("⚫ black", data="black"),
    Choice("⚡ ruff", data="ruff"),
    Choice("🔧 other", data="other"),
    Choice("❌ don't use a formatter", data="don't use a formatter"),
]

result = prompts.select("Which code formatter do you use?", choices=formatter_choices, default=formatter_choices[0])
if result.command is None:
    apologize_and_exit()
formatter = result.value.data if isinstance(result.value, Choice) else result.value

git_remote = ""
Exit Flow Consistency

Several prompts treat result.command is None as a cancel and immediately exit. Verify this matches desired UX in all places (e.g., module/tests selection, GH Actions setup) and won’t surprise users by exiting instead of re-prompting.

default_choice = project_name if project_name in module_subdir_options else module_subdir_options[0]
result = prompts.select(
    "Which Python module do you want me to optimize?", choices=module_subdir_options, default=default_choice
)
if result.command is None:
    apologize_and_exit()
module_root_answer = result.value
if module_root_answer == curdir_option:
API Stability

The wrapper relies on inquirer_textual internal widget classes and return structure. Confirm these APIs and the .run(inline=True) return shape (command/value) are stable across versions to prevent breakages.

def select(  # noqa: ANN201
    message: str, choices: list[str | Choice], default: str | Choice | None = None
):  # type: ignore[no-untyped-def]
    widget = InquirerSelect(message, choices, default, mandatory=True)
    app: CodeflashThemedApp = CodeflashThemedApp(widget, shortcuts=None, show_footer=False)
    return app.run(inline=True)


def confirm(message: str, *, default: bool = False):  # noqa: ANN201  # type: ignore[no-untyped-def]
    widget = InquirerConfirm(message, default=default, mandatory=True)
    app: CodeflashThemedApp = CodeflashThemedApp(widget, shortcuts=None, show_footer=False)
    return app.run(inline=True)


def text(message: str):  # noqa: ANN201  # type: ignore[no-untyped-def]
    widget = InquirerText(message)
    app: CodeflashThemedApp = CodeflashThemedApp(widget, shortcuts=None, show_footer=False)
    return app.run(inline=True)


def checkbox(  # noqa: ANN201
    message: str, choices: list[str | Choice], enabled: list[str | Choice] | None = None
):  # type: ignore[no-untyped-def]
    widget = InquirerCheckbox(message, choices, enabled)
    app: CodeflashThemedApp = CodeflashThemedApp(widget, shortcuts=None, show_footer=False)
    return app.run(inline=True)

@github-actions
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Use boolean confirm instead of select

Use a proper boolean confirm prompt to avoid fragile string comparisons and
localization issues. Replace the select with prompts.confirm and branch on its
boolean value.

codeflash/cli_cmds/cmd_init.py [573-577]

-result = prompts.select("Create pyproject.toml in the current directory?", choices=["Yes", "No"], default="Yes")
-if result.command is None or result.value == "No":
+result = prompts.confirm("Create pyproject.toml in the current directory?", default=True)
+if result.command is None or result.value is False:
     apologize_and_exit()
 create_empty_pyproject_toml(pyproject_toml_path)
Suggestion importance[1-10]: 7

__

Why: Replacing a Yes/No select with a boolean confirm reduces string-comparison fragility and improves UX; the improved_code aligns with the PR’s new prompt framework (prompts.confirm) and keeps behavior consistent.

Medium
Normalize select default and value handling

Ensure the default passed to select matches the widget’s expected type. Pass the
underlying value (label or Choice) consistently and avoid mixing plain strings and
Choice objects to prevent selection mismatch.

codeflash/cli_cmds/cmd_init.py [473-484]

 formatter_choices = [
     Choice("⚫ black", data="black"),
     Choice("⚡ ruff", data="ruff"),
     Choice("🔧 other", data="other"),
     Choice("❌ don't use a formatter", data="don't use a formatter"),
 ]
 
-result = prompts.select("Which code formatter do you use?", choices=formatter_choices, default=formatter_choices[0])
+default_choice = formatter_choices[0]
+result = prompts.select("Which code formatter do you use?", choices=formatter_choices, default=default_choice)
 if result.command is None:
     apologize_and_exit()
-formatter = result.value.data if isinstance(result.value, Choice) else result.value
+formatter = result.value.data
Suggestion importance[1-10]: 4

__

Why: Passing a Choice as default is already done and supported; forcing formatter = result.value.data may be slightly cleaner but the current isinstance guard is safe, making the improvement minor.

Low
General
Validate non-empty choices

Guard against empty choices to prevent runtime errors inside the widget and provide
a clear failure path. Validate input early and raise a helpful error message.

codeflash/cli_cmds/themed_prompts.py [69-75]

 def select(  # noqa: ANN201
     message: str, choices: list[str | Choice], default: str | Choice | None = None
 ):  # type: ignore[no-untyped-def]
+    if not choices:
+        raise ValueError("select() requires at least one choice")
     widget = InquirerSelect(message, choices, default, mandatory=True)
     app: CodeflashThemedApp = CodeflashThemedApp(widget, shortcuts=None, show_footer=False)
     return app.run(inline=True)
Suggestion importance[1-10]: 6

__

Why: Adding an early check for empty choices prevents runtime errors and clarifies failures; it's a small but useful robustness improvement that accurately updates the provided code block.

Low

@KRRT7 KRRT7 changed the title no more inquirer no more inquirer or clicker Dec 21, 2025
@codeflash-ai
Copy link
Contributor

codeflash-ai bot commented Dec 22, 2025

⚡️ Codeflash found optimizations for this PR

📄 55% (0.55x) speedup for RelativePathValidator.validate in codeflash/cli_cmds/validators.py

⏱️ Runtime : 3.22 milliseconds 2.08 milliseconds (best of 59 runs)

A dependent PR with the suggested changes has been created. Please review:

If you approve, it will be merged into this PR (branch inquirer).

Static Badge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants