Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@
## 2024-03-22 - CLI Interactive Fallbacks
**Learning:** CLI tools often fail hard when config is missing, but interactive contexts allow for graceful recovery. Users appreciate being asked for missing info instead of just receiving an error.
**Action:** When `sys.stdin.isatty()` is true, prompt for missing configuration instead of exiting with an error code.

## 2025-06-15 - Managing Visual Noise
**Learning:** Adding progress bars to verbose/chatty CLI processes (streams of logs) creates visual clutter and flickering. It's better to keep progress bars for "silent" wait states (like cache warming) and leave verbose processes as streams.
**Action:** Only implement progress bars for phases that are otherwise silent or have low log volume; avoid them for high-frequency logging loops.
35 changes: 35 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,37 @@
BOLD = ''
UNDERLINE = ''

class ProgressBar:
"""A simple CLI progress bar."""
def __init__(self, total: int, prefix: str = "Progress", length: int = 30):
self.total = total
self.prefix = prefix
self.length = length
self.current = 0

def increment(self):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing method docstring Warning

Missing method docstring

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing function or method docstring Warning

Missing function or method docstring
self.current += 1
self._print()

def clear(self):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing method docstring Warning

Missing method docstring

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing function or method docstring Warning

Missing function or method docstring

Check warning

Code scanning / Pylint (reported by Codacy)

Method could be a function Warning

Method could be a function

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Method could be a function Warning

Method could be a function
if USE_COLORS:
sys.stderr.write("\r\033[K")
sys.stderr.flush()

def _print(self):
if not USE_COLORS or self.total == 0:
return

percent = float(self.current) / self.total
filled = int(self.length * percent)
bar = '█' * filled + '-' * (self.length - filled)

Check warning

Code scanning / Prospector (reported by Codacy)

Black listed name "bar" (blacklisted-name) Warning

Black listed name "bar" (blacklisted-name)

Check warning

Code scanning / Pylint (reported by Codacy)

Black listed name "bar" Warning

Black listed name "bar"

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Black listed name "bar" Warning

Black listed name "bar"

sys.stderr.write(f"\r{Colors.CYAN}{self.prefix} |{bar}| {self.current}/{self.total}{Colors.ENDC}")

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (106/100) Warning

Line too long (106/100)

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (106/100) Warning

Line too long (106/100)
sys.stderr.flush()

if self.current == self.total:
sys.stderr.write("\n")

class ColoredFormatter(logging.Formatter):
"""Custom formatter to add colors to log levels."""
LEVEL_COLORS = {
Expand Down Expand Up @@ -387,11 +418,15 @@
log.info(f"Warming up cache for {len(urls_to_fetch)} URLs...")
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = {executor.submit(_gh_get, url): url for url in urls_to_fetch}
pbar = ProgressBar(len(futures), prefix="Fetching")
for future in concurrent.futures.as_completed(futures):
try:
future.result()
except Exception as e:
pbar.clear()
log.warning(f"Failed to pre-fetch {sanitize_for_log(futures[future])}: {e}")
finally:
pbar.increment()

def delete_folder(client: httpx.Client, profile_id: str, name: str, folder_id: str) -> bool:
try:
Expand Down
Loading