Compare commits
No commits in common. "364530fc313296a0ea38c619de1ca8a1c1496abc" and "d8e767408553080aec0a69b2c67f00698add76bb" have entirely different histories.
364530fc31
...
d8e7674085
6 changed files with 72 additions and 94 deletions
96
README.md
96
README.md
|
|
@ -1,83 +1,65 @@
|
||||||
# bwzy - bitwarden ... fuzzy
|
# bwzy - bitwarden ... fuzzy
|
||||||
|
|
||||||
bwzy is a fuzzy finder and auto-filler for Bitwarden (read-only at present).
|
bwzy is a fuzzy finder for Bitwarden using the official bitwarden cli.
|
||||||
It runs in the terminal and uses the official bitwarden CLI.
|
|
||||||
|
|
||||||

|
The `bw` cli is great, but not very user-friendly.
|
||||||
|
|
||||||
|
`bwzy` tries to make this quicker by caching the information and presenting it via the magnificient [fzf](https://junegunn.github.io/fzf/).
|
||||||
|
|
||||||
# current features
|
# current features
|
||||||
- terminal UI
|
- READ-ONLY ui
|
||||||
- more user-friendly than the `bw` command line client
|
|
||||||
- search based on name and folder
|
- search based on name and folder
|
||||||
- hide based on name (i.e. "hide archives")
|
|
||||||
- copy user/pass/totp
|
- copy user/pass/totp
|
||||||
- local cache for speed
|
- cache the items in shared memory (`/dev/shm/`) to make it fast
|
||||||
|
- cache does not persist through reboots (by default)
|
||||||
- refresh/flush cache
|
- refresh/flush cache
|
||||||
- preview items in `YAML` form
|
- preview items in `YAML` form
|
||||||
- auto-fill (currently working in hyprland)
|
- auto-fill for hyprland
|
||||||
- one-shot mode for use in scripts
|
|
||||||
|
|
||||||
# requirements
|
# requirements
|
||||||
|
|
||||||
The following software is needed by `bwzy`:
|
The following software is needed by `bwzy`:
|
||||||
|
|
||||||
- [bitwarden cli client](https://contributing.bitwarden.com/getting-started/clients/cli) to access bitwarden
|
|
||||||
- [fzf](https://junegunn.github.io/fzf/) for fuzzy finding
|
- [fzf](https://junegunn.github.io/fzf/) for fuzzy finding
|
||||||
|
- [bitwarden cli client](https://contributing.bitwarden.com/getting-started/clients/cli) to access bitwarden
|
||||||
- [jq](https://jqlang.github.io/jq/) to work with the JSON
|
- [jq](https://jqlang.github.io/jq/) to work with the JSON
|
||||||
- [OATH Toolkit](https://www.nongnu.org/oath-toolkit/) allows generating TOTP tokens
|
- [OATH Toolkit](https://www.nongnu.org/oath-toolkit/) allows generating TOTP tokens
|
||||||
- [charmbracelet - gum](https://github.com/charmbracelet/gum) for the loading spinner and color
|
- [charmbracelet - gum](https://github.com/charmbracelet/gum) for the loading spinner and color
|
||||||
|
|
||||||
It also expects `grep`, `sed` and `awk` to be available
|
it also expects `grep`, `sed` and `awk` to be available
|
||||||
|
|
||||||
Additionally, you will need clipboard and keyboard automation such as `wtype` and `wl-copy` under wayland.
|
Additinally, you will need clipboard and keyboard automation such as `wtype` and `wl-copy` under wayland.
|
||||||
|
|
||||||
## configuration
|
## configuration
|
||||||
|
|
||||||
All configuration is done via environment variables, with defaults shown
|
All configuration is done via environment variables, with defaults shown
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# functional settings
|
BWZY_CACHE=`/dev/shm/bwzy-cache` # where the passwords are cached
|
||||||
BWZY_CACHE=`/dev/shm/bwzy-cache` # where the passwords are cached
|
BWZY_KEEP_CACHE='true' # set to false and cache will be purged
|
||||||
BWZY_KEEP_CACHE='true' # set to false and cache will be purged on exit
|
BWZY_COPY_CMD='wl-copy' # the command to copy something to the clipboard
|
||||||
BWZY_COPY_CMD='wl-copy' # the command to copy something to the clipboard
|
BWZY_TYPE_CMD='wtype' # the command used to type / send keyboard events
|
||||||
BWZY_TYPE_CMD='wtype' # the command used to type / send keyboard events
|
BWZY_HIDE_CMD='' # the command to hide bwzy
|
||||||
BWZY_HIDE_CMD='' # the command to hide bwzy.desktop or a terminal named `bwzy`
|
BWZY_REFOCUS_CMD='' # the command to refocuse the previous window
|
||||||
BWZY_REFOCUS_CMD='' # the command to refocus the previous window
|
BWZY_COPY_AND_HIDE='true' # set to 'false' to not hide bwzy on copy
|
||||||
BWZY_COPY_AND_HIDE='true' # set to 'false' to not hide bwzy on copy - does not affect auto-fill
|
BWZY_NOTIFY_CMD='notify-send -i bitwarden' # send a notification
|
||||||
BWZY_NOTIFY_CMD='notify-send -i bitwarden' # send a notification (optional, but nice to know if a TOTP has been copied)
|
|
||||||
BWZY_FILTER="-zz~ " # exclude items with this string in name of folder
|
|
||||||
|
|
||||||
# cosmetic overrides which adjust the looks
|
# cosmetic overrides which adjust the looks
|
||||||
BWZY_USER_SYMBOL='u+' # new prompt on user copy
|
BWZY_USER_SYMBOL='u+'
|
||||||
BWZY_PASS_SYMBOL='p+' # new prompt on password copy
|
BWZY_PASS_SYMBOL='p+'
|
||||||
BWZY_TOTP_SYMBOL='t+' # new prompt on TOTP copy
|
BWZY_TOTP_SYMBOL='t+'
|
||||||
BWZY_LINK_SYMBOL='l+' # new prompt on link copy
|
BWZY_LINK_SYMBOL='l+'
|
||||||
BWZY_AUTO_SYMBOL='a+' # new prompt on auto-fill
|
BWZY_AUTO_SYMBOL='a+'
|
||||||
BWZY_FOLDER_SYMBOL='/' # new symbol used for a folder
|
BWZY_FOLDER_SYMBOL='/'
|
||||||
BWZY_POINTER_SYMBOL='> ' # the line marker used by FZF
|
BWZY_POINTER_SYMBOL='> '
|
||||||
BWZY_PROMPT_SYMBOL='? ' # the prompt symbol used by FZF
|
BWZY_PROMPT_SYMBOL='? '
|
||||||
```
|
```
|
||||||
|
|
||||||
`bwzy` is being tested as my daily driver under [Hyprland](https://hypr.land/) and [Wayland](https://wayland.freedesktop.org/) only, but may be adaptable by the intrepid adventurer. The configuration items to look at are:
|
|
||||||
|
|
||||||
- `BWZY_COPY_CMD`
|
|
||||||
- `BWZY_TYPE_CMD`
|
|
||||||
- `BWZY_HIDE_CMD`
|
|
||||||
- `BWZY_REFOCUS_CMD`
|
|
||||||
- `BWZY_COPY_AND_HIDE`
|
|
||||||
- `BWZY_NOTIFY_CMD`
|
|
||||||
|
|
||||||
Note: under [hyprland](https://hypr.land/) the following works:
|
Note: under [hyprland](https://hypr.land/) the following works:
|
||||||
```bash
|
```bash
|
||||||
BWZY_HIDE_CMD=hyprctl dispatch movetoworkspacesilent special:tools,title:bwzy
|
BWZY_HIDE_CMD=hyprctl dispatch movetoworkspacesilent special:tools,title:bwzy
|
||||||
BWZY_REFOCUS_CMD=hyprctl dispatch focuscurrentorlast
|
BWZY_REFOCUS_CMD=hyprctl dispatch focuscurrentorlast
|
||||||
```
|
```
|
||||||
|
which places the bwzy window launched vi the [bwzy.desktop](./bwzy.desktop) file into a special workspace when not needed.
|
||||||
This hides the bwzy window, a terminal window with the title set to `bwzy`, to a special workplace. A shortcut defined in my window manager brings that window to the foreground.
|
|
||||||
|
|
||||||
The [bwzy.desktop](./bwzy.desktop) file shows the way I launch it.
|
|
||||||
|
|
||||||
If you have a font and terminal with support for unicode, you can use fancy symbols. Here are mine:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
BWZY_USER_SYMBOL=' '
|
BWZY_USER_SYMBOL=' '
|
||||||
|
|
@ -90,13 +72,23 @@ BWZY_POINTER_SYMBOL=' '
|
||||||
BWZY_PROMPT_SYMBOL=' '
|
BWZY_PROMPT_SYMBOL=' '
|
||||||
```
|
```
|
||||||
|
|
||||||
# tips and tricks
|
## arch install
|
||||||
|
```bash
|
||||||
|
pacman -S fzf bitwarden-cli jq haskell-yaml oath-toolkit gum
|
||||||
|
```
|
||||||
|
## install dependency
|
||||||
|
|
||||||
By default the cache is removed on reboot since it lives in `/dev/shm/`. If you have a secure encrypted file system you can override the cache location so that it persists during reboots. I use this often as I'm often completely offline, but still need access to my passwords for offline work. Be safe and know your risks.
|
|
||||||
|
Arch Linux:
|
||||||
|
```bash
|
||||||
|
sudo pacman -S --needed wtype ydotool xdotool xvkbd wl-clipboard xclip xsel bat jq sed awk fzf
|
||||||
|
```
|
||||||
|
## tips and tricks
|
||||||
|
|
||||||
|
By default the cache is removed on reboot since it lives in `/dev/shm/`. if you have a secure encrypted file system you can override the cache location so that it persists during reboots. Be safe and know your risks.
|
||||||
|
|
||||||
# feature ideas
|
# feature ideas
|
||||||
- ~~auto-fill~~ (done)
|
- ~~auto-fill~~ (done)
|
||||||
- ~~"archive" feature to filter things~~ (done)
|
- ~~"archive" feature to filter thingsi~~ (done)
|
||||||
- edit an entry
|
- ability to edit an entry
|
||||||
- add a new entry
|
- ability to add a new entry
|
||||||
- folder based navigation (as in select from list of folders)
|
|
||||||
|
|
|
||||||
51
bwzy
51
bwzy
|
|
@ -10,10 +10,12 @@ cleanup() {
|
||||||
# defaults
|
# defaults
|
||||||
BWZY_CACHE="${BWZY_CACHE:-/dev/shm/bwzy-cache}"
|
BWZY_CACHE="${BWZY_CACHE:-/dev/shm/bwzy-cache}"
|
||||||
BWZY_FILTER="${BWZY_FILTER:-zz~ }"
|
BWZY_FILTER="${BWZY_FILTER:-zz~ }"
|
||||||
# options passed to fzf for default and oneshot modes
|
|
||||||
BWZY_DEFAULT_OPTS=(--layout reverse --height 100%)
|
BWZY_DEFAULT_OPTS=(--layout reverse --height 100%)
|
||||||
BWZY_ONESHOT_OPTS=(--layout default --height 10 --no-header)
|
BWZY_ONESHOT_OPTS=(--layout default --height 10 --no-header)
|
||||||
# visual settings
|
|
||||||
|
bwzy_autofill=${BWZY_AUTOFILL_HELPER:-"$(dirname "$0")/bwzy-autofill"}
|
||||||
|
|
||||||
BWZY_POINTER_SYMBOL=${BWZY_POINTER_SYMBOL:-> }
|
BWZY_POINTER_SYMBOL=${BWZY_POINTER_SYMBOL:-> }
|
||||||
BWZY_PROMPT_SYMBOL=${BWZY_PROMPT_SYMBOL:-? }
|
BWZY_PROMPT_SYMBOL=${BWZY_PROMPT_SYMBOL:-? }
|
||||||
BWZY_USER_SYMBOL=${BWZY_USER_SYMBOL:-u+}
|
BWZY_USER_SYMBOL=${BWZY_USER_SYMBOL:-u+}
|
||||||
|
|
@ -22,18 +24,12 @@ BWZY_TOTP_SYMBOL=${BWZY_TOTP_SYMBOL:-t+}
|
||||||
BWZY_LINK_SYMBOL=${BWZY_LINK_SYMBOL:-l+}
|
BWZY_LINK_SYMBOL=${BWZY_LINK_SYMBOL:-l+}
|
||||||
BWZY_AUTO_SYMBOL=${BWZY_AUTO_SYMBOL:-a+}
|
BWZY_AUTO_SYMBOL=${BWZY_AUTO_SYMBOL:-a+}
|
||||||
BWZY_FOLDER_SYMBOL=${BWZY_FOLDER_SYMBOL:-/}
|
BWZY_FOLDER_SYMBOL=${BWZY_FOLDER_SYMBOL:-/}
|
||||||
|
export GLAMOUR_STYLE=tokyo-night
|
||||||
|
|
||||||
# these are needed by the auto-completer
|
# these are needed by the auto-completer
|
||||||
export BWZY_COPY_CMD=${BWZY_COPY_CMD:-wl-copy}
|
export BWZY_COPY_CMD=${BWZY_COPY_CMD:-wl-copy}
|
||||||
export BWZY_TYPE_CMD=${BWZY_TYPE_CMD:-wtype}
|
export BWZY_TYPE_CMD=${BWZY_TYPE_CMD:-wtype}
|
||||||
|
|
||||||
# and the auto-completer itself
|
|
||||||
export BWZY_AUTOFILL_HELPER=${BWZY_AUTOFILL_HELPER:-$(dirname "$(realpath "$0")")/bwzy-autofill}
|
|
||||||
export BWZY_TOTP_COPY=${BWZY_TOTP_COPY:-$(dirname "$(realpath "$0")")/bwzy-copy-totp}
|
|
||||||
|
|
||||||
# set | rg BWZY
|
|
||||||
# exit 0
|
|
||||||
|
|
||||||
read -r -d '' HELP_TEXT<<'EOH'
|
read -r -d '' HELP_TEXT<<'EOH'
|
||||||
bwzy is a fuzzy wrapper to the bitwarden cli
|
bwzy is a fuzzy wrapper to the bitwarden cli
|
||||||
|
|
||||||
|
|
@ -49,13 +45,13 @@ Usage:
|
||||||
EOH
|
EOH
|
||||||
|
|
||||||
# set some defaults to override based on options
|
# set some defaults to override based on options
|
||||||
BWZY_OPTS=("${BWZY_DEFAULT_OPTS[@]}")
|
|
||||||
CLEAR_CACHE='false'
|
CLEAR_CACHE='false'
|
||||||
DEBUG='false'
|
|
||||||
FORCE_SYNC='false'
|
|
||||||
ONESHOT='false'
|
|
||||||
SYNC_CACHE='false'
|
SYNC_CACHE='false'
|
||||||
|
FORCE_SYNC='false'
|
||||||
|
DEBUG='false'
|
||||||
|
BWZY_OPTS=("${BWZY_DEFAULT_OPTS[@]}")
|
||||||
FILTER_ARG='-v' # argument to grep
|
FILTER_ARG='-v' # argument to grep
|
||||||
|
ONESHOT='false'
|
||||||
|
|
||||||
# read in the options
|
# read in the options
|
||||||
while getopts "acdfhis1" o; do
|
while getopts "acdfhis1" o; do
|
||||||
|
|
@ -80,12 +76,7 @@ while getopts "acdfhis1" o; do
|
||||||
;;
|
;;
|
||||||
h)
|
h)
|
||||||
# show help and exit
|
# show help and exit
|
||||||
( echo "$HELP_TEXT"
|
echo "$HELP_TEXT" | gum format
|
||||||
echo -e "\n# active settings:"
|
|
||||||
echo '```bash'
|
|
||||||
set | grep '^BWZY_' | sort
|
|
||||||
echo '```'
|
|
||||||
) | bat -l markdown --plain
|
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
s)
|
s)
|
||||||
|
|
@ -160,7 +151,7 @@ pre_action="execute-silent($BWZY_REFOCUS_CMD && $BWZY_HIDE_CMD)"
|
||||||
# set up queries for the fields
|
# set up queries for the fields
|
||||||
select_user="$jq_select_id | .login.username' <$items"
|
select_user="$jq_select_id | .login.username' <$items"
|
||||||
select_pass="$jq_select_id | .login.password' <$items"
|
select_pass="$jq_select_id | .login.password' <$items"
|
||||||
select_totp="$jq_select_id | .login.totp' <$items"
|
select_totp="$jq_select_id | .login.totp' <$items | sed 's/.*secret=//; s/&.*//' | oathtool -b --totp -"
|
||||||
select_link="$jq_select_id | .login.uris[1].uri' <$items"
|
select_link="$jq_select_id | .login.uris[1].uri' <$items"
|
||||||
select_user_pass_totp="$select_user; $select_pass; $select_totp"
|
select_user_pass_totp="$select_user; $select_pass; $select_totp"
|
||||||
|
|
||||||
|
|
@ -173,9 +164,9 @@ if [[ $ONESHOT == 'true' ]]; then
|
||||||
else
|
else
|
||||||
copy_user="execute-silent($select_user | $BWZY_COPY_CMD)"
|
copy_user="execute-silent($select_user | $BWZY_COPY_CMD)"
|
||||||
copy_pass="execute-silent($select_pass | $BWZY_COPY_CMD)"
|
copy_pass="execute-silent($select_pass | $BWZY_COPY_CMD)"
|
||||||
copy_totp="execute-silent($select_totp | $BWZY_TOTP_COPY)"
|
copy_totp="execute-silent($select_totp | $BWZY_COPY_CMD)"
|
||||||
copy_link="execute-silent($select_link | $BWZY_COPY_CMD)"
|
copy_link="execute-silent($select_link | $BWZY_COPY_CMD)"
|
||||||
auto_paste="execute-silent(($select_user_pass_totp) | $BWZY_AUTOFILL_HELPER)"
|
auto_paste="execute-silent(($select_user_pass_totp) | $bwzy_autofill)"
|
||||||
|
|
||||||
copy_user="${pre_action}+${copy_user}+change-prompt($BWZY_USER_SYMBOL)"
|
copy_user="${pre_action}+${copy_user}+change-prompt($BWZY_USER_SYMBOL)"
|
||||||
copy_pass="${pre_action}+${copy_pass}+change-prompt($BWZY_PASS_SYMBOL)"
|
copy_pass="${pre_action}+${copy_pass}+change-prompt($BWZY_PASS_SYMBOL)"
|
||||||
|
|
@ -187,9 +178,9 @@ fi
|
||||||
preview_item="$jq_select_id' < $items | json2yaml | bat --color=always -p -l yaml"
|
preview_item="$jq_select_id' < $items | json2yaml | bat --color=always -p -l yaml"
|
||||||
|
|
||||||
read -r -d '' fzf_header <<FZF_HEADER
|
read -r -d '' fzf_header <<FZF_HEADER
|
||||||
[a-.] preview on/off [a-/] preview wrap [a-?] this help
|
[a-/] preview on/off [a-w] preview wrap [a-h] this help
|
||||||
[a-u] copy username [a-p] copy password [a-t] copy totp
|
[a-u] copy username [a-p] copy password [a-t] copy totp
|
||||||
[a-l] copy link [enter] auto-fill [esc] clear/quit
|
[a-l] copy link [enter] auto-fill [esc] quit
|
||||||
FZF_HEADER
|
FZF_HEADER
|
||||||
|
|
||||||
# | awk -F "$TAB" '{ printf "%s\t%-35s\t%27s\n", $1, $2, $3 }' \
|
# | awk -F "$TAB" '{ printf "%s\t%-35s\t%27s\n", $1, $2, $3 }' \
|
||||||
|
|
@ -200,22 +191,22 @@ FZF_HEADER
|
||||||
jq -r '.[] | [ .id, .name, "`'"$BWZY_FOLDER_SYMBOL"'" + .folderId + "`" ] | join("'"$TAB"'")' <"$items" \
|
jq -r '.[] | [ .id, .name, "`'"$BWZY_FOLDER_SYMBOL"'" + .folderId + "`" ] | join("'"$TAB"'")' <"$items" \
|
||||||
| sed -e "$folder_sed" \
|
| sed -e "$folder_sed" \
|
||||||
| grep ${FILTER_ARG} "${BWZY_FILTER}" \
|
| grep ${FILTER_ARG} "${BWZY_FILTER}" \
|
||||||
| bat -l markdown --color=always --style=plain \
|
| gum format \
|
||||||
| fzf --ansi -i --delimiter="$TAB" --with-nth 2,3 \
|
| fzf --ansi -i --delimiter="$TAB" --with-nth 2,3 \
|
||||||
--header-first \
|
--header-first \
|
||||||
--marker='' --pointer="$BWZY_POINTER_SYMBOL" \
|
--marker='' --pointer="$BWZY_POINTER_SYMBOL" \
|
||||||
--prompt="$BWZY_PROMPT_SYMBOL" \
|
--prompt="$BWZY_PROMPT_SYMBOL" \
|
||||||
--info 'inline' \
|
--info 'inline-right:' \
|
||||||
--info-command 'echo "($FZF_MATCH_COUNT/$FZF_TOTAL_COUNT)"' \
|
--info-command 'echo "($FZF_MATCH_COUNT/$FZF_TOTAL_COUNT)"' \
|
||||||
--bind "alt-u:$copy_user" \
|
--bind "alt-u:$copy_user" \
|
||||||
--bind "alt-p:$copy_pass" \
|
--bind "alt-p:$copy_pass" \
|
||||||
--bind "alt-t:$copy_totp" \
|
--bind "alt-t:$copy_totp" \
|
||||||
--bind "alt-l:$copy_link" \
|
--bind "alt-l:$copy_link" \
|
||||||
--bind "enter:$auto_paste" \
|
--bind "enter:$auto_paste" \
|
||||||
--bind 'alt-,:toggle-preview' \
|
--bind 'alt-/:toggle-preview' \
|
||||||
--bind 'alt-/:toggle-preview-wrap' \
|
--bind 'alt-w:toggle-preview-wrap' \
|
||||||
--bind 'alt-?:toggle-header' \
|
--bind 'alt-h:toggle-header' \
|
||||||
--bind 'esc:cancel' \
|
--bind 'esc:abort' \
|
||||||
--bind 'focus:transform-preview-label:echo {2} / {3}' \
|
--bind 'focus:transform-preview-label:echo {2} / {3}' \
|
||||||
--bind "focus:change-prompt($BWZY_PROMPT_SYMBOL)" \
|
--bind "focus:change-prompt($BWZY_PROMPT_SYMBOL)" \
|
||||||
--preview-window 'down:75%:hidden' \
|
--preview-window 'down:75%:hidden' \
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,9 @@ $BWZY_TYPE_CMD \
|
||||||
-s $next_sleep \
|
-s $next_sleep \
|
||||||
-k return
|
-k return
|
||||||
|
|
||||||
$BWZY_TOTP_COPY <<<"$TOTP"
|
# Copy the TOTP to clipboard
|
||||||
|
if [[ -n "$TOTP" ]]; then
|
||||||
|
echo -n "$TOTP" | cli-copy
|
||||||
|
[[ -n "$BWZY_NOTIFY_CMD" ]] && $BWZY_NOTIFY_CMD "TOTP copied to clipboard"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#/bin/bash
|
|
||||||
|
|
||||||
read -r TOTP_STRING || TOTP_STRING="null"
|
|
||||||
|
|
||||||
# Copy the TOTP to clipboard
|
|
||||||
if [[ "$TOTP_STRING" != "null" ]]; then
|
|
||||||
TOTP=$(echo $TOTP_STRING | sed 's/.*secret=//; s/&.*//' | oathtool -b --totp -)
|
|
||||||
echo -n "$TOTP" | cli-copy
|
|
||||||
[[ -n "$BWZY_NOTIFY_CMD" ]] && $BWZY_NOTIFY_CMD "TOTP copied to clipboard"
|
|
||||||
fi
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
Name=bwzy
|
Name=bwzy
|
||||||
Categories=ConsoleOnly;
|
Categories=ConsoleOnly;
|
||||||
GenericName=Bitwarden Fuzzy
|
GenericName=Bitwarden Fuzzy
|
||||||
Comment=FZF bitwarden UI
|
Comment=Terminal MUA using notmuch mail
|
||||||
Exec=kitty -T 'bwzy' --detach bwzy
|
Exec=kitty -T 'bwzy' --detach bwzy
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Icon=bitwarden
|
Icon=bitwarden
|
||||||
|
|
|
||||||
BIN
bwzy.jpg
BIN
bwzy.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 774 KiB |
Loading…
Add table
Add a link
Reference in a new issue