Skip to content

🎨 Palette: Improved Dry Run Output#150

Closed
abhimehro wants to merge 3 commits intomainfrom
palette-dry-run-plan-output-15215056721859509049
Closed

🎨 Palette: Improved Dry Run Output#150
abhimehro wants to merge 3 commits intomainfrom
palette-dry-run-plan-output-15215056721859509049

Conversation

@abhimehro
Copy link
Owner

This PR improves the UX of the CLI tool by printing a detailed plan when running with --dry-run.

Previously, it only said "Dry-run complete: no API calls were made". Now, it lists the folders that would be created and how many rules each contains.

Also cleaned up a duplicate function definition in main.py.


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

- Added `print_dry_run_plan` to display a user-friendly summary of changes during a dry run.
- Updated `sync_profile` to call `print_dry_run_plan`.
- Removed a duplicate definition of `render_progress_bar` (kept the one with docstring).
- Added unit tests for the new output function.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 31, 2026 22:54
@google-labs-jules
Copy link

👋 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 31, 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.

@gemini-code-assist
Copy link

Summary of Changes

Hello @abhimehro, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user experience of the CLI tool by transforming the --dry-run command's output. Instead of a generic "Dry-run complete" message, users will now receive a comprehensive plan detailing which folders would be created and how many rules each contains, providing greater transparency and confidence before execution. The changes also include a minor code cleanup by removing a redundant function and introducing dedicated tests for the new dry-run output functionality.

Highlights

  • Improved Dry Run Output: The --dry-run command now provides a detailed plan, listing folders that would be created and the number of rules each contains, instead of a generic 'Dry-run complete' message.
  • Code Cleanup: A duplicate render_progress_bar function was removed from main.py, streamlining the codebase.
  • New Tests for Dry Run Output: Dedicated unit tests have been added for the new print_dry_run_plan function, covering scenarios with and without color output, and for cases with no folders.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

# print() typically calls write(string) and write('\n')
combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output
# ANSI codes should be present (main.Colors.HEADER starts with \033[95m)
assert "\033[" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output
# No ANSI codes
assert "\033[" not in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
main.print_dry_run_plan(plan)

combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])
assert "(No folders found to sync)" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request improves the dry run output by providing a detailed plan of what will be created. It also includes a cleanup by removing a duplicate function definition. The changes are well-implemented and include new tests for the dry run output functionality. I've suggested a couple of refactorings to simplify the new printing function and its tests, which will improve code readability and maintainability.

main.py Outdated
Comment on lines +1018 to +1046
profile = plan_entry["profile"]
folders = plan_entry["folders"]

if USE_COLORS:
print(
f"\n{Colors.HEADER}📝 Dry Run Plan for Profile: {Colors.BOLD}{profile}{Colors.ENDC}"
)
print(
f"{Colors.CYAN} The following folders will be created/replaced:{Colors.ENDC}"
)
else:
print(f"\n📝 Dry Run Plan for Profile: {profile}")
print(" The following folders will be created/replaced:")

if not folders:
print(
f" {Colors.WARNING}(No folders found to sync){Colors.ENDC}"
if USE_COLORS
else " (No folders found to sync)"
)

for folder in folders:
name = folder["name"]
rules = folder["rules"]
if USE_COLORS:
print(f" • {Colors.BOLD}{name}{Colors.ENDC}: {rules} rules")
else:
print(f" - {name}: {rules} rules")
print("")

Choose a reason for hiding this comment

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

medium

The print_dry_run_plan function can be simplified by fully leveraging the Colors class design. Since the class attributes are empty strings when colors are disabled, most of the explicit if USE_COLORS: checks are redundant. This refactoring reduces code duplication and improves readability. The conditional logic is only needed for the bullet point character, which is a deliberate UX choice.

    profile = plan_entry["profile"]
    folders = plan_entry["folders"]

    print(f"\n{Colors.HEADER}📝 Dry Run Plan for Profile: {Colors.BOLD}{profile}{Colors.ENDC}")
    print(f"{Colors.CYAN}   The following folders will be created/replaced:{Colors.ENDC}")

    if not folders:
        print(f"   {Colors.WARNING}(No folders found to sync){Colors.ENDC}")
    else:
        bullet = "•" if USE_COLORS else "-"
        for folder in folders:
            name = folder["name"]
            rules = folder["rules"]
            print(f"   {bullet} {Colors.BOLD}{name}{Colors.ENDC}: {rules} rules")
    print("")

Comment on lines +8 to +23
monkeypatch.setattr(main, "USE_COLORS", True)

# Since Colors class is evaluated at import time, we need to manually set color codes
# if the module was imported in a non-TTY environment
for attr, code in {
"HEADER": "\033[95m",
"BLUE": "\033[94m",
"CYAN": "\033[96m",
"GREEN": "\033[92m",
"WARNING": "\033[93m",
"FAIL": "\033[91m",
"ENDC": "\033[0m",
"BOLD": "\033[1m",
"UNDERLINE": "\033[4m",
}.items():
monkeypatch.setattr(main.Colors, attr, code)

Choose a reason for hiding this comment

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

medium

The current method of enabling colors for this test is a bit brittle. By manually setting each color code, the test can become outdated if the Colors class in main.py is updated. A more robust approach is to simulate a TTY environment and then reload the main module. This ensures that USE_COLORS is set correctly and the Colors class is initialized with the right values, just as it would be in a real TTY environment. You will need to add import importlib to the file's imports.

    # Force a TTY-like environment to test color output correctly
    monkeypatch.setattr(sys.stdout, "isatty", lambda: True)
    monkeypatch.setattr(sys.stderr, "isatty", lambda: True)
    monkeypatch.delenv("NO_COLOR", raising=False)

    # Reload the main module to re-evaluate USE_COLORS and the Colors class
    # based on the mocked environment.
    import importlib
    importlib.reload(main)

return folder_success


def print_dry_run_plan(plan_entry: Dict[str, Any]) -> None:

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing function or method docstring Warning

Missing function or method docstring
@@ -0,0 +1,89 @@
import sys

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing module docstring Warning test

Missing module docstring
# print() typically calls write(string) and write('\n')
combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output
# ANSI codes should be present (main.Colors.HEADER starts with \033[95m)
assert "\033[" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output
# No ANSI codes
assert "\033[" not in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
main.print_dry_run_plan(plan)

combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])
assert "(No folders found to sync)" in combined_output

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
return folder_success


def print_dry_run_plan(plan_entry: Dict[str, Any]) -> None:

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning

Missing function docstring
@@ -0,0 +1,89 @@
import sys

Check warning

Code scanning / Pylint (reported by Codacy)

Missing module docstring Warning test

Missing module docstring
# Since Colors class is evaluated at import time, we need to manually set color codes
# if the module was imported in a non-TTY environment
for attr, code in {
"HEADER": "\033[95m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
# if the module was imported in a non-TTY environment
for attr, code in {
"HEADER": "\033[95m",
"BLUE": "\033[94m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
for attr, code in {
"HEADER": "\033[95m",
"BLUE": "\033[94m",
"CYAN": "\033[96m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
"BLUE": "\033[94m",
"CYAN": "\033[96m",
"GREEN": "\033[92m",
"WARNING": "\033[93m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
"CYAN": "\033[96m",
"GREEN": "\033[92m",
"WARNING": "\033[93m",
"FAIL": "\033[91m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
"GREEN": "\033[92m",
"WARNING": "\033[93m",
"FAIL": "\033[91m",
"ENDC": "\033[0m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
"WARNING": "\033[93m",
"FAIL": "\033[91m",
"ENDC": "\033[0m",
"BOLD": "\033[1m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
"FAIL": "\033[91m",
"ENDC": "\033[0m",
"BOLD": "\033[1m",
"UNDERLINE": "\033[4m",

Check warning

Code scanning / Pylint (reported by Codacy)

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

Wrong hanging indentation before block (add 4 spaces).
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 user experience of the CLI tool's dry-run mode by adding detailed output that shows which folders would be created and how many rules each contains. It also removes a duplicate render_progress_bar function definition.

Changes:

  • Added print_dry_run_plan() function to display a formatted plan when --dry-run is used
  • Integrated the new function into the dry-run workflow to provide detailed output before the completion message
  • Removed duplicate render_progress_bar() function definition that had slightly different parameters

Reviewed changes

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

File Description
main.py Added print_dry_run_plan() function with color-aware formatting and removed duplicate render_progress_bar() definition
tests/test_palette_ux.py Added comprehensive test coverage for the new function covering colored output, non-colored output, and empty folder scenarios

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

Comment on lines +75 to +89
def test_print_dry_run_plan_empty_folders(monkeypatch):
"""Verify output when no folders are present."""
monkeypatch.setattr(main, "USE_COLORS", False)
mock_stdout = MagicMock()
monkeypatch.setattr(sys, "stdout", mock_stdout)

plan = {
"profile": "test_profile",
"folders": []
}

main.print_dry_run_plan(plan)

combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])
assert "(No folders found to sync)" in combined_output
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

The test should also set the Colors class attributes to empty strings when USE_COLORS is False. If the module was imported in a TTY environment, the Colors attributes would still contain ANSI codes even after setting USE_COLORS to False, which could cause the test to fail.

The same pattern from test_print_dry_run_plan_with_colors should be applied here, setting all Colors attributes to empty strings:

  • HEADER, BLUE, CYAN, GREEN, WARNING, FAIL, ENDC, BOLD, UNDERLINE should all be set to ""

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +73
def test_print_dry_run_plan_no_colors(monkeypatch):
"""Verify print_dry_run_plan output without colors."""
monkeypatch.setattr(main, "USE_COLORS", False)

mock_stdout = MagicMock()
monkeypatch.setattr(sys, "stdout", mock_stdout)

plan = {
"profile": "test_profile",
"folders": [
{"name": "Test Folder 1", "rules": 10},
]
}

main.print_dry_run_plan(plan)

combined_output = "".join([str(args[0]) for args, _ in mock_stdout.write.call_args_list])

assert "📝 Dry Run Plan for Profile:" in combined_output
assert "test_profile" in combined_output
assert "Test Folder 1" in combined_output
assert "10 rules" in combined_output
# No ANSI codes
assert "\033[" not in combined_output
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

The test should also set the Colors class attributes to empty strings when USE_COLORS is False, similar to how test_print_dry_run_plan_with_colors manually sets color codes. If the module was imported in a TTY environment, the Colors attributes would still contain ANSI codes even after setting USE_COLORS to False, which could cause the test to fail.

The same pattern from test_print_dry_run_plan_with_colors should be applied here, setting all Colors attributes to empty strings:

  • HEADER, BLUE, CYAN, GREEN, WARNING, FAIL, ENDC, BOLD, UNDERLINE should all be set to ""

Copilot uses AI. Check for mistakes.
google-labs-jules bot and others added 2 commits January 31, 2026 23:00
- Added `print_dry_run_plan` to display a user-friendly summary of changes during a dry run.
- Updated `sync_profile` to call `print_dry_run_plan`.
- Used `sanitize_for_log` on printed user inputs to satisfy CodeQL security checks.
- Removed a duplicate definition of `render_progress_bar`.
- Added unit tests for the new output function.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
- Added `print_dry_run_plan` to display a user-friendly summary of changes during a dry run.
- Updated `sync_profile` to call `print_dry_run_plan`.
- Used `sanitize_for_log` on printed user inputs to satisfy CodeQL security checks.
- Removed a duplicate definition of `render_progress_bar`.
- Added unit tests for the new output function.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 31, 2026 23:03
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

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


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

Copilot AI added a commit that referenced this pull request Feb 8, 2026
…itization, add dry-run plan details

Incorporates the best changes from 36 Jules PRs, addressing review feedback:

Bolt (Performance) - from PR #173:
- Pre-compile PROFILE_ID_PATTERN and RULE_PATTERN at module level
- Use compiled patterns in is_valid_profile_id_format, validate_profile_id, and is_valid_rule
- Supersedes PRs: #140, #143, #152, #155, #158, #161, #167, #170, #173

Sentinel (Security) - from PR #172 with review feedback:
- Enhance sanitize_for_log to redact Basic Auth credentials in URLs
- Redact sensitive query parameters (token, key, secret, password, etc.)
- Handle fragment separators (#) per Gemini Code Assist review
- Use [^&#\s]* pattern per Copilot reviewer suggestion
- Update docstring per reviewer suggestion
- Supersedes PRs: #142, #145, #148, #151, #154, #157, #160, #169, #172

Palette (UX) - from PR #174 with lint fixes:
- Add print_plan_details function for dry-run visibility
- Fix duplicate render_progress_bar definition bug
- Supersedes PRs: #139, #141, #144, #147, #150, #153, #156, #159, #162, #165, #168, #171, #174

Also: #146, #149, #164 (parallel folder deletion) and #166 (auto-fix .env perms) are independent features not consolidated here.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
@abhimehro abhimehro closed this Feb 9, 2026
@abhimehro abhimehro deleted the palette-dry-run-plan-output-15215056721859509049 branch February 9, 2026 00:21
abhimehro added a commit that referenced this pull request Feb 9, 2026
…itization, add dry-run plan details

Incorporates the best changes from 36 Jules PRs, addressing review feedback:

Bolt (Performance) - from PR #173:
- Pre-compile PROFILE_ID_PATTERN and RULE_PATTERN at module level
- Use compiled patterns in is_valid_profile_id_format, validate_profile_id, and is_valid_rule
- Supersedes PRs: #140, #143, #152, #155, #158, #161, #167, #170, #173

Sentinel (Security) - from PR #172 with review feedback:
- Enhance sanitize_for_log to redact Basic Auth credentials in URLs
- Redact sensitive query parameters (token, key, secret, password, etc.)
- Handle fragment separators (#) per Gemini Code Assist review
- Use [^&#\s]* pattern per Copilot reviewer suggestion
- Update docstring per reviewer suggestion
- Supersedes PRs: #142, #145, #148, #151, #154, #157, #160, #169, #172

Palette (UX) - from PR #174 with lint fixes:
- Add print_plan_details function for dry-run visibility
- Fix duplicate render_progress_bar definition bug
- Supersedes PRs: #139, #141, #144, #147, #150, #153, #156, #159, #162, #165, #168, #171, #174

Also: #146, #149, #164 (parallel folder deletion) and #166 (auto-fix .env perms) are independent features not consolidated here.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
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.

2 participants