This commit is contained in:
2026-08-31 16:49:41 +02:00
parent 10272ff8e2
commit bf6b8a93d8
10 changed files with 415 additions and 522 deletions
+53 -272
View File
@@ -1,33 +1,8 @@
# Omarchy Citizen 0.6.4 – Plug-&-Play-Installation
# Omarchy Citizen 0.7.0 – Rundum-Sorglos
## Ziel
## Installation
Der Nutzer soll Star Citizen unter Omarchy benutzen können, ohne Linux administrieren zu müssen.
Im normalen Alltag sind nur drei Dinge wichtig:
1. **EINRICHTEN & STARTKLAR MACHEN** bzw. **STAR CITIZEN STARTEN**
2. **Problem beheben**
3. **Support-Paket erstellen**
Wine-Runner, DXVK, einzelne Reparaturschritte, Logs und NGL befinden sich unter
**Erweiterte Optionen**.
---
## 1. Plugin installieren
### Mausfreundlich
Entpacke `omarchy-citizen-0.6.0.zip`.
Im entpackten Ordner liegt:
`INSTALLIEREN.sh`
Führe diese Datei über deinen Dateimanager als Programm aus.
Falls der Dateimanager Skripte nicht direkt ausführt, bleibt der Terminal-Fallback:
Entpacken und einmal ausführen:
```bash
./INSTALLIEREN.sh
@@ -39,267 +14,73 @@ oder:
./install.sh
```
Der Plugin-Installer benötigt kein `sudo` und schreibt nur nach:
Danach übernimmt **Autopilot**.
## Was automatisch aktuell gehalten wird
Ohne weitere Pflege des Nutzers:
- Omarchy Citizen selbst (wenn als Git-Plugin installiert)
- offizieller LUG Helper als AppImage
- stabiler LUG-Wine-Runner
- DXVK
- Auswahl des verwalteten Wine-Runners im Start-Script
Der Wartungstimer läuft alle sechs Stunden.
## Sicherheitsmechanismus für Wine Updates
Ein neuer Wine-Runner wird nicht einfach installiert.
Omarchy Citizen baut zuerst einen temporären Wine-Prefix und verlangt erfolgreich:
```text
~/.config/omarchy/plugins/local.omarchy-citizen/
wineboot
drive_c
system.reg
user.reg
%APPDATA%
```
Nach der Installation erscheint **✦SC** in der Omarchy-Leiste.
Erst danach wird der Runner aktiviert.
---
Damit hätte der Fehler, den wir während der Entwicklung gesehen haben
(`drive_c` fehlt / `%AppData% returned empty string`), bereits *vor* der echten
Star-Citizen-Installation den Autopilot-Test gestoppt.
## 2. Erstes Setup
## Warum kein AUR-LUG-Paket mehr?
Klicke:
Der offizielle LUG Helper wird als AppImage verwaltet. Dadurch hängt der
Star-Citizen-Workflow nicht mehr davon ab, ob das AUR-Paket, dessen Winetricks
oder dessen GUI-Abhängigkeiten gerade passend installiert sind.
**✦SC → EINRICHTEN & STARTKLAR MACHEN**
Bestehende AUR-LUG-Installationen dürfen vorhanden bleiben; Omarchy Citizen
bevorzugt jedoch seine eigene verwaltete AppImage-Kopie.
Omarchy Citizen übernimmt danach soweit möglich selbst:
## Systemupdates
- benötigte Systempakete prüfen/installieren
- `zenity`, `polkit`, `cabextract`, `unzip`
- LUG Helper aus dem AUR installieren
- LUG Preflight Check starten
- Star-Citizen-/RSI-Launcher-Einrichtung starten
- vorhandenen Wine-Prefix erkennen
- Start-Script erkennen/reparieren
Omarchy Citizen installiert absichtlich keine dauerhafte passwortlose
Pacman-/sudo-Regel.
Für Paketinstallationen kann einmal ein sichtbares Omarchy-Terminal erscheinen.
Das ist absichtlich so, damit Passwortabfragen sicher und nachvollziehbar bleiben.
Der Nutzer muss dort keine Paketnamen oder Linux-Befehle kennen.
Omarchy-System-, Kernel- und GPU-Treiberupdates bleiben bei:
---
## 3. Normaler Alltag
Wenn das Panel **FLIGHT READY** zeigt:
**✦SC → STAR CITIZEN STARTEN**
Das Plugin verwendet weiterhin das vom LUG Helper verwaltete `sc-launch.sh`.
---
## 4. Problem beheben
Klicke:
**✦SC → Problem beheben**
Der Assistent prüft zuerst automatisch, ob etwas offensichtlich fehlt.
Wenn das System grundsätzlich eingerichtet ist, fragt er nur nach dem Symptom:
- Automatisch prüfen
- RSI Launcher startet nicht / ist kaputt
- Star Citizen startet nicht
- Grafik / Performance / Abstürze
- NGL macht Probleme
- Problem unklar
Dahinter werden die passenden LUG-Helper-Funktionen aufgerufen.
Der Nutzer muss keine Begriffe wie Wine-Prefix, DXVK oder `vm.max_map_count` kennen.
---
## 5. Permanentes Debug-Log
Omarchy Citizen protokolliert seine eigenen Aktionen dauerhaft unter:
```text
~/.local/state/omarchy-citizen/omarchy-citizen.log
```bash
omarchy update -y
```
Darin stehen unter anderem:
Das ist der von Omarchy vorgesehene vollständige Updatepfad. Die Star-Citizen-
Komponenten selbst werden davon unabhängig durch Autopilot gepflegt.
- Plugin-Version
- aufgerufene Plugin-Aktionen
- Start-/Reparaturvorgänge
- LUG-Helper-Aufrufe
- Setup-/Update-Abläufe
- Fehlermeldungen des Plugins
## Support
Das lokale Roh-Log kann in **Erweiterte Optionen → Plugin-Debuglog öffnen**
angesehen werden.
Das Roh-Log wird nicht automatisch hochgeladen oder versendet. Ab ungefähr 4 MiB wird es automatisch gekürzt; die neuesten ungefähr 2 MiB bleiben erhalten.
---
## 6. Support-Paket für Nutzer
Klicke:
Bei einem Fehler:
**✦SC → Support-Paket erstellen**
Das Plugin erzeugt automatisch eine Datei wie:
Das Paket enthält zusätzlich:
```text
~/Downloads/Omarchy-Citizen-Support-OC-20260831-123456-abcdef.tar.gz
```
Zusätzlich wird eine **Support-ID** angezeigt.
### Standardmäßig enthalten
- Omarchy Citizen Status
- Plugin-Version
- `omarchy debug --no-sudo --print`
- Kernel/Desktop-Informationen
- GPU/Vulkan-Zusammenfassung
- RAM
- Dateisystemtyp und freier Speicher
- relevante Paketversionen
- Star-Citizen-Kernel-Limits
- Plugin-Validierung
- letzte Omarchy-Citizen-Debugmeldungen
- letzter Omarchy-Update-Logauszug, falls vorhanden
- Star-Citizen-/LUG-Pfadstatus
- begrenzter `sc-launch.log`-Auszug
- bereinigte Kopie des LUG-Start-Scripts
- Go-Updater-Status (Git/ZIP, Auto-Update, Commit-Stand)
- bereinigter Updater-Logauszug
### Nicht standardmäßig enthalten
- Browserdaten
- SSH-Schlüssel
- Passwortdateien
- vollständige Star-Citizen-Game.log-Dateien
- vollständige EAC-Logs
- Dateien aus dem RSI-Account/Browserprofil
### Automatische Maskierung beim Export
Das Support-Paket versucht folgende Daten zu maskieren:
- Home-Pfad
- Benutzername
- Hostname
- E-Mail-Adressen
- IPv4-Adressen
- MAC-Adressen
- Bearer-/JWT-Tokens
- typische `token`, `session`, `cookie`, `password`, `secret`-Werte
- typische Auth-Queryparameter in URLs
Die Maskierung ist eine Best-Effort-Funktion. Nutzer können das Archiv vor dem
Versenden selbst öffnen und prüfen.
---
## 7. Updates
### Plugin selbst
0.6.0 enthält ein statisch gebautes Go-Backend. Es erkennt automatisch, ob Omarchy
Citizen als Git-Plugin oder aus einem ZIP installiert wurde.
Bei einer Git-Installation gibt es unter **Erweiterte Optionen → Plugin-Updates**:
- **Plugin-Update prüfen**
- **Plugin jetzt aktualisieren**
- **Auto-Updates einschalten/ausschalten**
- **Updater-Log öffnen**
Beim Aktivieren von Auto-Updates wird das aktuelle Git-`origin` als vertrauenswürdige
Quelle gespeichert. Ein systemd-User-Timer prüft ungefähr alle sechs Stunden mit einer
zufälligen Verzögerung von bis zu 15 Minuten.
Ein automatisches Update wird verweigert, wenn:
- das Git-Remote nachträglich geändert wurde
- lokale Änderungen im Plugin-Checkout liegen
- der lokale Branch vom Upstream abgewichen ist
- bereits ein anderes Plugin-Update läuft
- Omarchys Plugin-Validierung fehlschlägt
Das Backend baut keinen eigenen Plugin-Paketmanager. Die eigentliche Aktualisierung läuft
über Omarchys offiziellen nicht-interaktiven Weg:
```bash
omarchy plugin update local.omarchy-citizen --yes
```
Dadurch bleiben Fast-Forward-Prüfung, Validierung und Rollback bei Omarchy.
Bei der aktuellen ZIP-Installation zeigt das Backend bewusst **ZIP / nicht Git-verwaltet**.
Es lädt dann nichts aus einer erfundenen oder unbekannten Quelle herunter. Sobald das
Projekt als GitHub-/Git-Repository veröffentlicht und mit `omarchy plugin add` installiert
wird, erkennt das Backend `origin` automatisch.
### LUG und Omarchy
Zusätzlich befinden sich unter **Erweiterte Optionen**:
- LUG Update prüfen
- LUG aktualisieren
- Omarchy aktualisieren
Systempakete werden weiter über den normalen `omarchy update`-Weg aktualisiert.
Dadurch bleiben Omarchy-Migrationen und der vorgesehene Update-Ablauf erhalten.
### Updater-Dateien
```text
~/.config/omarchy-citizen/updater.json
~/.local/state/omarchy-citizen/updater.log
~/.local/lib/omarchy-citizen/omarchy-citizen-backend
```
Der Updater läuft nicht als dauerhafter Webserver. Der systemd-User-Timer startet ihn nur
für die jeweilige Prüfung.
---
## 8. NGL
NGL bleibt unter **Erweiterte Optionen** und ist deutlich als experimentell markiert.
Der normale Star-Citizen-Betrieb ist nicht von NGL abhängig.
---
## 9. Supportablauf für dich als Plugin-Betreuer
Wenn ein Nutzer ein Problem meldet, kannst du ihn bitten:
1. **✦SC** öffnen
2. **Support-Paket erstellen** klicken
3. dir die erzeugte `.tar.gz` schicken
4. die angezeigte Support-ID nennen
Damit brauchst du im ersten Supportkontakt normalerweise keine Terminalbefehle
vom Nutzer anzufordern.
## Hotfix 0.6.4 – Setup-Button
Version 0.6.4 ändert die Ausführung der Panel-Aktionen grundlegend.
Beim Klick auf **EINRICHTEN & STARTKLAR MACHEN** wird die Aktion nun direkt als
Quickshell-Prozess gestartet. Das Panel zeigt sofort **WIRD GESTARTET**.
Wenn der Start fehlschlägt, bleibt das Panel offen und zeigt den Fehler an.
Außerdem wird der fehlgeschlagene Terminalstart in
`~/.local/state/omarchy-citizen/omarchy-citizen.log` protokolliert und landet
im Support-Paket.
Nach der Installation wird der Omarchy-Shellprozess einmal neu gestartet, damit
die neue QML-Version sicher aktiv ist.
## 0.6.4 – unvollständiger Wine-Prefix
Ein Ordner wie `~/Games/star-citizen` gilt jetzt erst dann als fertiger Wine-Prefix,
wenn mindestens `drive_c`, `system.reg` und `user.reg` existieren.
Wenn nur Runner/Teildateien vorhanden sind, zeigt das Plugin **SETUP REPAIR**.
Bei **SETUP SICHER REPARIEREN** wird der alte Ordner nicht gelöscht. Ohne erkannte
`Data.p4k`-Spieldatei wird er nach `star-citizen-incomplete-<Zeitstempel>` umbenannt,
die LUG-Zielkonfiguration wird gesichert und der offizielle LUG-Installer startet neu.
Das Support-Paket enthält jetzt außerdem den neuesten detaillierten
`lughelper-install-*.log`, damit Wine-/Winetricks-Fehler analysiert werden können.
- Autopilot-Status
- verwaltete LUG-/Wine-/DXVK-Versionen
- Wine-Selbsttest
- Maintenance-Ergebnis
- Updater-Log
+1
View File
@@ -49,6 +49,7 @@ omarchy-shell shell rescanPlugins >/dev/null 2>&1 || true
"$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend" install-service >/dev/null 2>&1 || true
omarchy plugin enable "$PLUGIN_ID" >/dev/null 2>&1 || true
"$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend" autopilot enable >/tmp/omarchy-citizen-autopilot-install.log 2>&1 || true
omarchy bar move "$PLUGIN_ID" --section right >/dev/null 2>&1 || true
# QML hot-reload is currently unreliable for third-party bar plugins.
+41 -9
View File
@@ -12,7 +12,7 @@ Panel {
property var anchorItem: null
property var hostWidget: null
property string pluginVersion: "0.6.4"
property string pluginVersion: "0.7.0"
property string health: "checking"
property string depsState: "checking"
property string depsMissing: ""
@@ -34,6 +34,11 @@ Panel {
property string pluginUpdate: "unavailable"
property string pluginLocalCommit: ""
property string pluginRemoteCommit: ""
property string autopilot: "false"
property string managedLUGVersion: ""
property string managedWineVersion: ""
property string managedDXVKVersion: ""
property string maintenanceResult: ""
property string actionStatus: ""
property string actionError: ""
property string actionKind: ""
@@ -97,7 +102,7 @@ Panel {
values[lines[i].slice(0, p)] = lines[i].slice(p + 1)
}
pluginVersion = values.plugin_version || "0.6.4"
pluginVersion = values.plugin_version || "0.7.0"
health = values.health || "setup"
depsState = values.deps || "missing"
depsMissing = values.deps_missing || ""
@@ -117,6 +122,11 @@ Panel {
pluginUpdate = values.plugin_update || "unavailable"
pluginLocalCommit = values.plugin_local_commit || ""
pluginRemoteCommit = values.plugin_remote_commit || ""
autopilot = values.autopilot || "false"
managedLUGVersion = values.managed_lug_version || ""
managedWineVersion = values.managed_wine_version || ""
managedDXVKVersion = values.managed_dxvk_version || ""
maintenanceResult = values.maintenance_result || ""
}
function stateIcon(state) {
@@ -160,6 +170,7 @@ Panel {
}
function headline() {
if (health === "ready" && root.autopilot === "true") return "FLIGHT READY · AUTOPILOT"
if (health === "ready") return "FLIGHT READY"
if (health === "recover-prefix") return "SETUP REPAIR"
if (health === "repair") return "REPAIR AVAILABLE"
@@ -523,9 +534,10 @@ Panel {
Text {
width: parent.width
text: "Version " + root.pluginVersion + " · LUG " +
(root.helperVersion !== "" ? root.helperVersion : "nicht eingerichtet") +
" · Plugin: " + (root.pluginManaged === "git" ? (root.pluginAuto === "true" ? "Auto" : "Git") : "ZIP")
text: "Version " + root.pluginVersion +
" · Autopilot " + (root.autopilot === "true" ? "AKTIV" : "aus") +
" · LUG " + (root.managedLUGVersion !== "" ? root.managedLUGVersion : "—") +
" · Wine " + (root.managedWineVersion !== "" ? root.managedWineVersion : "—")
color: root.muted
font.family: root.uiFont
font.pixelSize: Style.font.caption
@@ -599,6 +611,26 @@ Panel {
PanelSeparator { foreground: root.barForeground }
StatusLine {
label: "Autopilot"
state: root.autopilot === "true" ? "ready" : "warning"
value: root.autopilot === "true"
? "aktiv · Wartung alle 6 Stunden"
: "nicht aktiviert"
}
StatusLine {
label: "Managed Wine"
state: root.managedWineVersion !== "" ? "ready" : "unknown"
value: root.managedWineVersion !== "" ? root.managedWineVersion : "wird beim Setup geladen"
}
StatusLine {
label: "Managed DXVK"
state: root.managedDXVKVersion !== "" ? "ready" : "unknown"
value: root.managedDXVKVersion !== "" ? root.managedDXVKVersion : "nach Prefix-Setup"
}
Text {
text: "PLUGIN-UPDATES"
color: root.accent
@@ -699,11 +731,11 @@ Panel {
Button {
width: setupGrid.cellWidth
text: "LUG aktualisieren"
text: "Gaming-Stack aktualisieren"
foreground: root.barForeground
fontFamily: root.uiFont
bordered: true
onClicked: root.runAction("update-helper")
onClicked: root.runAction("autopilot-maintain")
}
Button {
@@ -726,11 +758,11 @@ Panel {
Button {
width: setupGrid.cellWidth
text: "Wine-Runner"
text: "Wine-Selbsttest"
foreground: root.barForeground
fontFamily: root.uiFont
bordered: true
onClicked: root.runAction("runners")
onClicked: root.runAction("wine-doctor")
}
Button {
+50 -87
View File
@@ -1,107 +1,70 @@
# Omarchy Citizen 0.6.4
# Omarchy Citizen 0.7.0
A plug-and-play Star Citizen control panel for Omarchy.
## Rundum-Sorglos / Autopilot
## Design goal
Omarchy Citizen 0.7.0 changes the architecture from "frontend for packages the
user maintains" to "self-maintaining Star Citizen appliance".
**Play Star Citizen, don't administer Linux.**
Autopilot manages the complete user-space gaming stack:
The default UI deliberately exposes only:
- Omarchy Citizen plugin updates (for clean Git-managed installs)
- official Star Citizen LUG Helper **AppImage**
- stable `lug-wine-tkg-git` Wine runner
- DXVK
- Wine prefix health testing
- launch-script Wine runner selection
- repair / recovery
- support logs
- Setup / Start
- Guided repair
- Create support bundle
The LUG Helper AppImage is preferred over the AUR package. Current LUG releases
bundle their GUI/runtime dependencies, reducing the amount of Arch package
knowledge required from the player.
Advanced Wine/DXVK/LUG/NGL controls remain available behind an advanced section.
### Update model
## 0.6.0 highlights
A systemd user timer runs every six hours. Each candidate Wine runner is tested
in a throw-away Wine prefix before it can become the active runner. The test
requires:
- one primary action that adapts to current system state
- guided first-time setup
- symptom-based repair assistant
- persistent plugin debug log
- one-click sanitized support bundle
- support ID for remote troubleshooting
- Omarchy's native `omarchy debug --no-sudo --print` included in support bundles
- advanced controls hidden by default
- optional NGL remains isolated from the normal launcher path
- Go-based plugin update backend with Git remote pinning
- optional automatic updates via systemd user timer
- updater status/log included in support bundles
- successful `wineboot`
- `drive_c`
- `system.reg`
- `user.reg`
- a valid `%APPDATA%` response
## Local debug log
If an upstream runner fails that test, the previous working runner stays active.
DXVK is only changed while the Star Citizen Wine prefix is not in use. Existing
DLLs are backed up before replacement.
### What Autopilot deliberately does not bypass
Kernel, GPU driver and base Omarchy package upgrades still belong to Omarchy's
blessed `omarchy update` pipeline. Omarchy Citizen does not install a passwordless
pacman/sudo backdoor.
That boundary lets the Star Citizen stack remain self-maintaining without giving
a third-party QML plugin permanent unattended root package-management rights.
## Local state
Managed components:
```text
~/.local/state/omarchy-citizen/omarchy-citizen.log
~/.local/share/omarchy-citizen/vendor/
├── lug-helper/
├── wine/
└── dxvk/
```
The log rotates automatically at roughly 4 MiB and keeps the newest ~2 MiB.
## Support bundle
One click creates:
Logs:
```text
~/Downloads/Omarchy-Citizen-Support-<support-id>.tar.gz
~/.local/state/omarchy-citizen/
├── omarchy-citizen.log
└── updater.log
```
The exported data is sanitized on a best-effort basis before packaging.
See [`INSTALLATION.md`](INSTALLATION.md) for details.
## License
MIT.
## Go update backend
The bundled static Go binary lives at:
```text
backend/bin/omarchy-citizen-backend
```
For Git-managed Omarchy installations it checks the checkout and delegates actual
updates to Omarchy's native `omarchy plugin update local.omarchy-citizen --yes`.
Automatic updates are opt-in and run through a systemd user timer roughly every six
hours. The Git `origin` present when auto-update is enabled is pinned as the trusted
remote; unattended updates stop if that remote changes or the checkout is dirty.
See [`backend/README.md`](backend/README.md) and [`GIT_DISTRIBUTION.md`](GIT_DISTRIBUTION.md).
## 0.6.4 hotfix
- primary/setup actions now run through a Quickshell `Process` instead of fire-and-forget `bar.run`
- the panel shows `WIRD GESTARTET` immediately after a click
- startup failures stay visible in the panel instead of silently closing it
- terminal launch has a monitored fallback path and logs immediate launcher failures
- installers restart the Omarchy shell after QML changes to avoid stale third-party plugin QML
## 0.6.4 UI / setup hotfix
- fixed `undefined` in reusable status rows and chips
- panel no longer inherits the bar's theme font; uses a neutral system sans font
- first-time setup keeps the panel open and shows a visible status message
- setup terminal is launched directly through `xdg-terminal-exec`/UWSM with separate argv
- failed package/AUR setup remains visible instead of the terminal disappearing immediately
## 0.6.4 incomplete-prefix recovery
- a configured folder is no longer considered a valid Wine prefix merely because it exists
- valid prefixes require `drive_c`, `system.reg`, and `user.reg`
- half-created prefixes are shown as `unvollständig`
- one-click recovery renames the incomplete directory to a timestamped backup instead of deleting it
- stale LUG target config files are backed up before a clean reinstall
- existing `Data.p4k` is never moved by Omarchy Citizen; migration is delegated to the LUG Helper
- support bundles now include the newest `/tmp/lughelper-install-*.log` and a prefix-health report
## 0.6.4 visible recovery hotfix
- incomplete-prefix recovery no longer spawns a hidden second background process
- `SETUP SICHER REPARIEREN` opens a visible terminal directly
- the incomplete prefix is automatically renamed to a timestamped backup; it is never deleted
- LUG reinstall output remains visible and is logged at the same time
- if recovery fails, the terminal stays open with the error code and support instructions
- guided setup, repair assistant, support bundle creation and NGL file selection no longer use nested `nohup` wrappers
- updater status `blocked-dirty` is displayed as the user-friendly `lokale Änderungen · Update pausiert`
Binary file not shown.
+116 -44
View File
@@ -16,34 +16,43 @@ import (
)
const (
appVersion = "0.6.4"
appVersion = "0.7.0"
pluginID = "local.omarchy-citizen"
)
type Config struct {
AutoApply bool `json:"auto_apply"`
TrustedRemote string `json:"trusted_remote,omitempty"`
LastCheck string `json:"last_check,omitempty"`
LastUpdate string `json:"last_update,omitempty"`
LastResult string `json:"last_result,omitempty"`
AutoApply bool `json:"auto_apply"`
AutoMaintain bool `json:"auto_maintain"`
TrustedRemote string `json:"trusted_remote,omitempty"`
LastCheck string `json:"last_check,omitempty"`
LastUpdate string `json:"last_update,omitempty"`
LastResult string `json:"last_result,omitempty"`
LastMaintenance string `json:"last_maintenance,omitempty"`
MaintenanceResult string `json:"maintenance_result,omitempty"`
}
type Status struct {
BackendVersion string `json:"backend_version"`
PluginID string `json:"plugin_id"`
PluginDir string `json:"plugin_dir"`
Managed string `json:"managed"`
AutoApply bool `json:"auto_apply"`
Remote string `json:"remote,omitempty"`
TrustedRemote string `json:"trusted_remote,omitempty"`
Branch string `json:"branch,omitempty"`
LocalCommit string `json:"local_commit,omitempty"`
RemoteCommit string `json:"remote_commit,omitempty"`
Dirty bool `json:"dirty"`
Update string `json:"update"`
LastCheck string `json:"last_check,omitempty"`
LastUpdate string `json:"last_update,omitempty"`
LastResult string `json:"last_result,omitempty"`
BackendVersion string `json:"backend_version"`
PluginID string `json:"plugin_id"`
PluginDir string `json:"plugin_dir"`
Managed string `json:"managed"`
AutoApply bool `json:"auto_apply"`
AutoMaintain bool `json:"auto_maintain"`
LUGVersion string `json:"lug_version,omitempty"`
WineVersion string `json:"wine_version,omitempty"`
DXVKVersion string `json:"dxvk_version,omitempty"`
LastMaintenance string `json:"last_maintenance,omitempty"`
MaintenanceResult string `json:"maintenance_result,omitempty"`
Remote string `json:"remote,omitempty"`
TrustedRemote string `json:"trusted_remote,omitempty"`
Branch string `json:"branch,omitempty"`
LocalCommit string `json:"local_commit,omitempty"`
RemoteCommit string `json:"remote_commit,omitempty"`
Dirty bool `json:"dirty"`
Update string `json:"update"`
LastCheck string `json:"last_check,omitempty"`
LastUpdate string `json:"last_update,omitempty"`
LastResult string `json:"last_result,omitempty"`
}
type App struct {
@@ -51,6 +60,9 @@ type App struct {
pluginDir string
configDir string
stateDir string
dataDir string
cacheDir string
vendorDir string
configPath string
logPath string
libDir string
@@ -100,6 +112,38 @@ func main() {
app.logf("tick failed: %v", err)
os.Exit(2)
}
case "maintain":
if err := app.maintainGamingStack(); err != nil {
app.logf("maintenance failed: %v", err)
fatal(err)
}
case "doctor":
if err := app.wineDoctor(); err != nil {
fatal(err)
}
case "autopilot":
if len(args) < 2 {
fatal(errors.New("usage: autopilot enable|disable|status"))
}
switch args[1] {
case "enable":
if err := app.enableAutopilot(); err != nil {
fatal(err)
}
case "disable":
if err := app.disableAutopilot(); err != nil {
fatal(err)
}
case "status":
cfg := app.loadConfig()
if cfg.AutoMaintain {
fmt.Println("enabled")
} else {
fmt.Println("disabled")
}
default:
fatal(errors.New("usage: autopilot enable|disable|status"))
}
case "auto":
if len(args) < 2 {
fatal(errors.New("usage: auto enable|disable|status"))
@@ -149,11 +193,17 @@ func newApp() (*App, error) {
self, _ = filepath.EvalSymlinks(self)
configHome := envOr("XDG_CONFIG_HOME", filepath.Join(home, ".config"))
stateHome := envOr("XDG_STATE_HOME", filepath.Join(home, ".local", "state"))
dataHome := envOr("XDG_DATA_HOME", filepath.Join(home, ".local", "share"))
cacheHome := envOr("XDG_CACHE_HOME", filepath.Join(home, ".cache"))
dataDir := filepath.Join(dataHome, "omarchy-citizen")
return &App{
home: home,
pluginDir: filepath.Join(configHome, "omarchy", "plugins", pluginID),
configDir: filepath.Join(configHome, "omarchy-citizen"),
stateDir: filepath.Join(stateHome, "omarchy-citizen"),
dataDir: dataDir,
cacheDir: filepath.Join(cacheHome, "omarchy-citizen"),
vendorDir: filepath.Join(dataDir, "vendor"),
configPath: filepath.Join(configHome, "omarchy-citizen", "updater.json"),
logPath: filepath.Join(stateHome, "omarchy-citizen", "updater.log"),
libDir: filepath.Join(home, ".local", "lib", "omarchy-citizen"),
@@ -164,16 +214,22 @@ func newApp() (*App, error) {
func (a *App) status(fetch bool) (Status, error) {
cfg := a.loadConfig()
st := Status{
BackendVersion: appVersion,
PluginID: pluginID,
PluginDir: a.pluginDir,
Managed: "manual",
AutoApply: cfg.AutoApply,
TrustedRemote: cfg.TrustedRemote,
Update: "unavailable",
LastCheck: cfg.LastCheck,
LastUpdate: cfg.LastUpdate,
LastResult: cfg.LastResult,
BackendVersion: appVersion,
PluginID: pluginID,
PluginDir: a.pluginDir,
Managed: "manual",
AutoApply: cfg.AutoApply,
AutoMaintain: cfg.AutoMaintain,
LUGVersion: readMetaVersion(filepath.Join(a.vendorDir, "lug-helper", "meta.json")),
WineVersion: readMetaVersion(filepath.Join(a.vendorDir, "wine", "meta.json")),
DXVKVersion: readMetaVersion(filepath.Join(a.vendorDir, "dxvk", "meta.json")),
LastMaintenance: cfg.LastMaintenance,
MaintenanceResult: cfg.MaintenanceResult,
TrustedRemote: cfg.TrustedRemote,
Update: "unavailable",
LastCheck: cfg.LastCheck,
LastUpdate: cfg.LastUpdate,
LastResult: cfg.LastResult,
}
if !isGitRepo(a.pluginDir) {
@@ -239,20 +295,30 @@ func (a *App) status(fetch bool) (Status, error) {
func (a *App) tick() error {
cfg := a.loadConfig()
if !cfg.AutoApply {
a.logf("tick: auto updates disabled")
return nil
var problems []string
if cfg.AutoMaintain {
if err := a.maintainGamingStack(); err != nil {
problems = append(problems, "gaming stack: "+err.Error())
}
}
st, err := a.status(true)
a.recordCheck(st, err)
if err != nil {
return err
if cfg.AutoApply {
st, err := a.status(true)
a.recordCheck(st, err)
if err != nil {
problems = append(problems, "plugin check: "+err.Error())
} else if st.Update == "available" {
if err := a.update(true); err != nil {
problems = append(problems, "plugin update: "+err.Error())
}
}
}
if st.Update != "available" {
a.logf("tick: no update applied; state=%s", st.Update)
return nil
if len(problems) > 0 {
return errors.New(strings.Join(problems, "; "))
}
return a.update(true)
return nil
}
func (a *App) update(automatic bool) error {
@@ -383,8 +449,8 @@ func (a *App) installService() error {
timerPath := filepath.Join(a.home, ".config", "systemd", "user", "omarchy-citizen-update.timer")
backendPath := filepath.Join(a.libDir, "omarchy-citizen-backend")
service := `[Unit]\nDescription=Omarchy Citizen automatic plugin updater\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=oneshot\nExecStart=` + backendPath + ` tick\n`
timer := `[Unit]\nDescription=Check Omarchy Citizen updates periodically\n\n[Timer]\nOnBootSec=10min\nOnUnitActiveSec=6h\nRandomizedDelaySec=15min\nPersistent=true\nUnit=omarchy-citizen-update.service\n\n[Install]\nWantedBy=timers.target\n`
service := `[Unit]\nDescription=Omarchy Citizen Autopilot maintenance\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=oneshot\nExecStart=` + backendPath + ` tick\n`
timer := `[Unit]\nDescription=Maintain Omarchy Citizen gaming stack automatically\n\n[Timer]\nOnBootSec=3min\nOnUnitActiveSec=6h\nRandomizedDelaySec=15min\nPersistent=true\nUnit=omarchy-citizen-update.service\n\n[Install]\nWantedBy=timers.target\n`
if err := os.WriteFile(servicePath, []byte(strings.ReplaceAll(service, `\n`, "\n")), 0o644); err != nil {
return err
@@ -655,6 +721,12 @@ func printStatusKV(s Status) {
fmt.Printf("backend_version=%s\n", s.BackendVersion)
fmt.Printf("managed=%s\n", s.Managed)
fmt.Printf("auto_apply=%t\n", s.AutoApply)
fmt.Printf("auto_maintain=%t\n", s.AutoMaintain)
fmt.Printf("lug_version=%s\n", s.LUGVersion)
fmt.Printf("wine_version=%s\n", s.WineVersion)
fmt.Printf("dxvk_version=%s\n", s.DXVKVersion)
fmt.Printf("last_maintenance=%s\n", s.LastMaintenance)
fmt.Printf("maintenance_result=%s\n", s.MaintenanceResult)
fmt.Printf("update=%s\n", s.Update)
fmt.Printf("remote=%s\n", s.Remote)
fmt.Printf("trusted_remote=%s\n", s.TrustedRemote)
+144 -106
View File
@@ -2,7 +2,7 @@
set -u
PLUGIN_ID="local.omarchy-citizen"
PLUGIN_VERSION="0.6.4"
PLUGIN_VERSION="0.7.0"
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/starcitizen-lug"
DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}"
@@ -17,6 +17,8 @@ PLUGIN_DIR="$(cd -- "$(dirname -- "$SELF")" && pwd)"
SANITIZER="$PLUGIN_DIR/support-sanitize.py"
BACKEND_EXTERNAL="$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend"
BACKEND_BUNDLED="$PLUGIN_DIR/backend/bin/omarchy-citizen-backend"
MANAGED_LUG="$DATA_DIR/omarchy-citizen/vendor/lug-helper/lug-helper.appimage"
MANAGED_WINE="$DATA_DIR/omarchy-citizen/vendor/wine/current"
GUI_PACKAGES=(zenity polkit cabextract unzip)
@@ -61,6 +63,27 @@ backend_status() {
"$backend" status
}
autopilot_enable() {
local backend
backend="$(find_backend 2>/dev/null)" || {
echo "Omarchy-Citizen-Backend fehlt." >&2
return 1
}
"$backend" autopilot enable
}
autopilot_maintain() {
local backend
backend="$(find_backend 2>/dev/null)" || return 1
"$backend" maintain
}
wine_doctor() {
local backend
backend="$(find_backend 2>/dev/null)" || return 1
"$backend" doctor
}
plugin_update_check() {
local backend output state
backend="$(find_backend 2>/dev/null)" || {
@@ -143,11 +166,17 @@ notify_error() {
find_helper() {
local candidate
# Omarchy Citizen owns this copy and keeps it current automatically.
if [[ -x "$MANAGED_LUG" ]]; then
printf '%s\n' "$MANAGED_LUG"
return 0
fi
# Compatibility fallbacks for existing users.
if command -v lug-helper >/dev/null 2>&1; then
command -v lug-helper
return 0
fi
if command -v lug-helper.sh >/dev/null 2>&1; then
command -v lug-helper.sh
return 0
@@ -156,33 +185,30 @@ find_helper() {
for candidate in \
"$HOME/.local/bin/lug-helper" \
"$HOME/.local/bin/lug-helper.sh" \
"$DATA_DIR/lug-helper/lug-helper.sh" \
"$HOME/lug-helper/lug-helper.sh"
"$DATA_DIR/lug-helper/lug-helper.sh"
do
if [[ -f "$candidate" ]]; then
printf '%s\n' "$candidate"
return 0
fi
[[ -f "$candidate" ]] && { printf '%s\n' "$candidate"; return 0; }
done
shopt -s nullglob
for candidate in \
"$HOME/Applications"/*LUG*Helper*.AppImage \
"$HOME/Applications"/lug-helper*.AppImage \
"$HOME/Downloads"/*LUG*Helper*.AppImage \
"$HOME/Downloads"/lug-helper*.AppImage
do
if [[ -x "$candidate" ]]; then
printf '%s\n' "$candidate"
shopt -u nullglob
return 0
fi
done
shopt -u nullglob
return 1
}
helper_exec() {
local helper="$1"
shift
if [[ "$helper" == "$MANAGED_LUG" || "${helper,,}" == *.appimage ]]; then
APPIMAGE_EXTRACT_AND_RUN=1 "$helper" "$@"
elif [[ "$helper" == *.sh ]]; then
bash "$helper" "$@"
else
"$helper" "$@"
fi
}
helper_version() {
local helper="$1"
APPIMAGE_EXTRACT_AND_RUN=1 "$helper" --version 2>/dev/null | head -n1 || true
}
run_helper_sync() {
local helper
helper="$(find_helper)" || {
@@ -190,12 +216,8 @@ run_helper_sync() {
return 1
}
log_line "lug-helper sync args=$*"
if [[ "$helper" == *.sh ]]; then
bash "$helper" "$@" >>"$LOG_FILE" 2>&1
else
"$helper" "$@" >>"$LOG_FILE" 2>&1
fi
log_line "lug-helper sync args=$* helper=$helper"
helper_exec "$helper" "$@" >>"$LOG_FILE" 2>&1
}
run_helper_visible() {
@@ -205,12 +227,8 @@ run_helper_visible() {
return 1
}
log_line "lug-helper visible args=$*"
if [[ "$helper" == *.sh ]]; then
bash "$helper" "$@"
else
"$helper" "$@"
fi
log_line "lug-helper visible args=$* helper=$helper"
helper_exec "$helper" "$@"
}
run_helper_gui() {
@@ -222,8 +240,10 @@ Wähle im SC-Panel „Einrichten“ – Omarchy Citizen installiert die benötig
return 1
}
log_line "lug-helper gui args=$*"
if [[ "$helper" == *.sh ]]; then
log_line "lug-helper gui args=$* helper=$helper"
if [[ "$helper" == "$MANAGED_LUG" || "${helper,,}" == *.appimage ]]; then
nohup env APPIMAGE_EXTRACT_AND_RUN=1 "$helper" "$@" >>"$LOG_FILE" 2>&1 &
elif [[ "$helper" == *.sh ]]; then
nohup bash "$helper" "$@" >>"$LOG_FILE" 2>&1 &
else
nohup "$helper" "$@" >>"$LOG_FILE" 2>&1 &
@@ -353,26 +373,23 @@ status() {
local prefix_state="missing" prefix_detail="" launcher_state="missing" game_state="missing"
local update_state="unknown" update_version="" health="setup"
for dep in "${GUI_PACKAGES[@]}"; do
if ! package_installed "$dep"; then
deps_state="missing"
if [[ -n "$missing_deps" ]]; then missing_deps+=","; fi
missing_deps+="$dep"
fi
done
# Core operation no longer depends on an AUR LUG package. The managed
# official LUG AppImage bundles its GUI/runtime dependencies.
if [[ ! -x "$MANAGED_LUG" ]]; then
deps_state="partial"
missing_deps="managed LUG AppImage"
fi
if package_installed lug-helper; then
if helper="$(find_helper 2>/dev/null)"; then
helper_state="ready"
helper_managed="aur"
version="$(installed_lug_version)"
elif helper="$(find_helper 2>/dev/null)"; then
helper_state="ready"
helper_managed="external"
if [[ "$helper" == *.sh ]]; then
version="$(bash "$helper" --version 2>/dev/null | head -n 1 || true)"
if [[ "$helper" == "$MANAGED_LUG" ]]; then
helper_managed="autopilot"
elif package_installed lug-helper; then
helper_managed="aur"
else
version="$("$helper" --version 2>/dev/null | head -n 1 || true)"
helper_managed="external"
fi
version="$(helper_version "$helper")"
version="${version//$'\n'/ }"
version="${version//$'\r'/ }"
fi
@@ -399,7 +416,7 @@ status() {
fi
fi
if [[ "$deps_state" != "ready" || "$helper_state" != "ready" ]]; then
if [[ "$helper_state" != "ready" ]]; then
health="setup"
elif [[ "$prefix_state" == "partial" ]]; then
health="recover-prefix"
@@ -438,6 +455,11 @@ status() {
printf 'plugin_update=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^update=//p' | head -n1)"
printf 'plugin_local_commit=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^local_commit=//p' | head -n1)"
printf 'plugin_remote_commit=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^remote_commit=//p' | head -n1)"
printf 'autopilot=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^auto_maintain=//p' | head -n1)"
printf 'managed_lug_version=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^lug_version=//p' | head -n1)"
printf 'managed_wine_version=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^wine_version=//p' | head -n1)"
printf 'managed_dxvk_version=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^dxvk_version=//p' | head -n1)"
printf 'maintenance_result=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^maintenance_result=//p' | head -n1)"
}
probe_detached_start() {
@@ -698,15 +720,13 @@ install_stack_terminal() {
echo "=================================================="
echo
echo "Fehlercode: $rc"
echo "Keine Sorge: Im SC-Panel kannst du anschließend"
echo "„Support-Paket erstellen“ wählen."
echo "Omarchy Citizen hat alle Ausgaben im Debug-Log gespeichert."
echo "Im SC-Panel genügt „Support-Paket erstellen“."
echo
log_line "install-stack failed rc=$rc"
notify "Omarchy Citizen" "Setup fehlgeschlagen. Bitte erstelle im SC-Panel ein Support-Paket."
log_line "autopilot setup failed rc=$rc"
notify "Omarchy Citizen" "Setup fehlgeschlagen. Support-Paket kann mit einem Klick erstellt werden."
if [[ -t 0 ]]; then
read -r -p "Drücke Enter, um dieses Fenster zu schließen … " _ || true
else
sleep 8
fi
exit "$rc"
}
@@ -714,72 +734,75 @@ install_stack_terminal() {
echo
echo "=================================================="
echo " Omarchy Citizen – Plug & Play Setup"
echo " Omarchy Citizen – Rundum-Sorglos Autopilot"
echo "=================================================="
echo
echo "Omarchy Citizen richtet die Linux-Gaming-Basis ein."
echo "Du musst keine Paketnamen oder Linux-Befehle kennen."
echo "Das Plugin verwaltet jetzt selbst:"
echo " ✓ Omarchy-Citizen-Updates (bei Git-Installation)"
echo " ✓ offiziellen LUG Helper als AppImage"
echo " ✓ stabilen LUG-Wine-Runner"
echo " ✓ DXVK"
echo " ✓ Wine-Selbsttest vor Aktivierung"
echo " ✓ Reparatur- und Support-Logs"
echo
echo "Installiert/überprüft werden:"
echo " - zenity / polkit"
echo " - cabextract / unzip"
echo " - Star Citizen LUG Helper aus dem AUR"
echo "Es wird kein AUR-LUG-Paket mehr benötigt."
echo
omarchy pkg add zenity polkit cabextract unzip
if package_installed lug-helper; then
echo "LUG Helper ist bereits installiert."
else
echo "Installiere LUG Helper..."
omarchy pkg aur add lug-helper
fi
rm -f "$UPDATE_CACHE"
echo "Aktiviere Autopilot und synchronisiere den Gaming-Stack …"
autopilot_enable
echo
echo "Systempakete sind bereit."
echo "Als Nächstes startet der grafische Star-Citizen-Assistent."
echo "Prüfe den verwalteten Wine-Runner in einem temporären Test-Prefix …"
wine_doctor
echo "✓ Wine-Selbsttest erfolgreich."
echo
run_helper_sync --preflight-check || true
if find_incomplete_prefix >/dev/null 2>&1; then
echo
echo "Eine frühere, unvollständige Wine-Prefix-Erstellung wurde erkannt."
echo "Öffne die sichere Reparatur in einem eigenen Fenster."
echo "Eine unvollständige frühere Installation wurde erkannt."
echo "Sie wird jetzt sicher über den vorhandenen Recovery-Pfad behandelt."
echo
trap - ERR
launch_terminal_action recover-prefix-terminal
return 0
elif ! read_prefix >/dev/null 2>&1; then
run_helper_sync --install || true
fi
echo "Starte LUG Preflight …"
run_helper_visible --preflight-check || true
if ! read_prefix >/dev/null 2>&1; then
echo
echo "Installiere den RSI Launcher mit dem aktuellen LUG Helper …"
run_helper_visible --install
fi
prefix="$(read_prefix 2>/dev/null || true)"
if [[ -n "$prefix" && ! -f "$prefix/sc-launch.sh" ]]; then
run_helper_visible --update-launch-script
fi
# Maintenance once more now that a prefix exists: switches sc-launch.sh to
# the tested managed runner and installs current DXVK.
echo
echo "Plug-&-Play-Setup beendet."
echo "Du kannst dieses Fenster schließen und ✦SC öffnen."
echo "Aktualisiere Wine/DXVK für den neu eingerichteten Prefix …"
autopilot_maintain
trap - ERR
notify "Omarchy Citizen" "Grundsetup abgeschlossen. Öffne ✦SC und starte Star Citizen."
log_line "install-stack complete"
notify "Omarchy Citizen" "Autopilot ist aktiv. Der Gaming-Stack wird künftig automatisch gepflegt."
log_line "autopilot setup complete"
echo
echo "=================================================="
echo " AUTOPILOT AKTIV"
echo "=================================================="
echo
echo "Künftig reicht der große STAR-CITIZEN-Button."
}
update_helper_terminal() {
set -e
set -Ee
exec > >(tee -a "$LOG_FILE") 2>&1
if ! package_installed lug-helper; then
echo "LUG Helper ist noch nicht als AUR-Paket installiert."
echo "Starte bitte zuerst das normale Omarchy-Citizen-Setup."
exit 1
fi
echo "Aktualisiere den LUG Helper..."
omarchy pkg aur add lug-helper
rm -f "$UPDATE_CACHE"
echo "LUG Helper ist aktuell."
installed_lug_version
log_line "lug-helper update complete"
echo "Synchronisiere LUG Helper, Wine Runner und DXVK über Autopilot …"
autopilot_maintain
echo "✓ Gaming-Stack ist aktuell."
}
system_update_terminal() {
@@ -809,7 +832,14 @@ launch_game() {
}
primary_action() {
local st health
local st health backend
# Keep normal launch instant. Autopilot maintenance is delegated to systemd
# and never blocks the player's click.
backend="$(find_backend 2>/dev/null || true)"
if [[ -n "$backend" ]]; then
systemctl --user start omarchy-citizen-update.service >/dev/null 2>&1 || true
fi
st="$("$SELF" status)"
health="$(printf '%s\n' "$st" | sed -n 's/^health=//p' | head -n1)"
@@ -1008,6 +1038,11 @@ EOF
capture_sanitized "$work/omarchy-debug.txt" omarchy debug --no-sudo --print
if backend="$(find_backend 2>/dev/null)"; then
capture_sanitized "$work/autopilot-status.txt" "$backend" status
capture_sanitized "$work/wine-doctor.txt" "$backend" doctor
fi
{
echo "=== Kernel / Desktop ==="
uname -rmo 2>/dev/null || true
@@ -1292,6 +1327,9 @@ ngl_install() {
case "$ACTION" in
status) status ;;
autopilot-enable) autopilot_enable ;;
autopilot-maintain) autopilot_maintain ;;
wine-doctor) wine_doctor ;;
primary) primary_action ;;
setup) guided_setup ;;
recover-prefix) recover_incomplete_prefix ;;
+6 -2
View File
@@ -36,7 +36,11 @@ omarchy-shell shell rescanPlugins
echo "Aktiviere Plugin..."
"$DEST/backend/bin/omarchy-citizen-backend" self-sync >/dev/null 2>&1 || true
"$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend" install-service >/dev/null 2>&1 || true
echo "Aktiviere Rundum-Sorglos Autopilot …"
"$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend" autopilot enable || {
echo "Hinweis: Autopilot konnte beim Installer noch nicht vollständig synchronisieren."
echo "Der SC-Setup-Button versucht es erneut und protokolliert die Ursache."
}
omarchy plugin enable "$PLUGIN_ID"
@@ -44,7 +48,7 @@ omarchy plugin enable "$PLUGIN_ID"
omarchy restart shell >/dev/null 2>&1 || true
echo
echo "Omarchy Citizen 0.6.4 wurde installiert:"
echo "Omarchy Citizen 0.7.0 wurde installiert:"
echo " $DEST"
echo
echo "Links-Klick auf 'SC' in der Omarchy-Leiste öffnet das Star-Citizen-Panel."
+2 -2
View File
@@ -2,10 +2,10 @@
"schemaVersion": 1,
"id": "local.omarchy-citizen",
"name": "Omarchy Citizen",
"version": "0.6.4",
"version": "0.7.0",
"author": "Community prototype",
"license": "MIT",
"description": "Plug-and-play Star Citizen controls for Omarchy. 0.6.4 removes nested background UI actions and performs incomplete-prefix recovery in a visible, logged terminal.",
"description": "Plug-and-play Star Citizen for Omarchy with Autopilot: automatic plugin, LUG Helper AppImage, LUG Wine runner and DXVK maintenance, health checks, self-healing setup and sanitized support bundles.",
"kinds": [
"bar-widget"
],
+2
View File
@@ -4,6 +4,8 @@ set -euo pipefail
PLUGIN_ID="local.omarchy-citizen"
DEST="$HOME/.config/omarchy/plugins/$PLUGIN_ID"
BACKEND="$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend"
[[ -x "$BACKEND" ]] && "$BACKEND" uninstall-service >/dev/null 2>&1 || true
omarchy plugin disable "$PLUGIN_ID" 2>/dev/null || true
BACKEND="$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend"