Claude-skill-registry loading

Imported skill loading from langchain

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/loading" ~/.claude/skills/majiayu000-claude-skill-registry-loading && rm -rf "$T"
manifest: skills/data/loading/SKILL.md
source content

"""Loading widget with animated spinner for agent activity."""

from future import annotations

from time import time from typing import TYPE_CHECKING, ClassVar

from textual.containers import Horizontal from textual.widgets import Static

if TYPE_CHECKING: from textual.app import ComposeResult

class BrailleSpinner: """Animated braille spinner."""

FRAMES: ClassVar[tuple[str, ...]] = (
    "⠋",
    "⠙",
    "⠹",
    "⠸",
    "⠼",
    "⠴",
    "⠦",
    "⠧",
    "⠇",
    "⠏",
)

def __init__(self) -> None:
    """Initialize spinner."""
    self._position = 0

def next_frame(self) -> str:
    """Get next animation frame."""
    frame = self.FRAMES[self._position]
    self._position = (self._position + 1) % len(self.FRAMES)
    return frame

def current_frame(self) -> str:
    """Get current frame without advancing."""
    return self.FRAMES[self._position]

class LoadingWidget(Static): """Animated loading indicator with status text and elapsed time.

Displays: ⠋ Thinking... (3s, esc to interrupt)
"""

DEFAULT_CSS = """
LoadingWidget {
    height: auto;
    padding: 0 1;
}

LoadingWidget .loading-container {
    height: auto;
    width: 100%;
}

LoadingWidget .loading-spinner {
    width: auto;
    color: $warning;
}

LoadingWidget .loading-status {
    width: auto;
    color: $warning;
}

LoadingWidget .loading-hint {
    width: auto;
    color: $text-muted;
    margin-left: 1;
}
"""

def __init__(self, status: str = "Thinking") -> None:
    """Initialize loading widget.

    Args:
        status: Initial status text to display
    """
    super().__init__()
    self._status = status
    self._spinner = BrailleSpinner()
    self._start_time: float | None = None
    self._spinner_widget: Static | None = None
    self._status_widget: Static | None = None
    self._hint_widget: Static | None = None
    self._paused = False
    self._paused_elapsed: int = 0

def compose(self) -> ComposeResult:
    """Compose the loading widget layout."""
    with Horizontal(classes="loading-container"):
        self._spinner_widget = Static(self._spinner.current_frame(), classes="loading-spinner")
        yield self._spinner_widget

        self._status_widget = Static(f" {self._status}... ", classes="loading-status")
        yield self._status_widget

        self._hint_widget = Static("(0s, esc to interrupt)", classes="loading-hint")
        yield self._hint_widget

def on_mount(self) -> None:
    """Start animation on mount."""
    self._start_time = time()
    self.set_interval(0.1, self._update_animation)

def _update_animation(self) -> None:
    """Update spinner and elapsed time."""
    if self._paused:
        return

    if self._spinner_widget:
        frame = self._spinner.next_frame()
        self._spinner_widget.update(f"[#FFD800]{frame}[/]")

    if self._hint_widget and self._start_time is not None:
        elapsed = int(time() - self._start_time)
        self._hint_widget.update(f"({elapsed}s, esc to interrupt)")

def set_status(self, status: str) -> None:
    """Update the status text.

    Args:
        status: New status text
    """
    self._status = status
    if self._status_widget:
        self._status_widget.update(f" {self._status}... ")

def pause(self, status: str = "Awaiting decision") -> None:
    """Pause the animation and update status.

    Args:
        status: Status to show while paused
    """
    self._paused = True
    if self._start_time is not None:
        self._paused_elapsed = int(time() - self._start_time)
    self._status = status
    if self._status_widget:
        self._status_widget.update(f" {status}... ")
    if self._hint_widget:
        self._hint_widget.update(f"(paused at {self._paused_elapsed}s)")
    if self._spinner_widget:
        self._spinner_widget.update("[dim]⏸[/dim]")

def resume(self) -> None:
    """Resume the animation."""
    self._paused = False
    self._status = "Thinking"
    if self._status_widget:
        self._status_widget.update(f" {self._status}... ")

def stop(self) -> None:
    """Stop the animation (widget will be removed by caller)."""