piotrmurach/tty
Toolkit for developing sleek command line apps.
Healthy across all four use cases
Permissive 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.
- ✓8 active contributors
- ✓MIT licensed
- ✓CI configured
Show 3 more →Show less
- ✓Tests present
- ⚠Stale — last commit 3y ago
- ⚠Single-maintainer risk — top contributor 87% of recent commits
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/piotrmurach/tty)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/piotrmurach/tty on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: piotrmurach/tty
Generated by RepoPilot · 2026-05-10 · 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/piotrmurach/tty 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 all four use cases
- 8 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 3y ago
- ⚠ Single-maintainer risk — top contributor 87% of recent commits
<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 piotrmurach/tty
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/piotrmurach/tty.
What it runs against: a local clone of piotrmurach/tty — 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 piotrmurach/tty | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 1256 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of piotrmurach/tty. If you don't
# have one yet, run these first:
#
# git clone https://github.com/piotrmurach/tty.git
# cd tty
#
# 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 piotrmurach/tty and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "piotrmurach/tty(\\.git)?\\b" \\
&& ok "origin remote is piotrmurach/tty" \\
|| miss "origin remote is not piotrmurach/tty (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 master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lib/tty.rb" \\
&& ok "lib/tty.rb" \\
|| miss "missing critical file: lib/tty.rb"
test -f "lib/tty/cli.rb" \\
&& ok "lib/tty/cli.rb" \\
|| miss "missing critical file: lib/tty/cli.rb"
test -f "lib/tty/cmd.rb" \\
&& ok "lib/tty/cmd.rb" \\
|| miss "missing critical file: lib/tty/cmd.rb"
test -f "lib/tty/commands/new.rb" \\
&& ok "lib/tty/commands/new.rb" \\
|| miss "missing critical file: lib/tty/commands/new.rb"
test -f "lib/tty/commands/add.rb" \\
&& ok "lib/tty/commands/add.rb" \\
|| miss "missing critical file: lib/tty/commands/add.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1256 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1226d)"
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/piotrmurach/tty"
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
TTY is a Ruby metaprojekt/toolkit that provides modular components for building sophisticated command-line applications. It includes a CLI scaffolding tool (teletype), a unified command/plugin system, and a generator that creates new CLI projects with templating support for multiple testing frameworks. The core problem it solves: eliminating boilerplate when developers want to build terminal UIs with structured commands, prompts, and consistent project layout. Monolithic package containing: CLI generator at lib/tty/cli.rb and lib/tty/commands/ (new/add commands), a plugin system at lib/tty/plugins/, and bundled ERB templates under lib/tty/templates/ for scaffolding new projects. The exe/teletype executable is the entry point. Core library at lib/tty.rb coordinates the whole toolkit.
👥Who it's for
Ruby developers building command-line tools, CLIs, and terminal applications who want to avoid reinventing input/output handling, command routing, and project structure. Specifically: DevOps tool builders, system utility authors, and anyone shipping interactive shell applications in Ruby.
🌱Maturity & risk
Actively maintained but niche maturity level. The repo shows comprehensive test coverage, GitHub Actions CI/CD setup (see .github/workflows/ci.yml), established conventions (.editorconfig, .rubocop.yml), and structured documentation. However, visible commit recency and issue/PR activity are not shown in provided data. The project predates modern JS tooling (established Ruby focus) suggesting production-readiness for its target audience.
Low risk for the Ruby CLI niche, but consider: single-maintainer pattern (piotrmurach) without visible secondary maintainers, metaproject status means many interdependent tty-* gems not visible in this repo, and reliance on Ruby ecosystem (version constraints unclear from file list). Breaking changes would cascade across dependent tty-* packages. No vendored dependencies visible, suggesting external gem dependency chain.
Active areas of work
The repo appears to be in maintenance mode—file structure is mature and complete (new/add command templates are fully populated with spec and test variants). CHANGELOG.md would show recent work, but specific recent commits/PRs are not provided in the data. The project seems feature-complete for scaffolding and command generation workflows.
🚀Get running
Clone and bundle: git clone https://github.com/piotrmurach/tty.git && cd tty && bundle install. Run tests with bundle exec rake or bundle exec rspec (.rspec config present). Try the generator: bundle exec exe/teletype new my_app.
Daily commands:
No traditional 'server' to run. Invoke CLI: bundle exec exe/teletype new project_name generates a new scaffolded project. Run tests on tty itself: bundle exec rake test or bundle exec rspec spec/.
🗺️Map of the codebase
lib/tty.rb— Main entry point that loads the entire TTY toolkit and exposes the public API for CLI development.lib/tty/cli.rb— Core CLI orchestrator that processes commands and delegates to command handlers; essential for understanding command routing.lib/tty/cmd.rb— Base command class that all CLI commands inherit from; defines the contract for command behavior and execution.lib/tty/commands/new.rb— Generator for new TTY-based CLI projects; demonstrates the templating and plugin system in action.lib/tty/commands/add.rb— Generator for adding new commands to existing TTY projects; shows how the toolkit scaffolds subcommands.lib/tty/templater.rb— Template engine that processes ERB templates for code generation; critical for the scaffold system.lib/tty/plugins.rb— Plugin system loader that enables third-party extensions; defines the extensibility architecture.
🧩Components & responsibilities
- CLI Router (lib/tty/cli.rb) (Ruby, OptionParser) — Parses command-line arguments and routes to appropriate command class; activates plugins
- Failure mode: Unrecognized commands fall through; plugin activation errors abort the CLI
- Command Classes (lib/tty/cmd.rb, commands/*.rb) (Ruby, File I/O) — Execute generation logic; validate inputs; orchestrate templater and file writes
- Failure mode: Invalid inputs or template errors raise exceptions; partial writes may leave corrupt projects
- Templater (lib/tty/templater.rb) (Ruby ERB) — Loads ERB templates and renders them with provided variables; writes to output directory
- Failure mode: Missing templates or rendering errors propagate; no partial rollback
- Plugin System (lib/tty/plugins.rb, plugin.rb) (Ruby require/load, introspection) — Discovers, loads, and activates plugins that extend TTY command sets
- Failure mode: Plugin load errors abort CLI; no isolation between plugin side effects
🔀Data flow
User shell→tty CLI executable— Command-line arguments (e.g., new/add subcommand, project name)CLI Router→Command classes— Parsed options and positional argumentsCommand classes→Templater— Template directory path, variable bindings (project name, author, license, etc.)Templater→Template files (lib/tty/templates/new or add)— Template file paths; returns rendered contentTemplater→File System— Rendered source code written to target directoriesPlugin System→CLI Router— Loaded plugins register additional commands and options
🛠️How to make changes
Generate a new TTY-based CLI project
- User runs
tty new myappwhich invokes the CLI dispatcher (lib/tty/cli.rb) - CLI routes to the NewCommand handler (
lib/tty/commands/new.rb) - Command instantiates Templater with template directory and target paths (
lib/tty/templater.rb) - Templater processes .tt ERB files from lib/tty/templates/new/ (
lib/tty/templates/new) - Generated project includes CLI structure, gemspec, and license templates (
lib/tty/templates/new/lib/newcli/cli.rb.tt)
Add a new command to an existing TTY project
- User runs
tty add mycmdfrom their TTY project directory (lib/tty/cli.rb) - CLI routes to AddCommand which resolves project structure (
lib/tty/commands/add.rb) - AddCommand uses PathHelpers to locate lib and spec directories (
lib/tty/path_helpers.rb) - Templater processes command templates from lib/tty/templates/add/ (
lib/tty/templates/add/command.rb.tt) - Generated command file and test files are written to the project (
lib/tty/templates/add/spec/integration/command_spec.rb.tt)
Create and activate a custom plugin for TTY
- Create a Ruby gem that requires 'tty/plugin' interface (
lib/tty/plugins/plugin.rb) - Plugin defines activate method that modifies TTY behavior or adds commands (
lib/tty/plugins/plugin.rb) - TTY loads plugins from registered directories at startup (
lib/tty/plugins.rb) - CLI instance invokes activate on all loaded plugins before command dispatch (
lib/tty/cli.rb)
🔧Why these technologies
- Ruby + ERB Templates — Provides rapid scaffolding and code generation with minimal dependencies; ERB is built-in to Ruby
- Plugin Architecture — Enables third-party extensions without modifying core; allows domain-specific command packs
- File-based Gemspec Parsing — Inspects generated gemspec files to validate dependencies and metadata without running untrusted code
⚖️Trade-offs already made
-
Scaffold-based code generation vs runtime framework
- Why: Scaffolding generates starter code once; users own and modify it independently
- Consequence: Generated projects don't inherit bug fixes from TTY automatically; requires manual dependency updates
-
Plugin system via require/activate vs declarative configuration
- Why: Activate pattern allows plugins full control over TTY behavior at runtime
- Consequence: Plugins can conflict with each other; no dependency resolution mechanism between plugins
-
ERB templates as source of truth vs Ruby DSL
- Why: ERB templates are simple, readable, and require no special abstractions
- Consequence: Complex variable interpolation in templates becomes hard to test and maintain
🚫Non-goals (don't propose these)
- Does not provide a runtime framework for executing generated CLIs (that is the user's domain)
- Does not manage dependencies automatically; users must run bundle install themselves
- Does not handle authentication, authorization, or security concerns in generated apps
- Does not provide remote deployment or cloud integration
🪤Traps & gotchas
No major traps visible in file list alone. Likely gotchas (inferred): template rendering assumes Ruby 2.3+ ERB availability; gemspec_dependency.rb suggests complex dependency resolution logic that may have version conflict edge cases; the separate spec and test templates imply users must choose RSpec vs Minitest at generation time with no easy migration. Verify Ruby version requirements in Gemfile and .github/workflows/ci.yml (not fully shown). The .yardopts suggests documentation generation—ensure yard gem is in development dependencies.
🏗️Architecture
💡Concepts to learn
- Template-based Code Generation (ERB metaprogramming) — This repo's entire value prop is generating boilerplate code from .tt templates—understanding ERB context, variable injection, and template composition is core to modifying or extending the scaffolder.
- Plugin Architecture / Lazy Loading — lib/tty/plugins/ implements a plugin system for tty-* components to register themselves; understanding how plugins hook into the generator is essential for extending the toolkit.
- Command Dispatcher / Routing — lib/tty/cmd.rb and lib/tty/cli.rb implement a custom command router similar to Rails routing; understanding this pattern is key to adding new scaffolding commands.
- Monorepo / Metapackage Pattern — This repo is a metapackage that depends on and orchestrates many tty-* packages; understanding how to declare and interact with semantic siblings is important for maintenance.
- Gemspec-driven Dependency Management — lib/tty/gemspec.rb and lib/tty/gemspec_dependency.rb parse and generate .gemspec files for scaffolded projects; understanding Ruby's gem dependency DSL is critical for generators.
- Test Template Duality (RSpec vs Minitest) — The generator maintains parallel spec and test template trees (lib/tty/templates/add/spec/ vs test/) allowing users to choose test framework; this dual-path approach is a non-obvious design pattern worth understanding.
- Unix CLI Conventions & Exit Codes — TTY scaffolds Unix-philosophy CLIs; understanding POSIX argument parsing, exit codes, and signal handling is assumed knowledge for anyone building generators in this space.
🔗Related repos
piotrmurach/tty-prompt— Companion tty-* component for interactive user prompts/input, installed and used by projects scaffolded by this generator.piotrmurach/tty-command— Companion tty-* component for executing external commands with structured output, often used in generated CLI projects.piotrmurach/tty-table— Companion tty-* component for formatted table output, frequently used in CLI tools scaffolded by this toolkit.davetron5000/gli— Alternative Ruby CLI scaffolding framework that solves the same problem (command routing, code generation) in the same ecosystem.erikhuda/thor— More widely-used Ruby CLI framework (Rails use) with similar scaffolding and command routing, main competitor in Ruby space.
🪄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 integration tests for tty/commands/add.rb
The lib/tty/commands/add.rb file implements the 'add' command for scaffolding new CLI commands, but there are no corresponding integration tests in spec/ that verify the actual file generation and template rendering. This is critical because the command generates boilerplate code with multiple template variations (RSpec vs Test::Unit, unit vs integration specs). Adding tests would prevent regressions when templates are modified.
- [ ] Create spec/integration/commands/add_spec.rb to test the add command end-to-end
- [ ] Verify that lib/tty/templates/add/command.rb.tt, namespace.rb.tt, and all spec templates render correctly
- [ ] Test both RSpec and Test::Unit output paths (currently template variants exist but untested)
- [ ] Validate generated file structure matches expectations for nested command namespaces
Add comprehensive integration tests for tty/commands/new.rb
The lib/tty/commands/new.rb file scaffolds entire new CLI projects with license selection (7 different license templates), but has no integration test coverage. Given the complexity of license template selection and multi-file generation, this is a high-risk area prone to regression. The templates exist (agplv3, apache, bsd2, bsd3, gplv2, gplv3, lgplv3, mit, mplv2) but are untested.
- [ ] Create spec/integration/commands/new_spec.rb to test full project scaffolding
- [ ] Test each license type (MIT, Apache, GPL variants, BSD variants, AGPL, MPL) generates the correct LICENSE.txt file
- [ ] Verify directory structure is created correctly (lib/newcli/cli.rb.tt, exe/newcli.tt, etc.)
- [ ] Test that the generated CLI skeleton is valid Ruby and follows the expected structure
Extract and unit test lib/tty/gemspec.rb and lib/tty/gemspec_dependency.rb
These files (lib/tty/gemspec.rb and lib/tty/gemspec_dependency.rb) handle parsing and validation of gemspec metadata, which is critical infrastructure used by the 'add' and 'new' commands. Currently there are no unit tests for these modules. Adding focused unit tests would ensure robust gemspec parsing and prevent silent failures when dependencies are added or modified.
- [ ] Create spec/unit/gemspec_spec.rb to test lib/tty/gemspec.rb methods
- [ ] Create spec/unit/gemspec_dependency_spec.rb to test lib/tty/gemspec_dependency.rb
- [ ] Test gemspec parsing with the fixture at spec/fixtures/foo-0.0.1.gemspec
- [ ] Test edge cases: missing fields, malformed dependencies, version constraints
🌿Good first issues
- Add examples or integration tests that exercise the full 'teletype new → teletype add → run generated specs' workflow end-to-end in lib/tty/templates/ or spec/integration/ directory.
- Document the template variable interpolation API: which ERB variables are available in .tt files under lib/tty/templates/new/ and lib/tty/templates/add/ (lib/tty/templater.rb context is unclear).
- Expand lib/tty/licenses.rb to support modern SPDX license codes (e.g., Apache-2.0, MPL-2.0) beyond the agplv3_LICENSE.txt.tt example visible in templates.
⭐Top contributors
Click to expand
Top contributors
- @piotrmurach — 87 commits
- @slowbro — 5 commits
- @rodrigovilina — 3 commits
- @d3mash — 1 commits
- @pjezusek — 1 commits
📝Recent commits
Click to expand
Recent commits
93ab5fe— Add changelog entry requirement to pull request template (piotrmurach)6e05a12— Change test to match text wrapping in the latest thor release (piotrmurach)0a63fb8— Add tty-progressbar to the list of tty gems in a generated gemspec (piotrmurach)8fb33ba— Add Ruby 3.0 and set timeout for test run in CI workflow (piotrmurach)1ab96b1— Change to update tty-box to the latest release (piotrmurach)e3536f9— Change CI workflow to allow failure on jruby (piotrmurach)785f572— Change to update tty-prompt to the latest release (piotrmurach)95d88d5— Fix tests to work on Ruby 3.0 with Bundler 2.2.0 (piotrmurach)5c5d492— Change to update tty-logger to the latest release (piotrmurach)e616111— Change appveyor config to allow failures due to rubygems SSL cert error (piotrmurach)
🔒Security observations
The TTY toolkit is a CLI application generator with moderate security considerations. The primary concerns involve template injection risks, potential command injection in generated code or CLI execution, and path traversal vulnerabilities in file operations. The project demonstrates good practices with CI/CD pipeline setup and code quality monitoring, but lacks visible evidence of strict input validation in critical areas. No hardcoded credentials or obvious misconfigurations were detected in the provided file structure. Recommendations focus on input sanitization, safe command execution patterns, and dependency monitoring.
- Medium · Template Injection Risk in Code Generation —
lib/tty/templater.rb, lib/tty/templates/. The codebase uses ERB templating (*.tt files) for code generation. Templates in lib/tty/templates/ are used to generate CLI applications. If user input is not properly sanitized before being passed to templates, this could lead to arbitrary code injection in generated applications. Fix: Validate and sanitize all user inputs (project names, namespaces, descriptions) before passing them to template rendering. Use allowlists for valid characters in identifiers. - Medium · Potential Command Injection in Command Execution —
lib/tty/cmd.rb, lib/tty/cli.rb. The CLI tool appears to execute system commands (exe/teletype, lib/tty/cmd.rb). If user-provided arguments are passed to system calls without proper escaping, this could lead to command injection vulnerabilities. Fix: Use safe methods for command execution (e.g., Kernel.system with array syntax or Open3 module) instead of shell interpolation. Always pass arguments as arrays to avoid shell interpretation. - Low · Missing Input Validation on File Operations —
lib/tty/path_helpers.rb, lib/tty/commands/new.rb, lib/tty/commands/add.rb. File path operations in lib/tty/path_helpers.rb and template processing may be vulnerable to path traversal if user input containing '../' or absolute paths is not validated. Fix: Implement strict path validation to prevent directory traversal attacks. Use File.expand_path and verify the result is within expected directories. Sanitize all user-provided path components. - Low · Dependency Management Without Lock File Visibility —
Gemfile, Gemfile.lock (missing). The Gemfile is present but there is no Gemfile.lock visible in the repository structure. This makes it difficult to track exact dependency versions and potential vulnerabilities. Fix: Ensure Gemfile.lock is committed to version control. Use 'bundle audit' or similar tools to regularly scan dependencies for known vulnerabilities. Consider using Dependabot for automated updates. - Low · Potential Insecure YAML Deserialization —
lib/tty/gems.yml. The presence of lib/tty/gems.yml suggests YAML file parsing. Unsafe YAML deserialization could lead to arbitrary code execution if untrusted YAML content is loaded. Fix: Use YAML.safe_load() instead of YAML.load() when parsing YAML files. Specify allowed_classes and aliases: false for restricted deserialization.
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.