diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..4144b59
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,17 @@
+name: CI
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ shellcheck:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install shellcheck
+ run: sudo apt-get install -y shellcheck
+ - name: Lint latest scripts
+ run: shellcheck latest/farmer latest/sprout
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5d18894
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,12 @@
+Copyright (C) 2023-2026 by the grlx contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/README.md b/README.md
index d9037ce..5dcb6e1 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,17 @@
# grlx Quickstart
+
##

+
+[](https://github.com/gogrlx/bootstrap.grlx.dev/actions/workflows/ci.yml)
+[](https://opensource.org/licenses/0BSD)
+
Want to get up and running as quickly as possible to see what all the fuss is about?
Use our bootstrap scripts!
Note that only Linux `sprout`s and `farmer`s are supported, but you can use the
CLI from macOS as well.
+## Install
+
1. Download and initialize the command line utility from our releases to your dev machine.
```bash
# replace 'linux' with darwin if you're on macOS
@@ -17,6 +24,7 @@ Once configured, the CLI prints out your administrator public key, which you'll
*It's recommended you now add `grlx` somewhere in your `$PATH`.*

+
2. On your control server, you'll need to install the `farmer`. This script may also be run as `root` instead of using sudo.
```bash
curl -L https://bootstrap.grlx.dev/latest/farmer | sudo bash
@@ -27,6 +35,7 @@ You'll be prompted for an admin public key, which you should have gotten from th
Make sure the certificate host name matches the external-facing interface (a domain or IP address) as it will be used for TLS validation!

+
3. On all of your fleet nodes, you'll need to install the `sprout`.
```bash
# Set FARMERINTERFACE to your farmer's domain name. FARMERBUSPORT and FARMERAPIPORT
@@ -47,3 +56,53 @@ grlx -T \* cmd run --out json -- uname -a
```

+
+## Non-Interactive Install
+
+Both scripts support environment variables for unattended installation:
+
+**Farmer:**
+```bash
+curl -L https://bootstrap.grlx.dev/latest/farmer | \
+ FARMERINTERFACE=0.0.0.0 \
+ FARMERAPIPORT=5405 \
+ FARMERBUSPORT=5406 \
+ FARMERORGANIZATION="My Org" \
+ ADMIN_PUBKEYS="ABC25HBCYNHYMIFTN372NCKASUQPJCTBA66GLKXFYM3QGRP42IC5BYYF" \
+ CERT_HOSTS="farmer.example.com" \
+ sudo -E bash
+```
+
+**Sprout:**
+```bash
+curl -L https://bootstrap.grlx.dev/latest/sprout | \
+ FARMERINTERFACE=farmer.example.com \
+ FARMERAPIPORT=5405 \
+ FARMERBUSPORT=5406 \
+ sudo -E bash
+```
+
+## Uninstall
+
+To uninstall either component, set the `UNINSTALL` environment variable:
+
+```bash
+# Uninstall farmer
+curl -L https://bootstrap.grlx.dev/latest/farmer | UNINSTALL=1 sudo -E bash
+
+# Uninstall sprout
+curl -L https://bootstrap.grlx.dev/latest/sprout | UNINSTALL=1 sudo -E bash
+```
+
+Each uninstall only removes its own files — running both components on the same host is safe.
+
+## Supported Architectures
+
+- x86_64 (amd64)
+- i686/i386 (386)
+- aarch64/arm64 (arm64)
+- armv7l (arm)
+
+## License
+
+[0BSD](LICENSE)
diff --git a/latest/farmer b/latest/farmer
index f3b8b11..1b7e52b 100755
--- a/latest/farmer
+++ b/latest/farmer
@@ -150,11 +150,16 @@ EOF
systemctl enable --now grlx-farmer
else
systemctl disable --now grlx-farmer
- userdel farmer
+ userdel farmer 2>/dev/null || true
rm -f /usr/local/bin/gum
rm -f /etc/systemd/system/grlx-farmer.service
+ systemctl daemon-reload
rm -f /usr/local/bin/grlx-farmer
- rm -rf /etc/grlx
- rm -rf /srv/grlx
- rm -rf /var/cache/grlx
+ rm -f /etc/grlx/farmer
+ rm -rf /etc/grlx/pki/farmer
+ # Only remove /etc/grlx if empty (sprout config may still exist)
+ rmdir /etc/grlx/pki 2>/dev/null || true
+ rmdir /etc/grlx 2>/dev/null || true
+ rm -rf /srv/grlx
+ rm -rf /var/cache/grlx/farmer
fi
diff --git a/latest/sprout b/latest/sprout
index 8d2a98b..81ce132 100755
--- a/latest/sprout
+++ b/latest/sprout
@@ -72,7 +72,14 @@ EOF
else
systemctl disable --now grlx-sprout
rm -f /etc/systemd/system/grlx-sprout.service
+ systemctl daemon-reload
rm -f /usr/local/bin/grlx-sprout
- rm -rf /etc/grlx
- rm -rf /var/cache/grlx
+ rm -f /etc/grlx/sprout
+ rm -rf /etc/grlx/pki/sprout
+ # Only remove /etc/grlx if empty (farmer config may still exist)
+ rmdir /etc/grlx/pki 2>/dev/null || true
+ rmdir /etc/grlx 2>/dev/null || true
+ rm -rf /var/cache/grlx/sprout
+ # Only remove /var/cache/grlx if empty
+ rmdir /var/cache/grlx 2>/dev/null || true
fi