Skip to content

🎨 Palette: Interactive input validation & cleanup#133

Merged
abhimehro merged 1 commit intomainfrom
palette-interactive-validation-5319312495894963983
Jan 27, 2026
Merged

🎨 Palette: Interactive input validation & cleanup#133
abhimehro merged 1 commit intomainfrom
palette-interactive-validation-5319312495894963983

Conversation

@google-labs-jules
Copy link

Improved CLI UX by adding interactive input validation loops for Profile ID and API Token prompts. This prevents the script from starting with invalid credentials and provides immediate feedback to the user. Also cleaned up some duplicate code.


PR created automatically by Jules for task 5319312495894963983 started by @abhimehro

- Add `get_validated_input` helper for robust interactive prompts.
- Validate Profile ID format immediately during input.
- Prevent empty API Token input.
- Refactor `validate_profile_id` to separate logic from logging.
- Remove duplicate `MAX_RESPONSE_SIZE` constant.
- Update `palette.md` with UX learnings.
@google-labs-jules
Copy link
Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@trunk-io
Copy link

trunk-io bot commented Jan 25, 2026

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

main.py Outdated

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (117/100) Warning

Line too long (117/100)
main.py Outdated

Check notice

Code scanning / Pylintpython3 (reported by Codacy)

Lambda may not be necessary Note

Lambda may not be necessary
if is_password:
value = getpass.getpass(prompt).strip()
else:
value = input(prompt).strip()

Check notice

Code scanning / Bandit (reported by Codacy)

The input method in Python 2 will read from standard input, evaluate and run the resulting string as python source code. This is similar, though in many ways worse, then using eval. On Python 2, use raw_input instead, input is safe in Python 3. Note

The input method in Python 2 will read from standard input, evaluate and run the resulting string as python source code. This is similar, though in many ways worse, then using eval. On Python 2, use raw_input instead, input is safe in Python 3.
main.py Outdated

Check warning

Code scanning / Prospector (reported by Codacy)

Lambda may not be necessary (unnecessary-lambda) Warning

Lambda may not be necessary (unnecessary-lambda)


def get_validated_input(
prompt: str,

Check warning

Code scanning / Pylint (reported by Codacy)

Wrong hanging indentation before block (add 4 spaces). Warning

Wrong hanging indentation before block (add 4 spaces).

def get_validated_input(
prompt: str,
validator: Callable[[str], bool],

Check warning

Code scanning / Pylint (reported by Codacy)

Wrong hanging indentation before block (add 4 spaces). Warning

Wrong hanging indentation before block (add 4 spaces).
def get_validated_input(
prompt: str,
validator: Callable[[str], bool],
error_msg: str,

Check warning

Code scanning / Pylint (reported by Codacy)

Wrong hanging indentation before block (add 4 spaces). Warning

Wrong hanging indentation before block (add 4 spaces).
prompt: str,
validator: Callable[[str], bool],
error_msg: str,
is_password: bool = False

Check warning

Code scanning / Pylint (reported by Codacy)

Wrong hanging indentation before block (add 4 spaces). Warning

Wrong hanging indentation before block (add 4 spaces).
log.error("Invalid profile ID length (max 64 chars)")
return False
return True

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning

Missing function docstring
lambda x: bool(x),
"Token cannot be empty.",
is_password=True
)

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning

Missing function docstring
main.py Outdated

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (117/100) Warning

Line too long (117/100)
main.py Outdated

Check notice

Code scanning / Pylint (reported by Codacy)

Lambda may not be necessary Note

Lambda may not be necessary
@abhimehro abhimehro marked this pull request as ready for review January 27, 2026 07:30
Copilot AI review requested due to automatic review settings January 27, 2026 07:30
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the CLI user experience by adding interactive input validation loops for Profile ID and API Token prompts. The changes prevent the script from proceeding with invalid credentials by validating input immediately and providing clear error messages. The PR also includes code cleanup by removing a duplicate constant definition.

Changes:

  • Added get_validated_input function to enable validation loops for interactive prompts
  • Refactored profile ID validation by extracting format checking into a separate is_valid_profile_id_format function
  • Updated interactive prompts in main() to use the new validation function for both Profile ID and API Token inputs
  • Removed duplicate MAX_RESPONSE_SIZE constant definition
  • Added documentation of the interactive validation pattern to .Jules/palette.md

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
main.py Added validation loop infrastructure with get_validated_input function; refactored profile ID validation; integrated validation into interactive prompts for Profile ID and Token; removed duplicate constant; added getpass import and Callable type
.Jules/palette.md Documented the interactive input validation pattern as a learned best practice

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +276 to 283
def validate_profile_id(profile_id: str) -> bool:
if not is_valid_profile_id_format(profile_id):
if not re.match(r"^[a-zA-Z0-9_-]+$", profile_id):
log.error("Invalid profile ID format (contains unsafe characters)")
elif len(profile_id) > 64:
log.error("Invalid profile ID length (max 64 chars)")
return False
return True
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The validate_profile_id function contains redundant validation logic. After calling is_valid_profile_id_format (line 277), the function re-checks the same conditions (regex match on line 278 and length check on line 280) that were already validated inside is_valid_profile_id_format. This duplicates the validation logic and makes the code harder to maintain. Consider simplifying this function to only call is_valid_profile_id_format and provide appropriate error messages based on which specific check failed, or refactor is_valid_profile_id_format to return more detailed information about why validation failed.

Copilot uses AI. Check for mistakes.
Comment on lines +144 to +161
def get_validated_input(
prompt: str,
validator: Callable[[str], bool],
error_msg: str,
is_password: bool = False
) -> str:
"""Prompts for input until the validator returns True."""
while True:
if is_password:
value = getpass.getpass(prompt).strip()
else:
value = input(prompt).strip()

if validator(value):
return value

print(f"{Colors.FAIL}❌ {error_msg}{Colors.ENDC}")

Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The new get_validated_input function and is_valid_profile_id_format function lack test coverage. While the test file (test_main.py) includes tests for other functions like check_api_access, push_rules, and interactive prompts, there are no tests for these new validation functions. Since the codebase has comprehensive test coverage for similar functions, these new functions should also be tested to ensure they work correctly, especially for edge cases like empty input, whitespace-only input, invalid characters, and length boundaries.

Copilot uses AI. Check for mistakes.
Comment on lines +269 to +274
def is_valid_profile_id_format(profile_id: str) -> bool:
if not re.match(r"^[a-zA-Z0-9_-]+$", profile_id):
log.error("Invalid profile ID format (contains unsafe characters)")
return False
if len(profile_id) > 64:
log.error("Invalid profile ID length (max 64 chars)")
return False
return True
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The new is_valid_profile_id_format function should also lack test coverage. While the test file (test_main.py) includes tests for other functions like check_api_access, push_rules, and interactive prompts, there are no tests for this new validation function. Since the codebase has comprehensive test coverage for similar functions, this function should also be tested to ensure it works correctly, especially for edge cases like empty input, whitespace-only input, invalid characters, and length boundaries.

Copilot uses AI. Check for mistakes.

t_input = get_validated_input(
f"{Colors.BOLD}Enter Control D API Token:{Colors.ENDC} ",
lambda x: bool(x),
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Suggested change
lambda x: bool(x),
bool,

Copilot uses AI. Check for mistakes.
@abhimehro abhimehro merged commit 6f4b7b7 into main Jan 27, 2026
23 of 24 checks passed
@abhimehro abhimehro deleted the palette-interactive-validation-5319312495894963983 branch January 27, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants