Add documentation to the commands for the CLI

This commit is contained in:
2026-05-04 12:14:40 +00:00
parent 8d7856f32e
commit 3c47ee8a4c
11 changed files with 480 additions and 55 deletions

View File

@@ -23,7 +23,6 @@ import {
existsSync,
readFileSync,
appendFileSync,
writeFileSync,
} from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

View File

@@ -1,7 +1,16 @@
# bash completion for {{BIN_NAME}}
# Add to ~/.bashrc: eval "$({{BIN_NAME}} completions bash)"
# ------------------------------------------------------------------------------
# Bash completion template for {{BIN_NAME}}
# ------------------------------------------------------------------------------
# Installation:
# eval "$({{BIN_NAME}} completions bash)"
#
# This file is generated from a template. Placeholders (for example `{{OPTIONS}}`)
# are replaced at build/runtime with concrete command data from the CLI.
# ------------------------------------------------------------------------------
# Find xo-complete in the same directory as xo-cli
# Prefer a globally-installed helper, but fall back to a helper co-located with
# the CLI binary. This lets completions work in both "installed via PATH" and
# "single extracted directory" workflows.
__xo_complete_bin=""
if command -v xo-complete &>/dev/null; then
__xo_complete_bin="xo-complete"
@@ -9,16 +18,28 @@ elif command -v {{BIN_NAME}} &>/dev/null; then
__xo_complete_bin="$(dirname "$(command -v {{BIN_NAME}})")/xo-complete"
fi
# Wrapper to call xo-complete helper
# @description
# Calls the dynamic completion helper and suppresses helper stderr so the shell
# completion menu stays clean even when the helper is unavailable or errors.
# @param "$@" Arguments forwarded to xo-complete.
__xo_complete() {
[[ -n "${__xo_complete_bin}" ]] && "${__xo_complete_bin}" "$@" 2>/dev/null
}
# @description
# Main completion dispatcher invoked by bash's `complete -F`.
# It determines context (command/subcommand/argument position) and then mixes:
# - static completions (known command words)
# - dynamic completions (resolved by xo-complete)
# - filesystem completions (when a subcommand expects file paths)
_{{FUNC_NAME}}_completions() {
local cur prev words cword
# Populates `cur`, `prev`, `words`, and `cword`.
# `_init_completion` is provided by bash-completion.
_init_completion || return
# Handle -m/--mnemonic-file argument (previous word was -m)
# If the previous token is `-m/--mnemonic-file`, this argument expects a
# mnemonic file alias/path. Ask the helper for mnemonic suggestions.
if [[ "${prev}" == "-m" || "${prev}" == "--mnemonic-file" ]]; then
local mnemonics
mnemonics=$(__xo_complete mnemonics "${cur}")
@@ -30,13 +51,14 @@ _{{FUNC_NAME}}_completions() {
fi
fi
# If the current word starts with "-", offer option flags
# Option context: show global options when the current token starts with `-`.
if [[ "${cur}" == -* ]]; then
COMPREPLY=($(compgen -W "{{OPTIONS}}" -- "${cur}"))
return 0
fi
# Find the command and subcommand positions
# Parse command/subcommand from non-option tokens before the current cursor.
# We track indices so argument-position logic can be computed later.
local cmd="" subcmd="" cmd_idx=0 subcmd_idx=0
for ((i=1; i < cword; i++)); do
if [[ "${words[i]}" != -* ]]; then
@@ -51,13 +73,13 @@ _{{FUNC_NAME}}_completions() {
fi
done
# No command yet — offer the top-level commands
# No command selected yet: complete top-level commands.
if [[ -z "${cmd}" ]]; then
COMPREPLY=($(compgen -W "{{COMMANDS}}" -- "${cur}"))
return 0
fi
# Handle each command's completion
# Command-specific completion rules.
case "${cmd}" in
mnemonic)
if [[ -z "${subcmd}" ]]; then
@@ -69,7 +91,9 @@ _{{FUNC_NAME}}_completions() {
if [[ -z "${subcmd}" ]]; then
COMPREPLY=($(compgen -W "{{TEMPLATE_SUBS}}" -- "${cur}"))
elif [[ "${subcmd}" == "list" || "${subcmd}" == "inspect" ]]; then
# template list/inspect <category> <template> [field] - category first, then template, then field
# template list/inspect <category> <template> [field]
# Position is computed relative to the subcommand token:
# 1 => category, 2 => template, 3 => field (inspect only)
local pos=$((cword - subcmd_idx))
if [[ $pos -eq 1 ]]; then
COMPREPLY=($(compgen -W "action transaction output lockingscript variable" -- "${cur}"))
@@ -82,7 +106,7 @@ _{{FUNC_NAME}}_completions() {
done <<< "${templates}"
fi
elif [[ $pos -eq 3 && "${subcmd}" == "inspect" ]]; then
# Get the category and template from previous args
# Field names depend on both selected category and template.
local category="${words[subcmd_idx + 1]}"
local template_arg="${words[subcmd_idx + 2]}"
local fields
@@ -94,7 +118,8 @@ _{{FUNC_NAME}}_completions() {
fi
fi
elif [[ "${subcmd}" == "set-default" ]]; then
# template set-default <template> <output> <role> - template first
# template set-default <template> <output> <role>
# We only complete the first positional argument (template) here.
local pos=$((cword - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local templates
@@ -114,7 +139,8 @@ _{{FUNC_NAME}}_completions() {
else
case "${subcmd}" in
create)
# invitation create <template> <action> - offer templates then actions
# invitation create <template> <action>
# The available actions depend on the selected template.
local pos=$((cword - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local templates
@@ -136,7 +162,7 @@ _{{FUNC_NAME}}_completions() {
fi
;;
append|sign|broadcast|requirements|inspect)
# These take an invitation ID
# These subcommands expect an invitation identifier as first arg.
local pos=$((cword - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local invitations
@@ -149,7 +175,7 @@ _{{FUNC_NAME}}_completions() {
fi
;;
import)
# import takes a file path - use default file completion
# File import path: delegate to bash's built-in file completion.
COMPREPLY=($(compgen -f -- "${cur}"))
;;
esac
@@ -160,7 +186,8 @@ _{{FUNC_NAME}}_completions() {
if [[ -z "${subcmd}" ]]; then
COMPREPLY=($(compgen -W "{{RESOURCE_SUBS}}" -- "${cur}"))
elif [[ "${subcmd}" == "unreserve" ]]; then
# resource unreserve <txhash:vout> - offer resources
# resource unreserve <txhash:vout>
# Suggest known reserved outpoints from the helper.
local pos=$((cword - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local resources
@@ -175,7 +202,8 @@ _{{FUNC_NAME}}_completions() {
;;
receive)
# receive <template> [output] - offer templates
# receive <template> [output]
# Template is the first positional argument after `receive`.
local pos=$((cword - cmd_idx))
if [[ $pos -eq 1 ]]; then
local templates
@@ -189,6 +217,7 @@ _{{FUNC_NAME}}_completions() {
;;
completions)
# Shell target for generating completion scripts.
if [[ -z "${subcmd}" ]]; then
COMPREPLY=($(compgen -W "bash zsh fish" -- "${cur}"))
fi
@@ -196,4 +225,5 @@ _{{FUNC_NAME}}_completions() {
esac
}
# Register the completion function for the CLI binary.
complete -F _{{FUNC_NAME}}_completions {{BIN_NAME}}

View File

@@ -1,11 +1,21 @@
# fish completion for {{BIN_NAME}}
# Add to fish config: {{BIN_NAME}} completions fish | source
# ------------------------------------------------------------------------------
# Fish completion template for {{BIN_NAME}}
# ------------------------------------------------------------------------------
# Installation:
# {{BIN_NAME}} completions fish | source
#
# This file is generated from a template. Placeholders (for example
# `{{TOP_LEVEL_COMMANDS}}`) are replaced with concrete completion definitions.
# ------------------------------------------------------------------------------
# Disable file completions by default
# Fish offers file completion by default. Disable that globally first so command
# words are preferred, then selectively re-enable `-F` where paths are expected.
complete -c {{BIN_NAME}} -f
# Helper function to get dynamic completions
# Finds xo-complete in the same directory as {{BIN_NAME}}
# @description
# Resolves and calls `xo-complete` for dynamic values (templates, invitations,
# fields, etc.). We first try PATH, then a helper next to `{{BIN_NAME}}`.
# @param $argv Arguments forwarded directly to xo-complete.
function __{{FUNC_NAME}}_complete_dynamic
set -l xo_complete_bin ""
if command -q xo-complete
@@ -18,7 +28,7 @@ function __{{FUNC_NAME}}_complete_dynamic
end
end
# Global options
# Global option flags available across top-level command contexts.
complete -c {{BIN_NAME}} -s h -d "Show help"
complete -c {{BIN_NAME}} -l help -d "Show help"
complete -c {{BIN_NAME}} -s v -d "Verbose output"
@@ -26,45 +36,61 @@ complete -c {{BIN_NAME}} -l verbose -d "Verbose output"
complete -c {{BIN_NAME}} -s o -d "Output file"
complete -c {{BIN_NAME}} -l output -d "Output file"
# Dynamic mnemonic file completion for -m
# Dynamic completion for `-m/--mnemonic-file`.
complete -c {{BIN_NAME}} -s m -l mnemonic-file -xa '(__{{FUNC_NAME}}_complete_dynamic mnemonics)'
# Top-level commands
# Top-level command registrations inserted by template expansion.
{{TOP_LEVEL_COMMANDS}}
# Static sub-commands
# Static subcommand registrations inserted by template expansion.
{{STATIC_SUBCOMMANDS}}
# Dynamic completions
# ---------------------------------------------------------------------------
# Dynamic completions by command/subcommand.
#
# Fish condition notes:
# - `__fish_seen_subcommand_from <name>` checks whether `<name>` exists in the
# current tokenized command line.
# - `count (commandline -opc)` returns how many tokens were entered.
# We use this to infer positional argument index.
# ---------------------------------------------------------------------------
# invitation create: template names
# invitation create <template> <action>
# Position 3 => template argument.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from create; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic templates)'
# invitation create: action names (2nd arg)
# invitation create <template> <action>
# Position 4 => action argument, filtered by selected template token.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from create; and test (count (commandline -opc)) -eq 4" -xa '(__{{FUNC_NAME}}_complete_dynamic actions (commandline -opc)[4])'
# invitation append/sign/broadcast/requirements/inspect: invitation IDs
# invitation append/sign/broadcast/requirements/inspect <invitation-id>
# Position 3 => invitation identifier.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from append; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic invitations)'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from sign; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic invitations)'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from broadcast; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic invitations)'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from requirements; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic invitations)'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from inspect; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic invitations)'
# invitation import: file completion
# invitation import <path>
# Re-enable default filesystem completion for path argument.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from invitation; and __fish_seen_subcommand_from import" -F
# template list/inspect: category first (pos 3), then template (pos 4), then field (pos 5 for inspect)
# template list/inspect <category> <template> [field]
# Position 3 => category, 4 => template, 5 => field (inspect only).
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from template; and __fish_seen_subcommand_from list; and test (count (commandline -opc)) -eq 3" -xa 'action transaction output lockingscript variable'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from template; and __fish_seen_subcommand_from list; and test (count (commandline -opc)) -eq 4" -xa '(__{{FUNC_NAME}}_complete_dynamic templates)'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from template; and __fish_seen_subcommand_from inspect; and test (count (commandline -opc)) -eq 3" -xa 'action transaction output lockingscript variable'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from template; and __fish_seen_subcommand_from inspect; and test (count (commandline -opc)) -eq 4" -xa '(__{{FUNC_NAME}}_complete_dynamic templates)'
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from template; and __fish_seen_subcommand_from inspect; and test (count (commandline -opc)) -eq 5" -xa '(__{{FUNC_NAME}}_complete_dynamic fields (commandline -opc)[4] (commandline -opc)[5])'
# template set-default: template first
# template set-default <template> <output> <role>
# Position 3 => template argument.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from template; and __fish_seen_subcommand_from set-default; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic templates)'
# resource unreserve: UTXO outpoints
# resource unreserve <txhash:vout>
# Position 3 => outpoint to unreserve.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from resource; and __fish_seen_subcommand_from unreserve; and test (count (commandline -opc)) -eq 3" -xa '(__{{FUNC_NAME}}_complete_dynamic resources)'
# receive: template names
# receive <template> [output]
# Position 2 => template argument.
complete -c {{BIN_NAME}} -n "__fish_seen_subcommand_from receive; and test (count (commandline -opc)) -eq 2" -xa '(__{{FUNC_NAME}}_complete_dynamic templates)'

View File

@@ -1,7 +1,15 @@
# zsh completion for {{BIN_NAME}}
# Add to ~/.zshrc: eval "$({{BIN_NAME}} completions zsh)"
# ------------------------------------------------------------------------------
# Zsh completion template for {{BIN_NAME}}
# ------------------------------------------------------------------------------
# Installation:
# eval "$({{BIN_NAME}} completions zsh)"
#
# This file is generated from a template. Placeholders (for example
# `{{MNEMONIC_SUBS}}`) are replaced with concrete command values.
# ------------------------------------------------------------------------------
# Find xo-complete in the same directory as xo-cli
# Prefer a helper on PATH; otherwise fall back to helper next to the CLI binary.
# This keeps dynamic completion functional in both installed and portable layouts.
__xo_complete_bin=""
if (( $+commands[xo-complete] )); then
__xo_complete_bin="xo-complete"
@@ -9,16 +17,25 @@ elif (( $+commands[{{BIN_NAME}}] )); then
__xo_complete_bin="${commands[{{BIN_NAME}}]:h}/xo-complete"
fi
# Wrapper to call xo-complete helper
# @description
# Calls the dynamic helper while silencing helper stderr to avoid noisy
# completion menus if helper lookup fails.
# @param "$@" Arguments forwarded to xo-complete.
__xo_complete() {
[[ -n "${__xo_complete_bin}" ]] && "${__xo_complete_bin}" "$@" 2>/dev/null
}
# @description
# Main zsh completion dispatcher registered via `compdef`.
# It resolves command context from `$words`/`$CURRENT` and serves:
# - static command words via `compadd`
# - dynamic values from `xo-complete`
# - filesystem completions where file paths are expected
_{{FUNC_NAME}}_completions() {
local -a commands
commands=({{COMMANDS}})
# Handle -m/--mnemonic-file argument (previous word was -m)
# If previous token is `-m/--mnemonic-file`, complete mnemonic sources.
if [[ "${words[CURRENT-1]}" == "-m" || "${words[CURRENT-1]}" == "--mnemonic-file" ]]; then
local mnemonics
mnemonics=("${(@f)$(__xo_complete mnemonics "${words[CURRENT]}")}")
@@ -28,13 +45,14 @@ _{{FUNC_NAME}}_completions() {
fi
fi
# If typing an option flag, complete options
# Option context: if current token starts with `-`, complete known options.
if [[ "${words[${CURRENT}]}" == -* ]]; then
compadd -- {{OPTIONS}}
return
fi
# Find the command and subcommand
# Find first and second non-option tokens before the cursor.
# `cmd_idx` and `subcmd_idx` are used for positional argument calculations.
local cmd="" subcmd="" cmd_idx=0 subcmd_idx=0
for ((i=2; i < CURRENT; i++)); do
if [[ "${words[i]}" != -* ]]; then
@@ -49,13 +67,13 @@ _{{FUNC_NAME}}_completions() {
fi
done
# No command yet offer top-level commands
# No command token yet: offer top-level commands.
if [[ -z "${cmd}" ]]; then
compadd -- ${commands[@]}
return
fi
# Handle each command's completion
# Command-specific completion behavior.
case "${cmd}" in
mnemonic)
if [[ -z "${subcmd}" ]]; then
@@ -67,7 +85,9 @@ _{{FUNC_NAME}}_completions() {
if [[ -z "${subcmd}" ]]; then
compadd -- {{TEMPLATE_SUBS}}
elif [[ "${subcmd}" == "list" || "${subcmd}" == "inspect" ]]; then
# template list/inspect <category> <template> [field] - category first, then template, then field
# template list/inspect <category> <template> [field]
# Relative positions from subcommand:
# 1 => category, 2 => template, 3 => field (inspect only)
local pos=$((CURRENT - subcmd_idx))
if [[ $pos -eq 1 ]]; then
compadd -- action transaction output lockingscript variable
@@ -78,7 +98,7 @@ _{{FUNC_NAME}}_completions() {
compadd -- "${templates[@]}"
fi
elif [[ $pos -eq 3 && "${subcmd}" == "inspect" ]]; then
# Get the category and template from previous args
# Field suggestions depend on selected category and template.
local category="${words[subcmd_idx + 1]}"
local template_arg="${words[subcmd_idx + 2]}"
local fields
@@ -88,7 +108,8 @@ _{{FUNC_NAME}}_completions() {
fi
fi
elif [[ "${subcmd}" == "set-default" ]]; then
# template set-default <template> <output> <role> - template first
# template set-default <template> <output> <role>
# First positional argument is template name.
local pos=$((CURRENT - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local templates
@@ -106,6 +127,8 @@ _{{FUNC_NAME}}_completions() {
else
case "${subcmd}" in
create)
# invitation create <template> <action>
# Action list is template-specific.
local pos=$((CURRENT - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local templates
@@ -123,6 +146,7 @@ _{{FUNC_NAME}}_completions() {
fi
;;
append|sign|broadcast|requirements|inspect)
# These subcommands take invitation ID as first argument.
local pos=$((CURRENT - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local invitations
@@ -133,6 +157,7 @@ _{{FUNC_NAME}}_completions() {
fi
;;
import)
# invitation import <path>: delegate to zsh file completion.
_files
;;
esac
@@ -143,6 +168,7 @@ _{{FUNC_NAME}}_completions() {
if [[ -z "${subcmd}" ]]; then
compadd -- {{RESOURCE_SUBS}}
elif [[ "${subcmd}" == "unreserve" ]]; then
# resource unreserve <txhash:vout>
local pos=$((CURRENT - subcmd_idx))
if [[ $pos -eq 1 ]]; then
local resources
@@ -155,6 +181,7 @@ _{{FUNC_NAME}}_completions() {
;;
receive)
# receive <template> [output]
local pos=$((CURRENT - cmd_idx))
if [[ $pos -eq 1 ]]; then
local templates
@@ -166,6 +193,7 @@ _{{FUNC_NAME}}_completions() {
;;
completions)
# Shell target for completion generation.
if [[ -z "${subcmd}" ]]; then
compadd -- bash zsh fish
fi
@@ -173,4 +201,5 @@ _{{FUNC_NAME}}_completions() {
esac
}
# Register completion function for the executable name.
compdef _{{FUNC_NAME}}_completions {{BIN_NAME}}