@celilo/e2e 0.7.11 → 0.7.13-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.celilo-website-cache/_astro/docs.DwsUauWZ.css +1 -0
- package/.celilo-website-cache/_astro/network.BB0RR2mM.css +1 -0
- package/.celilo-website-cache/diagrams/physical.svg +1 -0
- package/.celilo-website-cache/diagrams/zone-topology.svg +1 -0
- package/.celilo-website-cache/docs/index.html +250 -0
- package/.celilo-website-cache/docs/network/index.html +300 -0
- package/.celilo-website-cache/favicon.svg +4 -0
- package/.celilo-website-cache/fonts/theia-300.otf +0 -0
- package/.celilo-website-cache/fonts/theia-400.otf +0 -0
- package/.celilo-website-cache/fonts/theia-500.otf +0 -0
- package/.celilo-website-cache/index.html +93 -0
- package/.celilo-website-cache/install.sh +330 -0
- package/.celilo-website-cache/modules/index.html +86 -0
- package/.celilo-website-cache/modules/view/index.html +69 -0
- package/.celilo-website-cache/vision/index.html +121 -0
- package/.npm-registry-cache/celilo-capabilities-0.1.10.tgz +0 -0
- package/.npm-registry-cache/celilo-cli-0.3.30.tgz +0 -0
- package/.npm-registry-cache/celilo-cli-display-0.1.9.tgz +0 -0
- package/.npm-registry-cache/celilo-e2e-0.7.13.tgz +0 -0
- package/.npm-registry-cache/celilo-event-bus-0.1.4.tgz +0 -0
- package/netapps/authentik.netapp +0 -0
- package/netapps/caddy.netapp +0 -0
- package/netapps/celilo-website.netapp +0 -0
- package/netapps/greenwave.netapp +0 -0
- package/netapps/homebridge.netapp +0 -0
- package/netapps/iptables.netapp +0 -0
- package/netapps/knot-unbound-internal.netapp +0 -0
- package/netapps/namecheap.netapp +0 -0
- package/netapps/technitium.netapp +0 -0
- package/package.json +6 -3
- package/src/docker-compose-generator.ts +30 -2
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Celilo installer — https://celilo.computer
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# curl -fsSL https://celilo.computer/install.sh | bash
|
|
6
|
+
#
|
|
7
|
+
# What it does (non-interactive — safe to run from CI / cloud-init):
|
|
8
|
+
# 1. Installs Bun (https://bun.sh) if it's missing
|
|
9
|
+
# 2. Installs @celilo/cli, @celilo/event-bus, @celilo/e2e as global Bun packages
|
|
10
|
+
# 3. Prints next steps (PATH, `celilo system init`, optional event-bus daemon)
|
|
11
|
+
#
|
|
12
|
+
# It does NOT run `celilo system init` (interactive — needs you at the keyboard).
|
|
13
|
+
# It does NOT install the event-bus daemon. Both are listed in the next-steps
|
|
14
|
+
# block at the end so you can run them when you're ready.
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
# ---------- options ----------
|
|
19
|
+
# Lenient by design: this is the user's first contact with Celilo, and a
|
|
20
|
+
# hard-exit on a stale flag (e.g. someone copy-pastes an old curl-pipe from
|
|
21
|
+
# the docs that still has --skip-init) is a worse first impression than
|
|
22
|
+
# warning and continuing. We only recognize -h/--help; anything else gets
|
|
23
|
+
# a soft warning. If we add behavior-changing flags later, document the
|
|
24
|
+
# tradeoff at that time.
|
|
25
|
+
for arg in "$@"; do
|
|
26
|
+
case "$arg" in
|
|
27
|
+
-h|--help)
|
|
28
|
+
cat <<'EOF'
|
|
29
|
+
Celilo installer — https://celilo.computer
|
|
30
|
+
|
|
31
|
+
Usage:
|
|
32
|
+
curl -fsSL https://celilo.computer/install.sh | bash
|
|
33
|
+
|
|
34
|
+
The installer is non-interactive. It installs Bun, the Celilo CLI, the event
|
|
35
|
+
bus library, and the e2e harness, then prints next steps.
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
-h, --help Show this help
|
|
39
|
+
EOF
|
|
40
|
+
exit 0
|
|
41
|
+
;;
|
|
42
|
+
*) printf 'warning: ignoring unknown option: %s\n' "$arg" >&2 ;;
|
|
43
|
+
esac
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
# ---------- output helpers ----------
|
|
47
|
+
if [ -t 1 ]; then
|
|
48
|
+
RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m'
|
|
49
|
+
BLUE=$'\033[34m'; BOLD=$'\033[1m'; RESET=$'\033[0m'
|
|
50
|
+
else
|
|
51
|
+
RED=""; GREEN=""; YELLOW=""; BLUE=""; BOLD=""; RESET=""
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
info() { printf '%s[celilo]%s %s\n' "$BLUE" "$RESET" "$*"; }
|
|
55
|
+
ok() { printf '%s[celilo]%s %s\n' "$GREEN" "$RESET" "$*"; }
|
|
56
|
+
warn() { printf '%s[celilo]%s %s\n' "$YELLOW" "$RESET" "$*"; }
|
|
57
|
+
fail() { printf '%s[celilo]%s %s\n' "$RED" "$RESET" "$*" >&2; exit 1; }
|
|
58
|
+
|
|
59
|
+
# ---------- preflight ----------
|
|
60
|
+
case "$(uname -s)" in
|
|
61
|
+
Darwin|Linux) ;;
|
|
62
|
+
*) fail "Unsupported OS: $(uname -s). Celilo runs on macOS and Linux." ;;
|
|
63
|
+
esac
|
|
64
|
+
|
|
65
|
+
if ! command -v curl >/dev/null 2>&1; then
|
|
66
|
+
fail "Missing required command: curl. Install it and re-run."
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# ---------- 1. Bun ----------
|
|
70
|
+
export BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}"
|
|
71
|
+
export PATH="$BUN_INSTALL/bin:$PATH"
|
|
72
|
+
|
|
73
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
74
|
+
# Bun's installer ships its release as a .zip, so we need unzip — but only
|
|
75
|
+
# when Bun is actually missing. If Bun is already installed, no unzip needed.
|
|
76
|
+
if ! command -v unzip >/dev/null 2>&1; then
|
|
77
|
+
case "$(uname -s)" in
|
|
78
|
+
Linux)
|
|
79
|
+
if command -v apt-get >/dev/null 2>&1; then hint="sudo apt-get install unzip"
|
|
80
|
+
elif command -v dnf >/dev/null 2>&1; then hint="sudo dnf install unzip"
|
|
81
|
+
elif command -v yum >/dev/null 2>&1; then hint="sudo yum install unzip"
|
|
82
|
+
elif command -v pacman >/dev/null 2>&1; then hint="sudo pacman -S unzip"
|
|
83
|
+
elif command -v apk >/dev/null 2>&1; then hint="sudo apk add unzip"
|
|
84
|
+
else hint="install 'unzip' via your package manager"
|
|
85
|
+
fi
|
|
86
|
+
;;
|
|
87
|
+
Darwin) hint="brew install unzip (or use macOS's bundled unzip from /usr/bin)" ;;
|
|
88
|
+
*) hint="install 'unzip' via your package manager" ;;
|
|
89
|
+
esac
|
|
90
|
+
fail "Missing 'unzip' (needed to install Bun). Try: $hint"
|
|
91
|
+
fi
|
|
92
|
+
info "Bun not found — installing from https://bun.sh"
|
|
93
|
+
curl -fsSL https://bun.sh/install | bash
|
|
94
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
95
|
+
fail "Bun install completed but 'bun' is still not on PATH. Open a new shell, ensure $BUN_INSTALL/bin is on \$PATH, and re-run."
|
|
96
|
+
fi
|
|
97
|
+
ok "Bun installed: $(bun --version)"
|
|
98
|
+
else
|
|
99
|
+
ok "Bun already installed: $(bun --version)"
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# ---------- 2. Celilo packages ----------
|
|
103
|
+
info "Installing @celilo/cli, @celilo/event-bus, @celilo/e2e (global)…"
|
|
104
|
+
bun add -g @celilo/cli @celilo/event-bus @celilo/e2e
|
|
105
|
+
|
|
106
|
+
if ! command -v celilo >/dev/null 2>&1; then
|
|
107
|
+
fail "Celilo install finished, but 'celilo' is not on PATH. Add $BUN_INSTALL/bin to PATH and re-run."
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
ok "Celilo CLI installed: $(celilo --version 2>/dev/null || echo '<version check failed>')"
|
|
111
|
+
|
|
112
|
+
# ---------- 3. host prereqs (advisory) ----------
|
|
113
|
+
# Celilo shells out to ansible, ansible-galaxy, terraform, ssh, and git during
|
|
114
|
+
# `system init` and module deploy. They're not bundled with the CLI, and a
|
|
115
|
+
# missing prereq surfaces as a confusing "command not found" mid-deploy. Detect
|
|
116
|
+
# what's missing now and surface a per-OS install hint in the next-steps block.
|
|
117
|
+
|
|
118
|
+
have_apt=0; have_dnf=0; have_yum=0; have_pacman=0; have_apk=0; have_brew=0
|
|
119
|
+
case "$(uname -s)" in
|
|
120
|
+
Linux)
|
|
121
|
+
command -v apt-get >/dev/null 2>&1 && have_apt=1
|
|
122
|
+
command -v dnf >/dev/null 2>&1 && have_dnf=1
|
|
123
|
+
command -v yum >/dev/null 2>&1 && have_yum=1
|
|
124
|
+
command -v pacman >/dev/null 2>&1 && have_pacman=1
|
|
125
|
+
command -v apk >/dev/null 2>&1 && have_apk=1
|
|
126
|
+
;;
|
|
127
|
+
Darwin)
|
|
128
|
+
command -v brew >/dev/null 2>&1 && have_brew=1
|
|
129
|
+
;;
|
|
130
|
+
esac
|
|
131
|
+
|
|
132
|
+
# pm_install <pkg> — emit the install command for the detected package manager.
|
|
133
|
+
# Most prereqs share the same package name across pms; tools that don't
|
|
134
|
+
# (terraform) get a bespoke hint inline below.
|
|
135
|
+
pm_install() {
|
|
136
|
+
local pkg="$1"
|
|
137
|
+
if [ "$have_apt" = 1 ]; then printf 'sudo apt-get install -y %s' "$pkg"
|
|
138
|
+
elif [ "$have_dnf" = 1 ]; then printf 'sudo dnf install -y %s' "$pkg"
|
|
139
|
+
elif [ "$have_yum" = 1 ]; then printf 'sudo yum install -y %s' "$pkg"
|
|
140
|
+
elif [ "$have_pacman" = 1 ]; then printf 'sudo pacman -S --noconfirm %s' "$pkg"
|
|
141
|
+
elif [ "$have_apk" = 1 ]; then printf 'sudo apk add %s' "$pkg"
|
|
142
|
+
elif [ "$have_brew" = 1 ]; then printf 'brew install %s' "$pkg"
|
|
143
|
+
else printf 'install %s via your package manager' "$pkg"
|
|
144
|
+
fi
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Each entry: "<label>|<install command>"
|
|
148
|
+
PREREQ_HINTS=()
|
|
149
|
+
|
|
150
|
+
if ! command -v ansible >/dev/null 2>&1 || ! command -v ansible-galaxy >/dev/null 2>&1; then
|
|
151
|
+
PREREQ_HINTS+=("Ansible (runs playbooks)|$(pm_install ansible)")
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
if ! command -v terraform >/dev/null 2>&1; then
|
|
155
|
+
case "$(uname -s)" in
|
|
156
|
+
Linux)
|
|
157
|
+
if [ "$have_apt" = 1 ]; then
|
|
158
|
+
tf_hint='wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg && echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list && sudo apt update && sudo apt install -y terraform'
|
|
159
|
+
elif [ "$have_dnf" = 1 ] || [ "$have_yum" = 1 ]; then
|
|
160
|
+
tf_hint='see https://developer.hashicorp.com/terraform/install#linux for the HashiCorp dnf/yum repo'
|
|
161
|
+
elif [ "$have_pacman" = 1 ]; then
|
|
162
|
+
tf_hint='sudo pacman -S terraform'
|
|
163
|
+
else
|
|
164
|
+
tf_hint='see https://developer.hashicorp.com/terraform/install'
|
|
165
|
+
fi
|
|
166
|
+
;;
|
|
167
|
+
Darwin) tf_hint='brew tap hashicorp/tap && brew install hashicorp/tap/terraform' ;;
|
|
168
|
+
*) tf_hint='see https://developer.hashicorp.com/terraform/install' ;;
|
|
169
|
+
esac
|
|
170
|
+
PREREQ_HINTS+=("Terraform (provisions infrastructure)|$tf_hint")
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
174
|
+
PREREQ_HINTS+=("git (clones module sources)|$(pm_install git)")
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
if ! command -v ssh >/dev/null 2>&1; then
|
|
178
|
+
case "$(uname -s)" in
|
|
179
|
+
Linux) ssh_hint=$(pm_install openssh-client) ;;
|
|
180
|
+
Darwin) ssh_hint='ssh ships with macOS — if it is missing your system is unusual; reinstall via xcode-select --install' ;;
|
|
181
|
+
*) ssh_hint='install OpenSSH client via your package manager' ;;
|
|
182
|
+
esac
|
|
183
|
+
PREREQ_HINTS+=("OpenSSH client (deploys to remote hosts)|$ssh_hint")
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
# ---------- 4. shell completions ----------
|
|
187
|
+
# Write completion scripts for whichever shells are installed. We don't touch
|
|
188
|
+
# the user's rc files — Rule of Least Surprise — but we surface what they need
|
|
189
|
+
# to add (and a "reload your shell" reminder) in the next-steps block.
|
|
190
|
+
#
|
|
191
|
+
# Two parallel arrays drive the next-steps block:
|
|
192
|
+
# COMPLETIONS_INSTALLED — shells where a file was written successfully.
|
|
193
|
+
# Always triggers an "exec $SHELL to activate" hint.
|
|
194
|
+
# COMPLETION_RC_SNIPPETS — "<shell>|<rc-line>|<rc-target>" entries shown
|
|
195
|
+
# as conditional fallbacks ("if completion does not
|
|
196
|
+
# work, append this to your rc"). zsh always needs
|
|
197
|
+
# an fpath line; bash only needs a manual `source`
|
|
198
|
+
# when bash-completion v2 isn't auto-loading.
|
|
199
|
+
COMPLETIONS_INSTALLED=()
|
|
200
|
+
COMPLETION_RC_SNIPPETS=()
|
|
201
|
+
|
|
202
|
+
write_completion() {
|
|
203
|
+
local shell="$1" target="$2"
|
|
204
|
+
local target_dir
|
|
205
|
+
target_dir="$(dirname "$target")"
|
|
206
|
+
if ! mkdir -p "$target_dir" 2>/dev/null; then
|
|
207
|
+
return 1
|
|
208
|
+
fi
|
|
209
|
+
if ! celilo completion "$shell" >"$target" 2>/dev/null; then
|
|
210
|
+
rm -f "$target" 2>/dev/null
|
|
211
|
+
return 1
|
|
212
|
+
fi
|
|
213
|
+
return 0
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if command -v zsh >/dev/null 2>&1; then
|
|
217
|
+
ZSH_COMP="$HOME/.zsh/completions/_celilo"
|
|
218
|
+
if write_completion zsh "$ZSH_COMP"; then
|
|
219
|
+
ok "Wrote zsh completion to $ZSH_COMP"
|
|
220
|
+
COMPLETIONS_INSTALLED+=("zsh")
|
|
221
|
+
# Always surface the fpath/compinit snippet — the file alone is useless
|
|
222
|
+
# without zsh knowing to scan ~/.zsh/completions and run compinit. We
|
|
223
|
+
# frame it as "if completion does not work" so users with an existing
|
|
224
|
+
# custom fpath setup don't think they need to duplicate it.
|
|
225
|
+
COMPLETION_RC_SNIPPETS+=("zsh|fpath=(\"\$HOME/.zsh/completions\" \$fpath)
|
|
226
|
+
autoload -Uz compinit && compinit|$HOME/.zshrc")
|
|
227
|
+
else
|
|
228
|
+
warn "Could not write zsh completion to $ZSH_COMP — install manually with: celilo completion zsh > $ZSH_COMP"
|
|
229
|
+
fi
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
if command -v bash >/dev/null 2>&1; then
|
|
233
|
+
BASH_COMP="$HOME/.local/share/bash-completion/completions/celilo"
|
|
234
|
+
if write_completion bash "$BASH_COMP"; then
|
|
235
|
+
ok "Wrote bash completion to $BASH_COMP"
|
|
236
|
+
COMPLETIONS_INSTALLED+=("bash")
|
|
237
|
+
# bash-completion v2 (~/.local/share/bash-completion/completions auto-load)
|
|
238
|
+
# requires the bash-completion package to be installed AND the user's shell
|
|
239
|
+
# to source it from /etc/bash.bashrc or similar. We can't reliably detect
|
|
240
|
+
# the second part from a non-interactive shell, so always include the
|
|
241
|
+
# source fallback under "if completion does not work".
|
|
242
|
+
COMPLETION_RC_SNIPPETS+=("bash|source $BASH_COMP|$HOME/.bashrc")
|
|
243
|
+
else
|
|
244
|
+
warn "Could not write bash completion to $BASH_COMP — install manually with: celilo completion bash > $BASH_COMP"
|
|
245
|
+
fi
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
if command -v fish >/dev/null 2>&1; then
|
|
249
|
+
FISH_COMP="$HOME/.config/fish/completions/celilo.fish"
|
|
250
|
+
if write_completion fish "$FISH_COMP"; then
|
|
251
|
+
ok "Wrote fish completion to $FISH_COMP"
|
|
252
|
+
COMPLETIONS_INSTALLED+=("fish")
|
|
253
|
+
# Fish auto-loads from ~/.config/fish/completions/ — no rc snippet needed.
|
|
254
|
+
else
|
|
255
|
+
warn "Could not write fish completion to $FISH_COMP — install manually with: celilo completion fish > $FISH_COMP"
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
# ---------- 6. PATH advisory ----------
|
|
260
|
+
RC_FILE=""
|
|
261
|
+
case "${SHELL:-}" in
|
|
262
|
+
*/zsh) RC_FILE="$HOME/.zshrc" ;;
|
|
263
|
+
*/bash)
|
|
264
|
+
if [ -f "$HOME/.bashrc" ]; then RC_FILE="$HOME/.bashrc"
|
|
265
|
+
elif [ -f "$HOME/.bash_profile" ]; then RC_FILE="$HOME/.bash_profile"
|
|
266
|
+
fi
|
|
267
|
+
;;
|
|
268
|
+
*/fish) RC_FILE="$HOME/.config/fish/config.fish" ;;
|
|
269
|
+
esac
|
|
270
|
+
|
|
271
|
+
PATH_LINE='export PATH="$HOME/.bun/bin:$PATH"'
|
|
272
|
+
PATH_NEEDS_RC=0
|
|
273
|
+
if [ -n "$RC_FILE" ] && [ -f "$RC_FILE" ] && grep -qs '\.bun/bin' "$RC_FILE"; then
|
|
274
|
+
: # already set up by Bun's installer — nothing to do
|
|
275
|
+
else
|
|
276
|
+
PATH_NEEDS_RC=1
|
|
277
|
+
fi
|
|
278
|
+
|
|
279
|
+
# ---------- 7. summary / next steps ----------
|
|
280
|
+
echo
|
|
281
|
+
ok "Celilo is installed."
|
|
282
|
+
echo
|
|
283
|
+
echo "Next steps:"
|
|
284
|
+
STEP=1
|
|
285
|
+
if [ "$PATH_NEEDS_RC" = "1" ]; then
|
|
286
|
+
RC_TARGET="${RC_FILE:-your shell rc}"
|
|
287
|
+
printf " %d. Add Bun to your PATH so 'celilo' works in new shells:\n" "$STEP"
|
|
288
|
+
printf " echo %s >> %s\n" "'$PATH_LINE'" "$RC_TARGET"
|
|
289
|
+
printf " exec \$SHELL\n"
|
|
290
|
+
STEP=$((STEP + 1))
|
|
291
|
+
fi
|
|
292
|
+
if [ "${#PREREQ_HINTS[@]}" -gt 0 ]; then
|
|
293
|
+
printf ' %d. Install host prerequisites (Celilo shells out to these during deploy):\n' "$STEP"
|
|
294
|
+
for entry in "${PREREQ_HINTS[@]}"; do
|
|
295
|
+
label="${entry%%|*}"
|
|
296
|
+
cmd="${entry#*|}"
|
|
297
|
+
printf ' %s%s%s\n' "$BOLD" "$label" "$RESET"
|
|
298
|
+
printf ' %s\n' "$cmd"
|
|
299
|
+
done
|
|
300
|
+
STEP=$((STEP + 1))
|
|
301
|
+
fi
|
|
302
|
+
if [ "${#COMPLETIONS_INSTALLED[@]}" -gt 0 ]; then
|
|
303
|
+
shells_csv="$(IFS=', '; printf '%s' "${COMPLETIONS_INSTALLED[*]}")"
|
|
304
|
+
printf ' %d. Activate tab completion (installed for: %s):\n' "$STEP" "$shells_csv"
|
|
305
|
+
printf ' exec $SHELL\n'
|
|
306
|
+
printf ' Verify by typing: celilo <TAB><TAB>\n'
|
|
307
|
+
if [ "${#COMPLETION_RC_SNIPPETS[@]}" -gt 0 ]; then
|
|
308
|
+
printf ' If completion does not work, append the matching rc snippet first:\n'
|
|
309
|
+
for entry in "${COMPLETION_RC_SNIPPETS[@]}"; do
|
|
310
|
+
shell_name="${entry%%|*}"
|
|
311
|
+
rest="${entry#*|}"
|
|
312
|
+
rc_line="${rest%%|*}"
|
|
313
|
+
rc_target="${rest##*|}"
|
|
314
|
+
printf ' %s%s%s — %s%s%s:\n' "$BOLD" "$shell_name" "$RESET" "$BOLD" "$rc_target" "$RESET"
|
|
315
|
+
printf '%s\n' "$rc_line" | sed 's/^/ /'
|
|
316
|
+
done
|
|
317
|
+
fi
|
|
318
|
+
STEP=$((STEP + 1))
|
|
319
|
+
fi
|
|
320
|
+
printf ' %d. Initialize the Celilo database and network config (interactive):\n' "$STEP"
|
|
321
|
+
printf ' celilo system init\n'
|
|
322
|
+
STEP=$((STEP + 1))
|
|
323
|
+
printf ' %d. (Optional) Install the event-bus daemon to stream deploy progress\n' "$STEP"
|
|
324
|
+
printf ' through a persistent system service:\n'
|
|
325
|
+
printf ' celilo events install-daemon\n'
|
|
326
|
+
STEP=$((STEP + 1))
|
|
327
|
+
printf ' %d. Add an infrastructure provider (Proxmox, Digital Ocean, ...):\n' "$STEP"
|
|
328
|
+
printf ' celilo service add\n'
|
|
329
|
+
STEP=$((STEP + 1))
|
|
330
|
+
printf ' %d. Full walkthrough: https://celilo.computer/docs\n' "$STEP"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" data-astro-cid-5hce7sga> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="Browse the official Celilo module registry."><title>Modules — Celilo</title><link rel="icon" type="image/svg+xml" href="/favicon.svg"><script>
|
|
2
|
+
// Resolve theme BEFORE first paint to avoid the flash of wrong
|
|
3
|
+
// theme. Order: explicit user choice (localStorage) → system
|
|
4
|
+
// preference (prefers-color-scheme) → fallback dark. The
|
|
5
|
+
// resolved value lands on <html data-theme="...">; CSS variables
|
|
6
|
+
// below pick the matching palette.
|
|
7
|
+
(function () {
|
|
8
|
+
try {
|
|
9
|
+
const stored = localStorage.getItem('celilo-theme');
|
|
10
|
+
const sys =
|
|
11
|
+
window.matchMedia &&
|
|
12
|
+
window.matchMedia('(prefers-color-scheme: light)').matches
|
|
13
|
+
? 'light'
|
|
14
|
+
: 'dark';
|
|
15
|
+
const theme = stored === 'light' || stored === 'dark' ? stored : sys;
|
|
16
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
17
|
+
} catch (_e) {
|
|
18
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
</script><link rel="stylesheet" href="/_astro/docs.DwsUauWZ.css">
|
|
22
|
+
<style>.page-header[data-astro-cid-ywq4tbty]{padding:1.5rem 0;border-bottom:1px solid var(--border);margin-bottom:2rem}.page-header[data-astro-cid-ywq4tbty] h1[data-astro-cid-ywq4tbty]{font-size:2.5rem;font-weight:800;letter-spacing:-.03em;margin-bottom:.75rem}.page-header[data-astro-cid-ywq4tbty] p[data-astro-cid-ywq4tbty]{color:var(--muted);font-size:1.05rem}.search-bar[data-astro-cid-ywq4tbty]{margin-bottom:2rem;display:flex;gap:.75rem;flex-wrap:wrap;align-items:center}.search-bar[data-astro-cid-ywq4tbty] input[data-astro-cid-ywq4tbty],.search-bar[data-astro-cid-ywq4tbty] select[data-astro-cid-ywq4tbty]{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:.625rem 1rem;color:var(--text);font-size:.9rem;font-family:inherit;outline:none;transition:border-color .15s}.search-bar[data-astro-cid-ywq4tbty] input[data-astro-cid-ywq4tbty]{flex:1;min-width:14rem;max-width:28rem}.search-bar[data-astro-cid-ywq4tbty] select[data-astro-cid-ywq4tbty]{padding-right:2rem;cursor:pointer}.search-bar[data-astro-cid-ywq4tbty] input[data-astro-cid-ywq4tbty]:focus,.search-bar[data-astro-cid-ywq4tbty] select[data-astro-cid-ywq4tbty]:focus{border-color:var(--accent)}.search-bar[data-astro-cid-ywq4tbty] input[data-astro-cid-ywq4tbty]::placeholder{color:var(--muted)}.search-bar[data-astro-cid-ywq4tbty] label[data-astro-cid-ywq4tbty]{font-size:.85rem;color:var(--muted)}#module-grid[data-astro-cid-ywq4tbty]{display:grid;grid-template-columns:repeat(auto-fill,minmax(22rem,1fr));gap:1rem}.module-card[data-astro-cid-ywq4tbty]{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:1.5rem;display:flex;flex-direction:column;gap:.75rem;transition:border-color .15s}.module-card[data-astro-cid-ywq4tbty]:hover{border-color:var(--accent)}.module-header[data-astro-cid-ywq4tbty]{display:flex;align-items:baseline;gap:.75rem}.module-name[data-astro-cid-ywq4tbty]{font-family:var(--font-mono);font-size:1rem;font-weight:600;color:var(--accent-light);text-decoration:none}.module-name[data-astro-cid-ywq4tbty]:hover{text-decoration:underline}.module-version[data-astro-cid-ywq4tbty]{font-family:var(--font-mono);font-size:.75rem;color:var(--muted);background:var(--bg);border:1px solid var(--border);padding:.1em .5em;border-radius:4px}.module-description[data-astro-cid-ywq4tbty]{color:var(--muted);font-size:.875rem;line-height:1.6;flex:1}.module-tags[data-astro-cid-ywq4tbty]{display:flex;flex-wrap:wrap;gap:.375rem}.tag[data-astro-cid-ywq4tbty]{font-size:.7rem;padding:.2em .6em;border-radius:100px;background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent);font-family:var(--font-mono)}.module-footer[data-astro-cid-ywq4tbty]{display:flex;justify-content:space-between;align-items:center;font-size:.8rem;color:var(--muted)}.download-count[data-astro-cid-ywq4tbty]{font-family:var(--font-mono);font-size:.7rem;color:var(--muted);display:inline-flex;align-items:center;gap:.3rem}.module-install[data-astro-cid-ywq4tbty]{font-family:var(--font-mono);font-size:.775rem;background:var(--bg);border:1px solid var(--border);border-radius:6px;padding:.3rem .6rem;cursor:pointer;color:var(--green);display:flex;align-items:center;gap:.4rem}.module-install[data-astro-cid-ywq4tbty]:hover{border-color:var(--green)}#loading[data-astro-cid-ywq4tbty]{color:var(--muted);padding:3rem 0;text-align:center;font-size:.9rem}#error[data-astro-cid-ywq4tbty]{display:none;color:#dc2626;padding:1.5rem;background:color-mix(in srgb,#dc2626 8%,transparent);border:1px solid color-mix(in srgb,#dc2626 25%,transparent);border-radius:8px;font-size:.875rem}
|
|
23
|
+
</style></head> <body data-astro-cid-5hce7sga> <!--
|
|
24
|
+
Background pattern — vertical streams of falling water drawn in
|
|
25
|
+
the geometric vocabulary of a Greek meander. The <pattern>
|
|
26
|
+
tile (240×240) repeats seamlessly across the viewport. Strokes
|
|
27
|
+
use `currentColor` so the .bg-pattern CSS rule above can tint
|
|
28
|
+
them via `color: var(--bg-pattern-color)` without rebuilding
|
|
29
|
+
the SVG. To change the streams themselves, edit the four <path>
|
|
30
|
+
elements below.
|
|
31
|
+
--> <svg class="bg-pattern" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-astro-cid-5hce7sga> <defs data-astro-cid-5hce7sga> <pattern id="celilo-streams" width="240" height="240" patternUnits="userSpaceOnUse" data-astro-cid-5hce7sga> <!-- Streams flow downward — the patternTransform shifts the
|
|
32
|
+
pattern origin by one full tile (240px) over `dur`, then
|
|
33
|
+
loops seamlessly. Edit `dur` for speed; delete this
|
|
34
|
+
<animateTransform> to freeze the flow. --> <animateTransform attributeName="patternTransform" type="translate" from="0 0" to="0 240" dur="30s" repeatCount="indefinite" data-astro-cid-5hce7sga></animateTransform> <g fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" data-astro-cid-5hce7sga> <!-- Stroke color cycle — driven by SMIL inside the SVG
|
|
35
|
+
(not CSS `color`) because Chromium doesn't reliably
|
|
36
|
+
repaint strokes that resolve via currentColor when
|
|
37
|
+
the parent's CSS `color` is animated. Edit the
|
|
38
|
+
`values` list to pick your palette; semicolons
|
|
39
|
+
separate stops, last value should match first to
|
|
40
|
+
close the loop seamlessly. --> <animate attributeName="stroke" values="#818cf8;#f472b6;#4ade80;#22d3ee;#818cf8" dur="10s" repeatCount="indefinite" data-astro-cid-5hce7sga></animate> <!-- Stream A (x=40): big staircase cascade near top, single hook near bottom --> <path d="M 40,0 V 30 H 55 V 45 H 70 V 60 H 55 V 75 H 40 V 175 H 25 V 195 H 40 V 240" data-astro-cid-5hce7sga></path> <!-- Stream B (x=100): small step near top, three-tier cascade in middle --> <path d="M 100,0 V 60 H 85 V 80 H 100 V 130 H 115 V 145 H 130 V 160 H 115 V 175 H 100 V 240" data-astro-cid-5hce7sga></path> <!-- Stream C (x=160): three small hooks distributed top-to-bottom --> <path d="M 160,0 V 20 H 175 V 35 H 160 V 110 H 145 V 130 H 160 V 200 H 175 V 220 H 160 V 240" data-astro-cid-5hce7sga></path> <!-- Stream D (x=220): single deep cascade in the upper-middle --> <path d="M 220,0 V 85 H 205 V 100 H 190 V 115 H 220 V 240" data-astro-cid-5hce7sga></path> </g> </pattern> </defs> <rect width="100%" height="100%" fill="url(#celilo-streams)" data-astro-cid-5hce7sga></rect> </svg> <nav data-astro-cid-5hce7sga> <div class="nav-inner" data-astro-cid-5hce7sga> <a href="/" class="nav-logo" data-astro-cid-5hce7sga>celilo</a> <ul class="nav-links" data-astro-cid-5hce7sga> <li data-astro-cid-5hce7sga> <a href="/docs" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M4 5a2 2 0 0 1 2-2h11v18H6a2 2 0 0 1-2-2V5z" data-astro-cid-5hce7sga></path> <path d="M9 7h6M9 11h6M9 15h4" data-astro-cid-5hce7sga></path> </svg>
|
|
41
|
+
docs
|
|
42
|
+
</a> </li> <li data-astro-cid-5hce7sga> <a href="/modules" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <rect x="3" y="3" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> <rect x="14" y="3" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> <rect x="3" y="14" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> <rect x="14" y="14" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> </svg>
|
|
43
|
+
modules
|
|
44
|
+
</a> </li> <li data-astro-cid-5hce7sga> <a href="/vision" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z" data-astro-cid-5hce7sga></path> <circle cx="12" cy="12" r="3" data-astro-cid-5hce7sga></circle> </svg>
|
|
45
|
+
vision
|
|
46
|
+
</a> </li> <li data-astro-cid-5hce7sga> <a href="https://github.com/celilo/celilo" target="_blank" rel="noopener" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M9 19c-4.3 1.4-4.3-2.5-6-3m12 5v-3.5c0-1 .1-1.4-.5-2 2.8-.3 5.5-1.4 5.5-6a4.6 4.6 0 0 0-1.3-3.2 4.2 4.2 0 0 0-.1-3.2s-1.1-.3-3.5 1.3a12.3 12.3 0 0 0-6.2 0C6.5 2.8 5.4 3.1 5.4 3.1a4.2 4.2 0 0 0-.1 3.2A4.6 4.6 0 0 0 4 9.5c0 4.6 2.7 5.7 5.5 6-.6.6-.6 1.2-.5 2V21" data-astro-cid-5hce7sga></path> </svg>
|
|
47
|
+
github
|
|
48
|
+
</a> </li> <li data-astro-cid-5hce7sga> <button type="button" class="theme-toggle" id="theme-toggle" aria-label="Toggle light/dark theme" title="Toggle theme" data-astro-cid-5hce7sga> <svg class="icon-sun" viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <circle cx="12" cy="12" r="4" data-astro-cid-5hce7sga></circle> <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" data-astro-cid-5hce7sga></path> </svg> <svg class="icon-moon" viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" data-astro-cid-5hce7sga></path> </svg> </button> </li> </ul> </div> </nav> <script>
|
|
49
|
+
// Click handler for the toggle. Reads the current data-theme,
|
|
50
|
+
// flips it, persists to localStorage, applies to <html>. The
|
|
51
|
+
// resolution script in <head> already set the initial value
|
|
52
|
+
// (system-aware) before paint, so this only runs on user
|
|
53
|
+
// interaction.
|
|
54
|
+
(function () {
|
|
55
|
+
const btn = document.getElementById('theme-toggle');
|
|
56
|
+
if (!btn) return;
|
|
57
|
+
btn.addEventListener('click', function () {
|
|
58
|
+
const current = document.documentElement.getAttribute('data-theme');
|
|
59
|
+
const next = current === 'light' ? 'dark' : 'light';
|
|
60
|
+
document.documentElement.setAttribute('data-theme', next);
|
|
61
|
+
try {
|
|
62
|
+
localStorage.setItem('celilo-theme', next);
|
|
63
|
+
} catch (_e) {
|
|
64
|
+
// localStorage unavailable (private mode) — toggle still
|
|
65
|
+
// works for the session, just doesn't persist.
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
})();
|
|
69
|
+
</script> <main data-astro-cid-5hce7sga> <div class="page-header" data-astro-cid-ywq4tbty> <h1 data-astro-cid-ywq4tbty>Module registry</h1> <p data-astro-cid-ywq4tbty>Official modules for Celilo. Install any module with <code data-astro-cid-ywq4tbty>celilo module import <name></code>.</p> </div> <div class="search-bar" data-astro-cid-ywq4tbty> <input id="search" type="search" placeholder="Search modules..." autocomplete="off" data-astro-cid-ywq4tbty> <label for="sort" data-astro-cid-ywq4tbty>Sort:</label> <select id="sort" data-astro-cid-ywq4tbty> <option value="name" data-astro-cid-ywq4tbty>Alphabetical</option> <option value="downloads" data-astro-cid-ywq4tbty>Most downloaded</option> </select> </div> <div id="error" data-astro-cid-ywq4tbty></div> <div id="loading" data-astro-cid-ywq4tbty>Loading modules...</div> <div id="module-grid" style="display:none" data-astro-cid-ywq4tbty></div> <script type="module">const d=document.getElementById("module-grid"),c=document.getElementById("loading"),r=document.getElementById("error"),a=document.getElementById("search"),m=document.getElementById("sort");async function l(t=""){try{const e=new URLSearchParams({per_page:"50"});t&&e.set("q",t),m.value==="downloads"&&e.set("sort","downloads");const o=await fetch(`/registry/api/v1/modules?${e}`);if(!o.ok)throw new Error(`Registry returned ${o.status}`);const n=await o.json();p(n.modules)}catch(e){r.textContent=`Could not reach registry: ${e instanceof Error?e.message:String(e)}`,r.style.display="block",c.style.display="none"}}function p(t){c.style.display="none",d.style.display="grid",d.innerHTML=t.length===0?'<p style="color:var(--muted);grid-column:1/-1">No modules found.</p>':t.map(e=>g(e)).join("")}function s(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function g(t){const e=`celilo module import ${t.name}`,o=`/modules/view?name=${encodeURIComponent(t.name)}`,n=t.total_downloads,u=n===1?"1 download":`${n.toLocaleString()} downloads`;return`
|
|
70
|
+
<div class="module-card">
|
|
71
|
+
<div class="module-header">
|
|
72
|
+
<a href="${o}" class="module-name">${s(t.name)}</a>
|
|
73
|
+
<span class="module-version">${s(t.max_version)}</span>
|
|
74
|
+
</div>
|
|
75
|
+
<p class="module-description">${s(t.description||"No description.")}</p>
|
|
76
|
+
<div class="module-footer">
|
|
77
|
+
<button class="module-install" onclick="navigator.clipboard.writeText('${e}')" title="Copy install command">
|
|
78
|
+
📋 ${e}
|
|
79
|
+
</button>
|
|
80
|
+
<span class="download-count" title="Total downloads">⬇ ${u}</span>
|
|
81
|
+
</div>
|
|
82
|
+
<div style="text-align:right;margin-top:-0.25rem;">
|
|
83
|
+
<a href="${o}" style="color:var(--muted);font-size:0.75rem;">details →</a>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
`}let i;a.addEventListener("input",()=>{clearTimeout(i),i=setTimeout(()=>l(a.value.trim()),300)});m.addEventListener("change",()=>{l(a.value.trim())});l();</script> </main> <footer data-astro-cid-5hce7sga> <p data-astro-cid-5hce7sga>Celilo — home lab orchestration. Built with care.</p> </footer> </body></html>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" data-astro-cid-5hce7sga> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="Per-module detail in the Celilo registry."><title>Module — Celilo</title><link rel="icon" type="image/svg+xml" href="/favicon.svg"><script>
|
|
2
|
+
// Resolve theme BEFORE first paint to avoid the flash of wrong
|
|
3
|
+
// theme. Order: explicit user choice (localStorage) → system
|
|
4
|
+
// preference (prefers-color-scheme) → fallback dark. The
|
|
5
|
+
// resolved value lands on <html data-theme="...">; CSS variables
|
|
6
|
+
// below pick the matching palette.
|
|
7
|
+
(function () {
|
|
8
|
+
try {
|
|
9
|
+
const stored = localStorage.getItem('celilo-theme');
|
|
10
|
+
const sys =
|
|
11
|
+
window.matchMedia &&
|
|
12
|
+
window.matchMedia('(prefers-color-scheme: light)').matches
|
|
13
|
+
? 'light'
|
|
14
|
+
: 'dark';
|
|
15
|
+
const theme = stored === 'light' || stored === 'dark' ? stored : sys;
|
|
16
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
17
|
+
} catch (_e) {
|
|
18
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
</script><link rel="stylesheet" href="/_astro/docs.DwsUauWZ.css">
|
|
22
|
+
<style>.page-header[data-astro-cid-6o2hlio5]{padding:1.5rem 0;border-bottom:1px solid var(--border);margin-bottom:2rem}.page-header[data-astro-cid-6o2hlio5] .breadcrumb[data-astro-cid-6o2hlio5]{font-size:.85rem;color:var(--muted);margin-bottom:.5rem}.page-header[data-astro-cid-6o2hlio5] .breadcrumb[data-astro-cid-6o2hlio5] a[data-astro-cid-6o2hlio5]{color:var(--muted)}.page-header[data-astro-cid-6o2hlio5] .breadcrumb[data-astro-cid-6o2hlio5] a[data-astro-cid-6o2hlio5]:hover{color:var(--text)}.page-header[data-astro-cid-6o2hlio5] h1[data-astro-cid-6o2hlio5]{font-family:var(--font-mono);font-size:2rem;font-weight:700;letter-spacing:-.02em;color:var(--accent-light);margin-bottom:.5rem}.page-header[data-astro-cid-6o2hlio5] .summary[data-astro-cid-6o2hlio5]{color:var(--muted);font-size:1.05rem}.stats[data-astro-cid-6o2hlio5]{display:flex;gap:1.5rem;margin-top:.75rem;font-size:.85rem;color:var(--muted)}.stats[data-astro-cid-6o2hlio5] span[data-astro-cid-6o2hlio5]{display:inline-flex;align-items:center;gap:.4rem}.stats[data-astro-cid-6o2hlio5] strong[data-astro-cid-6o2hlio5]{color:var(--text);font-family:var(--font-mono);font-weight:600}.install-block[data-astro-cid-6o2hlio5]{margin:1.5rem 0 2rem}.install-label[data-astro-cid-6o2hlio5]{font-size:.85rem;color:var(--muted);margin-bottom:.5rem}.install-pre[data-astro-cid-6o2hlio5]{font-family:var(--font-mono);background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:.75rem 1rem;display:flex;justify-content:space-between;align-items:center;gap:1rem;font-size:.9rem;color:var(--green);overflow-x:auto}.install-pre[data-astro-cid-6o2hlio5] button[data-astro-cid-6o2hlio5]{flex-shrink:0;background:transparent;border:1px solid var(--border);border-radius:4px;color:var(--muted);cursor:pointer;font-family:inherit;font-size:.75rem;padding:.25rem .6rem}.install-pre[data-astro-cid-6o2hlio5] button[data-astro-cid-6o2hlio5]:hover{color:var(--text);border-color:var(--text)}h2[data-astro-cid-6o2hlio5]{font-size:1.15rem;font-weight:600;margin-bottom:.75rem;color:var(--text)}.versions[data-astro-cid-6o2hlio5]{list-style:none;border:1px solid var(--border);border-radius:8px;background:var(--surface);overflow:hidden}.versions[data-astro-cid-6o2hlio5] li[data-astro-cid-6o2hlio5]{display:flex;justify-content:space-between;align-items:center;padding:.5rem 1rem;border-bottom:1px solid var(--border);font-size:.85rem}.versions[data-astro-cid-6o2hlio5] li[data-astro-cid-6o2hlio5]:last-child{border-bottom:none}.version-num[data-astro-cid-6o2hlio5]{font-family:var(--font-mono);color:var(--accent-light)}.version-num[data-astro-cid-6o2hlio5].latest:after{content:"latest";font-family:var(--font-sans);font-size:.65rem;color:var(--green);background:color-mix(in srgb,var(--green) 12%,transparent);border:1px solid color-mix(in srgb,var(--green) 30%,transparent);padding:.1em .5em;border-radius:100px;margin-left:.6rem;font-weight:500}.version-num[data-astro-cid-6o2hlio5].yanked{color:var(--muted);text-decoration:line-through}.yanked-tag[data-astro-cid-6o2hlio5]{font-size:.7rem;color:#dc2626;font-family:var(--font-sans)}#loading[data-astro-cid-6o2hlio5]{color:var(--muted);padding:3rem 0;text-align:center;font-size:.9rem}#error[data-astro-cid-6o2hlio5]{display:none;color:#dc2626;padding:1.5rem;background:color-mix(in srgb,#dc2626 8%,transparent);border:1px solid color-mix(in srgb,#dc2626 25%,transparent);border-radius:8px;font-size:.875rem}#content[data-astro-cid-6o2hlio5]{display:none}
|
|
23
|
+
</style></head> <body data-astro-cid-5hce7sga> <!--
|
|
24
|
+
Background pattern — vertical streams of falling water drawn in
|
|
25
|
+
the geometric vocabulary of a Greek meander. The <pattern>
|
|
26
|
+
tile (240×240) repeats seamlessly across the viewport. Strokes
|
|
27
|
+
use `currentColor` so the .bg-pattern CSS rule above can tint
|
|
28
|
+
them via `color: var(--bg-pattern-color)` without rebuilding
|
|
29
|
+
the SVG. To change the streams themselves, edit the four <path>
|
|
30
|
+
elements below.
|
|
31
|
+
--> <svg class="bg-pattern" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-astro-cid-5hce7sga> <defs data-astro-cid-5hce7sga> <pattern id="celilo-streams" width="240" height="240" patternUnits="userSpaceOnUse" data-astro-cid-5hce7sga> <!-- Streams flow downward — the patternTransform shifts the
|
|
32
|
+
pattern origin by one full tile (240px) over `dur`, then
|
|
33
|
+
loops seamlessly. Edit `dur` for speed; delete this
|
|
34
|
+
<animateTransform> to freeze the flow. --> <animateTransform attributeName="patternTransform" type="translate" from="0 0" to="0 240" dur="30s" repeatCount="indefinite" data-astro-cid-5hce7sga></animateTransform> <g fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" data-astro-cid-5hce7sga> <!-- Stroke color cycle — driven by SMIL inside the SVG
|
|
35
|
+
(not CSS `color`) because Chromium doesn't reliably
|
|
36
|
+
repaint strokes that resolve via currentColor when
|
|
37
|
+
the parent's CSS `color` is animated. Edit the
|
|
38
|
+
`values` list to pick your palette; semicolons
|
|
39
|
+
separate stops, last value should match first to
|
|
40
|
+
close the loop seamlessly. --> <animate attributeName="stroke" values="#818cf8;#f472b6;#4ade80;#22d3ee;#818cf8" dur="10s" repeatCount="indefinite" data-astro-cid-5hce7sga></animate> <!-- Stream A (x=40): big staircase cascade near top, single hook near bottom --> <path d="M 40,0 V 30 H 55 V 45 H 70 V 60 H 55 V 75 H 40 V 175 H 25 V 195 H 40 V 240" data-astro-cid-5hce7sga></path> <!-- Stream B (x=100): small step near top, three-tier cascade in middle --> <path d="M 100,0 V 60 H 85 V 80 H 100 V 130 H 115 V 145 H 130 V 160 H 115 V 175 H 100 V 240" data-astro-cid-5hce7sga></path> <!-- Stream C (x=160): three small hooks distributed top-to-bottom --> <path d="M 160,0 V 20 H 175 V 35 H 160 V 110 H 145 V 130 H 160 V 200 H 175 V 220 H 160 V 240" data-astro-cid-5hce7sga></path> <!-- Stream D (x=220): single deep cascade in the upper-middle --> <path d="M 220,0 V 85 H 205 V 100 H 190 V 115 H 220 V 240" data-astro-cid-5hce7sga></path> </g> </pattern> </defs> <rect width="100%" height="100%" fill="url(#celilo-streams)" data-astro-cid-5hce7sga></rect> </svg> <nav data-astro-cid-5hce7sga> <div class="nav-inner" data-astro-cid-5hce7sga> <a href="/" class="nav-logo" data-astro-cid-5hce7sga>celilo</a> <ul class="nav-links" data-astro-cid-5hce7sga> <li data-astro-cid-5hce7sga> <a href="/docs" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M4 5a2 2 0 0 1 2-2h11v18H6a2 2 0 0 1-2-2V5z" data-astro-cid-5hce7sga></path> <path d="M9 7h6M9 11h6M9 15h4" data-astro-cid-5hce7sga></path> </svg>
|
|
41
|
+
docs
|
|
42
|
+
</a> </li> <li data-astro-cid-5hce7sga> <a href="/modules" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <rect x="3" y="3" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> <rect x="14" y="3" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> <rect x="3" y="14" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> <rect x="14" y="14" width="7" height="7" rx="1" data-astro-cid-5hce7sga></rect> </svg>
|
|
43
|
+
modules
|
|
44
|
+
</a> </li> <li data-astro-cid-5hce7sga> <a href="/vision" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z" data-astro-cid-5hce7sga></path> <circle cx="12" cy="12" r="3" data-astro-cid-5hce7sga></circle> </svg>
|
|
45
|
+
vision
|
|
46
|
+
</a> </li> <li data-astro-cid-5hce7sga> <a href="https://github.com/celilo/celilo" target="_blank" rel="noopener" data-astro-cid-5hce7sga> <svg viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M9 19c-4.3 1.4-4.3-2.5-6-3m12 5v-3.5c0-1 .1-1.4-.5-2 2.8-.3 5.5-1.4 5.5-6a4.6 4.6 0 0 0-1.3-3.2 4.2 4.2 0 0 0-.1-3.2s-1.1-.3-3.5 1.3a12.3 12.3 0 0 0-6.2 0C6.5 2.8 5.4 3.1 5.4 3.1a4.2 4.2 0 0 0-.1 3.2A4.6 4.6 0 0 0 4 9.5c0 4.6 2.7 5.7 5.5 6-.6.6-.6 1.2-.5 2V21" data-astro-cid-5hce7sga></path> </svg>
|
|
47
|
+
github
|
|
48
|
+
</a> </li> <li data-astro-cid-5hce7sga> <button type="button" class="theme-toggle" id="theme-toggle" aria-label="Toggle light/dark theme" title="Toggle theme" data-astro-cid-5hce7sga> <svg class="icon-sun" viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <circle cx="12" cy="12" r="4" data-astro-cid-5hce7sga></circle> <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" data-astro-cid-5hce7sga></path> </svg> <svg class="icon-moon" viewBox="0 0 24 24" aria-hidden="true" data-astro-cid-5hce7sga> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" data-astro-cid-5hce7sga></path> </svg> </button> </li> </ul> </div> </nav> <script>
|
|
49
|
+
// Click handler for the toggle. Reads the current data-theme,
|
|
50
|
+
// flips it, persists to localStorage, applies to <html>. The
|
|
51
|
+
// resolution script in <head> already set the initial value
|
|
52
|
+
// (system-aware) before paint, so this only runs on user
|
|
53
|
+
// interaction.
|
|
54
|
+
(function () {
|
|
55
|
+
const btn = document.getElementById('theme-toggle');
|
|
56
|
+
if (!btn) return;
|
|
57
|
+
btn.addEventListener('click', function () {
|
|
58
|
+
const current = document.documentElement.getAttribute('data-theme');
|
|
59
|
+
const next = current === 'light' ? 'dark' : 'light';
|
|
60
|
+
document.documentElement.setAttribute('data-theme', next);
|
|
61
|
+
try {
|
|
62
|
+
localStorage.setItem('celilo-theme', next);
|
|
63
|
+
} catch (_e) {
|
|
64
|
+
// localStorage unavailable (private mode) — toggle still
|
|
65
|
+
// works for the session, just doesn't persist.
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
})();
|
|
69
|
+
</script> <main data-astro-cid-5hce7sga> <div id="error" data-astro-cid-6o2hlio5></div> <div id="loading" data-astro-cid-6o2hlio5>Loading module...</div> <div id="content" data-astro-cid-6o2hlio5> <div class="page-header" data-astro-cid-6o2hlio5> <div class="breadcrumb" data-astro-cid-6o2hlio5><a href="/modules" data-astro-cid-6o2hlio5>← all modules</a></div> <h1 id="m-name" data-astro-cid-6o2hlio5></h1> <p class="summary" id="m-description" data-astro-cid-6o2hlio5></p> <div class="stats" data-astro-cid-6o2hlio5> <span data-astro-cid-6o2hlio5>⬇ <strong id="m-downloads" data-astro-cid-6o2hlio5></strong> downloads</span> <span data-astro-cid-6o2hlio5>📦 <strong id="m-version-count" data-astro-cid-6o2hlio5></strong> versions</span> </div> </div> <div class="install-block" data-astro-cid-6o2hlio5> <div class="install-label" data-astro-cid-6o2hlio5>Install</div> <div class="install-pre" data-astro-cid-6o2hlio5> <code id="m-install" data-astro-cid-6o2hlio5></code> <button id="m-copy" type="button" data-astro-cid-6o2hlio5>Copy</button> </div> </div> <h2 data-astro-cid-6o2hlio5>Versions</h2> <ul class="versions" id="m-versions" data-astro-cid-6o2hlio5></ul> </div> <script type="module">const r=document.getElementById("loading"),d=document.getElementById("error"),y=document.getElementById("content");function s(e){d.textContent=e,d.style.display="block",r.style.display="none"}function g(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}async function p(){const e=new URLSearchParams(window.location.search).get("name");if(!e){s("No module name in URL. Try /modules/view?name=<module>.");return}try{const t=await fetch(`/registry/api/v1/modules/${encodeURIComponent(e)}`);if(t.status===404){s(`Module "${e}" not found in the registry.`);return}if(!t.ok){s(`Registry returned ${t.status}.`);return}const o=await t.json();E(o)}catch(t){s(`Could not reach registry: ${t instanceof Error?t.message:String(t)}`)}}function E(e){document.title=`${e.name} — Celilo`,document.getElementById("m-name").textContent=e.name,document.getElementById("m-description").textContent=e.description||"No description.",document.getElementById("m-downloads").textContent=(e.total_downloads??0).toLocaleString(),document.getElementById("m-version-count").textContent=e.versions.length.toString();const t=`celilo module import ${e.name}`;document.getElementById("m-install").textContent=t;const o=document.getElementById("m-copy");o.addEventListener("click",()=>{navigator.clipboard.writeText(t),o.textContent="Copied!",setTimeout(()=>{o.textContent="Copy"},1200)});const i=[...e.versions].reverse(),c=i.find(n=>!n.yanked),l=document.getElementById("m-versions");l.innerHTML=i.map(n=>{const m=n===c,a=["version-num"];m&&a.push("latest"),n.yanked&&a.push("yanked");const u=n.yanked?'<span class="yanked-tag">yanked</span>':"<span></span>";return`<li><span class="${a.join(" ")}">${g(n.num)}</span>${u}</li>`}).join(""),r.style.display="none",y.style.display="block"}p();</script> </main> <footer data-astro-cid-5hce7sga> <p data-astro-cid-5hce7sga>Celilo — home lab orchestration. Built with care.</p> </footer> </body></html>
|