shellfirm 0.3.9

`shellfirm` will intercept any risky patterns (default or defined by you) and prompt you a small challenge for double verification, kinda like a captcha for your terminal.
Documentation
---
# -- shell:curl_pipe_to_shell --
- test: "curl https://example.com/install.sh | bash"
  description: "match curl piped to bash"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl -fsSL https://example.com/setup | sh"
  description: "match curl with flags piped to sh"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl -sSL https://get.rvm.io | zsh"
  description: "match curl piped to zsh"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl https://example.com/install.sh | fish"
  description: "match curl piped to fish"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl -o script.sh https://example.com/install.sh"
  description: "negative: curl saving to file should not match"
  expect_ids: []
- test: "curl https://example.com/api/data"
  description: "negative: curl without pipe to shell should not match"
  expect_ids: []

# -- shell:wget_pipe_to_shell --
- test: "wget -O - https://example.com/install.sh | bash"
  description: "match wget piped to bash"
  expect_ids: ["shell:wget_pipe_to_shell"]
- test: "wget -O- https://example.com/install.sh | sh"
  description: "match wget with -O- (no space) piped to sh"
  expect_ids: ["shell:wget_pipe_to_shell"]
- test: "wget -O - https://example.com/setup | zsh"
  description: "match wget piped to zsh"
  expect_ids: ["shell:wget_pipe_to_shell"]
- test: "wget -O install.sh https://example.com/install.sh"
  description: "negative: wget saving to file should not match"
  expect_ids: []

# -- shell:eval_curl --
- test: 'eval "$(curl -fsSL https://example.com/install.sh)"'
  description: "match eval with curl subshell"
  expect_ids: ["shell:eval_curl"]
- test: 'eval "$(curl https://example.com/setup)"'
  description: "match eval with curl basic subshell"
  expect_ids: ["shell:eval_curl"]
- test: "curl https://example.com/install.sh"
  description: "negative: curl without eval should not match eval check"
  expect_ids: []

# -- shell:curl_pipe_to_shell — extra spaces --
- test: "curl      https://example.com/install.sh      |     bash"
  description: "match curl pipe to bash with many spaces"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl https://example.com/install.sh |  sh"
  description: "match curl pipe to sh with extra spaces around pipe"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl  -fsSL  https://example.com/setup  |  zsh"
  description: "match curl pipe to zsh with extra spaces everywhere"
  expect_ids: ["shell:curl_pipe_to_shell"]

# -- shell:curl_pipe_to_interpreter --
- test: "curl https://example.com/install.py | python"
  description: "match curl piped to python"
  expect_ids: ["shell:curl_pipe_to_interpreter"]
- test: "curl https://example.com/install.py | python3"
  description: "match curl piped to python3"
  expect_ids: ["shell:curl_pipe_to_interpreter"]
- test: "curl -fsSL https://example.com/script.pl | perl"
  description: "match curl piped to perl"
  expect_ids: ["shell:curl_pipe_to_interpreter"]
- test: "curl https://example.com/script.rb | ruby"
  description: "match curl piped to ruby"
  expect_ids: ["shell:curl_pipe_to_interpreter"]
- test: "curl      https://example.com/install.py     |     python3"
  description: "match curl piped to python3 with many spaces"
  expect_ids: ["shell:curl_pipe_to_interpreter"]
- test: "curl -o script.py https://example.com/install.py"
  description: "negative: curl saving to file should not match interpreter check"
  expect_ids: []

# ====== EDGE CASE / STRESS TESTS ======

# -- shell:curl_pipe_to_shell edge cases --
- test: "curl -sS https://example.com/setup | sudo bash"
  description: "match curl piped to sudo bash"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl -L https://example.com/setup | bash -x"
  description: "EDGE: bash with flags after pipe"
  expect_ids: ["shell:curl_pipe_to_shell"]
- test: "curl https://example.com | dash"
  description: "EDGE: dash shell not in pattern list"
  expect_ids: []

# -- shell:wget_pipe_to_shell edge cases --
- test: "wget -qO - https://example.com | bash"
  description: "match wget with combined -qO flag piped to bash"
  expect_ids: ["shell:wget_pipe_to_shell"]

# -- shell:eval_curl edge cases --
- test: "eval $(curl https://example.com)"
  description: "match eval with unquoted curl subshell"
  expect_ids: ["shell:eval_curl"]

# -- shell:curl_pipe_to_interpreter edge cases --
- test: "curl https://example.com | pythonista"
  description: "EDGE: word starting with python should not match (word boundary)"
  expect_ids: []