Uebliche.dev
Uebliche.dev is a small egui desktop app that replaces dev.sh with a GUI. It lets you pick projects, loaders, and versions, run or build targets, and view logs in a single window. Projects and actions are discovered from uebliche.dev files inside the repo.
Features
- Project + loader + version selection in draggable project windows (from
uebliche.dev+ mcmeta/buildFromVersion). - Project cards open on demand by clicking project names in the support matrix.
- Optional snapshot toggle in App settings (uses Mojang release/snapshot manifest).
- Run/build actions with hotkeys.
- Launcher account selection for client runs, quick play, and extra Gradle args.
- Reload mcmeta versions and loader caches.
- Run launcher and local server tasks (vanilla/paper/fabric/forge/neoforge/quilt).
- Server configs live in
~/.uebliche/devtool/servers/<id>/server.jsonand vanilla downloads validate the jar version before reuse. - Run build.moe web/app dev servers and hub loader tasks (via action configs).
- Modrinth project actions (open/upload/sync body) for projects with a Modrinth ID.
- Build/test all versions across loaders from the Global actions window.
- Background validation rebuilds a project after 5 minutes of no code changes and marks validated ranges.
- Background task card with queue/running/history plus pause/play.
- Background task card supports per-project filtering.
- Build cache skips background rebuilds when a project has no git changes.
The build cache is stored in .uebliche.dev.build-cache.json and is only used when the project directory has no uncommitted git changes.
- Create new
uebliche.devprojects from the Uebliche.dev menu. - Edit existing
uebliche.devprojects from the Uebliche.dev menu. - Use the Support and Discord buttons next to Tools in the menu bar to open Patreon and Discord.
- Check for app updates in App settings (stable/beta channels).
- Publish local releases with
app/uebliche.dev/scripts/release.sh. - Open projects/configs in an editor with per-project or default editor settings.
- Multiple concurrent processes with embedded logs.
- Send commands to running tasks from log windows.
- Persistent log catalog backed by
.uebliche.dev.logswith configurable retention. - Hot reload for mcmeta and app source changes.
Run locally
cd app/uebliche.dev
cargo runConfig
Uebliche.dev scans the repo for uebliche.dev files:
kind: "project"describes Gradle-based targets (loaders/versions + tasks).kind: "actions"registers standalone buttons (launcher, build.moe, etc).
Action groups can declare editable variables (saved to .uebliche.dev.settings.json) and reuse them in commands/args/env via {var} placeholders. Secrets work the same way but are masked in the UI:
{
"kind": "actions",
"name": "Public API",
"vars": [
{ "key": "port", "label": "Port", "default": "8080" }
],
"actions": [
{
"label": "Public API local",
"command": "cargo",
"args": ["run"],
"env": {
"PUBLIC_API_PORT": "{port}"
}
}
]
}Launcher actions can optionally provide SIGNING_LISTENER_CMD, SIGNING_LISTENER_CWD, and SIGNING_LISTENER_LOG. When set, app/launcher/dev.sh spawns the signing listener as a subprocess before starting the launcher.
Project configs can also declare vars/secrets that are injected into task templates and Gradle args via {var} placeholders. This is useful for optional run settings like the Paper server port:
{
"kind": "project",
"name": "Connect",
"vars": [
{
"key": "paper_port",
"label": "Paper port",
"default": ""
}
],
"gradleArgsByLoader": {
"paper": ["-Ppaper_port={paper_port}"]
}
}Secrets example:
{
"kind": "actions",
"name": "Public API",
"secrets": [
{
"key": "jwt_secret",
"label": "JWT secret",
"description": "Used to sign session tokens."
}
],
"actions": [
{
"label": "Public API local",
"command": "cargo",
"args": ["run"],
"env": {
"JWT_SECRET": "{jwt_secret}"
}
}
]
}Optional loader-specific version overrides:
{
"loaderVersions": {
"minestom": ["1.21.11"],
"minestom-ffa": ["1.21.11"]
}
}Optional Modrinth config for projects:
{
"modrinth": {
"projectId": "gKnps0Mz",
"pageType": "project",
"tokenEnv": "MODRINTH_TOKEN",
"uploadTask": "modrinth",
"syncBodyTask": "modrinthSyncBody"
}
}The Modrinth block is used by Uebliche.dev and the modrinth-publish workflow.
Optional editor config per project:
{
"editor": {
"command": "code",
"args": ["-g", "{file}"]
}
}The default editor is stored in .uebliche.dev.settings.json at the repo root. Log retention is configured in the same settings file and log files are stored in .uebliche.dev.logs.
Accounts are read from the launcher data store (~/.uebliche/launcher). Use the device code/QR flow in App settings to add new accounts.
CI workflow
The Uebliche.dev CI workflow (.github/workflows/uebliche-dev.yml) runs actions defined in uebliche.dev files using the Rust helpers in tools/uebliche-dev. Only actions with a ci field are included in the matrix. Trigger it via workflow_dispatch and use the inputs to filter by project, loader, version, or action label. Set DEV_INCLUDE_SNAPSHOTS=1 or pass --include-snapshots to include snapshot versions in the matrix.
Example action with CI metadata:
{
"label": "Build",
"command": "bash",
"args": ["dev.sh", "build"],
"ci": "build",
"runsOn": "ubuntu-latest",
"env": {
"JAVA_HOME": "{root}/.java"
}
}ci can be a string or list (build, test, deploy). runsOn is optional and defaults to ubuntu-latest. The CI runner supports the same placeholders as Uebliche.dev: {loader}, {mcVersion}, {root}, {project}, {loader_cache_file}, and {task}.
Requirements
- Rust toolchain (edition 2021)
- Python 3 (loader cache + vanilla download helpers)
- Java 21 for builds and runs