Skip to content

zph/tome-cli

Repository files navigation

tome-cli

A rewrite of sub and tome and my fork of tome but with a different internal implementation in order to support:

  1. Improved auto-completion
  2. Improved usage/help outputs
  3. Faster development
  4. Testable interfaces

tome-cli transforms a directory of scripts into a unified CLI interface with automatic help generation, tab completion, and support for any programming language.

Table of Contents

Quick Start

Option 1: Direct Usage (Simple)

Use tome-cli directly by pointing it at your scripts directory:

# Execute a script
tome-cli --root ~/my-scripts exec myscript arg1 arg2

# Get help for a script
tome-cli --root ~/my-scripts help myscript

# Enable tab completion for your shell
eval "$(tome-cli completion bash)"   # for bash
eval "$(tome-cli completion zsh)"    # for zsh
tome-cli completion fish | source    # for fish

Option 2: Create a Custom CLI (Recommended)

Create a personalized command that embeds your scripts location:

# Generate a wrapper script called 'kit' that knows about your scripts
tome-cli --root ~/my-scripts --executable kit alias --output ~/bin/kit
chmod +x ~/bin/kit

# Now use your custom command (no need to specify --root anymore)
kit help                    # list all commands
kit myscript arg1 arg2      # run a script
kit completion fish | source  # setup completions for your custom CLI

The alias approach is recommended because:

  • No need to type --root every time
  • Shorter command names (e.g., kit vs tome-cli)
  • Completions work with your custom name
  • Can be shared with your team

Your First Script

Create a simple executable script in your scripts directory:

#!/usr/bin/env bash
# USAGE: hello [name]
# Greets the user by name
#
# Examples:
#   hello Alice
#   hello World

echo "Hello ${1:-World}!"

Make it executable: chmod +x hello

Now run it: tome-cli --root ~/my-scripts exec hello Alice

Script Requirements

  • Must be executable (chmod +x)
  • Should include a USAGE: or SUMMARY: line in a comment for automatic help generation
  • Can be written in any language (bash, python, ruby, node, deno, etc.)
  • Help text is extracted from comments between USAGE:/SUMMARY: and the first blank line

See examples/ directory for more script examples including completion support.

Environment Variables

tome-cli automatically injects these environment variables into your scripts:

Variable Description Example
TOME_ROOT Absolute path to your scripts directory /Users/you/my-scripts
TOME_EXECUTABLE Name of the CLI command being used tome-cli or kit
{NAME}_ROOT Uppercase version of executable name + _ROOT KIT_ROOT (if executable is kit)
{NAME}_EXECUTABLE Uppercase version of executable name + _EXECUTABLE KIT_EXECUTABLE

These are useful for scripts that need to reference other scripts or shared libraries:

#!/usr/bin/env bash
# Load a shared library from your scripts directory
source "$TOME_ROOT/lib/common.sh"

# Reference the CLI name in help text
echo "Usage: $TOME_EXECUTABLE myscript [options]"

See docs for expanded instructions

Features

Core Features

  • Multi-language support: Works with any scripting language (bash, python, ruby, node, deno, etc.) via standard shebang (#!)
  • Automatic help generation: Extracts usage text from USAGE: comments in your scripts
  • Powerful completions: Tab-complete commands, subcommands, and even script-specific arguments/flags
  • Custom CLI creation: Generate personalized CLI commands with embedded configuration via the alias feature
  • Script organization: Organize scripts in directories that become command namespaces
  • Selective execution: Use .tomeignore (gitignore-like syntax) to control which scripts are exposed example

Auto-Completion Features

tome-cli provides intelligent tab completion for:

  • Built-in subcommands (exec, help, completion, etc.)
  • Directory names in your scripts folder
  • Script names in your scripts folder
  • Script-specific flags and arguments (when scripts implement the --complete interface with TOME_COMPLETION)

See examples/foo for a working example of script-level completion.

Advanced Features

.tomeignore File

Control which scripts are exposed as commands using a .tomeignore file in your scripts root directory. It uses gitignore-like syntax:

# Ignore all TypeScript source files (if you have compiled versions)
*.ts

# Ignore hidden files
.*

# Ignore specific scripts
folder/executable-ignored

See examples/.tomeignore for a working example.

Script-Level Completions

Your scripts can provide their own tab completions for arguments and flags. This creates a seamless user experience:

  1. Add TOME_COMPLETION in a comment in your script
  2. Handle the --complete flag to output completions
  3. Format: one completion per line as value<TAB>description

Example from examples/foo:

#!/usr/bin/env bash
# TOME_COMPLETION

case $1 in
  --complete)
    echo -e "--help\tShow help message"
    echo -e "--verbose\tEnable verbose output"
    echo -e "start\tStart the service"
    ;;
  *)
    # Normal script logic
    ;;
esac

Flexible Root Detection

tome-cli determines the scripts root directory from multiple sources (in order of precedence):

  1. --root CLI flag
  2. Environment variable named after the executable (e.g., PARROT_ROOT if executable is parrot)
  3. TOME_ROOT environment variable
  4. Current directory (default)

This flexibility allows team members to customize locations without changing the CLI tool itself.

Development Status

Implemented

  • ✅ Execute scripts from any directory structure
  • ✅ Auto-complete script names with descriptions
  • ✅ Cross-platform compilation via goreleaser
  • ✅ E2E test harness with deno
  • ✅ Backwards compatibility with original tome
  • ✅ Custom CLI aliasing
  • ✅ .gitignore-style file filtering
  • ✅ Script-level argument completion
  • ✅ Environment variable injection
  • ✅ Structured logging with levels
  • ✅ Generated documentation

Planned

  • ⏳ ActiveHelp integration for contextual assistance
  • ⏳ Pre/post hooks (hooks.d folder execution)
  • ⏳ Enhanced directory help (show all subcommands in tree)
  • ⏳ Improved completion output filtering

Troubleshooting

Completions not working

  1. For direct tome-cli usage: Make sure you've added the completion script to your shell's rc file:

    # Add to ~/.bashrc or ~/.bash_profile
    eval "$(tome-cli completion bash)"
    
    # Add to ~/.zshrc
    eval "$(tome-cli completion zsh)"
    
    # Add to ~/.config/fish/config.fish
    tome-cli completion fish | source
  2. For custom CLI aliases: Use your alias name in the completion command:

    # If your alias is 'kit'
    eval "$(kit completion bash)"
  3. After adding completions: Restart your shell or run source ~/.bashrc (or equivalent)

  4. Check script permissions: Scripts must be executable (chmod +x script-name)

Script not found

  1. Verify the script exists and is in the right location:

    ls -la "$TOME_ROOT/path/to/script"
  2. Check if your script is being ignored by .tomeignore:

    • Look for a .tomeignore file in your TOME_ROOT
    • Files matching patterns in .tomeignore won't be available as commands
    • By default, hidden files (starting with .) are often ignored
  3. Ensure the script is executable:

    chmod +x ~/my-scripts/script-name
  4. Use --debug flag to see what tome-cli is doing:

    tome-cli --debug --root ~/my-scripts exec script-name

Help text not showing / "USAGE:" or "SUMMARY:" not being parsed

The help parser looks for a USAGE: or SUMMARY: comment near the top of your script:

#!/usr/bin/env bash
# USAGE: myscript <arg1> [arg2]
# This is the help text
# It continues until the first blank line
#
# This line won't be included (after blank line)

Requirements:

  • Must use exactly USAGE: or SUMMARY: (case-sensitive, with colon)
  • Should be in a comment within the first ~20 lines
  • Help text continues from the line after USAGE:/SUMMARY: until first blank line
  • Works in any language that supports # or // comments

Note: USAGE: is recommended for new scripts. SUMMARY: is supported for backward compatibility with original tome.

Tab completion not suggesting arguments

To enable argument/flag completion for your script:

  1. Add TOME_COMPLETION anywhere in your script (in a comment)
  2. Implement a --complete flag that outputs completions
  3. Format: completion<TAB>description\n

Example:

#!/usr/bin/env bash
# TOME_COMPLETION

case $1 in
  --complete)
    echo -e "--help\tShow help message"
    echo -e "--verbose\tEnable verbose output"
    echo -e "start\tStart the service"
    echo -e "stop\tStop the service"
    ;;
  *)
    # Your script logic here
    ;;
esac

See examples/foo for a complete example.

Permission denied errors

Make sure:

  1. Your script is executable: chmod +x script-name
  2. The script has a valid shebang: #!/usr/bin/env bash (or python, ruby, etc.)
  3. You have execute permissions on all parent directories

Documentation

Getting Started

Core Documentation

Examples

Additional Resources

Non Features

  • Does not support sourcing scripts into shell environment because it adds implementation complexity for other core commands

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published