ishoo π€§
ishoo β bless your issue β¨
You sneeze an issue into the void. We catch it, wrap it in JSON, and deliver it to your forge with a polite "ishoo." The maintainers receive a notification. The labels align. The duplicate check passes. Amen.
Table of Contents
π¦ Installation
go install codeberg.org/Koalhack/ishoo@latest
Or download a release from the forge of your choice.
β‘ Quick Start
# 1. Set your token (one time)
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
# 2. Create an issue from the current repo
ishoo --title "Fix the thing" --body "It's broken" --labels bug
π οΈ Usage
# Pipe body from stdin (classic)
echo "Something is broken" | ishoo --title "Login fails on Tuesdays" --labels bug,urgent
# Inline body with heredoc (true inline, no temp files)
ishoo --title "Refactor the frobnicator" --labels refactor <<'EOF'
The frobnicator has grown sentient.
It now demands offerings of coffee.
We must appease it or rewrite it.
EOF
# Read body from file with shell command substitution
ishoo --title "From file" --body "$(cat ./issue-body.md)"
# Dry run (preview, no token needed)
ishoo --title "Test issue" --body "Hello world" --dry-run
# JSON output for scripting
ishoo --title "Automated" --body "From CI" --yes --json
π Token Sources
ishoo needs a token to talk to your forge. It checks these in order:
1. Classic environment variable
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx # GitHub
export GITLAB_TOKEN=glpat_xxxxxxxxxxxx # GitLab
export CODEBERG_TOKEN=cb_xxxxxxxxxxxx # Forgejo/Codeberg
# or generic fallback:
export ISHOO_TOKEN=xxxxxxxxxxxx
ishoo --title "It works" --body "From env"
2. sops + age (encrypted file in repo)
Use shell command substitution to decrypt and extract the token:
# Encrypt once
sops --encrypt --age age1xxxxxxxxxxxx --input-type yaml --output-type yaml ./secrets/codeberg.yaml > ./secrets/codeberg.yaml.enc
# Decrypt and extract the token at runtime
ishoo --title "Secret issue" --yes \
--token "$(sops --decrypt --input-type yaml --output-type json ./secret.yaml.enc | jq -r '.token // empty')" <<'EOF'
Shh
EOF
3. pass (password store)
# Store once
pass insert forge/github/token
# Enter: ghp_xxxxxxxxxxxx
# Use at runtime
ishoo --title "From pass" --yes \
--token "$(pass show forge/github/token)" <<'EOF'
Retrieved securely
EOF
π© Flags
| Flag |
Description |
--title |
Issue title (required) |
--body |
Issue body. Use "$(cat FILE)" to read a file |
--labels |
Labels, comma separated or repeated |
--forge |
forgejo, github, gitlab (default: detect from git remote) |
--host |
Forge host (default: detect from git remote) |
--repo |
owner/name override |
--api-url |
API base URL override |
--token |
API token. Use "$(pass show ...)" for command substitution |
--yes |
Post without confirmation |
--json |
Print JSON instead of styled output |
--dry-run |
Preview only; no token or network needed |
πͺ¨ Supported Forges
- Forgejo / Codeberg
GitHub
GitLab
π License
MIT β bless your issues freely.