Add terminal TUI and shell completion

This commit is contained in:
Luna 2026-07-08 20:47:58 -07:00
parent a7535cfc56
commit cab60cd633
11 changed files with 612 additions and 0 deletions

View file

@ -0,0 +1,102 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""Shell completion script generation."""
from __future__ import annotations
COMMANDS = (
"run", "check", "baseline", "list-detectors", "rules", "web", "tui",
"triage", "fim-baseline", "fim-update", "fim-check", "pkgdb-check",
"pkgdb-verify", "rootcheck", "status", "incident", "posture", "respond",
"watchdog", "completion",
)
RULE_ACTIONS = ("list", "show", "test", "docs")
BASELINE_ACTIONS = ("build", "accept", "revoke", "list")
INCIDENT_ACTIONS = ("list", "show", "export")
POSTURE_ACTIONS = ("check",)
RESPOND_ACTIONS = ("plan",)
COMPLETION_SHELLS = ("bash", "zsh")
def bash_completion(prog: str = "enodia-sentinel") -> str:
commands = " ".join(COMMANDS)
rule_actions = " ".join(RULE_ACTIONS)
baseline_actions = " ".join(BASELINE_ACTIONS)
incident_actions = " ".join(INCIDENT_ACTIONS)
posture_actions = " ".join(POSTURE_ACTIONS)
respond_actions = " ".join(RESPOND_ACTIONS)
shells = " ".join(COMPLETION_SHELLS)
return f"""# bash completion for {prog}
_{prog.replace('-', '_')}_complete() {{
local cur prev cmd
COMPREPLY=()
cur="${{COMP_WORDS[COMP_CWORD]}}"
prev="${{COMP_WORDS[COMP_CWORD-1]}}"
cmd=""
for word in "${{COMP_WORDS[@]:1}}"; do
case "$word" in
-* ) ;;
* ) cmd="$word"; break ;;
esac
done
if [[ $COMP_CWORD -le 1 || -z "$cmd" ]]; then
COMPREPLY=( $(compgen -W "--version --config -c {commands}" -- "$cur") )
return 0
fi
case "$cmd" in
rules) COMPREPLY=( $(compgen -W "{rule_actions} --json" -- "$cur") ) ;;
baseline) COMPREPLY=( $(compgen -W "{baseline_actions} --reason --expires --force --stale --json" -- "$cur") ) ;;
incident) COMPREPLY=( $(compgen -W "{incident_actions} --json" -- "$cur") ) ;;
posture) COMPREPLY=( $(compgen -W "{posture_actions} --json" -- "$cur") ) ;;
respond) COMPREPLY=( $(compgen -W "{respond_actions} --json" -- "$cur") ) ;;
completion) COMPREPLY=( $(compgen -W "{shells}" -- "$cur") ) ;;
check|fim-check|status) COMPREPLY=( $(compgen -W "--json --packages" -- "$cur") ) ;;
pkgdb-verify) COMPREPLY=( $(compgen -W "--sample" -- "$cur") ) ;;
watchdog) COMPREPLY=( $(compgen -W "--url --token --max-age --insecure-tls" -- "$cur") ) ;;
esac
}}
complete -F _{prog.replace('-', '_')}_complete {prog}
"""
def zsh_completion(prog: str = "enodia-sentinel") -> str:
command_specs = " ".join(f"{c}:{c}" for c in COMMANDS)
return f"""#compdef {prog}
# zsh completion for {prog}
local -a commands
commands=({command_specs})
_arguments -C \\
'(-h --help)'{{-h,--help}}'[show help]' \\
'--version[show version]' \\
'(-c --config)'{{-c,--config}}'[path to TOML config]:config file:_files' \\
'1:command:->command' \\
'*::arg:->args'
case $state in
command)
_describe 'command' commands
;;
args)
case $words[2] in
rules) _arguments '1:action:((list show test docs))' '--json[emit JSON]' ;;
baseline) _arguments '1:action:((build accept revoke list))' '2:kind:((fim pkgfile listener suid))' '--reason[reason]' '--expires[TTL]' '--force[force]' '--stale[stale]' '--json[emit JSON]' ;;
incident) _arguments '1:action:((list show export))' '--json[emit JSON]' ;;
posture) _arguments '1:action:((check))' '--json[emit JSON]' ;;
respond) _arguments '1:action:((plan))' '--json[emit JSON]' ;;
completion) _arguments '1:shell:((bash zsh))' ;;
check|status) _arguments '--json[emit JSON]' ;;
fim-check) _arguments '--packages[verify package-owned files]' ;;
pkgdb-verify) _arguments '--sample[package sample size]' ;;
watchdog) _arguments '--url[dashboard URL]' '--token[bearer token]' '--max-age[seconds]' '--insecure-tls[allow self-signed TLS]' ;;
esac
;;
esac
"""
def script(shell: str, prog: str = "enodia-sentinel") -> str:
if shell == "bash":
return bash_completion(prog)
if shell == "zsh":
return zsh_completion(prog)
raise ValueError(f"unsupported shell: {shell}")