A rewrite of sub and tome and my fork of tome but with a different internal implementation in order to support:
- Improved auto-completion
- Improved usage/help outputs
- Faster development
- 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.
- Quick Start
- Your First Script
- Environment Variables
- Features
- Advanced Features
- Troubleshooting
- Documentation
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 fishCreate 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 CLIThe alias approach is recommended because:
- No need to type
--rootevery time - Shorter command names (e.g.,
kitvstome-cli) - Completions work with your custom name
- Can be shared with your team
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
- Must be executable (
chmod +x) - Should include a
USAGE:orSUMMARY: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.
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
- 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
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
--completeinterface withTOME_COMPLETION)
See examples/foo for a working example of script-level completion.
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.
Your scripts can provide their own tab completions for arguments and flags. This creates a seamless user experience:
- Add
TOME_COMPLETIONin a comment in your script - Handle the
--completeflag to output completions - 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
;;
esactome-cli determines the scripts root directory from multiple sources (in order of precedence):
--rootCLI flag- Environment variable named after the executable (e.g.,
PARROT_ROOTif executable isparrot) TOME_ROOTenvironment variable- Current directory (default)
This flexibility allows team members to customize locations without changing the CLI tool itself.
- ✅ 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
- ⏳ ActiveHelp integration for contextual assistance
- ⏳ Pre/post hooks (hooks.d folder execution)
- ⏳ Enhanced directory help (show all subcommands in tree)
- ⏳ Improved completion output filtering
-
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
-
For custom CLI aliases: Use your alias name in the completion command:
# If your alias is 'kit' eval "$(kit completion bash)"
-
After adding completions: Restart your shell or run
source ~/.bashrc(or equivalent) -
Check script permissions: Scripts must be executable (
chmod +x script-name)
-
Verify the script exists and is in the right location:
ls -la "$TOME_ROOT/path/to/script" -
Check if your script is being ignored by
.tomeignore:- Look for a
.tomeignorefile in yourTOME_ROOT - Files matching patterns in
.tomeignorewon't be available as commands - By default, hidden files (starting with
.) are often ignored
- Look for a
-
Ensure the script is executable:
chmod +x ~/my-scripts/script-name -
Use
--debugflag to see what tome-cli is doing:tome-cli --debug --root ~/my-scripts exec script-name
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:orSUMMARY:(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.
To enable argument/flag completion for your script:
- Add
TOME_COMPLETIONanywhere in your script (in a comment) - Implement a
--completeflag that outputs completions - 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
;;
esacSee examples/foo for a complete example.
Make sure:
- Your script is executable:
chmod +x script-name - The script has a valid shebang:
#!/usr/bin/env bash(or python, ruby, etc.) - You have execute permissions on all parent directories
- Quick Start - Get running in minutes
- Your First Script - Create your first script
- Writing Scripts Guide - Comprehensive guide to writing scripts
- Completion Guide - Implement custom tab completions
- Migration Guide - Migrate from original tome/sub
- tome-cli Command Reference - Complete command-line reference
- alias Command - Create custom CLI wrappers
- completion Command - Shell completion setup
- exec Command - Execute scripts
- help Command - Display script help
- examples/ - Working examples of scripts with various features
- examples/foo - Script with custom completions
- examples/.tomeignore - Ignore file example
- CHANGELOG.md - Version history and changes
- Troubleshooting - Common issues and solutions
- Does not support sourcing scripts into shell environment because it adds implementation complexity for other core commands