Skip to content

CLI Reference

Stephen Cross edited this page Jun 9, 2026 · 3 revisions

CLI Reference

All commands follow the hermes custom-dangerous-patterns <verb> pattern.

list — Show your patterns

hermes custom-dangerous-patterns list                    # all patterns
hermes custom-dangerous-patterns list --type block       # block patterns only
hermes custom-dangerous-patterns list --type allow       # allow patterns only
hermes custom-dangerous-patterns list --type deny        # deny patterns only
hermes custom-dangerous-patterns list --group cloud      # patterns in a group
hermes custom-dangerous-patterns list --disabled         # only disabled patterns
hermes custom-dangerous-patterns list --enabled          # only active patterns
hermes custom-dangerous-patterns list --search aws       # search descriptions and patterns
hermes custom-dangerous-patterns list --builtins         # include Hermes built-in patterns (snapshot)

Note: --builtins uses a static snapshot of Hermes's built-in patterns bundled at plugin install time. These may drift from Hermes core updates.

test <command> — Verify patterns before running

Test a command against all patterns without running it.

hermes custom-dangerous-patterns test "vultr instance delete"
hermes custom-dangerous-patterns test "vultr account info" --verbose
hermes custom-dangerous-patterns test "git push --force" --skip-builtins

Shows which patterns match and the result: DENY (blocked immediately), ALLOW (runs freely), APPROVAL PROMPT (interactive prompt), or PASS (no patterns matched).

--verbose shows full pattern regex and built-in matches. --skip-builtins omits Hermes's built-in patterns to focus on custom patterns.

init — First-run bootstrap

Config is always created as a directory (custom-dangerous-patterns/).

  • Creates ~/.hermes/custom-dangerous-patterns/
  • --with-examples: Copy all bundled example files individually (01-cloud.yaml, 02-infra.yaml, etc.)
  • -f, --force: Overwrite existing config without prompting
hermes custom-dangerous-patterns init                    # minimal config with safe [TEST] patterns (all disabled)
hermes custom-dangerous-patterns init --with-examples    # full example config (all enabled for demonstration)
hermes custom-dangerous-patterns init --force            # overwrite existing config without prompting

Default starter files:

  • 00-test.yaml — safe [TEST] patterns (all disabled)
  • All bundled example files copied individually (01-cloud.yaml, 02-infra.yaml, 03-tools.yaml, 04-package-managers.yaml) — fully-enabled (only with --with-examples)

enable / disable — Toggle patterns

Toggle patterns on/off without editing YAML. Target by index, description substring, or group.

hermes custom-dangerous-patterns enable 1                          # by index (from list output)
hermes custom-dangerous-patterns disable "Vultr"                    # by description substring
hermes custom-dangerous-patterns enable --group cloud               # all patterns in a group
hermes custom-dangerous-patterns enable --group testing --dry-run   # preview without saving

With no target or group specified, enable and disable launch interactive selection automatically.

After any write command, the CLI reminds you to restart Hermes for changes to take effect.

validate — Check config syntax

hermes custom-dangerous-patterns validate                    # validate default config
hermes custom-dangerous-patterns validate --path /tmp/cfg.yaml  # validate a specific file
hermes custom-dangerous-patterns validate --quiet            # exit code only (CI/CD)

Validates YAML syntax, regex compilation, and pattern consistency. In addition to basic checks, if a pattern defines both glob and pattern and the stored regex differs from what the glob would generate, a warning is emitted to flag the discrepancy.

Exit code 0 = valid, 1 = errors found, 2 = file not found.

info — State dashboard

Shows config path, pattern counts by type, integrity status, protected patterns, and group breakdown.

hermes custom-dangerous-patterns info

logs — Extract plugin log entries

hermes custom-dangerous-patterns logs                          # all plugin log entries
hermes custom-dangerous-patterns logs --level WARNING          # filter by minimum level
hermes custom-dangerous-patterns logs --limit 20               # last 20 entries
hermes custom-dangerous-patterns logs --since 2026-06-01       # entries since a date
hermes custom-dangerous-patterns logs --follow                 # tail the log (Ctrl+C to exit)

add — Add a pattern

Interactive guided prompts or CLI flags for scripting.

# Interactive (guided prompts for each field, with glob-to-regex support)
hermes custom-dangerous-patterns add

# Write to a specific file in the config directory
hermes custom-dangerous-patterns add --target 02-mycloud.yaml --type block \
    --pattern '\bheroku\s+(apps:destroy|pg:reset)\b' \
    --description 'Heroku destructive commands' \
    --group cloud

# Glob-style pattern entry (converted to regex automatically).
# * matches ONE word, ** matches ANYTHING, {a,b} for alternatives.
hermes custom-dangerous-patterns add --type block \
    --glob 'heroku *destroy*' \
    --description 'Heroku destructive commands'

# Non-interactive (full CLI flags)
hermes custom-dangerous-patterns add --type block \
    --pattern '\bheroku\s+(apps:destroy|pg:reset)\b' \
    --description 'Heroku destructive commands' \
    --group cloud

add flags

Flag Description
-t / --type Pattern type: block, allow, or deny (required non-interactive)
-p / --pattern Raw regex pattern (required non-interactive; mutually exclusive with --glob)
--glob Glob-style pattern like echo hello — converted to regex automatically (mutually exclusive with --pattern)
-d / --description Human-readable description
-g / --group Optional group tag for categorization
--examples One or more example commands
--disabled Add as disabled (default: enabled)
--protected Mark as protected (integrity tracked across sessions)
--dry-run Preview without saving
--target <filename> Write to a specific .yaml file in the config directory (requires directory mode; file must have .yaml extension; no path separators)

Note: --pattern and --glob are mutually exclusive. Without any flags, add launches interactive mode with guided prompts and glob-to-regex conversion.

add --target — writing to a specific file

The --target <filename> flag writes the new pattern entry directly to a named file in the config directory, bypassing the delta system.

Rules:

  • Requires directory mode (config path must be a directory)
  • File name must end with .yaml
  • File name must not contain path separators (no /)
  • If the file doesn't exist, it is created

Use case: Organize patterns by tool or team:

hermes custom-dangerous-patterns add --target 10-cloud.yaml --type block \
    --pattern '\bvultr\b' --description 'Vultr CLI' --group cloud

hermes custom-dangerous-patterns add --target 20-database.yaml --type block \
    --pattern '\bDROP\s+DATABASE\b' --description 'SQL DROP' --group database

See Glob Syntax below for glob-to-regex conversion rules.

remove — Remove a pattern

# Interactive (shows numbered list)
hermes custom-dangerous-patterns remove

# By index (from `list` output)
hermes custom-dangerous-patterns remove 3

# By description substring
hermes custom-dangerous-patterns remove "Heroku"

# Force removal without confirmation prompt
hermes custom-dangerous-patterns remove 3 --force

# Preview without deleting
hermes custom-dangerous-patterns remove 7 --dry-run

remove flags

Flag Description
target Pattern index (from list) or description substring
-t / --type Filter by type: block, allow, or deny
--force Skip confirmation prompt
--dry-run Preview without deleting

Unlike enable/disable (which write delta entries to 99-custom.yaml), remove truly deletes the pattern from the source YAML file — the lines are removed, no remnant written.

Protected patterns cannot be removed via CLI regardless of --force — edit the config file directly.

Glob Syntax

The add command's --glob flag (and interactive mode) accepts glob-style patterns that are automatically converted to regex. This lets you type intuitive patterns like echo hello instead of raw regex like \becho\s+hello\b.

Conversion rules

Glob syntax Meaning Generated regex
Whitespace Word separator \s+
* One argument — matches a single non-whitespace word \S+
** Super wildcard — matches anything including whitespace .*
? Exactly one character .
{a,b} Brace expansion — match a or b (prefix shared) (?:a|b)

Regex meta-characters (. ^ $ + [ ] \ | ( )) are automatically escaped. Word boundaries (\b) are added at alphanumeric start/end positions.

Additionally, when the first token starts with an alphanumeric character, a negative lookahead (?!/) is inserted after it to prevent the command name from matching directory components. For example, aws ** matches /opt/bin/aws --help (the command name is a distinct token) but not /opt/aws/command (where aws is part of a directory path).

Examples

Glob Generated regex What it matches
echo hello \becho(?!/)\s+hello\b Exactly the two words. (?!/) prevents matching directory components like /echo/hello.
rm -rf /tmp/* \brm\s+-rf\s+/tmp/\S+ Trailing * matches one path component
docker ** rm \bdocker\s+.*\s+rm\b ** matches any arguments between docker and rm
docker * rm \bdocker\s+\S+\s+rm\b * matches exactly ONE argument between docker and rm
mycli * delete * \bmycli\s+\S+\s+delete\s+\S+\b Positional: delete must be the second argument
ls *.{env,bak} \bls\s+(?:\S+\.env|\S+\.bak) Match .env or .bak extension
deploy {prod,staging} \bdeploy\s+(?:prod|staging) Match deploy prod or deploy staging

* vs ** — positional vs super wildcard

  • * between tokens matches exactly one argument (a single non-whitespace word). Use it when you know the command structure — e.g., mycli * delete * matches mycli instance delete instance1 but NOT mycli instance interface delete interface1 (too many args before delete).

  • ** between tokens matches any number of arguments (including zero). Use it when the argument count is unknown — e.g., docker ** rm matches docker container rm AND docker container network rm.

Brace expansion {a,b}

Shell-compatible brace expansion: the prefix before { is shared by all alternatives. Each alternative is glob-processed as a complete unit.

Glob What it expands to
{prod,staging} (?:prod|staging) — matches prod or staging
*.{env,bak} (?:\S+\.env|\S+\.bak) — prefix *. shared with each alt
{hello}{a,b} Skips single-alt {hello}, expands {a,b} as (?:{hello}a|{hello}b)

A single alternative ({hello}) or empty braces ({}) are treated as literal text, not expansion.