Complete Phase 1: parallel sync, IPC, theme colors, lazy CLI loading

- Sync: Parallelize message downloads with asyncio.gather (batch size 5)
- Sync: Increase HTTP semaphore from 2 to 5 concurrent requests
- Sync: Add IPC notifications to sync daemon after sync completes
- Mail: Replace all hardcoded RGB colors with theme variables
- Mail: Remove envelope icon/checkbox gap (padding cleanup)
- Mail: Add IPC listener for refresh notifications from sync
- Calendar: Style current time line with error color and solid line
- Tasks: Fix table not displaying (CSS grid to horizontal layout)
- CLI: Implement lazy command loading for faster startup (~12s to ~0.3s)
- Add PROJECT_PLAN.md with full improvement roadmap
- Add src/utils/ipc.py for Unix socket cross-app communication
This commit is contained in:
Bendt
2025-12-19 10:29:53 -05:00
parent a41d59e529
commit d4226caf0a
11 changed files with 1096 additions and 103 deletions

View File

@@ -1,37 +1,55 @@
# CLI module for the application
# Uses lazy imports to speed up startup time
import click
from .sync import sync
from .drive import drive
from .email import email
from .calendar import calendar
from .ticktick import ticktick
from .godspeed import godspeed
from .gitlab_monitor import gitlab_monitor
from .tasks import tasks
import importlib
@click.group()
class LazyGroup(click.Group):
"""A click Group that lazily loads subcommands."""
def __init__(self, *args, lazy_subcommands=None, **kwargs):
super().__init__(*args, **kwargs)
self._lazy_subcommands = lazy_subcommands or {}
def list_commands(self, ctx):
base = super().list_commands(ctx)
lazy = list(self._lazy_subcommands.keys())
return sorted(base + lazy)
def get_command(self, ctx, cmd_name):
if cmd_name in self._lazy_subcommands:
return self._load_command(cmd_name)
return super().get_command(ctx, cmd_name)
def _load_command(self, cmd_name):
module_path, attr_name = self._lazy_subcommands[cmd_name]
# Handle relative imports
if module_path.startswith("."):
module = importlib.import_module(module_path, package="src.cli")
else:
module = importlib.import_module(module_path)
return getattr(module, attr_name)
# Create CLI with lazy loading - commands only imported when invoked
@click.group(
cls=LazyGroup,
lazy_subcommands={
"sync": (".sync", "sync"),
"drive": (".drive", "drive"),
"email": (".email", "email"),
"mail": (".email", "email"), # alias
"calendar": (".calendar", "calendar"),
"ticktick": (".ticktick", "ticktick"),
"tt": (".ticktick", "ticktick"), # alias
"godspeed": (".godspeed", "godspeed"),
"gs": (".godspeed", "godspeed"), # alias
"gitlab_monitor": (".gitlab_monitor", "gitlab_monitor"),
"glm": (".gitlab_monitor", "gitlab_monitor"), # alias
"tasks": (".tasks", "tasks"),
},
)
def cli():
"""Root command for the CLI."""
"""LUK - Local Unix Kit for productivity."""
pass
cli.add_command(sync)
cli.add_command(drive)
cli.add_command(email)
cli.add_command(calendar)
cli.add_command(ticktick)
cli.add_command(godspeed)
cli.add_command(gitlab_monitor)
cli.add_command(tasks)
# Add 'mail' as an alias for email
cli.add_command(email, name="mail")
# Add 'tt' as a short alias for ticktick
cli.add_command(ticktick, name="tt")
# Add 'gs' as a short alias for godspeed
cli.add_command(godspeed, name="gs")
# Add 'glm' as a short alias for gitlab_monitor
cli.add_command(gitlab_monitor, name="glm")

View File

@@ -14,6 +14,7 @@ from typing import Optional, Dict, Any
from src.cli.sync import _sync_outlook_data, should_run_godspeed_sync, should_run_sweep
from src.cli.sync import run_godspeed_sync, run_task_sweep, load_sync_state
from src.utils.ipc import notify_all, notify_refresh
class SyncDaemon:
@@ -247,6 +248,13 @@ class SyncDaemon:
notify=self.config.get("notify", False),
)
self.logger.info("Sync completed successfully")
# Notify all running TUI apps to refresh their data
results = await notify_all({"source": "sync_daemon"})
notified = [app for app, success in results.items() if success]
if notified:
self.logger.info(f"Notified apps to refresh: {', '.join(notified)}")
except Exception as e:
self.logger.error(f"Sync failed: {e}")