···
${pkgs.gum}/bin/gum style --foreground 35 "✓ Default push remote is origin"
103
+
assh = pkgs.writeShellScriptBin "assh" ''
104
+
# SSH auto-reconnect
108
+
if [[ -z "$host" || -z "$port" ]]; then
109
+
${pkgs.gum}/bin/gum style --foreground 196 "Usage: assh <host> <port>"
113
+
${pkgs.gum}/bin/gum style --foreground 212 "Connecting to $host:$port (auto-reconnect enabled)..."
116
+
${pkgs.openssh}/bin/ssh -p "$port" -o "BatchMode yes" "$host" || {
117
+
${pkgs.gum}/bin/gum style --foreground 214 "Connection lost. Reconnecting in 1s..."
123
+
hackatime-summary = pkgs.writeShellScriptBin "hackatime-summary" ''
124
+
# Hackatime summary
127
+
if [[ -z "$user_id" ]]; then
128
+
user_id=$(${pkgs.gum}/bin/gum input --placeholder "Enter user ID" --prompt "User ID: ")
129
+
if [[ -z "$user_id" ]]; then
130
+
${pkgs.gum}/bin/gum style --foreground 196 "No user ID provided"
135
+
${pkgs.gum}/bin/gum spin --spinner dot --title "Fetching Hackatime summary for $user_id..." -- \
136
+
${pkgs.curl}/bin/curl -s -X 'GET' \
137
+
"https://waka.hackclub.com/api/summary?user=''${user_id}&interval=month" \
138
+
-H 'accept: application/json' \
139
+
-H 'Authorization: Bearer 2ce9e698-8a16-46f0-b49a-ac121bcfd608' \
140
+
> /tmp/hackatime-$$.json
142
+
${pkgs.jq}/bin/jq '. + {
143
+
"total_categories_sum": (.categories | map(.total) | add),
144
+
"total_categories_human_readable": (
145
+
(.categories | map(.total) | add) as $total_seconds |
146
+
"\($total_seconds / 3600 | floor)h \(($total_seconds % 3600) / 60 | floor)m \($total_seconds % 60)s"
149
+
.projects | sort_by(-.total) | map(.key)
151
+
}' /tmp/hackatime-$$.json
153
+
rm -f /tmp/hackatime-$$.json
156
+
now = pkgs.writeShellScriptBin "now" ''
157
+
# Post AtProto status updates
159
+
prompt_message=true
162
+
while [[ $# -gt 0 ]]; do
166
+
prompt_message=false
170
+
${pkgs.gum}/bin/gum style --foreground 196 "Usage: now [-m|--message \"your message\"]"
176
+
# Load account information from agenix secrets
177
+
if [[ -f "/run/agenix/bluesky" ]]; then
178
+
source "/run/agenix/bluesky"
180
+
${pkgs.gum}/bin/gum style --foreground 196 "Error: Bluesky credentials file not found at /run/agenix/bluesky"
184
+
# Prompt for message if none provided
185
+
if [[ "$prompt_message" = true ]]; then
186
+
message=$(${pkgs.gum}/bin/gum input --placeholder "What's happening?" --prompt "$ACCOUNT1 is: ")
187
+
if [[ -z "$message" ]]; then
188
+
${pkgs.gum}/bin/gum style --foreground 214 "No message provided. Aborting."
193
+
${pkgs.gum}/bin/gum spin --spinner dot --title "Posting to Bluesky..." -- /bin/bash <<EOF
194
+
# Generate JWT for ACCOUNT1
195
+
account1_response=\$(${pkgs.curl}/bin/curl -s -X POST \
196
+
-H "Content-Type: application/json" \
198
+
"identifier": "'$ACCOUNT1'",
199
+
"password": "'$ACCOUNT1_PASSWORD'"
201
+
"https://bsky.social/xrpc/com.atproto.server.createSession")
203
+
account1_jwt=\$(echo "\$account1_response" | ${pkgs.jq}/bin/jq -r '.accessJwt')
205
+
if [[ -z "\$account1_jwt" || "\$account1_jwt" == "null" ]]; then
206
+
echo "Failed to authenticate account $ACCOUNT1" >&2
207
+
echo "Response: \$account1_response" >&2
211
+
# Generate JWT for ACCOUNT2
212
+
account2_response=\$(${pkgs.curl}/bin/curl -s -X POST \
213
+
-H "Content-Type: application/json" \
215
+
"identifier": "'$ACCOUNT2'",
216
+
"password": "'$ACCOUNT2_PASSWORD'"
218
+
"https://bsky.social/xrpc/com.atproto.server.createSession")
220
+
account2_jwt=\$(echo "\$account2_response" | ${pkgs.jq}/bin/jq -r '.accessJwt')
222
+
if [[ -z "\$account2_jwt" || "\$account2_jwt" == "null" ]]; then
223
+
echo "Failed to authenticate account $ACCOUNT2" >&2
224
+
echo "Response: \$account2_response" >&2
228
+
# Post to ACCOUNT1 as a.status.updates
229
+
account1_post_response=\$(${pkgs.curl}/bin/curl -s -X POST \
230
+
-H "Content-Type: application/json" \
231
+
-H "Authorization: Bearer \$account1_jwt" \
233
+
"collection": "a.status.update",
234
+
"repo": "'$ACCOUNT1'",
236
+
"\$type": "a.status.update",
237
+
"text": "'"$message"'",
238
+
"createdAt": "'\$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
241
+
"https://bsky.social/xrpc/com.atproto.repo.createRecord")
243
+
if [[ \$(echo "\$account1_post_response" | ${pkgs.jq}/bin/jq -r 'has("error")') == "true" ]]; then
244
+
echo "Error posting to $ACCOUNT1:" >&2
245
+
echo "\$account1_post_response" | ${pkgs.jq}/bin/jq >&2
249
+
# Post to ACCOUNT2 as normal post
250
+
account2_post_response=\$(${pkgs.curl}/bin/curl -s -X POST \
251
+
-H "Content-Type: application/json" \
252
+
-H "Authorization: Bearer \$account2_jwt" \
254
+
"collection": "app.bsky.feed.post",
255
+
"repo": "'$ACCOUNT2'",
257
+
"\$type": "app.bsky.feed.post",
258
+
"text": "'"$message"'",
259
+
"createdAt": "'\$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
262
+
"https://bsky.social/xrpc/com.atproto.repo.createRecord")
264
+
if [[ \$(echo "\$account2_post_response" | ${pkgs.jq}/bin/jq -r 'has("error")') == "true" ]]; then
265
+
echo "Error posting to $ACCOUNT2:" >&2
266
+
echo "\$account2_post_response" | ${pkgs.jq}/bin/jq >&2
271
+
if [[ $? -eq 0 ]]; then
272
+
${pkgs.gum}/bin/gum style --foreground 35 "✓ Posted successfully!"
274
+
${pkgs.gum}/bin/gum style --foreground 196 "✗ Failed to post"
279
+
ghostty-setup = pkgs.writeShellScriptBin "ghostty-setup" ''
280
+
# Copy Ghostty terminfo to remote host
283
+
if [[ -z "$target" ]]; then
284
+
target=$(${pkgs.gum}/bin/gum input --placeholder "user@host" --prompt "Remote host: ")
285
+
if [[ -z "$target" ]]; then
286
+
${pkgs.gum}/bin/gum style --foreground 196 "No target provided"
291
+
${pkgs.gum}/bin/gum style --bold --foreground 212 "Setting up Ghostty on $target"
294
+
${pkgs.gum}/bin/gum spin --spinner dot --title "Copying SSH key to $target..." -- \
295
+
${pkgs.openssh}/bin/ssh-copy-id "$target" 2>&1
297
+
if [[ $? -ne 0 ]]; then
298
+
${pkgs.gum}/bin/gum style --foreground 196 "✗ SSH key copy failed"
302
+
${pkgs.gum}/bin/gum style --foreground 35 "✓ SSH key copied"
304
+
${pkgs.gum}/bin/gum spin --spinner dot --title "Installing xterm-ghostty terminfo on $target..." -- \
305
+
bash -c "${pkgs.ncurses}/bin/infocmp -x xterm-ghostty | ${pkgs.openssh}/bin/ssh '$target' 'tic -x -'" 2>&1
307
+
if [[ $? -ne 0 ]]; then
308
+
${pkgs.gum}/bin/gum style --foreground 196 "✗ Terminfo transfer failed"
312
+
${pkgs.gum}/bin/gum style --foreground 35 "✓ Terminfo installed"
314
+
${pkgs.gum}/bin/gum style --foreground 35 --bold "Done! Ghostty is ready on $target"
options.atelier.shell.enable = lib.mkEnableOption "Custom shell config";
···
237
-
#ssh auto reconnect
242
-
ssh -p $port -o "BatchMode yes" $host || sleep 1
245
-
# hackatime summary
249
-
"https://waka.hackclub.com/api/summary?user=''${user_id}&interval=month" \
250
-
-H 'accept: application/json' \
251
-
-H 'Authorization: Bearer 2ce9e698-8a16-46f0-b49a-ac121bcfd608' | jq '. + {
252
-
"total_categories_sum": (.categories | map(.total) | add),
253
-
"total_categories_human_readable": (
254
-
(.categories | map(.total) | add) as $total_seconds |
255
-
"\($total_seconds / 3600 | floor)h \(($total_seconds % 3600) / 60 | floor)m \($total_seconds % 60)s"
258
-
.projects | sort_by(-.total) | map(.key)
263
-
# Post AtProto status updates
266
-
local prompt_message=true
267
-
local account1_name=""
268
-
local account2_name=""
269
-
local account1_jwt=""
270
-
local account2_jwt=""
272
-
# Load account information from agenix secrets
273
-
if [[ -f "/run/agenix/bluesky" ]]; then
274
-
source "/run/agenix/bluesky"
276
-
echo "Error: Bluesky credentials file not found at /run/agenix/bluesky"
281
-
while [[ $# -gt 0 ]]; do
285
-
prompt_message=false
289
-
echo "Usage: now [-m|--message \"your message\"]"
295
-
# Prompt for message if none provided
296
-
if [[ "$prompt_message" = true ]]; then
297
-
echo -n "$ACCOUNT1 is: "
300
-
if [[ -z "$message" ]]; then
301
-
echo "No message provided. Aborting."
306
-
# Generate JWT for ACCOUNT1
307
-
local account1_response=$(curl -s -X POST \
308
-
-H "Content-Type: application/json" \
310
-
"identifier": "'$ACCOUNT1'",
311
-
"password": "'$ACCOUNT1_PASSWORD'"
313
-
"https://bsky.social/xrpc/com.atproto.server.createSession")
315
-
account1_jwt=$(echo "$account1_response" | jq -r '.accessJwt')
317
-
if [[ -z "$account1_jwt" || "$account1_jwt" == "null" ]]; then
318
-
echo "Failed to authenticate account $ACCOUNT1"
319
-
echo "Response: $account1_response"
323
-
# Generate JWT for ACCOUNT2
324
-
local account2_response=$(curl -s -X POST \
325
-
-H "Content-Type: application/json" \
327
-
"identifier": "'$ACCOUNT2'",
328
-
"password": "'$ACCOUNT2_PASSWORD'"
330
-
"https://bsky.social/xrpc/com.atproto.server.createSession")
332
-
account2_jwt=$(echo "$account2_response" | jq -r '.accessJwt')
334
-
if [[ -z "$account2_jwt" || "$account2_jwt" == "null" ]]; then
335
-
echo "Failed to authenticate account $ACCOUNT2"
336
-
echo "Response: $account2_response"
340
-
# Post to ACCOUNT1 as a.status.updates
341
-
local account1_post_response=$(curl -s -X POST \
342
-
-H "Content-Type: application/json" \
343
-
-H "Authorization: Bearer $account1_jwt" \
345
-
"collection": "a.status.update",
346
-
"repo": "'$ACCOUNT1'",
348
-
"$type": "a.status.update",
349
-
"text": "'"$message"'",
350
-
"createdAt": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
353
-
"https://bsky.social/xrpc/com.atproto.repo.createRecord")
355
-
if [[ $(echo "$account1_post_response" | jq -r 'has("error")') == "true" ]]; then
356
-
echo "Error posting to $ACCOUNT1:"
357
-
echo "$account1_post_response" | jq
361
-
# Post to ACCOUNT2 as normal post
362
-
local account2_post_response=$(curl -s -X POST \
363
-
-H "Content-Type: application/json" \
364
-
-H "Authorization: Bearer $account2_jwt" \
366
-
"collection": "app.bsky.feed.post",
367
-
"repo": "'$ACCOUNT2'",
369
-
"$type": "app.bsky.feed.post",
370
-
"text": "'"$message"'",
371
-
"createdAt": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
374
-
"https://bsky.social/xrpc/com.atproto.repo.createRecord")
376
-
if [[ $(echo "$account2_post_response" | jq -r 'has("error")') == "true" ]]; then
377
-
echo "Error posting to $ACCOUNT2:"
378
-
echo "$account2_post_response" | jq
388
-
if [[ -z "$target" ]]; then
389
-
echo "Usage: ghostty_setup <user@host>"
394
-
echo "Copying SSH key to $target..."
395
-
ssh-copy-id "$target" || { echo "ssh-copy-id failed"; return 2; }
397
-
# Pipe infocmp output to tic on remote host
398
-
echo "Sending xterm-ghostty terminfo to $target..."
399
-
infocmp -x xterm-ghostty | ssh "$target" 'tic -x -' || { echo "Terminfo transfer failed"; return 3; }
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
zstyle ':completion:*' list-colors "''${(s.:.)LS_COLORS}"
zstyle ':completion:*' menu no
···
home.packages = with pkgs; [
pkgs.unstable.wakatime-cli
inputs.terminal-wakatime.packages.${pkgs.system}.default