Skip to content

refactor(tui): replace magic numbers with named constants for eval form fields#139

Merged
yuval-qf merged 2 commits intoqualifire-dev:mainfrom
puwun:improvement/tui-code-quality
Dec 26, 2025
Merged

refactor(tui): replace magic numbers with named constants for eval form fields#139
yuval-qf merged 2 commits intoqualifire-dev:mainfrom
puwun:improvement/tui-code-quality

Conversation

@puwun
Copy link
Contributor

@puwun puwun commented Dec 21, 2025

Description

In the TUI, replacing magic numbers used for EvaluationState.currentField with named constants, making the code more readable and maintainable

Type of Change

  • 🎨 Code style/refactoring (no functional changes)

Changes Made

The currentField integer was used with hardcoded values (0, 1, 2, 3, 4, 5) scattered across multiple files, making it difficult to understand which field each number represented and error-prone when making changes

Solution

  • Introduced EvalFormField type with named constants:
    EvalFieldAgentURL = 0
    EvalFieldProtocol = 1
    EvalFieldTransport = 2
    EvalFieldJudgeModel = 3
    EvalFieldDeepTest = 4
    EvalFieldStartButton = 5
  • Added mirrored constants in evaluations/types.go to avoid import cycles
  • Updated all usages across the codebase

Related Issues/PRs

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

Summary by CodeRabbit

  • Refactor
    • Replaced hard-coded field indices with named constants across the evaluation form logic to improve clarity and maintainability. No changes to user-facing behavior or workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Replaces magic numeric field indices with named constants/types for the evaluation TUI form across rendering, controllers, keyboard handling, and paste logic; adds FormField/EvalFormField constant sets and adjusts a cast when creating FormState.

Changes

Cohort / File(s) Summary
Field enum/type definitions
packages/tui/internal/tui/eval_types.go, packages/tui/internal/screens/evaluations/types.go
Add EvalFormField and FormField integer types and constants (AgentURL, Protocol, Transport, JudgeModel, DeepTest, StartButton, plus count sentinel). EvaluationViewState.currentField changed from int to EvalFormField; mirror FormField* constants added to avoid import cycles.
Form rendering update
packages/tui/internal/screens/evaluations/form_view.go
Replace hard-coded index check for the Start button (== 5) with == FormFieldStartButton.
Form state initialization
packages/tui/internal/tui/eval_form_view.go
Cast EvaluationViewState.currentField to int when constructing FormState (int(m.evalState.currentField)).
Controllers and input handling
packages/tui/internal/tui/form_controller.go, packages/tui/internal/tui/common_controller.go, packages/tui/internal/tui/keyboard_controller.go
Replace scattered numeric field-index checks with EvalField* constants across navigation (up/down/left/right), cursor logic, tab/space/backspace behavior, paste handling, slash handler, and Enter key handling; remove legacy ParallelRuns special-case handling and an unused import.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to consistency between EvalFormField and FormField constant values across packages.
  • Verify no remaining numeric literals referencing field indices were missed.
  • Check removed ParallelRuns handling is intentional and covered by tests/requirements.

Possibly related PRs

Suggested reviewers

  • drorIvry
  • yuval-qf

Poem

🐰 I hopped through fields with numbers bright,
Replaced the digits with names tonight.
No more magic, clear and neat,
Start button knows its proper seat.
Code carrots lined up — what a sight! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and accurately summarizes the main change: replacing magic numbers with named constants for eval form fields.
Description check ✅ Passed The PR description covers the key aspects: motivation (magic numbers scattered across code), solution (introduced EvalFormField type with named constants), and related issue reference.
Linked Issues check ✅ Passed The PR successfully addresses issue #117 by replacing all magic numbers with semantic named constants (EvalFieldAgentURL, EvalFieldProtocol, etc.) across all affected files.
Out of Scope Changes check ✅ Passed All changes are directly related to replacing magic numbers with named constants; no extraneous refactoring or unrelated functionality changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/tui/internal/tui/keyboard_controller.go (1)

149-163: Fix logic error: slash insertion broken for Judge Model field.

The condition m.evalState.currentField <= EvalFieldProtocol (line 149) only allows fields 0 and 1, but the switch statement (lines 152-161) handles both EvalFieldAgentURL (0) and EvalFieldJudgeModel (3). This means the "/" character cannot be inserted into the Judge Model field because the condition fails when currentField is 3.

🔎 Proposed fix
-	if m.currentScreen == NewEvaluationScreen && m.evalState != nil && m.evalState.currentField <= EvalFieldProtocol {
+	if m.currentScreen == NewEvaluationScreen && m.evalState != nil && 
+		(m.evalState.currentField == EvalFieldAgentURL || m.evalState.currentField == EvalFieldJudgeModel) {
 		// Handle "/" character directly in text fields
 		s := "/"
 		switch m.evalState.currentField {
 		case EvalFieldAgentURL:
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e24b6c and a558dad.

📒 Files selected for processing (7)
  • packages/tui/internal/screens/evaluations/form_view.go (1 hunks)
  • packages/tui/internal/screens/evaluations/types.go (2 hunks)
  • packages/tui/internal/tui/common_controller.go (1 hunks)
  • packages/tui/internal/tui/eval_form_view.go (1 hunks)
  • packages/tui/internal/tui/eval_types.go (2 hunks)
  • packages/tui/internal/tui/form_controller.go (6 hunks)
  • packages/tui/internal/tui/keyboard_controller.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/tui/internal/tui/form_controller.go (1)
packages/tui/internal/tui/eval_types.go (6)
  • EvalFieldAgentURL (32-32)
  • EvalFieldJudgeModel (35-35)
  • EvalFieldStartButton (37-37)
  • EvalFieldProtocol (33-33)
  • EvalFieldTransport (34-34)
  • EvalFieldDeepTest (36-36)
packages/tui/internal/screens/evaluations/form_view.go (1)
packages/tui/internal/screens/evaluations/types.go (1)
  • FormFieldStartButton (12-12)
packages/tui/internal/tui/common_controller.go (1)
packages/tui/internal/tui/eval_types.go (2)
  • EvalFieldAgentURL (32-32)
  • EvalFieldJudgeModel (35-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: codestyle
🔇 Additional comments (10)
packages/tui/internal/tui/eval_types.go (2)

28-41: LGTM! Well-structured constant definitions.

The new EvalFormField type and associated constants provide clear, self-documenting field indices. Including EvalFieldCount for bounds checking is a good practice.


69-70: LGTM! Type change improves type safety.

Changing currentField from int to EvalFormField provides better type safety and makes the intent explicit.

packages/tui/internal/screens/evaluations/form_view.go (1)

174-174: LGTM! Excellent use of named constant.

Replacing the magic number 5 with FormFieldStartButton makes the code self-documenting.

packages/tui/internal/tui/eval_form_view.go (1)

35-35: LGTM! Type cast is appropriate here.

The cast from EvalFormField to int is necessary since FormState.CurrentField is defined as int in the evaluations package (to avoid import cycles).

packages/tui/internal/tui/common_controller.go (1)

50-61: LGTM! Clear use of semantic constants.

Replacing numeric literals with EvalFieldAgentURL and EvalFieldJudgeModel makes the paste handling logic much more readable.

packages/tui/internal/tui/keyboard_controller.go (1)

284-294: LGTM! Correct use of field constants.

The Enter key handling correctly uses EvalFieldStartButton and EvalFieldJudgeModel constants, making the intent clear.

packages/tui/internal/screens/evaluations/types.go (1)

3-13: LGTM! Well-documented constant mirroring.

The mirrored FormField* constants are a good solution to avoid import cycles while maintaining consistency. The comment clearly explains the relationship to EvalFormField.

packages/tui/internal/tui/form_controller.go (3)

20-48: LGTM! Navigation logic correctly uses constants.

The up/down navigation properly uses EvalFieldStartButton for bounds checking and EvalFieldAgentURL/EvalFieldJudgeModel for cursor positioning in text fields.


50-80: LGTM! Left/right handling correctly distinguishes field types.

The code appropriately uses constants to differentiate between text fields (EvalFieldAgentURL, EvalFieldJudgeModel) and dropdown fields (EvalFieldProtocol, EvalFieldTransport), applying the correct behavior for each.


82-132: LGTM! Special key and text input handling uses clear constants.

All field-specific operations (Space for toggle, Tab for dialog, Backspace and character insertion for text fields) correctly use the named constants, making the code much more maintainable.

Comment on lines 3 to 14
// FormField represents the field indices for the evaluation form
// These constants mirror the EvalFormField constants in the tui package
// to avoid import cycles while maintaining consistency
const (
FormFieldAgentURL = 0
FormFieldProtocol = 1
FormFieldTransport = 2
FormFieldJudgeModel = 3
FormFieldDeepTest = 4
FormFieldStartButton = 5
)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider:

Suggested change
// FormField represents the field indices for the evaluation form
// These constants mirror the EvalFormField constants in the tui package
// to avoid import cycles while maintaining consistency
const (
FormFieldAgentURL = 0
FormFieldProtocol = 1
FormFieldTransport = 2
FormFieldJudgeModel = 3
FormFieldDeepTest = 4
FormFieldStartButton = 5
)
// FormField represents the field indices for the evaluation form
// These constants mirror the EvalFormField constants in the tui package
// to avoid import cycles while maintaining consistency
type FormField int
const (
FormFieldAgentURL FormField = iota
FormFieldProtocol
FormFieldTransport
FormFieldJudgeModel
FormFieldDeepTest
FormFieldStartButton
)

Copy link
Collaborator

@yuval-qf yuval-qf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work @puwun, really appreciate this!

I left a few comments that might help us maintain this logic.
Please ping me once those are fixed :)

Comment on lines 31 to 42
const (
EvalFieldAgentURL EvalFormField = 0
EvalFieldProtocol EvalFormField = 1
EvalFieldTransport EvalFormField = 2
EvalFieldJudgeModel EvalFormField = 3
EvalFieldDeepTest EvalFormField = 4
EvalFieldStartButton EvalFormField = 5

// EvalFieldCount is the total number of fields (for bounds checking)
EvalFieldCount = 6
)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider:

Suggested change
const (
EvalFieldAgentURL EvalFormField = 0
EvalFieldProtocol EvalFormField = 1
EvalFieldTransport EvalFormField = 2
EvalFieldJudgeModel EvalFormField = 3
EvalFieldDeepTest EvalFormField = 4
EvalFieldStartButton EvalFormField = 5
// EvalFieldCount is the total number of fields (for bounds checking)
EvalFieldCount = 6
)
const (
EvalFieldAgentURL EvalFormField = iota
EvalFieldProtocol
EvalFieldTransport
EvalFieldJudgeModel
EvalFieldDeepTest
EvalFieldStartButton
)
const EvalFieldCount = 6

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/tui/internal/screens/evaluations/types.go (1)

33-33: Consider changing CurrentField to FormField type for better type safety.

While the comment correctly documents the use of FormField* constants, the field itself remains typed as int. Changing it to FormField would provide compile-time type checking and make misuse more difficult.

🔎 Proposed type change
-	CurrentField int // Use FormField* constants for field indices
+	CurrentField FormField // Field index in the evaluation form

Note: This change may require explicit conversions (e.g., int(f.CurrentField)) in other parts of the codebase where integer operations are performed, but it would provide stronger type safety guarantees.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a558dad and da6e394.

📒 Files selected for processing (3)
  • packages/tui/internal/screens/evaluations/form_view.go
  • packages/tui/internal/screens/evaluations/types.go
  • packages/tui/internal/tui/eval_types.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/tui/internal/screens/evaluations/form_view.go
  • packages/tui/internal/tui/eval_types.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: codestyle
🔇 Additional comments (1)
packages/tui/internal/screens/evaluations/types.go (1)

3-15: LGTM! Clean implementation of form field constants.

The FormField type and constants are well-defined using idiomatic Go with iota. The documentation clearly explains the rationale for mirroring constants to avoid import cycles, which is a standard Go pattern.

Copy link
Collaborator

@yuval-qf yuval-qf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @puwun for this change!

@yuval-qf yuval-qf merged commit 3d04b56 into qualifire-dev:main Dec 26, 2025
9 checks passed
This was referenced Dec 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Improvement] - TUI code quality - Use consts for currentField

2 participants