Uebliche.devDev console for the uebliche stack
A focused desktop GUI for running, building, and validating the repo.
A focused desktop GUI for running, building, and validating the repo.
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.
dev.sh now auto-reloads the app when changes are detected if cargo watch, watchexec, or fswatch is installed. After updating Uebliche.dev, review logs/uebliche.dev-current.log to confirm the app restarted cleanly.
uebliche.dev + mcmeta/buildFromVersion).~/.uebliche/devtool/servers/<id>/server.json and vanilla downloads validate the jar version before reuse.uebliche.dev project configs directly from the project list.group in uebliche.dev.uebliche.code-workspace) for all projects.The build cache is stored in .uebliche.dev.build-cache.json and is only used when the project directory has no uncommitted git changes.
uebliche.dev projects from the Uebliche.dev menu.uebliche.dev projects from the Uebliche.dev menu.app/uebliche.dev/scripts/release.sh..uebliche.dev.logs with configurable retention.eula.txt for server runs after a project has been accepted in the EULA tool.cd app/uebliche.dev
cargo runDevtool docs live under /dev/devtool/ and cover UI behavior, release notes, and tooling specifics.
Quick links:
/dev/devtool//dev/devtool/changelogcd app/uebliche.dev
./scripts/install-uebliche-dev.shcd app/uebliche.dev
./scripts/build-app-bundle.sh
open target/release/Uebliche.dev.appThe bundle script signs the app if a codesign identity is available. Set UEBLICHE_CODESIGN_IDENTITY to force a specific identity or UEBLICHE_CODESIGN_DISABLE=1 to skip signing.
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). You can optionally set group on projects to visually group them in the list. Use group/subgroup to create a nested subgroup under a top-level group.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}"
}
}
]
}Variables can also load dynamic dropdown values by setting optionsKey. Use optionsKey: "docker_contexts" to pull the local Docker contexts list.
Actions can upload artifacts to S3 after completion by defining uploads. Each upload supports a path, optional key template (including {filename} and {relpath}), and optional acl (defaults to public-read):
{
"label": "Release upload",
"command": "./scripts/build.sh",
"uploads": [
{
"path": "release/*.zip",
"key": "releases/{filename}",
"acl": "public-read"
}
]
}Publish uses a central S3 config in Settings -> S3 stores. Set a publish store and prefix there to control where release artifacts are uploaded.
Docker Swarm secrets can be managed in Settings -> Docker. Use the List secrets button to see existing secret names for the selected context, and Add/Update secret to write new values.
Deploy actions can define deployTargets (e.g. s3, modrinth). When Modrinth is selected, Uebliche.dev generates an English summary from the configured changelogPath via Codex CLI and asks for confirmation before publishing.
Deploy actions can also post the generated summary to Discord. Configure a project-level discord block with a channel id, optional body, and link list. Uebliche.dev uses DISCORD_BOT_TOKEN unless tokenEnv is provided. If the env token is missing, it falls back to the Discord bot token stored in Uebliche.dev Tools -> Discord bot:
{
"discord": {
"channelId": "123456789012345678",
"body": "Release notes below.",
"links": [
{ "label": "Modrinth", "url": "https://modrinth.com/plugin/spawnlite" },
{ "label": "S3", "url": "https://updates.uebliche.net/spawnlite/release/" }
]
}
}Launcher actions can optionally provide SIGNING_LISTENER_CMD, SIGNING_LISTENER_CWD, and SIGNING_LISTENER_LOG. Leave them empty to let app/launcher/dev.sh use its defaults (launcher root + bundled script). When set, the script spawns the signing listener as a subprocess before starting the launcher.
Set UEBLICHE_DEVTOOLS=1 when running the launcher to auto-open the Tauri devtools for all windows (requires a debug build).
Launcher updates use the Tauri updater plugin. Keep app/launcher/apps/ui-tauri/src-tauri/tauri.conf.json updated with the updater endpoints and pubkey, and ensure updater artifacts/signatures are generated when building release bundles.
Local builds keep bundle.createUpdaterArtifacts disabled to avoid requiring signing keys; enable it in release/CI when TAURI_SIGNING_PRIVATE_KEY is available.
See docs/dev/mcp/index.md for MCP setup and tool docs.
The MCP server also supports adding/removing Docker log watches so Codex can stream Swarm service logs in the Log Catalog. Use add_docker_watch with:
service (required): Docker Swarm service name.context (optional): Docker context to use. Defaults to the saved Docker context in Settings (or default).To remove a watch, use remove_docker_watch with:
id (optional): Process id from the Log Catalog entry.service (required if id is not set): Docker Swarm service name.context (optional): Docker context, defaults to Settings (or default).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}"]
}
}Project configs can also define dockerSecrets to list expected Docker Swarm secrets for the project. Each entry is compared against the Docker secrets list in Settings -> Docker so you can spot missing secrets and see when they were set:
{
"dockerSecrets": [
{
"key": "public_api_token",
"label": "Public API token",
"description": "Token used by the proxy to access Public API."
}
]
}Set changelogPath in uebliche.dev to point at the changelog file for the project (relative to the project root):
{
"kind": "project",
"name": "Hub",
"changelogPath": "docs/changelog.md"
}You can define Minecraft version ranges directly in uebliche.dev via versionRange and optionally skip specific versions:
{
"versionRange": {
"min": "1.20.5",
"max": "1.21.11",
"skippedVersions": ["1.21.2"]
}
}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 loader disable list (hide loaders from selection):
{
"disabledLoaders": ["forge"]
}Optional loader-specific run modes (override runModes for a loader):
{
"runModesByLoader": {
"forge": []
}
}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. JVM hotswap settings (optional JAVA_HOME override, extra JVM opts) are stored in .uebliche.dev.settings.json and applied to Java runs when enabled. The HotswapAgent jar is stored in the Uebliche.dev app data folder and downloaded automatically. For Minecraft dev runs (Fabric/Forge/NeoForge), HotswapAgent is disabled by default due to classloader conflicts. Set UEBLICHE_FORCE_HOTSWAP_AGENT=1 to force it on.
Open Tools → DB Monitor to manage database health checks, backups, and restores. Configure MongoDB/Postgres/MySQL/Redis connections in Settings → Database servers. Backup output is stored in the Uebliche.dev app data folder at ~/.uebliche/devtool/db-backups/<store-id> unless an S3 target is selected. Schedules are interval-based (minutes) with a retention count and run while the app is open. Mongo/Postgres/MySQL backups invoke the local database CLI tools (mongodump, mongorestore, pg_dump, pg_restore, mysqldump, mysql, mysqladmin).
Open Tools → Ressourcen-Monitor to review running Uebliche.dev processes and their durations (including the app itself), plus CPU, memory, threads, and listening ports. The monitor also keeps a RAM usage history graph for the app. Use the filter and minimum seconds controls to spot tasks that are taking longer than expected, and open or kill a process directly from the table. Enable auto refresh to keep the list and RAM graph updated on a timer.
Accounts are read from the launcher data store (~/.uebliche/launcher). Use the device code/QR flow in App settings to add new accounts.
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}.