alexpasmantier/television
A very fast, portable and hackable fuzzy finder.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1w ago
- ✓31+ active contributors
- ✓Distributed ownership (top contributor 44% of recent commits)
Show all 6 evidence items →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/alexpasmantier/television)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/alexpasmantier/television on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: alexpasmantier/television
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/alexpasmantier/television shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 1w ago
- 31+ active contributors
- Distributed ownership (top contributor 44% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live alexpasmantier/television
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/alexpasmantier/television.
What it runs against: a local clone of alexpasmantier/television — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in alexpasmantier/television | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 39 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of alexpasmantier/television. If you don't
# have one yet, run these first:
#
# git clone https://github.com/alexpasmantier/television.git
# cd television
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of alexpasmantier/television and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "alexpasmantier/television(\\.git)?\\b" \\
&& ok "origin remote is alexpasmantier/television" \\
|| miss "origin remote is not alexpasmantier/television (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "television/lib.rs" \\
&& ok "television/lib.rs" \\
|| miss "missing critical file: television/lib.rs"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "build.rs" \\
&& ok "build.rs" \\
|| miss "missing critical file: build.rs"
test -f ".config/config.toml" \\
&& ok ".config/config.toml" \\
|| miss "missing critical file: .config/config.toml"
test -f "cable/unix/channels.toml" \\
&& ok "cable/unix/channels.toml" \\
|| miss "missing critical file: cable/unix/channels.toml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 39 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~9d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/alexpasmantier/television"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Television (tv) is a blazing-fast, cross-platform fuzzy finder written in Rust that searches across arbitrary data sources (files, git repos, Kubernetes objects, environment variables, etc.) with real-time preview and custom action bindings. It replaces tools like fzf by providing a pluggable "channel" architecture where each channel (defined in TOML under ~/.config/television/cable/) maps a command's output to searchable, previewable items with custom keybindings. Monorepo structure: television/lib.rs is the core library exposing channels API; src/main.rs is the CLI binary; .config/config.toml defines built-in channels (files, text, git-files, git-repos, etc.); cable/ subdirectories under ~/.config/television hold user-defined channel TOMLs. Async task spawning via tokio for concurrent source data fetching and filtering via television-nucleo crate.
👥Who it's for
Terminal power users, DevOps engineers, and developers who need fast contextual search across heterogeneous data sources (Kubernetes, Docker, git workflows, SSH hosts, AWS buckets). Contributors are typically Rust developers building CLI tools or adding new "channels" for domain-specific use cases.
🌱Maturity & risk
Actively maintained and production-ready (v0.15.6). Strong CI/CD setup with multiple GitHub workflows for changelog, docs deployment, and platform-specific releases (WinGet, Homebrew). Available via 6+ package managers (Arch pacman, Homebrew, Cargo, Scoop, WinGet, Nix). Regular releases and responsive issue handling, though single primary maintainer (alexpasmantier) introduces some continuity risk.
Moderate dependency footprint (~40 direct deps) centered on tokio (async runtime), ratatui (TUI), and crossterm (terminal control); all well-maintained. Last significant activity appears recent (CI workflows active). Primary risk: single-maintainer project (alexpasmantier) with no obvious succession plan. Breaking changes possible in pre-1.0 versioning, though currently stable at 0.15.x.
Active areas of work
Active development on shell integration (init commands for zsh/bash), documentation site deployment, and platform-specific installers. GitHub workflows for changelog auto-generation, CLI help text updates, and cross-platform CI checks. Recent focus on editor integrations (tv.nvim, tv.vim, VSCode extension) and custom channel TOML documentation.
🚀Get running
git clone https://github.com/alexpasmantier/television.git
cd television
cargo build --release
./target/release/television --help
Or via Cargo: cargo install television. Then run tv to search files (default), tv text for content search, tv --help for all channels.
Daily commands:
cargo build --release
# Run the default channel (files)
./target/release/television
# Or specify a channel
./target/release/television git-files
# Development with logs
RUST_LOG=debug ./target/release/television
For shell integration: eval "$(tv init zsh)" (or bash/fish variants).
🗺️Map of the codebase
television/lib.rs— Primary library entry point; defines all public APIs and core module structure for the fuzzy finder engineCargo.toml— Workspace manifest with tokio async runtime and key dependencies; required to understand build configuration and feature flagsbuild.rs— Build script that generates code or assets at compile time; critical for understanding how the binary is constructed.config/config.toml— Default configuration schema; essential for understanding how channels and user preferences are structuredcable/unix/channels.toml— Core channel definitions that showcase the plugin/channel architecture; demonstrates how data sources are connectedbenches/main.rs— Benchmark suite entry point; shows performance-critical paths that shape architectural decisions
🧩Components & responsibilities
- Channel Loader (cable/*.toml) (TOML parsing, Tokio process spawning) — Parses channel definitions and executes configured commands to fetch data sources
- Failure mode: If command fails or is malformed, channel shows error or empty results; gracefully degrades
- Core Search Engine (television/lib.rs) (Rust iterators, string processing, scoring algorithms) — Implements fuzzy matching algorithm, candidate ranking, and incremental filtering
- Failure mode: If matching logic is slow, user perceives lag; impacts responsiveness on large datasets
- TUI Renderer (benches/main/render.rs, ui.rs) (Terminal drawing library, event polling) — Renders interactive UI with results, preview pane, and theme application
- Failure mode: If frame time exceeds ~16ms, terminal flickers or becomes unresponsive
- Preview Engine (benches/main/previewer.rs) (File I/O, syntax highlighting (implicit)) — Fetches and renders preview content (file contents, diffs, etc.) for selected candidate
- Failure mode: If preview fetch is slow or fails, user sees stale or empty preview pane
- Configuration System (.config/config.toml) (TOML parsing, directory discovery (directories crate)) — Loads user themes, keybindings, and application preferences
- Failure mode: If config is invalid, falls back to defaults; malformed config does not crash app
🔀Data flow
User input (terminal)→TUI event loop— Keyboard keystrokes captured and enqueued for processingChannel definition (TOML)→Command executor— Channel metadata (command, args, output format) passed to system command launcherSystem command output→Candidate cache— Raw output lines from external commands parsed and stored in memory cacheCandidate cache + user query→Fuzzy matcher— Cached candidates filtered and ranked against current search stringRanked results→TUI renderer— Sorted matches passed to display layer for rendering with themeSelected candidate→Preview engine— User-selected result sent to preview generator for content displayPreview content→TUI renderer— undefined
🛠️How to make changes
Add a new data source channel
- Create a new TOML file in cable/unix/ directory following naming convention (
cable/unix/example-source.toml) - Define command execution, output format, and preview configuration in the TOML (
cable/unix/files.toml) - Reference the new channel in the main channels configuration (
cable/unix/channels.toml) - Update documentation if needed, new channels are auto-discovered (
README.md)
Optimize search performance
- Add benchmark for the bottleneck path in benches/main/ (
benches/main/load_candidates.rs) - Profile using the benchmark suite to measure improvements (
benches/main.rs) - Implement optimization in core library module referenced in lib.rs (
television/lib.rs)
Add UI theme or feature
- Define theme colors and styling in configuration schema (
.config/config.toml) - Implement theme rendering in TUI layer (
benches/main/render.rs) - Add benchmark to ensure rendering performance stays acceptable (
benches/main/ui.rs)
🔧Why these technologies
- Rust + Tokio async runtime — Enables portable, high-performance concurrent data fetching with minimal dependencies; supports non-blocking search while streaming results
- TOML-based channel definitions (cable/) — Allows users to easily define new data sources without recompiling; hackable and declarative plugin system
- TUI terminal framework (implied from benches) — Provides responsive, real-time interactive fuzzy finding in terminal without external dependencies
- Devicons + base64 encoding — Enables rich icon display and inline asset embedding for portable binary distribution
⚖️Trade-offs already made
-
In-memory candidate caching vs persistent storage
- Why: In-memory cache provides instant repeat queries within same session without I/O latency
- Consequence: Cache is lost on exit; no cross-session persistence but optimal performance for typical interactive workflows
-
TOML channel definitions vs hardcoded integrations
- Why: TOML is user-hackable and requires no recompilation; avoids binary bloat from every possible integration
- Consequence: Requires Tokio/system command execution overhead; less optimal for single-purpose binaries but maximum flexibility
-
Incremental fuzzy matching on user input
- Why: Provides instant visual feedback and sub-millisecond perceived responsiveness
- Consequence: Higher memory usage for candidate storage; CPU usage increases with dataset size
🚫Non-goals (don't propose these)
- Not a persistent database or storage system
- Not intended for non-interactive batch processing
- Does not provide network-native channels (channels execute local commands only)
- Does not include built-in authentication (delegates to underlying commands)
🪤Traps & gotchas
No required env vars for basic use, but RUST_LOG=debug enables verbose output for troubleshooting. Shell init is context-specific: tv init zsh must be sourced (not exec'd) in ~/.zshrc; manual setup required for non-standard shells. Custom channel paths: ~/.config/television/cable/ must exist; typos in TOML syntax silently fail (no schema validation). Preview command timeout: Long-running preview commands (e.g., tldr on first load) may feel sluggish; no configurable timeout visible in config.toml. macOS-specific crossterm feature: macos target uses 'use-dev-tty' feature; behavior may differ on Linux/Windows for terminal I/O.
🏗️Architecture
💡Concepts to learn
- Fuzzy Matching (Nucleo Algorithm) — Television's search speed and ranking quality depend entirely on the nucleo-based scoring; understanding match scoring, gap penalties, and case sensitivity is essential for tuning search behavior and debugging unexpected rankings.
- Async Task Spawning (Tokio) — Each data source (channel command) runs in a separate Tokio task to keep the TUI responsive; contributors modifying data fetching or filtering must understand async/await and task cancellation.
- Terminal User Interface (TUI) with Ratatui — The entire visual layer (input box, search results, preview pane, keybinding display) is rendered via Ratatui widgets; UI modifications require knowledge of Ratatui's widget composition and event loop.
- Configuration as Code (TOML Channels) — Television's core innovation: channels are defined declaratively in TOML (not Rust code), making it trivially extensible without recompilation. Understanding TOML schema validation and source/preview/action parsing is key to adding new channels.
- Command Piping and Shell Integration — Channels execute arbitrary shell commands and parse their output; shell integration scripts (zsh/bash) hook Television into terminal history and keybindings. Contributors adding new shells must understand shell function scoping and command substitution.
- Cross-Platform Terminal Control (Crossterm) — Crossterm abstracts terminal I/O across Windows, macOS, and Linux (with platform-specific features like macOS's use-dev-tty); understanding its event handling and raw mode is critical for input processing and terminal state management.
- ANSI-to-TUI Rendering — Preview commands often output ANSI-colored text (e.g., git diff, tldr pages); the ansi-to-tui crate converts ANSI escape codes to Ratatui text styling. Understanding this pipeline is essential for preserving formatting in previews.
🔗Related repos
junegunn/fzf— Direct predecessor and primary inspiration; fzf is the most widely-used fuzzy finder. Television reimplements fzf's core functionality in pure Rust with a more extensible channel architecture.BurntSushi/ripgrep— Sibling tool in the Rust CLI ecosystem; ripgrep (rg) is a fast line-search tool often piped into fzf. Television's text channel subsumes this use case.alexpasmantier/tv.nvim— Official Neovim integration plugin; demonstrates how to embed Television as a picker in editor workflows, key companion for Neovim users.prabirshrestha/tv.vim— Community Vim integration plugin; extends Television's reach to traditional Vim without Neovim-only features.nucleo-rs/nucleo— Upstream fuzzy matching library; Television uses the television-nucleo fork of nucleo for core filter/scoring logic; understanding this dependency is crucial for search behavior.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive benchmarks for channel loading performance across data sources
The repo has a benches/main/load_candidates.rs file but it's likely incomplete or underutilized. Given that 'fast' is a core value proposition and the repo showcases many channels (aws-buckets, k8s-pods, git-files, etc.), adding detailed benchmarks comparing performance across different channel types would help maintain speed guarantees and catch regressions. This is critical for a fuzzy finder claiming to be 'very fast'.
- [ ] Expand benches/main/load_candidates.rs with benchmarks for at least 5 different channel types (git-files, k8s-pods, ssh-hosts, file walking, text streaming)
- [ ] Add criterion-based benchmarks to measure memory usage and initialization time for each channel
- [ ] Create a benchmark comparison document in benches/main/ showing expected performance metrics
- [ ] Add a CI workflow (or extend .github/workflows/ci.yml) to track benchmark results across commits
Create integration tests for core channels against real-world data sources
While the repo has dev-dependencies for testing (criterion, tempfile, phantom-test), there's no visible integration test suite for the various channels (git-files, k8s-pods, ssh-hosts, aws-buckets, etc.). Adding integration tests would ensure channels work reliably with actual tools like kubectl, git, aws-cli, and prevent regressions when dependencies change.
- [ ] Create tests/channels/ directory structure mirroring the channels shown in assets/channels/
- [ ] Add integration tests for at least 3-5 high-value channels (git-files, ssh-hosts, man-pages, k8s-pods) with mocked or fixture-based data
- [ ] Use tempfile dependency to create test fixtures for filesystem-based channels
- [ ] Add a new GitHub workflow (.github/workflows/integration-tests.yml) to run these tests with optional feature flags for external tool availability
Document the custom channel development API with worked examples
The repo lists many channels (aws-buckets, distrobox-list, jj-diff, launchd-services, opencode-sessions, etc.) but there's no visible channel development guide. New contributors wanting to add channels need clear documentation. This should include the channel trait/interface definition, a complete worked example, and how to register custom channels via config.toml.
- [ ] Create docs/CHANNEL_DEVELOPMENT.md explaining the channel interface/trait system
- [ ] Add a minimal worked example showing how to create a custom channel (e.g., a 'process-list' channel or 'docker-images' channel)
- [ ] Reference the configuration system in .config/config.toml and document how channels are registered
- [ ] Add code snippets showing how to implement filtering, preview generation, and action execution for a custom channel
🌿Good first issues
- Add integration tests for custom channels: The repository has unit test coverage but no E2E tests validating that a TOML channel (e.g., tldr.toml) loads, sources data, filters, and executes actions correctly. New contributor could add test fixtures in tests/ with sample channel TOMLs and mock command outputs.
- Document the television-nucleo fuzzy matching tuning parameters: The crate is used but no docs explain how scoring thresholds, case sensitivity, or gap penalties affect search results. Add a guide in docs/ with examples showing how these parameters change rankings for different data types.
- Implement a
tv completionsubcommand for shell-agnostic completions: Currently shell init scripts are hardcoded per shell. A structured completion system (via clap_complete or similar) would unify zsh/bash/fish/nushell handling and reduce maintenance burden.
⭐Top contributors
Click to expand
Top contributors
- @alexpasmantier — 44 commits
- @github-actions[bot] — 11 commits
- @dependabot[bot] — 5 commits
- @delafthi — 4 commits
- @qaqland — 4 commits
📝Recent commits
Click to expand
Recent commits
8db108d— chore(nix): update flake.lock (#1045) (tukanoidd)8c48b41— chore(deps): bump softprops/action-gh-release from 2 to 3 (#1038) (dependabot[bot])bfc82a2— fix(website): regenerate pnpm-lock.yaml (alexpasmantier)4f092bd— docs(cable): update channel documentation (auto) (#1042) (github-actions[bot])bcc2e35— chore(changelog): update changelog (auto) (#1041) (github-actions[bot])8891e08— fix(cable): separate closing apostrophe from multi-line literal delimiter in opencode-sessions (alexpasmantier)76d5ca3— chore: release version 0.15.6 (alexpasmantier)9e4e61d— fix(actions): fix execute/fork actions when tv runs under shell integration (#998) (lalvarezt)f39c586— test: drop redundant escape send in test_multiple_keybindings_override (alexpasmantier)38e8854— chore(just): cap integration test parallelism at 4 (alexpasmantier)
🔒Security observations
The Television fuzzy finder codebase demonstrates generally good security practices with proper dependency management and no hardcoded secrets detected. However, there are moderate concerns around command execution safety given the nature of the tool (executing commands from various sources via cable channels), and minor issues with dependency configuration (incomplete declaration) and overly permissive feature flags. The biggest risk area is ensuring proper input validation and sanitization across all cable channel implementations to prevent command injection attacks. The codebase would benefit from security-focused input validation, stricter tokio feature specification, and explicit MSRV testing in CI/CD pipelines.
- Medium · Incomplete Dev Dependency Declaration —
Cargo.toml - dev-dependencies section. The dev-dependency 'phantom-test' has an incomplete version specification (missing closing brace). This could cause unpredictable dependency resolution or build failures. While not a direct security vulnerability, it indicates insufficient testing and CI/CD validation. Fix: Complete the dependency declaration: { version = "0.1" } and ensure all dependencies are properly formatted. Run 'cargo check' and 'cargo build' to validate. - Medium · Unsafe External Command Execution Risk —
Dependencies: ureq, walkdir, string_pipeline - used across cable channel definitions. The codebase uses 'ureq' for HTTP requests and appears to be a fuzzy finder that executes commands from multiple sources (cable channels include git commands, docker commands, k8s commands, etc.). This creates potential for command injection if user input or external data isn't properly sanitized. Fix: Implement strict input validation and sanitization for all command execution paths. Use parameterized/safe command construction rather than string interpolation. Audit all cable channel definitions for command injection risks. - Low · Use of
whichCrate for Command Resolution —Cargo.toml - dependencies: which = "8.0". The 'which' crate is used for command resolution. While necessary for CLI tool execution, PATH-based command resolution can be exploited if the PATH environment is manipulated by an attacker. Fix: Validate and restrict the PATH environment variable where possible. Use absolute paths for critical commands when feasible. Document security implications in the configuration guide. - Low · Clipboard Access Without User Consent Indicator —
Cargo.toml - target-specific dependencies for Windows. The dependency 'clipboard-win' is included for Windows targets. Clipboard operations should provide clear user feedback and be performed only with explicit user intent to prevent silent data exfiltration. Fix: Ensure clipboard operations are explicitly triggered by user actions. Log clipboard access events. Consider requiring explicit user confirmation for clipboard operations. - Low · Overly Permissive Tokio Feature Set —
Cargo.toml - dependencies: tokio = { version = "1.48", features = ["full"] }. The tokio dependency uses 'full' features, which includes unnecessary features for a CLI tool (e.g., signal handling, process spawning). This increases the attack surface unnecessarily. Fix: Specify only required tokio features instead of 'full'. Analyze actual usage and include only: ["rt", "io-util", "sync", "time"] or similar minimal subset. - Low · Base64 Encoding Without Context Validation —
Cargo.toml - dependencies: base64 = "0.22". The 'base64' crate is included but without clear indication of its usage context. Base64 is often used for credential or data encoding, which requires careful handling. Fix: Review all base64 encoding/decoding operations. Ensure it's not used for obfuscating sensitive data. Validate decoded data thoroughly before processing. - Low · Missing MSRV Enforcement in CI/CD —
.github/workflows/ci.yml (not fully visible but inferred from structure). While rust-version = "1.90" is declared, the GitHub workflows don't show explicit MSRV testing. This could allow accidental introduction of features requiring newer Rust versions. Fix: Add explicit MSRV testing in CI/CD pipeline: 'cargo +1.90 check' to verify compatibility with declared minimum supported Rust version.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.