A lightweight DevSecOps CLI utility for creating, managing, and running "triggers" — named commands that can be saved, reused, and executed with dynamic arguments and embedded scripts.
NOTICE: XDXD TOOL COMPLETELY Very Inefficient But Entertaining CODED. I'm gonna refactor it later. I just want some tool like that.
- Create Triggers — Register named commands with optional default arguments and save them to disk
- List Triggers — View all registered triggers and their commands
- Run Triggers — Execute triggers by name with:
- Argument Substitution — Use
[arg0],[arg1], etc. as placeholders for runtime arguments - Payload Piping — Pass JSON/text payloads via stdin
- Timeout Support — Kill long-running commands
- Dry-run Mode — Preview what would execute without running
- Argument Substitution — Use
- Script Embedding — Automatically detect and embed script files (
.sh,.py,.js,.rb,.php,.pl,.lua,.groovy,.swift) so they don't need to exist on disk - Sign Payloads — Compute HMAC-SHA256 signatures using
TRIGGER_SECRETenv var (useful for webhook verification) - Shell Completions — Generate completion scripts for bash, zsh, fish, and powershell
git clone https://github.com/steugen/trigger.git
cd trigger
go build -o trigger main.goTriggers are stored in $XDG_CONFIG_HOME/trigger/triggers.json (or ~/.config/trigger/triggers.json on most systems).
Scripts are embedded and stored in ~/.config/trigger/scripts/.
Create a simple trigger that runs a command:
trigger create mycommand -- echo "Hello, World!"Delete a trigger with name:
trigger delete --name mycommand Create a trigger with placeholder arguments that can be filled at runtime:
trigger create backup -- tar -czf '[arg0]' /etcWhen running, you can provide arguments:
trigger run --name backup --args ./backup.tar.gz
# Executes: tar -czf ./backup.tar.gz /etcMultiple argument placeholders:
trigger create copy -- cp '[arg0]' '[arg1]'trigger run --name copy --args /source/file.txt /dest/file.txt
# Executes: cp /source/file.txt /dest/file.txtNote: Quote the placeholder arguments ([arg0], [arg1], etc.) to prevent your shell from interpreting the square brackets as glob patterns.
Create a trigger from a script file. The script content is automatically embedded, so you don't need to have the script present when running the trigger:
trigger create alert-slack -- ./send_slack_alert.shThis will:
- Read the content of
./send_slack_alert.sh - Embed it into the trigger configuration
- Store it in
~/.config/trigger/scripts/alert-slack.sh
When you run it, the embedded script will be executed:
trigger run --name alert-slack --payload message.jsontrigger create process-data -- ./transform.py '[arg0]' '[arg1]'trigger run --name process-data --args input.csv output.csv
# Executes: transform.py input.csv output.csvView all registered triggers:
trigger listOutput:
- backup: tar -czf [arg0] /etc
- alert-slack: /home/user/.config/trigger/scripts/alert-slack.sh [embedded: send_slack_alert.sh]
- copy: cp [arg0] [arg1]
trigger run --name mycommandtrigger run --name backup --args ./backup.tar.gz
trigger run --name copy --args file1.txt file2.txtPipe a file to stdin (useful for webhooks, data processing):
trigger run --name alert-slack --payload event.jsonThe file contents will be written to the command's stdin.
Kill the command if it takes too long:
trigger run --name long-task --timeout 30sPreview what would execute without actually running it:
trigger run --name backup --args ./backup.tar.gz --dry-run
# Output: [dry-run] would run: tar -czf ./backup.tar.gz /etctrigger run --name mycommand --verboseCompute HMAC-SHA256 signatures for webhook verification or payload authentication:
Set the secret:
export TRIGGER_SECRET="your-secret-key"Sign a payload file:
trigger sign --payload message.jsonSign from stdin:
echo '{"event":"push"}' | trigger signOutput: hexadecimal HMAC-SHA256 digest
Generate completion scripts for your shell:
trigger completion bash > /etc/bash_completion.d/trigger
# or
trigger completion bash > ~/.bash_completion.d/trigger
source ~/.bash_completion.d/triggertrigger completion zsh > ~/.zsh/completions/_triggertrigger completion fish > ~/.config/fish/completions/trigger.fishtrigger completion powershell | Out-String | Invoke-Expression# Create a backup trigger with date argument
trigger create db-backup -- mysqldump -u root [arg0] > /backups/[arg0]-$(date +%Y%m%d).sql
trigger run --name db-backup --args mydb# Create script: send_slack.sh
#!/bin/bash
curl -X POST -H 'Content-type: application/json' \
--data @- \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
# Register it
trigger create notify-slack -- ./send_slack.sh
# Use it
trigger run --name notify-slack --payload alert.jsontrigger create process-logs -- gawk -f '[arg0]' '[arg1]'
trigger run --name process-logs --args filter.awk access.log# Create a webhook handler script
trigger create webhook-handler -- ./verify_and_process.sh
# Sign incoming webhook
trigger sign --payload webhook_payload.json
# Run handler with payload
trigger run --name webhook-handler --payload webhook_payload.json--config string Config file (optional)
--dry-run Don't execute commands; show what would run
-v, --verbose Verbose output
~/.config/trigger/
├── triggers.json # All registered triggers
└── scripts/ # Embedded script files
├── alert-slack.sh
├── process-data.py
└── ...
Each trigger is stored in triggers.json:
{
"name": "backup",
"command": "tar",
"args": ["-czf", "[arg0]", "/etc"],
"script_content": "",
"script_path": "",
"created_at": "2024-01-15T10:30:00Z"
}For embedded scripts:
{
"name": "alert-slack",
"command": "/home/user/.config/trigger/scripts/alert-slack.sh",
"args": [],
"script_content": "#!/bin/bash\ncurl ...",
"script_path": "send_slack_alert.sh",
"created_at": "2024-01-15T10:35:00Z"
}Scripts are identified by file extension. Supported extensions:
.sh,.py,.js,.rb,.php,.pl,.lua,.groovy,.swift
When a script file is detected during trigger creation, its content is:
- Read from disk
- Embedded into the trigger JSON
- Written to
~/.config/trigger/scripts/for execution
This approach allows triggers to be portable — the script doesn't need to exist at the original path when running.
Placeholders use the format [argN] where N is a zero-indexed number:
[arg0]— First runtime argument[arg1]— Second runtime argument[arg2]— Third runtime argument- etc.
Example:
trigger create deploy -- rsync -av '[arg0]' '[arg1]'
trigger run --name deploy --args ./src/ user@server:/dest/This resolves to: rsync -av ./src/ user@server:/dest/
TRIGGER_SECRET— Used by thesigncommand to compute HMAC-SHA256XDG_CONFIG_HOME— Config directory (defaults to~/.configif not set)
See LICENSE file for details.
Contributions are welcome! Please feel free to submit issues and pull requests.