+8
.github/workflows/deploy.yaml
+8
.github/workflows/deploy.yaml
···
-1
README.md
-1
README.md
···
+101
-49
flake.lock
+101
-49
flake.lock
·························································
·························································
+7
-1
flake.nix
+7
-1
flake.nix
·········
·········
+10
machines/atalanta/default.nix
+10
machines/atalanta/default.nix
···
+68
-2
machines/atalanta/home/default.nix
+68
-2
machines/atalanta/home/default.nix
······
+1
machines/atalanta/home-manager.nix
+1
machines/atalanta/home-manager.nix
+5
machines/ember/default.nix
+5
machines/ember/default.nix
-35
machines/john/default.nix
-35
machines/john/default.nix
···
···
-2
machines/moonlark/home/default.nix
-2
machines/moonlark/home/default.nix
+1
machines/moonlark/home-manager.nix
+1
machines/moonlark/home-manager.nix
+5
machines/nest/default.nix
+5
machines/nest/default.nix
+1
-1
machines/prattle/default.nix
+1
-1
machines/prattle/default.nix
+7
-2
machines/prattle/home/default.nix
+7
-2
machines/prattle/home/default.nix
+1
machines/prattle/home-manager.nix
+1
machines/prattle/home-manager.nix
+1
machines/tacyon/default.nix
+1
machines/tacyon/default.nix
+1
-1
machines/terebithia/default.nix
+1
-1
machines/terebithia/default.nix
+4
-2
machines/terebithia/home/default.nix
+4
-2
machines/terebithia/home/default.nix
+1
machines/terebithia/home-manager.nix
+1
machines/terebithia/home-manager.nix
+158
modules/home/apps/anthropic-manager/anthropic-manager.1.md
+158
modules/home/apps/anthropic-manager/anthropic-manager.1.md
···
···+**anthropic-manager** is a tool for managing multiple Anthropic OAuth credential profiles. It implements PKCE-based OAuth authentication with automatic token refresh, allowing you to switch between different Anthropic accounts easily.+Profile credentials are stored in **~/.config/crush/anthropic.\***profile\* directories with individual bearer tokens, refresh tokens, and expiration timestamps.+: Print the current bearer token to stdout. Automatically refreshes if expired. Designed for non-interactive use.+When run without arguments in an interactive terminal, **anthropic-manager** displays a menu with the following options:+**anthropic-manager** is designed to replace **bunx anthropic-api-key** in crush configurations:
+25
modules/home/apps/anthropic-manager/completions/anthropic-manager.bash
+25
modules/home/apps/anthropic-manager/completions/anthropic-manager.bash
···
···+if [[ "$prev" == "--init" ]] || [[ "$prev" == "-i" ]] || [[ "$prev" == "--swap" ]] || [[ "$prev" == "-s" ]]; then+local profiles=$(find "$config_dir" -maxdepth 1 -type d -name "anthropic.*" 2>/dev/null | sed 's/.*anthropic\.//' | sort)
+17
modules/home/apps/anthropic-manager/completions/anthropic-manager.fish
+17
modules/home/apps/anthropic-manager/completions/anthropic-manager.fish
···
···+set -l config_dir (test -n "$ANTHROPIC_CONFIG_DIR"; and echo $ANTHROPIC_CONFIG_DIR; or echo "$HOME/.config/crush")+find "$config_dir" -maxdepth 1 -type d -name "anthropic.*" 2>/dev/null | sed 's/.*anthropic\.//' | sort+complete -c anthropic-manager -s i -l init -d "Initialize a new profile" -xa "(__anthropic_manager_profiles)"+complete -c anthropic-manager -s s -l swap -d "Switch to a profile" -xa "(__anthropic_manager_profiles)"
+21
modules/home/apps/anthropic-manager/completions/anthropic-manager.zsh
+21
modules/home/apps/anthropic-manager/completions/anthropic-manager.zsh
···
···+profiles=(${(f)"$(find "$config_dir" -maxdepth 1 -type d -name "anthropic.*" 2>/dev/null | sed 's/.*anthropic\.//' | sort)"})
+505
modules/home/apps/anthropic-manager/default.nix
+505
modules/home/apps/anthropic-manager/default.nix
···
···+echo "https://claude.ai/oauth/authorize?response_type=code&client_id=$CLIENT_ID&redirect_uri=https://console.anthropic.com/oauth/code/callback&scope=org:create_api_key+user:profile+user:inference&code_challenge=$challenge&code_challenge_method=S256&state=$verifier"+chmod 600 "$profile_dir/bearer_token" "$profile_dir/refresh_token" "$profile_dir/bearer_token.expires"+code=$(${pkgs.gum}/bin/gum input --placeholder "Paste the authorization code from Anthropic" --prompt "Code: ")+current_profile=$(basename "$(readlink "$CONFIG_DIR/anthropic")" | ${pkgs.gnused}/bin/sed 's/^anthropic\.//')+${pkgs.gum}/bin/gum style --foreground 214 "No profiles found. Use 'anthropic-manager --init <name>' to create one."+current=$(basename "$(readlink "$CONFIG_DIR/anthropic")" | ${pkgs.gnused}/bin/sed 's/^anthropic\.//')+profile=$(${pkgs.gum}/bin/gum input --placeholder "Profile name (e.g., work, personal)" --prompt "Profile name: ")+if [[ ! -L "$CONFIG_DIR/anthropic" ]] || ${pkgs.gum}/bin/gum confirm "Set '$profile' as active profile?"; then+${pkgs.gum}/bin/gum style --foreground 214 "Use 'anthropic-manager --init <name>' to create one"+selected=$(printf '%s\n' "''${profiles[@]}" | ${pkgs.gum}/bin/gum choose --header "Select profile:")+current_profile=$(basename "$(readlink "$CONFIG_DIR/anthropic")" | ${pkgs.gnused}/bin/sed 's/^anthropic\.//')+${pkgs.gum}/bin/gum style --bold --foreground 212 "anthropic-manager - Manage Anthropic OAuth profiles"+echo " anthropic-manager --swap [profile] Switch to a profile (interactive if no profile given)"+echo "Error: anthropic-manager requires an interactive terminal when called without arguments" >&2+options.atelier.apps.anthropic-manager.enable = lib.mkEnableOption "Enable anthropic-manager";
+131
modules/home/apps/bore/bore.1.md
+131
modules/home/apps/bore/bore.1.md
···
···+**bore** is a tunneling service that uses frp (fast reverse proxy) to expose local services to the internet via bore.dunkirk.sh. It provides a simple CLI for creating and managing HTTP, TCP, and UDP tunnels with optional labels and persistent configuration.+: The subdomain to use for the tunnel (e.g., "myapp" creates myapp.bore.dunkirk.sh). Must contain only lowercase letters, numbers, and hyphens.+Tunnel configurations can be saved to a **bore.toml** file in the current directory. This file uses TOML format and can be committed to repositories.+When running **bore** without arguments in a directory with bore.toml, you'll be prompted to choose between creating a new tunnel or using a saved configuration.
+38
modules/home/apps/bore/completions/bore.bash
+38
modules/home/apps/bore/completions/bore.bash
···
···
+21
modules/home/apps/bore/completions/bore.fish
+21
modules/home/apps/bore/completions/bore.fish
···
···
+42
modules/home/apps/bore/completions/bore.zsh
+42
modules/home/apps/bore/completions/bore.zsh
···
···
+499
modules/home/apps/bore/default.nix
+499
modules/home/apps/bore/default.nix
···
···+echo "$tunnels" | ${pkgs.jq}/bin/jq -r '.proxies[] | select(.status == "online" and .conf != null) | if .type == "http" then "\(.name) โ https://\(.conf.subdomain).${cfg.domain} [http]" elif .type == "tcp" then "\(.name) โ tcp://\(.conf.remotePort) โ localhost:\(.conf.localPort) [tcp]" elif .type == "udp" then "\(.name) โ udp://\(.conf.remotePort) โ localhost:\(.conf.localPort) [udp]" else "\(.name) [\(.type)]" end' | while read -r line; do+${pkgs.gum}/bin/gum style --foreground 35 "โ $current_tunnel โ localhost:$port [$proto_display] [$label]"+${pkgs.gum}/bin/gum style --foreground 35 "โ $current_tunnel โ localhost:$port [$proto_display]"+${pkgs.gum}/bin/gum style --foreground 35 "โ $current_tunnel โ localhost:$port [$proto_display] [$label]"+${pkgs.gum}/bin/gum style --foreground 35 "โ $current_tunnel โ localhost:$port [$proto_display]"+saved_names=$(${pkgs.gnugrep}/bin/grep '^\[' "$CONFIG_FILE" | ${pkgs.gnused}/bin/sed 's/^\[\(.*\)\]$/\1/')+${pkgs.gum}/bin/gum style --foreground 35 "โ Loaded from bore.toml: $tunnel_name โ localhost:$port [$proto_display]''${label:+ [$label]}"+${pkgs.gum}/bin/gum style --foreground 196 "Invalid subdomain (use only lowercase letters, numbers, and hyphens)"+# Prompt for protocol if not provided via flag and not loaded from saved config and not already set+labels=$(${pkgs.gum}/bin/gum choose --no-limit --header "Labels (select multiple):" "dev" "prod" "custom")+if [ -f "$CONFIG_FILE" ] && ${pkgs.gnugrep}/bin/grep -q "^\[$tunnel_name\]" "$CONFIG_FILE"; then+admin_port=$(${pkgs.python3}/bin/python3 -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()')+${pkgs.gum}/bin/gum style --foreground 196 "Invalid protocol: $protocol (must be http, tcp, or udp)"+${pkgs.gum}/bin/gum style --foreground 214 "Connecting to ${cfg.serverAddr}:${toString cfg.serverPort}..."+proxy_status=$(${pkgs.curl}/bin/curl -s http://127.0.0.1:$admin_port/api/status 2>/dev/null || echo "{}")+remote_addr=$(echo "$proxy_status" | ${pkgs.jq}/bin/jq -r ".tcp[]? | select(.name == \"$proxy_name\") | .remote_addr" 2>/dev/null)+remote_addr=$(echo "$proxy_status" | ${pkgs.jq}/bin/jq -r ".udp[]? | select(.name == \"$proxy_name\") | .remote_addr" 2>/dev/null)
+3
-1
modules/home/apps/crush.nix
+3
-1
modules/home/apps/crush.nix
······
······
-138
modules/home/apps/frpc.nix
-138
modules/home/apps/frpc.nix
···-echo "$tunnels" | ${pkgs.jq}/bin/jq -r '.proxies[] | select(.status == "online" and .conf != null) | "\(.name) โ https://\(.conf.subdomain).${cfg.domain}"' | while read -r line; do-${pkgs.gum}/bin/gum style --foreground 196 "Invalid subdomain (use only lowercase letters, numbers, and hyphens)"-${pkgs.gum}/bin/gum style --foreground 214 "Connecting to ${cfg.serverAddr}:${toString cfg.serverPort}..."
···
+183
modules/home/apps/ssh.nix
+183
modules/home/apps/ssh.nix
···
···
-85
modules/home/apps/vscode.nix
-85
modules/home/apps/vscode.nix
···
···
-26
modules/home/system/nixpkgs.nix
-26
modules/home/system/nixpkgs.nix
···
···
+26
modules/home/system/nixpkgs.nix.disabled
+26
modules/home/system/nixpkgs.nix.disabled
···
···
+11
-3
modules/home/system/shell.nix
+11
-3
modules/home/system/shell.nix
·········-template = "{{if not .Detached}}{{ .HEAD }}{{else}}@{{ printf \"%.7s\" .Commit.Sha }}{{end}}{{ if .Staging.Changed }} ({{ .Staging.String }}){{ end }}{{ if .Working.Changed }}*{{ end }} <cyan>{{ if .BranchStatus }}{{ .BranchStatus }}{{ end }}</>";······
·········+template = "{{if not .Detached}}{{ .HEAD }}{{else}}@{{ printf \"%.7s\" .Commit.Sha }}{{end}}{{ if .Staging.Changed }} ({{ .Staging.String }}){{ end }}{{ if .Working.Changed }}*{{ end }}{{ if .BranchStatus }}<cyan> {{ .BranchStatus }}</>{{ end }}";······
+48
modules/nixos/services/bore/README.md
+48
modules/nixos/services/bore/README.md
···
···++Bore is a lightweight wrapper around `frp` which provides a dashboard and a nice `gum` based cli. It supports HTTP, TCP, and UDP tunneling. If you would like to run this in your own nix flake then simplify vendor this folder and `./modules/home/bore` and import the folders into the appropriate home manager and nixos configurations.+The secret file is just a oneline file with the key in it. If you do end up deploying this feel free to email me and let me know! I would love to hear about your setup!
+190
modules/nixos/services/bore/bore.nix
+190
modules/nixos/services/bore/bore.nix
···
···
+24
modules/nixos/services/bore/bore.toml.example
+24
modules/nixos/services/bore/bore.toml.example
···
···
+147
-8
modules/nixos/services/bore/dashboard.html
+147
-8
modules/nixos/services/bore/dashboard.html
···href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>๐</text></svg>">···························html += '<div style="color: #8b949e; font-size: 0.85rem; margin-bottom: 0.75rem;">recently disconnected</div>';<span class="offline-tunnel-stats">in: <span data-traffic-in="${proxy.name}">0 B</span> โข out: <span data-traffic-out="${proxy.name}">0 B</span></span>···<span class="offline-tunnel-stats">in: <span data-traffic-in="${proxy.name}">0 B</span> โข out: <span data-traffic-out="${proxy.name}">0 B</span></span>···
···+<meta name="description" content="bore - secure tunneling service for exposing local services to the internet">+<meta property="og:description" content="secure tunneling service powered by frp on bore.dunkirk.sh">+<meta name="twitter:description" content="secure tunneling service powered by frp on bore.dunkirk.sh">href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>๐</text></svg>">··················+document.getElementById('totalUpload').textContent = formatBytes(serverData.totalTrafficOut || 0);+document.getElementById('totalDownload').textContent = formatBytes(serverData.totalTrafficIn || 0);······+return `<span class="tunnel-label" style="color: ${style.color}; background: ${style.bgColor}; border-color: ${style.borderColor};">${trimmedLabel}</span>`;···html += '<div style="color: #8b949e; font-size: 0.85rem; margin-bottom: 0.75rem;">recently disconnected</div>';<span class="offline-tunnel-stats">in: <span data-traffic-in="${proxy.name}">0 B</span> โข out: <span data-traffic-out="${proxy.name}">0 B</span></span>···<span class="offline-tunnel-stats">in: <span data-traffic-in="${proxy.name}">0 B</span> โข out: <span data-traffic-out="${proxy.name}">0 B</span></span>···
-174
modules/nixos/services/bore/frps.nix
-174
modules/nixos/services/bore/frps.nix
···
···
+48
packages/zmx.nix
+48
packages/zmx.nix
···
···