Skip to content
This repository was archived by the owner on Dec 31, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
9c8caee
Convert webroot to vue with better structure (Has many bugs)
FixeQD Dec 13, 2025
672a9df
Make index.vue shorter and fix detecting device interfaces
FixeQD Dec 13, 2025
6048a45
Fix some lint errors
FixeQD Dec 13, 2025
02d947a
Add missing LoadingScreen and fix StatusSection buttons
FixeQD Dec 13, 2025
ce82704
feat(console/status/features): restore console logs, make chroot actions
FixeQD Dec 13, 2025
46fc341
Add file picker dialog component
FixeQD Dec 13, 2025
76359e5
Forgot to remove that bruh
FixeQD Dec 13, 2025
0c88ef7
revert(DEFAULT_BACKUP_DIR): I forgot that I'm using this 💀
FixeQD Dec 13, 2025
559ca3d
feat(settings): load post-exec script before opening settings popup
FixeQD Dec 13, 2025
7f001e4
Add `terser` minification and fix status detection
FixeQD Dec 13, 2025
aceb349
I don't want to talk about this :/
FixeQD Dec 13, 2025
359afb2
fix(console): Hide debug info while DEBUG setting is disabled
FixeQD Dec 13, 2025
29060fe
Fix uninstallation and add rootfs not found page
FixeQD Dec 13, 2025
a5f3617
Add watcher for runAtBoot to write boot file
FixeQD Dec 13, 2025
3939938
feat(build): build webroot and package built version
FixeQD Dec 13, 2025
846500a
Remove unwanted run commands from `package.json` and fix hotspot
FixeQD Dec 14, 2025
4680d50
Remove old webroot files
FixeQD Dec 14, 2025
28ea06d
Enable nuxt ssr
FixeQD Dec 14, 2025
d83a5ee
feat(ui): asynchronous command execution using `runCommandAsyncPromise`
FixeQD Dec 14, 2025
4c10374
feat(ui): make some chroot operations asynchronous
FixeQD Dec 14, 2025
86ed69c
perf(ui): optimize startup animations by parallelizing async operations
FixeQD Dec 14, 2025
8225b25
Format code + fix error in `useChroot.ts`
FixeQD Dec 14, 2025
0797693
Add Bun setup to build workflow
FixeQD Dec 14, 2025
d622583
feat(ui): add backup progress popup to prevent UI lag during operations
FixeQD Dec 14, 2025
50e6fe3
Unify backup and (fix) restore progress UI
FixeQD Dec 14, 2025
2211f31
Stop chroot before backup/restore
FixeQD Dec 14, 2025
aefd402
Broooooo I forgot bt that, I'm stupid 😭
FixeQD Dec 14, 2025
8567cef
Bruh
FixeQD Dec 14, 2025
02054d7
Ohhhh
FixeQD Dec 14, 2025
e5341aa
FINALLY PIECE OF SHI- Commit ;)
FixeQD Dec 14, 2025
fe616d0
fix: disable all UI elements during actions, fix blinking indicator, …
FixeQD Dec 17, 2025
0b4b80d
fix: prevent 500 error when command bridge unavailable
FixeQD Dec 17, 2025
f6c3430
Move status update after console setup
FixeQD Dec 17, 2025
d63a39b
Add chroot update confirmation popup
FixeQD Dec 18, 2025
78d127f
Await DOM update when closing settings popup
FixeQD Dec 18, 2025
8638696
Inline component styles and scope CSS
FixeQD Dec 18, 2025
291cd9e
Revert "Inline component styles and scope CSS"
FixeQD Dec 18, 2025
4b82e8a
fix(webui): prevent chroot auto-start on load, add command timeouts, and
FixeQD Dec 20, 2025
af52334
fix(webui): make command timeout optional to prevent interrupting long
FixeQD Dec 20, 2025
79374e9
Fix popup layout
FixeQD Dec 20, 2025
d2a46a5
Fix chroot existence check and UI handling
FixeQD Dec 20, 2025
0ee79ef
Add Uninstall Confirmation Popup
FixeQD Dec 20, 2025
a2cf37c
Use icon from `Icon.vue` instead of svg
FixeQD Dec 20, 2025
3e54c5f
Render app only when not loading or not found
FixeQD Dec 20, 2025
c33c7a8
Fix import error in `uninstall.ts`
FixeQD Dec 20, 2025
c4ea0ce
fix(backup-restore): suppress Vue component import TypeScript error
FixeQD Dec 20, 2025
3cbfa3c
refactor: rename BackupProgressPopup to ProgressPopup and move popup
FixeQD Dec 20, 2025
ed8f458
Show progress during chroot uninstall
FixeQD Dec 20, 2025
951cfd2
Fix orange loading screen
FixeQD Dec 20, 2025
660c326
feat: disable UI functionality when chroot not found
FixeQD Dec 21, 2025
188716e
Add theme-specific styles for UI components
FixeQD Dec 22, 2025
3fcd3f0
Remove example echo from placeholder
FixeQD Dec 22, 2025
37a6203
Apply some dark theme button tweaks and sortout css
FixeQD Dec 22, 2025
72f1d0c
Retry chroot status fetch and delay before refresh
FixeQD Dec 24, 2025
345f272
fix(ui): resolve button issues and improve UX
FixeQD Dec 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/build-gui-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ name: Build and Release GUI and CLI
on:
push:
tags:
- 'v*'
- "v*"
workflow_dispatch:
inputs:
version:
description: 'Release Version (e.g., v3.1)'
description: "Release Version (e.g., v3.1)"
required: true
update_jsons_only:
description: 'Only update the JSONs and Changelog (skip build and release)'
description: "Only update the JSONs and Changelog (skip build and release)"
type: boolean
default: false
only_build_update_zip:
description: 'Only build the update ZIP (skip rootfs and full ZIP)'
description: "Only build the update ZIP (skip rootfs and full ZIP)"
type: boolean
default: false

Expand All @@ -34,6 +34,10 @@ jobs:
ref: main
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install dependencies
run: sudo apt update && sudo apt install -y jq
Expand Down Expand Up @@ -112,7 +116,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ matrix.branch }}
fetch-depth: 0 # Fetch all history for proper tag comparison
fetch-depth: 0 # Fetch all history for proper tag comparison

- name: Install dependencies
run: sudo apt update && sudo apt install -y rsync python3
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
*.tar*
*.zip
*.conf

**/.nuxt
**/.output
**/dist
**/node_modules
14 changes: 12 additions & 2 deletions build_zip.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -e

# Check for required dependencies
deps=("rsync" "python3")
deps=("rsync" "python3" "bun")
for dep in "${deps[@]}"; do
if ! command -v "$dep" >/dev/null 2>&1; then
echo "$dep is required but not installed."
Expand Down Expand Up @@ -44,8 +44,18 @@ rm -f "$ZIP_NAME"

TMP_DIR=$(mktemp -d)

# Build webroot
cd webroot
bun i
bun run generate
cd ..

# Copy all files except excluded
rsync -a --exclude='.git*' --exclude='Screenshots' --exclude='Docker' --exclude='CHANGELOG.md' --exclude='out' --exclude='update-*.json' --exclude='update_meta.sh' --exclude='build_zip.sh' "$PWD/" "$TMP_DIR/"
rsync -a --exclude='.git*' --exclude='node_modules' --exclude='Screenshots' --exclude='Docker' --exclude='CHANGELOG.md' --exclude='out' --exclude='update-*.json' --exclude='update_meta.sh' --exclude='build_zip.sh' "$PWD/" "$TMP_DIR/"

# Replace webroot/app with built .output
rm -rf "$TMP_DIR/webroot"
cp -r webroot/.output/public "$TMP_DIR/webroot"

# For update builds, remove tar.gz files and add update marker
if [ "$UPDATE_FLAG" = "--update" ]; then
Expand Down
33 changes: 31 additions & 2 deletions tools/chroot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ HOLDER_PID_FILE="${BASE_CHROOT_DIR}/holder.pid"
SILENT=0
SKIP_POST_EXEC=0
CHROOT_SETUP_IN_PROGRESS=0
NO_AUTO_START=0

# --- Debug mode ---
LOGGING_ENABLED=${LOGGING_ENABLED:-0}
Expand Down Expand Up @@ -71,6 +72,7 @@ usage() {
echo " [user] Username to log in as (default: root)."
echo " --no-shell Setup chroot without entering an interactive shell."
echo " --skip-post-exec Skip running post-execution scripts."
echo " --no-auto-start Prevent automatic chroot startup for commands."
echo " -s Silent mode (suppress informational output)."
exit 1
}
Expand Down Expand Up @@ -139,7 +141,7 @@ run_in_chroot() {
local command="$*"

# Ensure chroot is started if not running - but prevent recursion during setup
if [ "$CHROOT_SETUP_IN_PROGRESS" -eq 0 ]; then
if [ "$CHROOT_SETUP_IN_PROGRESS" -eq 0 ] && [ "$NO_AUTO_START" -eq 0 ]; then
if ! is_chroot_running; then
log "Starting chroot for command execution..."
start_chroot > /dev/null 2>&1 || {
Expand Down Expand Up @@ -773,11 +775,35 @@ show_status() {
fi
}

show_raw_status() {
if is_chroot_running; then
echo "RUNNING"
else
echo "STOPPED"
fi
}

list_users() {
if [ "$NO_AUTO_START" -eq 1 ] && ! is_chroot_running; then
echo ""
return
fi
run_in_chroot "awk -F: '\$3 >= 1000 && \$3 < 65534 {print \$1}' /etc/passwd 2>/dev/null | tr '\n' ',' | sed 's/,$//'"
}

check_existing() {
if [ -d "$CHROOT_PATH" ] || [ -f "$ROOTFS_IMG" ]; then
echo "exists"
else
echo "not_exists"
fi
}

run_command() {
if [ "$NO_AUTO_START" -eq 1 ] && ! is_chroot_running; then
error "Chroot is not running and auto-start is disabled"
return 1
fi
local command="$*"
run_in_chroot "$command"
}
Expand Down Expand Up @@ -1157,11 +1183,12 @@ WEBUI_MODE=0

for arg in "$@"; do
case "$arg" in
start|stop|restart|status|umount|fstrim|backup|restore|uninstall|list-users|run|resize)
start|stop|restart|status|raw-status|umount|fstrim|backup|restore|uninstall|list-users|run|resize|check_existing)
COMMAND="$arg" ;;
--no-shell) NO_SHELL_FLAG=1 ;;
--webui) WEBUI_MODE=1 ;;
--skip-post-exec) SKIP_POST_EXEC=1 ;;
--no-auto-start) NO_AUTO_START=1 ;;
-s) SILENT=1 ;;
-h|--help) usage ;;
-*) echo "Unknown option: $arg"; usage ;;
Expand Down Expand Up @@ -1191,6 +1218,7 @@ case "$COMMAND" in
if [ "$NO_SHELL_FLAG" -eq 0 ]; then enter_chroot "$USER_ARG"; else log "Chroot setup complete (no-shell mode). Use 'sh $0 start' to enter."; fi
;;
status) show_status ;;
raw-status) show_raw_status ;;
umount)
log "Umounting chroot filesystems..."; umount_chroot; log "Chroot filesystems unmounted successfully." ;;
fstrim)
Expand Down Expand Up @@ -1221,5 +1249,6 @@ case "$COMMAND" in
exit 1
fi
resize_sparse "$RESIZE_SIZE" ;;
check_existing) check_existing ;;
*) error "Invalid command: $COMMAND"; usage ;;
esac
13 changes: 13 additions & 0 deletions webroot/app/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<div>
<NuxtRouteAnnouncer />
<NuxtPage />
</div>
</template>

<script setup>
import "@/assets/css/light.css";
import "@/assets/css/dark.css";
import "@/assets/css/animations.css";
</script>
>
80 changes: 80 additions & 0 deletions webroot/app/assets/css/animations.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.6;
}
}

@keyframes fadeInUp {
from {
opacity: 0;
transform: translate3d(0, 8px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}

@keyframes chunkFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes dotFill {
0%,
20.1%,
100% {
opacity: 0.3;
}
0.1%,
20% {
opacity: 1;
}
}

.loading-dot {
animation: dotFill 3.75s infinite;
}

.loading-dot:nth-child(1) {
animation-delay: 0s;
}
.loading-dot:nth-child(2) {
animation-delay: 0.75s;
}
.loading-dot:nth-child(3) {
animation-delay: 1.5s;
}
.loading-dot:nth-child(4) {
animation-delay: 2.25s;
}
.loading-dot:nth-child(5) {
animation-delay: 3s;
}

.console > div.progress-indicator.log-immediate {
animation: pulse 1.5s ease-in-out infinite !important;
}

.console > div.log-immediate {
animation: none;
}

.console > div.log-chunk-fade {
animation: chunkFadeIn 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.console > div.log-fade-in {
animation: fadeInUp 0.35s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.console .progress-indicator {
animation: pulse 1.5s ease-in-out infinite;
}
Loading