npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

plugin-gentleman

v1.3.3

Published

OpenCode TUI plugin featuring Mustachi - an animated ASCII mascot with eyes, mustache, and optional motivational phrases during busy states

Readme

Plugin Gentleman

For the Gentleman Programming community — Bringing Mustachi, our beloved mascot, into your OpenCode terminal.

An OpenCode TUI plugin crafted for the Gentleman Programming community. Mustachi, the official mascot of Gentleman Programming, now accompanies you through your coding sessions with visual flair and environment awareness:

  • 🎭 Prominent ASCII mustache on the home screen
  • 👤 Full Mustachi face with eyes in the sidebar
  • 👀 Subtle eye animations (optional, low-frequency)
  • 💬 Motivational phrases during busy states (Rioplatense Spanish style)
  • 🎨 Gentleman theme installed and applied automatically
  • 🖥️ Environment detection — displays your OS and LLM providers
  • ⚙️ Fully configurable via opencode.json

Installation

Quick Start

Install the plugin globally with OpenCode:

opencode plugin plugin-gentleman --global

OpenCode will download the package and update your TUI config automatically.

Restart OpenCode to see:

  • Prominent ASCII mustache on the home screen
  • OpenCode branding text
  • Detected: <OS> · <providers> below the prompt area
  • Full Mustachi face in the sidebar

Updating

If you already have Plugin Gentleman installed, force OpenCode to refresh the cached npm package:

opencode plugin plugin-gentleman@latest --global --force

--force matters: when a plugin is already configured, OpenCode may otherwise keep the existing cached package/config entry. Restart OpenCode after updating.

Alternative: Manual Configuration

If you prefer managing config yourself, add this to ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["plugin-gentleman@latest"]
}

OpenCode will install npm plugins automatically on startup.


Mustachi phrases

Mustachi currently uses the bundled local phrase library only. Experimental model-generated phrases, the Mascot Model command, and the CLI model configuration flow are disabled for stability.


For Developers

Local Testing with npm link:

npm link

Then add to ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["plugin-gentleman"]
}

Restart OpenCode to see changes.

Local Testing with Tarball:

npm pack
opencode plugin ./plugin-gentleman-<version>.tgz --global

If your OpenCode version doesn't accept a tarball path, use the published package flow instead.

Local Cache Smoke Check:

./mini-local-check.sh

This repository script packs the current workspace, clears the local OpenCode cache for plugin-gentleman, installs the tarball into OpenCode's active local package slot, and prints a short manual runtime checklist. It is intended for developer smoke checks before publishing; it is not a general end-user installer.


Features

Visual Components

Home Screen:

  • Prominent ASCII mustache (no face, just the mustache)
  • "OpenCode" branding text
  • Environment detection showing OS · Providers below the prompt area

Sidebar:

  • Full Mustachi face with eyes and mustache
  • Animated blink, random look-around in 8 directions (when animations enabled)
  • Tongue and motivational phrases during busy states (when animations enabled)
  • Periodic expressive cycle every 45-60s to showcase animations (when animations enabled)

The Mustachi Mascot

Mustachi is the official mascot of the Gentleman Programming community — not something invented just for this plugin, but a character beloved by the community and now integrated into your coding environment.

The ASCII representation features:

  • Eyes that blink and look in 8 directions (center, up, down, left, right, and 4 diagonals) (sidebar only)
  • Mustache rendered in grayscale gradient on home screen, semantic zone colors in sidebar
  • Tongue that appears during busy states or periodic expressive cycles (sidebar only)
  • Motivational phrases in Rioplatense Spanish style — rotating while expressive (36+ phrase library) (sidebar only)

Example phrases during busy states:

  • "Ponete las pilas, hermano..."
  • "Dale que va, dale que va..."
  • "Ya casi, ya casi..."
  • "Ahí vamos, loco..."
  • "Un toque más y listo..."
  • "Aguantá que estoy pensando..."

Animations

Low complexity, low frequency — subtle and non-intrusive:

Blink (when animations: true)

  • Natural eyelid motion: open → half → closed → half → open
  • Progressive top-to-bottom animation (80-100ms per frame)
  • ~35% chance every 2s (average ~5-6 seconds between blinks)

Eye Direction (when animations: true)

  • Every ~3 seconds, eyes randomly look in one of 8 directions or stay center
  • 60% chance to stay centered, 40% chance to look around
  • Supports: up, down, left, right, and 4 diagonal positions
  • Returns to center frequently for natural feel

Busy/Expressive State (when animations: true)

  • Tongue appears when OpenCode is processing
  • Eyes squint during expressive state
  • Motivational phrases rotate every 3.5 seconds while Mustachi is in expressive/busy state (36+ phrase library)
  • Active during detected busy states OR periodic expressive cycles

Expressive Cycle Fallback (when animations: true)

  • First cycle: 45-60s after load
  • Subsequent cycles: every 45-60s
  • Duration: 8 seconds per cycle
  • Ensures tongue + phrases are visible even if runtime busy detection is unreliable

Disabled (when animations: false)

  • Mustachi stays in neutral position
  • No blink, no eye movement, no tongue, no phrases
  • Completely static face

Gentleman Theme

A refined dark color palette:

  • Background: Deep navy (#06080f)
  • Primary: Soft blue (#7FB4CA)
  • Accent: Warm gold (#E0C15A)
  • Text: Clean white (#F3F6F9)

Home screen mustache: 3-tone grayscale gradient for better readability

  • Top: Light gray (#C0C0C0)
  • Middle: Mid gray (#808080)
  • Bottom: Dark gray (#505050)

Sidebar Mustachi: Semantic zone colors for visual clarity

  • Monocle: Soft silver (#B8B8B8)
  • Eyes: Mid gray (#808080)
  • Mustache: Dark gray (#606060)
  • Tongue: Pink/red (#FF4466)

Environment Detection

Displays a "Detected" line with:

  • OS Detection: Reads distro name on Linux, shows "macOS" or "Windows" on other platforms
  • Provider Detection: Lists active LLM providers (OpenAI, Copilot, Google, etc.)

Both are fully configurable and can be hidden.


Configuration

Options can be configured via plugin tuple syntax in OpenCode config files.

Quick tip: To disable animations, add { "animations": false } to your plugin config (see examples below).

Default Settings

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "plugin-gentleman",
      {
        "enabled": true,
        "theme": "gentleman",
        "set_theme": false,
        "show_detected": true,
        "show_os": true,
        "show_providers": true,
        "show_metrics": true,
        "show_face": true,
        "animations": true,
        "personality_enabled": true
      }
    ]
  ]
}

Granular override keys (show_branch, show_tokens, show_cost, show_mcp) are intentionally absent from package.json exported defaults. If OpenCode merged those defaults into the options object, the runtime could not distinguish between a default true and a genuinely explicit user override — breaking the precedence system below.

Available Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | enabled | boolean | true | Enable/disable the plugin entirely | | theme | string | "gentleman" | Name of the bundled theme to install | | set_theme | boolean | false | Automatically activate the theme on load | | show_detected | boolean | true | Show the "Detected" environment info line | | show_os | boolean | true | Show detected operating system name | | show_providers | boolean | true | Show detected LLM providers | | show_metrics | boolean | true | Legacy master switch: show/hide tokens, cost, and MCP as a group. Does NOT affect branch visibility (legacy guarantee). | | show_face | boolean | true | Show Mustachi face in the sidebar | | show_branch | boolean | true | Show current branch name below the face | | show_tokens | boolean | true | Show token usage bar | | show_cost | boolean | true | Show cost bar | | show_mcp | boolean | true | Show MCP status row | | animations | boolean | true | Enable Mustachi animations (eyes, busy state) | | personality_enabled | boolean | true | Enable personality phrases and tongue expression |

Personality settings

  • personality_enabled (default true): turns Mustachi personality UX (tongue + local phrases) on/off.
  • Legacy personality_mode and personality_model values may still exist in older configs, but model-generated speech is disabled and these values are ignored by the phrase renderer.

Examples

Disable Animations:

If you prefer a completely static Mustachi (no eye movement, no busy-state tongue/phrases):

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    ["plugin-gentleman", { "animations": false }]
  ]
}

This sets animations: false, which:

  • Disables blink animation
  • Keeps eyes in neutral center position (no looking around)
  • Hides tongue and motivational phrases during busy states
  • Disables periodic expressive cycles
  • Mustachi remains completely static

Logo Only (No Detection):

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    ["plugin-gentleman", { "show_detected": false }]
  ]
}

Shows only Mustachi and OpenCode branding, no OS/provider info.

Show Only OS:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "plugin-gentleman",
      {
        "show_detected": true,
        "show_os": true,
        "show_providers": false
      }
    ]
  ]
}

Granular Metric Visibility:

Instead of the legacy show_metrics toggle, you can control each sidebar section independently.

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "plugin-gentleman",
      {
        "show_face": true,
        "show_branch": false,
        "show_tokens": true,
        "show_cost": false,
        "show_mcp": true
      }
    ]
  ]
}

Visibility Precedence (show_metrics + granular flags)

show_metrics is preserved for backward compatibility and NEVER controlled branch visibility. The precedence rules (highest to lowest):

  1. Explicit granular flag — if the user set show_branch, show_tokens, show_cost, or show_mcp, that specific flag overrides everything below.
  2. show_metrics (legacy) — if explicitly set, it acts as the base for tokens, cost, and MCP together. Does not affect branch.
  3. Package defaults — visibility flags default to true in code. Only granular metric keys (show_branch, show_tokens, show_cost, show_mcp) are excluded from package.json exports; show_face remains exported with the rest of the non-granular defaults.

Why granular keys are excluded from package.json exports: OpenCode may merge a plugin's package.json exports["*"].config defaults into the options object at runtime. If granular keys like show_branch or show_tokens were in those exports, every options object would include boolean defaults — making it impossible for the plugin to distinguish between a merged default (true) and a genuinely explicit user override. The raw boolean override check would always match, breaking the precedence system. The fix is to keep only non-granular defaults in package.json and rely on cfg() defaults in code.

Examples:

| User Config | Branch | Tokens | Cost | MCP | |---|---|---|---|---| | (none) | visible | visible | visible | visible | | { show_metrics: false } | visible | hidden | hidden | hidden | | { show_branch: false } | hidden | visible | visible | visible | | { show_metrics: false, show_tokens: true } | visible | visible | hidden | hidden | | { show_branch: false, show_tokens: false } | hidden | hidden | visible | visible |

How granular vs legacy mode is detected: The plugin checks whether each granular key is present in the raw options object with a boolean value. Boolean granular values are explicit overrides. Malformed values are treated as absent and fall back to show_metrics (for tokens/cost/mcp) or the hardcoded default true (for branch). This only works correctly when the options object does NOT contain injected defaults for those keys — which is why granular keys are deliberately excluded from package.json exports.config. To use granular overrides, add the exact boolean key(s) you want to control to your plugin config tuple.


How It Works

The plugin integrates with OpenCode's TUI system through slot registration:

  1. Theme Installation: Installs gentleman.json into OpenCode themes on load
  2. Theme Activation: Switches to the gentleman theme (if set_theme: true)
  3. Home Logo Slot: Registers home_logo with mustache-only ASCII art (grayscale gradient)
  4. Environment Detection Slot: Registers home_bottom with OS/provider info below the prompt
  5. Sidebar Slot: Registers sidebar_content with full Mustachi face and animations
  6. Animation Loops: Starts independent interval timers for:
    • Blink animation (~5-6s average interval)
    • Random eye look-around (~3s interval)
    • Phrase rotation during expressive states (3.5s interval)
    • Periodic expressive cycles (45-60s interval) (All sidebar-only, when animations: true)
  7. Busy State Detection: Attempts to read api.state.session.running for reactive busy state (best-effort; may not be exposed by all OpenCode versions)
  8. Expressive Cycle Fallback: If busy detection is unreliable, periodic cycles ensure animations are visible

Technical Stack

  • No Build Step: Plain TSX transpiled at runtime by OpenCode
  • Solid.js Reactivity: Uses createSignal and createEffect for all animations
  • Safe Detection: All OS/provider detection wrapped in try-catch blocks
  • Cleanup: Uses onCleanup to clear all intervals when components unmount
  • Multi-file Architecture: Separated concerns for maintainability (see Architecture below)

Architecture

The plugin is structured as a multi-file module for maintainability and clarity:

  • tui.tsx — Plugin entry point. Handles initialization, theme setup, slot registration, and busy state detection.
  • ui/ — Solid.js UI components (HomeLogo, SidebarMustachi, DetectedEnv) plus sidebar-specific helpers/effects.
  • ascii-frames.ts — All ASCII art assets: 9 eye position frames, 3 blink frames, squinted eyes, mustache designs, 3 tongue frames, and zone color definitions.
  • phrases.ts — Library of 36+ motivational phrases (Rioplatense Spanish style) shown during expressive states.
  • config.ts — Configuration parsing with type-safe defaults and validation helpers.
  • utils/ — OS/provider/stack detection, animation utilities, MCP helpers, and message/cost formatting.
  • runtime/ — Plugin API helpers, busy detection, model resolution compatibility helpers, Mustachi context summarization, and personality layer orchestration.

Supported Providers

Friendly name mapping for LLM providers:

| Provider ID | Display Name | |-------------|--------------| | openai | OpenAI | | google | Google | | github-copilot | Copilot | | opencode-go | OpenCode GO | | anthropic | Claude | | deepseek | DeepSeek | | openrouter | OpenRouter | | mistral | Mistral | | groq | Groq | | cohere | Cohere | | together | Together | | perplexity | Perplexity |

Unknown provider IDs display the configured name or raw ID.


Important Notes

TUI Plugin vs System Plugin

This is a TUI plugin for npm installation.

If you copy .ts files to ~/.config/opencode/plugins/ (system plugin):

  • NO visual changes — system plugins cannot modify the TUI
  • NO Mustachi — only TUI plugins can register slot components
  • NO animations — JSX/Solid.js components only work in TUI plugins

For full features, use npm installation (recommended global method above).

Package Contents

Files included in npm package (via files field in package.json):

  • tui.tsx — plugin entry point and slot registration
  • ui/ — UI components and sidebar effects/helpers
  • runtime/ — runtime helpers, model resolver/client seam, and personality layer
  • utils/ — detection, animation, MCP, and message utilities
  • bin/ — disabled plugin-gentleman CLI compatibility entrypoint
  • ascii-frames.ts — all ASCII art frames, eye positions, and color definitions
  • phrases.ts — motivational phrases library for busy states
  • config.ts — configuration parsing helpers and type definitions
  • types.ts — shared type definitions
  • root compatibility re-exports: detection.ts, animation-utils.ts, message-utils.ts, mcp-utils.ts
  • progress-components.tsx — sidebar metrics/MCP rendering components
  • gentleman.json — theme definition
  • package.json — auto-included by npm
  • README.md — auto-included by npm

Repository-only files (excluded from npm package):

  • mini-local-check.sh — developer-only local cache smoke-check script
  • .atl/ — local Agent Teams/SDD artifact metadata when present

Known Limitations

  1. Busy State Detection: The plugin attempts to detect busy states via api.state.session.running, but this may not be exposed in all OpenCode versions. If unavailable, a periodic expressive cycle fallback (every 45-60s) ensures animations remain visible.

  2. Animation Frequency: Current timing intervals:

    • Blink: ~5-6 seconds average (35% chance every 2s)
    • Look-around: 3 seconds (60% center, 40% random direction)
    • Phrase rotation: every 3.5 seconds during expressive state
    • Expressive cycle: first at 45-60s, then every 45-60s

    To adjust, modify the intervals in ui/sidebar/expression-effects.ts.

  3. Slot Usage: The plugin uses these OpenCode TUI slots:

    • home_logo — mustache-only ASCII art (grayscale gradient)
    • home_bottom — environment detection (OS + providers)
    • sidebar_content — full Mustachi face with animations

    The plugin requests mode: "replace" as a best-effort strategy, but host-native sections such as Context / MCP / LSP / Modified Files are controlled by OpenCode and may still appear.

  4. Theme Compatibility: The plugin installs and optionally activates the Gentleman theme. If you prefer a custom theme, set set_theme: false.


Development

Modifying the Plugin

The plugin is organized into focused modules for easy customization:

Adding new content:

  • Motivational phrases: Edit phrases.ts — add new phrases to the busyPhrases array (currently 36+ phrases)
  • ASCII art frames: Edit ascii-frames.ts — modify eye positions (9 variants), blink frames (3 stages), mustache designs, or tongue states (binary on/off)
  • UI logic: Edit ui/ — adjust components, sidebar effects, and layout
  • Configuration: Edit config.ts — add new config options with type-safe defaults
  • Detection logic: Edit utils/detection.ts and related utils/ helpers — add OS/provider/stack patterns or marker behavior
  • Plugin behavior: Edit tui.tsx — modify slot registration, initialization flow, or busy detection

Testing locally:

  1. Make your changes in the appropriate file(s)
  2. Test with npm link, npm pack, or ./mini-local-check.sh (see "For Developers" section above)
  3. No build step needed — OpenCode transpiles TSX at runtime
  4. Restart OpenCode to see changes

Animation timing customization:

Animation intervals are handled in ui/sidebar/expression-effects.ts:

  • Look-around interval: Currently 3000ms (3s)
  • Blink interval: Currently 2000ms with 35% chance (~5-6s average)
  • Blink frame timing: Currently 80-100ms per frame progression
  • Phrase rotation: Every 3500ms while expressive/busy
  • Expressive cycle timing: First cycle at 45-60s, then every 45-60s
  • Expressive cycle duration: Currently 8000ms (8s)

Color customization:

  • Zone colors (sidebar): Edit zoneColors object in ascii-frames.ts (monocle, eyes, mustache, tongue)
  • Home grayscale gradient: Edit HomeLogo component in ui/home-logo.tsx (top/middle/bottom color values)
  • Theme colors: Edit gentleman.json for the full color palette

License

ISC