agentleFS
involvexinvolvex/youtube-music-cli/.github/copilot-instructions.md

youtube-music-cli

Copilot instructions461 starsChanged 3 months agoMITView on GitHub

This is a Terminal User Interface (TUI) music player for YouTube Music, built with React and TypeScript using Ink for terminal rendering. Key Commands: State Management (all follow the same pattern: Provider + useHook): Services (abstraction over external dependencies): Components (organized by feature, use Ink primitives: Box, Text, etc.): Types (core domain models): React Hooks & Context: All custom hooks throw an error if used outside their provider. Always verify the provider wrapper is in place before using a hook.

We split this copilot-instructions.md into the rules it gives an agent

19 rules. About 1 is common, 6 are distinctive, and 12 are very specific to this project.

  • ≈1

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Common:

    React Hooks & Context: All custom hooks throw an error if used outside their provider.

    line 60
  2. Very specific:

    Terminal Size Responsiveness: Use useTerminalSize() to scale UI elements and truncate text based on terminal width.

    line 64
  3. Very specific:

    Use useKeyBinding hook to register global shortcuts

    line 114
  4. Distinctive:

    Avoid adding raw stdin listeners directly.

    line 116
  5. Distinctive:

    Security: Always sanitize audio URLs to prevent shell injection

    line 122
  6. Very specific:

    Search is polymorphic: returns discriminated union of Track/Album/Artist/Playlist results

    line 126
  7. Distinctive:

    Search triggering happens on Enter key press

    line 127
  8. Very specific:

    All text must be wrapped in <Text> components

    line 132
  9. Very specific:

    Use <Box> with flexbox-style positioning

    line 133
  10. Very specific:

    Never place raw text outside of <Text> components (will cause Ink render errors)

    line 134
  11. Very specific:

    Type Errors: Run bun run typecheck without emitting to catch TS errors quickly

    line 138
  12. Very specific:

    Render Crashes: Check that all text is wrapped in <Text> components

    line 139
  13. Distinctive:

    State Not Updating: Verify the store provider is wrapping the consuming component tree

    line 140
  14. Very specific:

    Keyboard Events Not Firing: Use useKeyBinding hook instead of raw stdin listeners

    line 141
  15. Very specific:

    API Failures: Check youtube-music service error handling.

    line 142
  16. Distinctive:

    Keep component logic surgical: move business logic to hooks/services

    line 146
  17. Very specific:

    Place reusable logic in source/hooks/

    line 147
  18. Very specific:

    Use TypeScript types from source/types/ for all public APIs

    line 148
  19. Distinctive:

    Avoid circular dependencies between stores and components

    line 150

≈ “Common” is an estimate: at least 1 in 5 of the 3,669 Copilot instructions files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
copilot-instructions.md

Copilot Instructions for youtube-music-cli

Quick Start

This is a Terminal User Interface (TUI) music player for YouTube Music, built with React and TypeScript using Ink for terminal rendering.

Key Commands:

bun run dev          # Start in watch mode (TypeScript compilation)
bun run build        # Compile TypeScript to dist/
bun run start        # Run compiled CLI binary
bun run lint:fix     # Fix linting and formatting issues
bun run test         # Run full test suite (formatting + linting + tests)

Architecture Overview

Entry Points

  • CLI Entry: source/cli.tsx - Parses CLI arguments with meow, handles direct commands (play, search, playlist)
  • App Root: source/app.tsx → source/main.tsx - Root React component that sets up providers
  • Compiled Binary: dist/source/cli.js (referenced in package.json bin field)

Core Layers

State Management (all follow the same pattern: Provider + useHook):

  • source/stores/player.store.tsx - Player state (playback, queue, volume, shuffle/repeat) with action-based reducers
  • source/stores/navigation.store.tsx - View navigation state
  • source/contexts/theme.context.tsx - Theme management

Services (abstraction over external dependencies):

  • source/services/youtube-music/ - Wrapper around node-youtube-music API for search and track lookup
  • source/services/player/ - Audio playback via play-sound
  • source/services/config/ - Configuration persistence (theme, volume settings)

Components (organized by feature, use Ink primitives: Box, Text, etc.):

source/components/
├── layouts/       # Main UI containers (PlayerLayout, SearchLayout, etc.)
├── player/        # Player-specific UI (PlayerControls, QueueList, etc.)
├── search/        # Search UI (SearchBar, SearchResults)
├── playlist/      # Playlist management UI
├── theme/         # Theme switching UI
└── common/        # Shared components (Help, ErrorBoundary, etc.)

Types (core domain models):

  • source/types/player.types.ts - PlayerState, PlayerAction
  • source/types/youtube-music.types.ts - Track, Album, Artist, Playlist, SearchResult
  • source/types/theme.types.ts - Theme interface
  • source/types/cli.types.ts - CLI flags and options

Key Patterns

React Hooks & Context: All custom hooks throw an error if used outside their provider. Always verify the provider wrapper is in place before using a hook.

Action-Based Reducers: Player state changes happen through action categories (PLAY, PAUSE, NEXT, SEEK, etc.) dispatched to the reducer. Check PlayerAction type for available actions.

Terminal Size Responsiveness: Use useTerminalSize() to scale UI elements and truncate text based on terminal width.

Development Conventions

Imports & Modules

  • ESM Modules: Project uses "type": "module" - all imports use ES syntax
  • TypeScript Extensions: Imports include .ts/.tsx extensions (compiler rewrites them)
  • Bun Runtime: Primary runtime and package manager (scripts use bun run)

Code Quality

  • Linting: ESLint with flat config, extends XO and XO-React
  • Formatting: Prettier with @vdemedes/prettier-config and import organization plugins
  • TypeScript: Strict mode via @sindresorhus/tsconfig
  • React Transform: JSX uses automatic transform (jsx: "react-jsx")

Testing

  • Test Runner: AVA (configured for TypeScript modules)
  • TUI Testing: ink-testing-library for asserting on terminal output
  • Test Location: test.tsx and other .test.ts/tsx files
  • Single Test: bunx ava test.tsx --match "test name" to run specific test

CLI Commands

Interactive Mode

youtube-music-cli                    # Launch interactive UI
youtube-music-cli --theme=matrix     # Set theme via flag

Subcommands

youtube-music-cli play <track-id>    # Play specific track directly
youtube-music-cli search <query>     # Search and play
youtube-music-cli playlist <id>      # Play playlist
youtube-music-cli pause              # Pause playback
youtube-music-cli resume             # Resume playback
youtube-music-cli skip               # Skip to next track
youtube-music-cli back               # Go to previous track
youtube-music-cli --headless         # Run without TUI

Critical Implementation Details

Keyboard Event Management

  • Use useKeyBinding hook to register global shortcuts
  • Keyboard events are centralized to prevent MaxListenersExceededWarning
  • Avoid adding raw stdin listeners directly; use the hook instead

Audio Streaming

  • High-quality audio for downloads: yt-dlp first, then youtubei.js, then Invidious (health persisted under ~/.youtube-music-cli/invidious-health.json)
  • Playback passes YouTube watch URLs to mpv (yt-dlp resolves streams)
  • Security: Always sanitize audio URLs to prevent shell injection

Search & Results

  • Search is polymorphic: returns discriminated union of Track/Album/Artist/Playlist results
  • Search triggering happens on Enter key press
  • Results are paginated to avoid excessive API calls

Terminal Rendering

  • All text must be wrapped in <Text> components
  • Use <Box> with flexbox-style positioning
  • Never place raw text outside of <Text> components (will cause Ink render errors)

Common Debugging Tips

  1. Type Errors: Run bun run typecheck without emitting to catch TS errors quickly
  2. Render Crashes: Check that all text is wrapped in <Text> components
  3. State Not Updating: Verify the store provider is wrapping the consuming component tree
  4. Keyboard Events Not Firing: Use useKeyBinding hook instead of raw stdin listeners
  5. API Failures: Check youtube-music service error handling; Innertube API may require authentication tokens

File Organization Standards

  • Keep component logic surgical: move business logic to hooks/services
  • Place reusable logic in source/hooks/
  • Use TypeScript types from source/types/ for all public APIs
  • Services should be stateless or singleton (like MusicService via getMusicService())
  • Avoid circular dependencies between stores and components

MCP Servers

The .mcp/servers.json file configures Model Context Protocol servers for enhanced Copilot capabilities:

  • Node MCP - Runtime analysis and module introspection for Node.js dependencies
  • Filesystem MCP - Safe directory and file operations within the repo
  • Git MCP - Git history, diff, and version control operations

These provide deeper context for code analysis and can be enabled in compatible Copilot environments.

See Also

  • CLAUDE.md - Detailed developer documentation
  • GEMINI.md - Architecture and recent updates overview
  • package.json - Full list of dependencies and scripts
  • .mcp/servers.json - MCP server configuration

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.