tools
age-detect
android-webcam
build-installer-iso
deploy
flaxget
gh-act
install-ssh-keys
jellyseekrr
lockscreen
memhack
menu
mic-to-text
name-generator
pass-otp
passmenu
payment-qr
pinentry-rofi
pinentry-rofi-age
power-profile
record
s
ssh-yubikey
tor-ssh-service
tornade
video-webcam
vm-boot
whatsong
wifi-qr
workspace-manager
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.age-detect = (pkgs.writeShellApplication {
7
7
-
name = "age-detect";
8
8
-
runtimeInputs =
9
9
-
with pkgs;
10
10
-
[
11
11
-
age
12
12
-
age-plugin-yubikey
13
13
-
age-plugin-fido2-hmac
14
14
-
age-plugin-tpm
15
15
-
yubikey-manager
16
16
-
libfido2
17
17
-
]
18
18
-
++ (pkgs.lib.optionals pkgs.stdenv.isDarwin [
19
19
-
pkgs.age-plugin-se
20
20
-
]);
21
21
-
text = builtins.readFile ./age-detect;
22
22
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.age-detect =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "age-detect";
9
9
+
runtimeInputs =
10
10
+
with pkgs;
11
11
+
[
12
12
+
age
13
13
+
age-plugin-yubikey
14
14
+
age-plugin-fido2-hmac
15
15
+
age-plugin-tpm
16
16
+
yubikey-manager
17
17
+
libfido2
18
18
+
]
19
19
+
++ (pkgs.lib.optionals pkgs.stdenv.isDarwin [
20
20
+
pkgs.age-plugin-se
21
21
+
]);
22
22
+
text = builtins.readFile ./age-detect;
23
23
+
}).overrideAttrs
24
24
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
23
25
};
24
26
}
···
6
6
ffmpeg-placebo = pkgs.ffmpeg.override { withPlacebo = true; };
7
7
in
8
8
{
9
9
-
packages.android-webcam = (pkgs.writeShellApplication {
10
10
-
name = "android-webcam";
11
11
-
runtimeInputs = [
12
12
-
pkgs.scrcpy
13
13
-
ffmpeg-placebo
14
14
-
pkgs.gnused
15
15
-
];
16
16
-
text = builtins.replaceStrings [ "@shaderPath@" ] [ "${./ascii.hook}" ] (
17
17
-
builtins.readFile ./android-webcam.sh
18
18
-
);
19
19
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
9
9
+
packages.android-webcam =
10
10
+
(pkgs.writeShellApplication {
11
11
+
name = "android-webcam";
12
12
+
runtimeInputs = [
13
13
+
pkgs.scrcpy
14
14
+
ffmpeg-placebo
15
15
+
pkgs.gnused
16
16
+
];
17
17
+
text = builtins.replaceStrings [ "@shaderPath@" ] [ "${./ascii.hook}" ] (
18
18
+
builtins.readFile ./android-webcam.sh
19
19
+
);
20
20
+
}).overrideAttrs
21
21
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
20
22
};
21
23
}
···
168
168
perSystem =
169
169
{ pkgs, ... }:
170
170
{
171
171
-
packages.build-installer-iso = (pkgs.writeShellApplication {
172
172
-
name = "build-installer-iso";
173
173
-
runtimeInputs = with pkgs; [
174
174
-
xorriso
175
175
-
coreutils
176
176
-
nix
177
177
-
];
178
178
-
text = ''
179
179
-
# Export flake root for the script to use
180
180
-
export FLAKE_ROOT="${self}"
181
181
-
${builtins.readFile ./build-installer-iso.sh}
182
182
-
'';
183
183
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
171
171
+
packages.build-installer-iso =
172
172
+
(pkgs.writeShellApplication {
173
173
+
name = "build-installer-iso";
174
174
+
runtimeInputs = with pkgs; [
175
175
+
xorriso
176
176
+
coreutils
177
177
+
nix
178
178
+
];
179
179
+
text = ''
180
180
+
# Export flake root for the script to use
181
181
+
export FLAKE_ROOT="${self}"
182
182
+
${builtins.readFile ./build-installer-iso.sh}
183
183
+
'';
184
184
+
}).overrideAttrs
185
185
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
184
186
};
185
187
}
···
14
14
inputs.clan-core.packages.${system}.clan-cli
15
15
];
16
16
text = ''
17
17
+
set -x
17
18
DEPLOY_TMPDIR=$(mktemp -d)
18
19
chmod 700 "$DEPLOY_TMPDIR"
19
20
trap 'rm -rf "$DEPLOY_TMPDIR"' EXIT
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.flaxget = (pkgs.writeShellApplication {
7
7
-
name = "flaxget";
8
8
-
runtimeInputs = [
9
9
-
pkgs.curl
10
10
-
pkgs.fzf
11
11
-
pkgs.coreutils
12
12
-
pkgs.aria2
13
13
-
];
14
14
-
text = builtins.readFile ./flaxget.sh;
15
15
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.flaxget =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "flaxget";
9
9
+
runtimeInputs = [
10
10
+
pkgs.curl
11
11
+
pkgs.fzf
12
12
+
pkgs.coreutils
13
13
+
pkgs.aria2
14
14
+
];
15
15
+
text = builtins.readFile ./flaxget.sh;
16
16
+
}).overrideAttrs
17
17
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
16
18
};
17
19
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.gh-act = (pkgs.writeShellApplication {
7
7
-
name = "gh-act";
8
8
-
runtimeInputs = with pkgs; [
9
9
-
yq
10
10
-
coreutils
11
11
-
];
12
12
-
text = ''
13
13
-
workflow="''${1:-.github/workflows/ci.yml}"
6
6
+
packages.gh-act =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "gh-act";
9
9
+
runtimeInputs = with pkgs; [
10
10
+
yq
11
11
+
coreutils
12
12
+
];
13
13
+
text = ''
14
14
+
workflow="''${1:-.github/workflows/ci.yml}"
14
15
15
15
-
if [ ! -f "$workflow" ]; then
16
16
-
echo "Usage: gh-act [workflow.yml]"
17
17
-
echo "Run GitHub Actions workflow steps locally"
18
18
-
exit 1
19
19
-
fi
16
16
+
if [ ! -f "$workflow" ]; then
17
17
+
echo "Usage: gh-act [workflow.yml]"
18
18
+
echo "Run GitHub Actions workflow steps locally"
19
19
+
exit 1
20
20
+
fi
20
21
21
21
-
echo "Running: $workflow"
22
22
-
echo "=================="
22
22
+
echo "Running: $workflow"
23
23
+
echo "=================="
23
24
24
24
-
# Extract each step and run it
25
25
-
for job in $(yq -r '.jobs | keys[]' "$workflow"); do
26
26
-
echo "=== Job: $job ==="
27
27
-
step_count=$(yq -r ".jobs[\"$job\"].steps | length" "$workflow")
28
28
-
for i in $(seq 0 $((step_count - 1))); do
29
29
-
name=$(yq -r ".jobs[\"$job\"].steps[$i].name // \"Step $i\"" "$workflow")
30
30
-
run_cmd=$(yq -r ".jobs[\"$job\"].steps[$i].run // empty" "$workflow")
31
31
-
32
32
-
if [ -n "$run_cmd" ]; then
33
33
-
echo ">>> Running: $name"
34
34
-
echo "---"
35
35
-
bash -c "$run_cmd"
36
36
-
echo
37
37
-
fi
25
25
+
# Extract each step and run it
26
26
+
for job in $(yq -r '.jobs | keys[]' "$workflow"); do
27
27
+
echo "=== Job: $job ==="
28
28
+
step_count=$(yq -r ".jobs[\"$job\"].steps | length" "$workflow")
29
29
+
for i in $(seq 0 $((step_count - 1))); do
30
30
+
name=$(yq -r ".jobs[\"$job\"].steps[$i].name // \"Step $i\"" "$workflow")
31
31
+
run_cmd=$(yq -r ".jobs[\"$job\"].steps[$i].run // empty" "$workflow")
32
32
+
33
33
+
if [ -n "$run_cmd" ]; then
34
34
+
echo ">>> Running: $name"
35
35
+
echo "---"
36
36
+
bash -c "$run_cmd"
37
37
+
echo
38
38
+
fi
39
39
+
done
38
40
done
39
39
-
done
40
40
-
'';
41
41
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
41
41
+
'';
42
42
+
}).overrideAttrs
43
43
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
42
44
};
43
45
}
···
11
11
'';
12
12
in
13
13
{
14
14
-
packages.install-ssh-keys = (pkgs.writeShellApplication {
15
15
-
name = "install-ssh-keys";
16
16
-
runtimeInputs = [ ];
17
17
-
text = ''
18
18
-
set -euo pipefail
14
14
+
packages.install-ssh-keys =
15
15
+
(pkgs.writeShellApplication {
16
16
+
name = "install-ssh-keys";
17
17
+
runtimeInputs = [ ];
18
18
+
text = ''
19
19
+
set -euo pipefail
19
20
20
20
-
# Check if we're running as root
21
21
-
if [[ $EUID -ne 0 ]]; then
22
22
-
echo "Not running as root. Using sudo to install keys to /root/.ssh/authorized_keys"
23
23
-
exec sudo "$0" "$@"
24
24
-
fi
21
21
+
# Check if we're running as root
22
22
+
if [[ $EUID -ne 0 ]]; then
23
23
+
echo "Not running as root. Using sudo to install keys to /root/.ssh/authorized_keys"
24
24
+
exec sudo "$0" "$@"
25
25
+
fi
25
26
26
26
-
# Create /root/.ssh directory if it doesn't exist
27
27
-
mkdir -p /root/.ssh
28
28
-
chmod 700 /root/.ssh
27
27
+
# Create /root/.ssh directory if it doesn't exist
28
28
+
mkdir -p /root/.ssh
29
29
+
chmod 700 /root/.ssh
29
30
30
30
-
# Append the authorized_keys
31
31
-
cat ${authorizedKeysFile} >> /root/.ssh/authorized_keys
32
32
-
chmod 600 /root/.ssh/authorized_keys
31
31
+
# Append the authorized_keys
32
32
+
cat ${authorizedKeysFile} >> /root/.ssh/authorized_keys
33
33
+
chmod 600 /root/.ssh/authorized_keys
33
34
34
34
-
echo "Appended SSH keys to /root/.ssh/authorized_keys: ${lib.concatStringsSep ", " (lib.attrNames self.keys.ssh)}"
35
35
-
'';
36
36
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
35
35
+
echo "Appended SSH keys to /root/.ssh/authorized_keys: ${lib.concatStringsSep ", " (lib.attrNames self.keys.ssh)}"
36
36
+
'';
37
37
+
}).overrideAttrs
38
38
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
37
39
};
38
40
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.jellyseekrr = (pkgs.writeShellApplication {
7
7
-
name = "jellyseekrr";
8
8
-
runtimeInputs = with pkgs; [
9
9
-
self.packages.${pkgs.system}.menu
10
10
-
self.packages.${pkgs.system}.pass
11
11
-
curl
12
12
-
jq
13
13
-
];
14
14
-
text = builtins.readFile ./jellyseekrr.sh;
15
15
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.jellyseekrr =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "jellyseekrr";
9
9
+
runtimeInputs = with pkgs; [
10
10
+
self.packages.${pkgs.system}.menu
11
11
+
self.packages.${pkgs.system}.pass
12
12
+
curl
13
13
+
jq
14
14
+
];
15
15
+
text = builtins.readFile ./jellyseekrr.sh;
16
16
+
}).overrideAttrs
17
17
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
16
18
};
17
19
}
···
2
2
perSystem =
3
3
{ pkgs, ... }:
4
4
{
5
5
-
packages.lockscreen = (pkgs.writeShellApplication {
6
6
-
name = "lockscreen";
7
7
-
runtimeInputs = [
8
8
-
pkgs.ffmpeg
9
9
-
pkgs.coreutils
10
10
-
pkgs.procps
11
11
-
pkgs.swaylock-plugin
12
12
-
pkgs.mpvpaper
13
13
-
];
14
14
-
text = ''
15
15
-
VIDEO=$(shuf -n1 -e "$HOME"/lockscreens/*.mp4)
16
16
-
DURATION=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$VIDEO" 2>/dev/null | cut -d. -f1)
17
17
-
START=$((RANDOM % ''${DURATION:-300}))
18
18
-
exec swaylock-plugin --command "mpvpaper -o \"no-audio loop start=$START\" '*' \"$VIDEO\"" "$@"
19
19
-
'';
20
20
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
5
5
+
packages.lockscreen =
6
6
+
(pkgs.writeShellApplication {
7
7
+
name = "lockscreen";
8
8
+
runtimeInputs = [
9
9
+
pkgs.ffmpeg
10
10
+
pkgs.coreutils
11
11
+
pkgs.procps
12
12
+
pkgs.swaylock-plugin
13
13
+
pkgs.mpvpaper
14
14
+
];
15
15
+
text = ''
16
16
+
VIDEO=$(shuf -n1 -e "$HOME"/lockscreens/*.mp4)
17
17
+
DURATION=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$VIDEO" 2>/dev/null | cut -d. -f1)
18
18
+
START=$((RANDOM % ''${DURATION:-300}))
19
19
+
exec swaylock-plugin --command "mpvpaper -o \"no-audio loop start=$START\" '*' \"$VIDEO\"" "$@"
20
20
+
'';
21
21
+
}).overrideAttrs
22
22
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
21
23
};
22
24
}
···
12
12
};
13
13
in
14
14
{
15
15
-
packages.memhack = (pkgs.writeShellApplication {
16
16
-
name = "memhack";
17
17
-
runtimeInputs = [
18
18
-
pkgs.procps
19
19
-
pkgs.fzf
20
20
-
memhack-repl
21
21
-
];
22
22
-
text = builtins.readFile ./memhack.sh;
23
23
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
15
15
+
packages.memhack =
16
16
+
(pkgs.writeShellApplication {
17
17
+
name = "memhack";
18
18
+
runtimeInputs = [
19
19
+
pkgs.procps
20
20
+
pkgs.fzf
21
21
+
memhack-repl
22
22
+
];
23
23
+
text = builtins.readFile ./memhack.sh;
24
24
+
}).overrideAttrs
25
25
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
24
26
};
25
27
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.mic-to-text = (pkgs.writeShellApplication {
7
7
-
name = "mic-to-text";
8
8
-
runtimeInputs = [
9
9
-
pkgs.sox
10
10
-
pkgs.whisper-cpp
11
11
-
pkgs.curl
12
12
-
];
13
13
-
text = builtins.readFile ./mic-to-text.sh;
14
14
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.mic-to-text =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "mic-to-text";
9
9
+
runtimeInputs = [
10
10
+
pkgs.sox
11
11
+
pkgs.whisper-cpp
12
12
+
pkgs.curl
13
13
+
];
14
14
+
text = builtins.readFile ./mic-to-text.sh;
15
15
+
}).overrideAttrs
16
16
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
15
17
};
16
18
}
···
13
13
};
14
14
in
15
15
{
16
16
-
packages.name-generator = (pkgs.writeShellApplication {
17
17
-
name = "name-generator";
18
18
-
runtimeInputs = [ pkgs.bash ];
19
19
-
text = ''
20
20
-
# Data files location
21
21
-
DATA_DIR="${dataFiles}"
22
22
-
# Default separator
23
23
-
SEPARATOR="-"
24
24
-
# Parse command line options
25
25
-
while [[ $# -gt 0 ]]; do
26
26
-
case $1 in
27
27
-
-s|--separator)
28
28
-
SEPARATOR="$2"
29
29
-
shift 2
30
30
-
;;
31
31
-
-h|--help)
32
32
-
echo "Usage: $0 [OPTIONS]"
33
33
-
echo "Generate a random name in the format: adjective-noun"
34
34
-
echo ""
35
35
-
echo "Options:"
36
36
-
echo " -s, --separator CHAR Use CHAR as separator (default: -)"
37
37
-
echo " -h, --help Show this help message"
38
38
-
exit 0
39
39
-
;;
40
40
-
*)
41
41
-
echo "Unknown option: $1"
42
42
-
exit 1
43
43
-
;;
44
44
-
esac
45
45
-
done
46
46
-
# Read adjectives and nouns
47
47
-
mapfile -t ADJECTIVES < "$DATA_DIR/adjectives.txt"
48
48
-
mapfile -t NOUNS < "$DATA_DIR/nouns.txt"
49
49
-
# Select random adjective and noun
50
50
-
ADJ_INDEX=$((RANDOM % ''${#ADJECTIVES[@]}))
51
51
-
NOUN_INDEX=$((RANDOM % ''${#NOUNS[@]}))
52
52
-
# Output the generated name
53
53
-
echo "''${ADJECTIVES[$ADJ_INDEX]}''${SEPARATOR}''${NOUNS[$NOUN_INDEX]}"
54
54
-
'';
55
55
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
16
16
+
packages.name-generator =
17
17
+
(pkgs.writeShellApplication {
18
18
+
name = "name-generator";
19
19
+
runtimeInputs = [ pkgs.bash ];
20
20
+
text = ''
21
21
+
# Data files location
22
22
+
DATA_DIR="${dataFiles}"
23
23
+
# Default separator
24
24
+
SEPARATOR="-"
25
25
+
# Parse command line options
26
26
+
while [[ $# -gt 0 ]]; do
27
27
+
case $1 in
28
28
+
-s|--separator)
29
29
+
SEPARATOR="$2"
30
30
+
shift 2
31
31
+
;;
32
32
+
-h|--help)
33
33
+
echo "Usage: $0 [OPTIONS]"
34
34
+
echo "Generate a random name in the format: adjective-noun"
35
35
+
echo ""
36
36
+
echo "Options:"
37
37
+
echo " -s, --separator CHAR Use CHAR as separator (default: -)"
38
38
+
echo " -h, --help Show this help message"
39
39
+
exit 0
40
40
+
;;
41
41
+
*)
42
42
+
echo "Unknown option: $1"
43
43
+
exit 1
44
44
+
;;
45
45
+
esac
46
46
+
done
47
47
+
# Read adjectives and nouns
48
48
+
mapfile -t ADJECTIVES < "$DATA_DIR/adjectives.txt"
49
49
+
mapfile -t NOUNS < "$DATA_DIR/nouns.txt"
50
50
+
# Select random adjective and noun
51
51
+
ADJ_INDEX=$((RANDOM % ''${#ADJECTIVES[@]}))
52
52
+
NOUN_INDEX=$((RANDOM % ''${#NOUNS[@]}))
53
53
+
# Output the generated name
54
54
+
echo "''${ADJECTIVES[$ADJ_INDEX]}''${SEPARATOR}''${NOUNS[$NOUN_INDEX]}"
55
55
+
'';
56
56
+
}).overrideAttrs
57
57
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
56
58
};
57
59
}
···
3
3
perSystem =
4
4
{ pkgs, lib, ... }:
5
5
{
6
6
-
packages.pass-otp = (pkgs.writeShellApplication {
7
7
-
name = "pass-otp";
8
8
-
runtimeInputs = [
9
9
-
pkgs.oath-toolkit
10
10
-
]
11
11
-
++ lib.optionals (!pkgs.stdenv.isDarwin) [
12
12
-
pkgs.xclip
13
13
-
pkgs.wl-clipboard
14
14
-
];
15
15
-
text = ''
16
16
-
set -euo pipefail
17
17
-
# Tool-agnostic OTP generator that accepts secret via stdin or args
6
6
+
packages.pass-otp =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "pass-otp";
9
9
+
runtimeInputs = [
10
10
+
pkgs.oath-toolkit
11
11
+
]
12
12
+
++ lib.optionals (!pkgs.stdenv.isDarwin) [
13
13
+
pkgs.xclip
14
14
+
pkgs.wl-clipboard
15
15
+
];
16
16
+
text = ''
17
17
+
set -euo pipefail
18
18
+
# Tool-agnostic OTP generator that accepts secret via stdin or args
18
19
19
19
-
show_usage() {
20
20
-
echo "Usage: pass-otp [--clip,-c] <secret>"
21
21
-
echo " echo <secret> | pass-otp [--clip,-c]"
22
22
-
echo ""
23
23
-
echo "Accepts OTP secret as argument or via stdin"
24
24
-
echo "Secret can be:"
25
25
-
echo " - Raw base32 secret"
26
26
-
echo " - otpauth:// URL"
27
27
-
echo " - Multi-line text with secret on line 2+"
28
28
-
}
20
20
+
show_usage() {
21
21
+
echo "Usage: pass-otp [--clip,-c] <secret>"
22
22
+
echo " echo <secret> | pass-otp [--clip,-c]"
23
23
+
echo ""
24
24
+
echo "Accepts OTP secret as argument or via stdin"
25
25
+
echo "Secret can be:"
26
26
+
echo " - Raw base32 secret"
27
27
+
echo " - otpauth:// URL"
28
28
+
echo " - Multi-line text with secret on line 2+"
29
29
+
}
29
30
30
30
-
clip=false
31
31
-
secret_input=""
31
31
+
clip=false
32
32
+
secret_input=""
32
33
33
33
-
# Parse arguments
34
34
-
while [[ $# -gt 0 ]]; do
35
35
-
case "$1" in
36
36
-
"--clip"|"-c")
37
37
-
clip=true
38
38
-
shift
39
39
-
;;
40
40
-
"--help"|"-h")
41
41
-
show_usage
42
42
-
exit 0
43
43
-
;;
44
44
-
*)
45
45
-
secret_input="$1"
46
46
-
shift
47
47
-
;;
48
48
-
esac
49
49
-
done
34
34
+
# Parse arguments
35
35
+
while [[ $# -gt 0 ]]; do
36
36
+
case "$1" in
37
37
+
"--clip"|"-c")
38
38
+
clip=true
39
39
+
shift
40
40
+
;;
41
41
+
"--help"|"-h")
42
42
+
show_usage
43
43
+
exit 0
44
44
+
;;
45
45
+
*)
46
46
+
secret_input="$1"
47
47
+
shift
48
48
+
;;
49
49
+
esac
50
50
+
done
50
51
51
51
-
# If no argument provided, read from stdin
52
52
-
if [[ -z "$secret_input" ]]; then
53
53
-
secret_input=$(cat)
54
54
-
fi
52
52
+
# If no argument provided, read from stdin
53
53
+
if [[ -z "$secret_input" ]]; then
54
54
+
secret_input=$(cat)
55
55
+
fi
55
56
56
56
-
if [[ -z "$secret_input" ]]; then
57
57
-
echo "Error: No OTP secret provided"
58
58
-
show_usage
59
59
-
exit 1
60
60
-
fi
61
61
-
62
62
-
# Extract TOTP secret from input
63
63
-
if echo "$secret_input" | grep -q "^otpauth://"; then
64
64
-
# Extract secret from otpauth URL
65
65
-
secret_key=$(echo "$secret_input" | sed -n 's/.*secret=\([^&]*\).*/\1/p')
66
66
-
elif echo "$secret_input" | wc -l | grep -q "^1$"; then
67
67
-
# Single line - assume it's the raw secret
68
68
-
secret_key=$(echo "$secret_input" | tr -d ' ')
69
69
-
else
70
70
-
# Multi-line - assume secret is on line 2 or later
71
71
-
secret_key=$(echo "$secret_input" | tail -n +2 | head -n 1 | tr -d ' ')
72
72
-
fi
73
73
-
74
74
-
if [[ -z "$secret_key" ]]; then
75
75
-
echo "Error: Could not extract OTP secret from input"
76
76
-
exit 1
77
77
-
fi
78
78
-
79
79
-
# Generate OTP code
80
80
-
otp_code=$(oathtool --totp --base32 "$secret_key")
81
81
-
82
82
-
# Output or copy to clipboard
83
83
-
if [[ "$clip" == "true" ]]; then
84
84
-
if [[ "$(uname)" == "Darwin" ]]; then
85
85
-
echo -n "$otp_code" | pbcopy
86
86
-
echo "Copied OTP code to clipboard."
87
87
-
elif [[ -n "''${WAYLAND_DISPLAY:-}" ]] && command -v wl-copy >/dev/null 2>&1; then
88
88
-
echo -n "$otp_code" | wl-copy
89
89
-
echo "Copied OTP code to clipboard (Wayland)."
90
90
-
elif [[ -n "''${DISPLAY:-}" ]] && command -v xclip >/dev/null 2>&1; then
91
91
-
echo -n "$otp_code" | xclip -selection clipboard
92
92
-
echo "Copied OTP code to clipboard (X11)."
93
93
-
else
94
94
-
echo "Error: No clipboard tool found (tried pbcopy, wl-copy, xclip)"
95
95
-
echo "$otp_code"
57
57
+
if [[ -z "$secret_input" ]]; then
58
58
+
echo "Error: No OTP secret provided"
59
59
+
show_usage
96
60
exit 1
97
61
fi
98
98
-
else
99
99
-
echo "$otp_code"
100
100
-
fi
101
101
-
'';
102
102
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
62
62
+
63
63
+
# Extract TOTP secret from input
64
64
+
if echo "$secret_input" | grep -q "^otpauth://"; then
65
65
+
# Extract secret from otpauth URL
66
66
+
secret_key=$(echo "$secret_input" | sed -n 's/.*secret=\([^&]*\).*/\1/p')
67
67
+
elif echo "$secret_input" | wc -l | grep -q "^1$"; then
68
68
+
# Single line - assume it's the raw secret
69
69
+
secret_key=$(echo "$secret_input" | tr -d ' ')
70
70
+
else
71
71
+
# Multi-line - assume secret is on line 2 or later
72
72
+
secret_key=$(echo "$secret_input" | tail -n +2 | head -n 1 | tr -d ' ')
73
73
+
fi
74
74
+
75
75
+
if [[ -z "$secret_key" ]]; then
76
76
+
echo "Error: Could not extract OTP secret from input"
77
77
+
exit 1
78
78
+
fi
79
79
+
80
80
+
# Generate OTP code
81
81
+
otp_code=$(oathtool --totp --base32 "$secret_key")
82
82
+
83
83
+
# Output or copy to clipboard
84
84
+
if [[ "$clip" == "true" ]]; then
85
85
+
if [[ "$(uname)" == "Darwin" ]]; then
86
86
+
echo -n "$otp_code" | pbcopy
87
87
+
echo "Copied OTP code to clipboard."
88
88
+
elif [[ -n "''${WAYLAND_DISPLAY:-}" ]] && command -v wl-copy >/dev/null 2>&1; then
89
89
+
echo -n "$otp_code" | wl-copy
90
90
+
echo "Copied OTP code to clipboard (Wayland)."
91
91
+
elif [[ -n "''${DISPLAY:-}" ]] && command -v xclip >/dev/null 2>&1; then
92
92
+
echo -n "$otp_code" | xclip -selection clipboard
93
93
+
echo "Copied OTP code to clipboard (X11)."
94
94
+
else
95
95
+
echo "Error: No clipboard tool found (tried pbcopy, wl-copy, xclip)"
96
96
+
echo "$otp_code"
97
97
+
exit 1
98
98
+
fi
99
99
+
else
100
100
+
echo "$otp_code"
101
101
+
fi
102
102
+
'';
103
103
+
}).overrideAttrs
104
104
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
103
105
};
104
106
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.payment-qr = (pkgs.writeShellApplication {
7
7
-
name = "payment-qr";
8
8
-
runtimeInputs = [
9
9
-
pkgs.qrencode
10
10
-
];
11
11
-
text = builtins.readFile ./payment-qr.sh;
12
12
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.payment-qr =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "payment-qr";
9
9
+
runtimeInputs = [
10
10
+
pkgs.qrencode
11
11
+
];
12
12
+
text = builtins.readFile ./payment-qr.sh;
13
13
+
}).overrideAttrs
14
14
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
13
15
};
14
16
}
···
2
2
perSystem =
3
3
{ pkgs, ... }:
4
4
{
5
5
-
packages.pinentry-rofi-age = (pkgs.writeShellApplication {
6
6
-
name = "pinentry-rofi-age";
7
7
-
runtimeInputs = with pkgs; [
8
8
-
rofi
9
9
-
coreutils
10
10
-
gnused
11
11
-
keyutils
12
12
-
];
13
13
-
text = builtins.readFile ./pinentry-rofi-age.sh;
14
14
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
5
5
+
packages.pinentry-rofi-age =
6
6
+
(pkgs.writeShellApplication {
7
7
+
name = "pinentry-rofi-age";
8
8
+
runtimeInputs = with pkgs; [
9
9
+
rofi
10
10
+
coreutils
11
11
+
gnused
12
12
+
keyutils
13
13
+
];
14
14
+
text = builtins.readFile ./pinentry-rofi-age.sh;
15
15
+
}).overrideAttrs
16
16
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
15
17
};
16
18
}
···
2
2
perSystem =
3
3
{ pkgs, ... }:
4
4
{
5
5
-
packages.pinentry-rofi = (pkgs.writeShellApplication {
6
6
-
name = "pinentry-rofi";
7
7
-
runtimeInputs = with pkgs; [
8
8
-
rofi
9
9
-
coreutils
10
10
-
gnused
11
11
-
keyutils
12
12
-
];
13
13
-
text = builtins.readFile ./pinentry-rofi.sh;
14
14
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
5
5
+
packages.pinentry-rofi =
6
6
+
(pkgs.writeShellApplication {
7
7
+
name = "pinentry-rofi";
8
8
+
runtimeInputs = with pkgs; [
9
9
+
rofi
10
10
+
coreutils
11
11
+
gnused
12
12
+
keyutils
13
13
+
];
14
14
+
text = builtins.readFile ./pinentry-rofi.sh;
15
15
+
}).overrideAttrs
16
16
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
15
17
};
16
18
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.power-profile = (pkgs.writeShellApplication {
7
7
-
name = "power-profile";
8
8
-
text = builtins.readFile ./power-profile.sh;
9
9
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.power-profile =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "power-profile";
9
9
+
text = builtins.readFile ./power-profile.sh;
10
10
+
}).overrideAttrs
11
11
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
10
12
};
11
13
}
···
3
3
perSystem =
4
4
{ pkgs, self', ... }:
5
5
{
6
6
-
packages.record = (pkgs.writeShellApplication {
7
7
-
name = "record";
8
8
-
runtimeInputs = [
9
9
-
pkgs.ffmpeg
10
10
-
pkgs.gum
11
11
-
]
12
12
-
++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs.pulseaudio ]
13
13
-
++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin [ self'.packages.system-audio-dump ];
14
14
-
text = builtins.readFile ./rec.sh;
15
15
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.record =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "record";
9
9
+
runtimeInputs = [
10
10
+
pkgs.ffmpeg
11
11
+
pkgs.gum
12
12
+
]
13
13
+
++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs.pulseaudio ]
14
14
+
++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin [ self'.packages.system-audio-dump ];
15
15
+
text = builtins.readFile ./rec.sh;
16
16
+
}).overrideAttrs
17
17
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
16
18
};
17
19
}
···
93
93
'';
94
94
in
95
95
{
96
96
-
packages.s = (pkgs.writeShellApplication {
97
97
-
name = "s";
98
98
-
runtimeInputs = [ pkgs.nix ];
99
99
-
text = ''
100
100
-
# Use local checkout if it exists, otherwise fall back to self
101
101
-
if [ -d "$HOME/src/superconfig" ]; then
102
102
-
flake="$HOME/src/superconfig"
103
103
-
else
104
104
-
flake="${self}"
105
105
-
fi
96
96
+
packages.s =
97
97
+
(pkgs.writeShellApplication {
98
98
+
name = "s";
99
99
+
runtimeInputs = [ pkgs.nix ];
100
100
+
text = ''
101
101
+
# Use local checkout if it exists, otherwise fall back to self
102
102
+
if [ -d "$HOME/src/superconfig" ]; then
103
103
+
flake="$HOME/src/superconfig"
104
104
+
else
105
105
+
flake="${self}"
106
106
+
fi
106
107
107
107
-
if [ $# -eq 0 ]; then
108
108
-
echo "Usage: s <package> [args...]" >&2
109
109
-
echo "Runs a package from superconfig ($flake)" >&2
110
110
-
exit 1
111
111
-
fi
108
108
+
if [ $# -eq 0 ]; then
109
109
+
echo "Usage: s <package> [args...]" >&2
110
110
+
echo "Runs a package from superconfig ($flake)" >&2
111
111
+
exit 1
112
112
+
fi
112
113
113
113
-
pkg="$1"
114
114
-
shift
114
114
+
pkg="$1"
115
115
+
shift
115
116
116
116
-
exec nix run "$flake#$pkg" -- "$@"
117
117
-
'';
118
118
-
}).overrideAttrs (old: {
119
119
-
buildCommand =
120
120
-
old.buildCommand
121
121
-
+ ''
122
122
-
mkdir -p $out/share/zsh/site-functions
123
123
-
cp ${zshCompletion} $out/share/zsh/site-functions/_s
117
117
+
exec nix run "$flake#$pkg" -- "$@"
124
118
'';
125
125
-
passthru = (old.passthru or { }) // {
126
126
-
usage = builtins.readFile ./usage.kdl;
127
127
-
};
128
128
-
});
119
119
+
}).overrideAttrs
120
120
+
(old: {
121
121
+
buildCommand = old.buildCommand + ''
122
122
+
mkdir -p $out/share/zsh/site-functions
123
123
+
cp ${zshCompletion} $out/share/zsh/site-functions/_s
124
124
+
'';
125
125
+
passthru = (old.passthru or { }) // {
126
126
+
usage = builtins.readFile ./usage.kdl;
127
127
+
};
128
128
+
});
129
129
};
130
130
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.ssh-yubikey = (inputs.wrappers.lib.wrapPackage {
7
7
-
pkgs = pkgs;
8
8
-
package = pkgs.openssh;
9
9
-
env = {
10
10
-
KEYS_DIR = "${self}/keys";
11
11
-
SSH = "${pkgs.openssh}/bin/ssh";
12
12
-
};
13
13
-
runtimeInputs = with pkgs; [
14
14
-
age
15
15
-
age-plugin-yubikey
16
16
-
age-plugin-fido2-hmac
17
17
-
yubikey-manager
18
18
-
libfido2
19
19
-
self.packages.${pkgs.system}.age-detect
20
20
-
];
21
21
-
wrapper =
22
22
-
{ envString, ... }:
23
23
-
''
24
24
-
${envString}
25
25
-
${builtins.readFile ./ssh-yubikey}
26
26
-
'';
27
27
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.ssh-yubikey =
7
7
+
(inputs.wrappers.lib.wrapPackage {
8
8
+
pkgs = pkgs;
9
9
+
package = pkgs.openssh;
10
10
+
env = {
11
11
+
KEYS_DIR = "${self}/keys";
12
12
+
SSH = "${pkgs.openssh}/bin/ssh";
13
13
+
};
14
14
+
runtimeInputs = with pkgs; [
15
15
+
age
16
16
+
age-plugin-yubikey
17
17
+
age-plugin-fido2-hmac
18
18
+
yubikey-manager
19
19
+
libfido2
20
20
+
self.packages.${pkgs.system}.age-detect
21
21
+
];
22
22
+
wrapper =
23
23
+
{ envString, ... }:
24
24
+
''
25
25
+
${envString}
26
26
+
${builtins.readFile ./ssh-yubikey}
27
27
+
'';
28
28
+
}).overrideAttrs
29
29
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
28
30
};
29
31
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.tor-ssh-service = (pkgs.writeShellApplication {
7
7
-
name = "tor-ssh-service";
8
8
-
runtimeInputs = with pkgs; [
9
9
-
tor
10
10
-
coreutils
11
11
-
gnugrep
12
12
-
procps
13
13
-
qrencode
14
14
-
];
15
15
-
text = builtins.readFile ./tor-ssh-service.sh;
16
16
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.tor-ssh-service =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "tor-ssh-service";
9
9
+
runtimeInputs = with pkgs; [
10
10
+
tor
11
11
+
coreutils
12
12
+
gnugrep
13
13
+
procps
14
14
+
qrencode
15
15
+
];
16
16
+
text = builtins.readFile ./tor-ssh-service.sh;
17
17
+
}).overrideAttrs
18
18
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
17
19
};
18
20
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.tornade = (pkgs.writeShellApplication {
7
7
-
name = "tornade";
8
8
-
runtimeInputs = with pkgs; [
9
9
-
tor
10
10
-
torsocks
11
11
-
coreutils
12
12
-
procps
13
13
-
];
14
14
-
text = builtins.readFile ./tornade.sh;
15
15
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.tornade =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "tornade";
9
9
+
runtimeInputs = with pkgs; [
10
10
+
tor
11
11
+
torsocks
12
12
+
coreutils
13
13
+
procps
14
14
+
];
15
15
+
text = builtins.readFile ./tornade.sh;
16
16
+
}).overrideAttrs
17
17
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
16
18
};
17
19
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.video-webcam = (pkgs.writeShellApplication {
7
7
-
name = "video-webcam";
8
8
-
runtimeInputs = [
9
9
-
pkgs.ffmpeg
10
10
-
];
11
11
-
text = builtins.readFile ./video-webcam.sh;
12
12
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.video-webcam =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "video-webcam";
9
9
+
runtimeInputs = [
10
10
+
pkgs.ffmpeg
11
11
+
];
12
12
+
text = builtins.readFile ./video-webcam.sh;
13
13
+
}).overrideAttrs
14
14
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
13
15
};
14
16
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.vm-boot = (pkgs.writeShellApplication {
7
7
-
name = "vm-boot";
8
8
-
runtimeInputs = with pkgs; [
9
9
-
qemu
10
10
-
file
11
11
-
util-linux
12
12
-
nix
13
13
-
];
14
14
-
text = builtins.readFile ./vm-boot.sh;
15
15
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.vm-boot =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "vm-boot";
9
9
+
runtimeInputs = with pkgs; [
10
10
+
qemu
11
11
+
file
12
12
+
util-linux
13
13
+
nix
14
14
+
];
15
15
+
text = builtins.readFile ./vm-boot.sh;
16
16
+
}).overrideAttrs
17
17
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
16
18
};
17
19
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.whatsong = (pkgs.writeShellApplication {
7
7
-
name = "whatsong";
8
8
-
runtimeInputs = [
9
9
-
pkgs.sox
10
10
-
pkgs.songrec
11
11
-
pkgs.jq
12
12
-
pkgs.yt-dlp
13
13
-
];
14
14
-
text = builtins.readFile ./whatsong.sh;
15
15
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.whatsong =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "whatsong";
9
9
+
runtimeInputs = [
10
10
+
pkgs.sox
11
11
+
pkgs.songrec
12
12
+
pkgs.jq
13
13
+
pkgs.yt-dlp
14
14
+
];
15
15
+
text = builtins.readFile ./whatsong.sh;
16
16
+
}).overrideAttrs
17
17
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
16
18
};
17
19
}
···
3
3
perSystem =
4
4
{ pkgs, ... }:
5
5
{
6
6
-
packages.wifi-qr = (pkgs.writeShellApplication {
7
7
-
name = "wifi-qr";
8
8
-
runtimeInputs = [
9
9
-
pkgs.zbar
10
10
-
pkgs.gawk
11
11
-
];
12
12
-
text = builtins.readFile ./wifi-qr.sh;
13
13
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
6
6
+
packages.wifi-qr =
7
7
+
(pkgs.writeShellApplication {
8
8
+
name = "wifi-qr";
9
9
+
runtimeInputs = [
10
10
+
pkgs.zbar
11
11
+
pkgs.gawk
12
12
+
];
13
13
+
text = builtins.readFile ./wifi-qr.sh;
14
14
+
}).overrideAttrs
15
15
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
14
16
};
15
17
}
···
6
6
python = pkgs.python3;
7
7
in
8
8
{
9
9
-
packages.workspace-manager = (pkgs.writeShellApplication {
10
10
-
name = "workspace-manager";
11
11
-
runtimeInputs = [
12
12
-
pkgs.socat
13
13
-
pkgs.jq
14
14
-
];
15
15
-
text = builtins.readFile ./workspace-manager.sh;
16
16
-
}).overrideAttrs { passthru.usage = builtins.readFile ./usage.kdl; };
9
9
+
packages.workspace-manager =
10
10
+
(pkgs.writeShellApplication {
11
11
+
name = "workspace-manager";
12
12
+
runtimeInputs = [
13
13
+
pkgs.socat
14
14
+
pkgs.jq
15
15
+
];
16
16
+
text = builtins.readFile ./workspace-manager.sh;
17
17
+
}).overrideAttrs
18
18
+
{ passthru.usage = builtins.readFile ./usage.kdl; };
17
19
18
20
packages.workspace-manager-daemon = pkgs.stdenv.mkDerivation {
19
21
pname = "workspace-manager-daemon";