Kieran's opinionated (and probably slightly dumb) nix config

feat: add completions and man page for bore

dunkirk.sh 2c227844 1a03933b

verified
Changed files
+284 -4
modules
home
nixos
services
+107
modules/home/apps/bore/bore.1.md
···
+
% BORE(1) bore 1.0
+
% Kieran Klukas
+
% December 2024
+
+
# NAME
+
+
bore - secure tunneling service for exposing local services to the internet
+
+
# SYNOPSIS
+
+
**bore** [*SUBDOMAIN*] [*PORT*] [**--label** *LABEL*] [**--save**]
+
+
**bore** **--list** | **-l**
+
+
**bore** **--saved** | **-s**
+
+
# DESCRIPTION
+
+
**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 tunnels with optional labels and persistent configuration.
+
+
# OPTIONS
+
+
**-l**, **--list**
+
: List all active tunnels on the bore server.
+
+
**-s**, **--saved**
+
: List all saved tunnel configurations from bore.toml in the current directory.
+
+
**--label** *LABEL*
+
: Assign a label/tag to the tunnel for organization and identification.
+
+
**--save**
+
: Save the tunnel configuration to bore.toml in the current directory for future use.
+
+
# ARGUMENTS
+
+
*SUBDOMAIN*
+
: The subdomain to use for the tunnel (e.g., "myapp" creates myapp.bore.dunkirk.sh). Must contain only lowercase letters, numbers, and hyphens.
+
+
*PORT*
+
: The local port to expose (e.g., 8000 for localhost:8000).
+
+
# CONFIGURATION
+
+
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.
+
+
## bore.toml Format
+
+
```toml
+
[myapp]
+
port = 8000
+
+
[api]
+
port = 3000
+
label = "dev"
+
```
+
+
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.
+
+
# EXAMPLES
+
+
Create a simple tunnel:
+
```
+
$ bore myapp 8000
+
```
+
+
Create a tunnel with a label:
+
```
+
$ bore api 3000 --label dev
+
```
+
+
Save a tunnel configuration:
+
```
+
$ bore frontend 5173 --label local --save
+
```
+
+
List active tunnels:
+
```
+
$ bore --list
+
```
+
+
List saved configurations:
+
```
+
$ bore --saved
+
```
+
+
Interactive mode (choose saved or new):
+
```
+
$ bore
+
```
+
+
# FILES
+
+
**bore.toml**
+
: Local tunnel configuration file (current directory)
+
+
# SEE ALSO
+
+
Dashboard: https://bore.dunkirk.sh
+
+
# BUGS
+
+
Report bugs at: https://github.com/yourusername/dots/issues
+
+
# AUTHORS
+
+
Kieran Klukas <crush@charm.land>
+32
modules/home/apps/bore/completions/bore.bash
···
+
# bash completion for bore
+
+
_bore_completion() {
+
local cur prev opts
+
COMPREPLY=()
+
cur="${COMP_WORDS[COMP_CWORD]}"
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
+
opts="--list --saved --label --save -l -s"
+
+
# Complete flags
+
if [[ ${cur} == -* ]]; then
+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+
return 0
+
fi
+
+
# Complete label value after --label or -l
+
if [[ ${prev} == "--label" ]] || [[ ${prev} == "-l" ]]; then
+
# Could potentially read from bore.toml for label suggestions
+
return 0
+
fi
+
+
# Complete saved tunnel names as first argument
+
if [[ ${COMP_CWORD} -eq 1 ]] && [[ -f "bore.toml" ]]; then
+
local tunnels=$(grep '^\[' bore.toml | sed 's/^\[\(.*\)\]$/\1/')
+
COMPREPLY=( $(compgen -W "${tunnels}" -- ${cur}) )
+
return 0
+
fi
+
+
return 0
+
}
+
+
complete -F _bore_completion bore
+20
modules/home/apps/bore/completions/bore.fish
···
+
# fish completion for bore
+
+
# Helper function to get saved tunnel names
+
function __bore_saved_tunnels
+
if test -f bore.toml
+
grep '^\[' bore.toml | sed 's/^\[\(.*\)\]$/\1/'
+
end
+
end
+
+
# Complete flags
+
complete -c bore -s l -l list -d 'List active tunnels'
+
complete -c bore -s s -l saved -d 'List saved tunnels from bore.toml'
+
complete -c bore -l label -d 'Assign a label to the tunnel' -r
+
complete -c bore -l save -d 'Save tunnel configuration to bore.toml'
+
+
# Complete subdomain from saved tunnels (first argument)
+
complete -c bore -n '__fish_is_first_token' -a '(__bore_saved_tunnels)' -d 'Saved tunnel'
+
+
# Port is always a number (second argument)
+
complete -c bore -n 'test (count (commandline -opc)) -eq 2' -d 'Local port'
+40
modules/home/apps/bore/completions/bore.zsh
···
+
#compdef bore
+
+
_bore() {
+
local -a tunnels
+
local curcontext="$curcontext" state line
+
typeset -A opt_args
+
+
# Read saved tunnels from bore.toml if it exists
+
if [[ -f "bore.toml" ]]; then
+
tunnels=(${(f)"$(grep '^\[' bore.toml | sed 's/^\[\(.*\)\]$/\1/')"})
+
fi
+
+
_arguments -C \
+
'1: :->subdomain' \
+
'2: :->port' \
+
'--list[List active tunnels]' \
+
'-l[List active tunnels]' \
+
'--saved[List saved tunnels from bore.toml]' \
+
'-s[List saved tunnels from bore.toml]' \
+
'--label[Assign a label to the tunnel]:label:' \
+
'--save[Save tunnel configuration to bore.toml]' \
+
&& return 0
+
+
case $state in
+
subdomain)
+
if [[ ${#tunnels[@]} -gt 0 ]]; then
+
_describe 'saved tunnels' tunnels
+
else
+
_message 'subdomain (e.g., myapp)'
+
fi
+
;;
+
port)
+
_message 'local port (e.g., 8000)'
+
;;
+
esac
+
+
return 0
+
}
+
+
_bore "$@"
+43 -1
modules/home/apps/frpc.nix modules/home/apps/bore/default.nix
···
let
cfg = config.atelier.bore;
-
bore = pkgs.writeShellScriptBin "bore" ''
+
boreScript = pkgs.writeShellScript "bore" ''
CONFIG_FILE="bore.toml"
# Check for flags
···
exec ${pkgs.frp}/bin/frpc -c $config_file
'';
+
+
bore = pkgs.stdenv.mkDerivation {
+
pname = "bore";
+
version = "1.0";
+
+
dontUnpack = true;
+
+
nativeBuildInputs = with pkgs; [ pandoc installShellFiles ];
+
+
manPageSrc = ./bore.1.md;
+
bashCompletionSrc = ./completions/bore.bash;
+
zshCompletionSrc = ./completions/bore.zsh;
+
fishCompletionSrc = ./completions/bore.fish;
+
+
buildPhase = ''
+
# Convert markdown man page to man format
+
${pkgs.pandoc}/bin/pandoc -s -t man $manPageSrc -o bore.1
+
'';
+
+
installPhase = ''
+
mkdir -p $out/bin
+
+
# Install binary
+
cp ${boreScript} $out/bin/bore
+
chmod +x $out/bin/bore
+
+
# Install man page
+
installManPage bore.1
+
+
# Install completions
+
installShellCompletion --bash --name bore $bashCompletionSrc
+
installShellCompletion --zsh --name _bore $zshCompletionSrc
+
installShellCompletion --fish --name bore.fish $fishCompletionSrc
+
'';
+
+
meta = with lib; {
+
description = "Secure tunneling service CLI";
+
homepage = "https://bore.dunkirk.sh";
+
license = licenses.mit;
+
maintainers = [ ];
+
};
+
};
in
{
options.atelier.bore = {
+42 -3
modules/nixos/services/bore/dashboard.html
···
opacity: 0;
}
+
.loading-bar {
+
position: fixed;
+
top: 0;
+
left: 0;
+
width: 100%;
+
height: 3px;
+
background: transparent;
+
z-index: 9999;
+
overflow: hidden;
+
}
+
+
.loading-bar::before {
+
content: '';
+
position: absolute;
+
top: 0;
+
left: 0;
+
width: 100%;
+
height: 100%;
+
background: linear-gradient(90deg, #14b8a6, #fb923c);
+
animation: loading 1.5s ease-in-out infinite;
+
}
+
+
body:not(.loading) .loading-bar {
+
display: none;
+
}
+
+
@keyframes loading {
+
0% {
+
transform: translateX(-100%);
+
}
+
50% {
+
transform: translateX(0%);
+
}
+
100% {
+
transform: translateX(100%);
+
}
+
}
+
.container {
max-width: 1200px;
margin: 0 auto;
···
</head>
<body class="loading">
+
<div class="loading-bar"></div>
<main class="container">
<header>
<h1>🚇 bore</h1>
···
}
document.getElementById('lastUpdated').textContent = new Date().toLocaleTimeString();
+
+
// Remove loading class after first successful fetch
+
document.body.classList.remove('loading');
} catch (error) {
fetchFailCount++;
document.getElementById('serverStatus').textContent = 'offline';
···
// Update relative times every 10 seconds
setInterval(updateRelativeTimes, 10000);
-
-
// Remove loading class after initial fetch
-
document.body.classList.remove('loading');
</script>
</body>
modules/nixos/services/bore/frps.nix modules/nixos/services/bore/bore.nix