letzte Kanten: Hermes-Abruf 60 s statt 25 s, kein Pfeil auf dieselbe Version, Homelab-Container mit Sicherheitsupdates

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-24 19:05:56 +02:00
co-authored by Claude Opus 5.5
parent 39320b446d
commit 83c33584e4
13 changed files with 18 additions and 15 deletions
+3 -3
View File
@@ -201,7 +201,7 @@ def _hermes_agent_update() -> dict:
branch = (subprocess.run(["git", "-C", path, "rev-parse", "--abbrev-ref", "HEAD"],
capture_output=True, text=True, timeout=8).stdout.strip() or "main")
fetch = subprocess.run(["git", "-C", path, "fetch", "-q", "origin", branch],
capture_output=True, text=True, timeout=25)
capture_output=True, text=True, timeout=60)
info["reachable"] = (fetch.returncode == 0)
if fetch.returncode == 0:
cnt = subprocess.run(["git", "-C", path, "rev-list", "--count", f"HEAD..origin/{branch}"],
@@ -311,7 +311,7 @@ def _os_held_back() -> list[dict]:
try:
out = subprocess.run(
["bash", "-c", "LC_ALL=C apt-get -s upgrade 2>/dev/null"],
capture_output=True, text=True, timeout=25)
capture_output=True, text=True, timeout=60)
reason: str | None = None
for line in (out.stdout or "").splitlines():
hdr = sections.get(line.strip())
@@ -513,7 +513,7 @@ def hermes_update_details() -> dict:
capture_output=True, text=True, timeout=8).stdout.strip() or "main")
info["branch"] = branch
subprocess.run(["git", "-C", path, "fetch", "-q", "origin", branch],
capture_output=True, text=True, timeout=25)
capture_output=True, text=True, timeout=60)
log = subprocess.run(["git", "-C", path, "log", "--pretty=format:%h\x1f%s\x1f%cr",
f"HEAD..origin/{branch}"], capture_output=True, text=True, timeout=10)
commits = []
+4 -1
View File
@@ -8,7 +8,10 @@ ZIEL=/opt/mc2
PARTNER="${1:-http://192.168.178.151:9001}"
apt-get update -q
DEBIAN_FRONTEND=noninteractive apt-get install -y -q python3 python3-venv curl ca-certificates
DEBIAN_FRONTEND=noninteractive apt-get install -y -q python3 python3-venv curl ca-certificates unattended-upgrades
# Der Container trägt nur das Etikett mc2: Der Orchestrator aktualisiert sich nicht selbst. Sicherheitsupdates
# spielt Debian deshalb selbst ein (unattended-upgrades, Standard: nur Security).
systemctl enable --now unattended-upgrades.service apt-daily-upgrade.timer >/dev/null 2>&1 || true
id mc2 >/dev/null 2>&1 || useradd --system --home-dir /var/lib/mc2 --shell /usr/sbin/nologin mc2
install -d -o mc2 -g mc2 -m 750 /var/lib/mc2
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{c as e,i as t,p as n,s as r,t as i,u as a}from"./button-BheHBEml.js";import{H as o,I as s,Q as c,U as l,b as u,s as d}from"./index-SRwQwEnh.js";import{a as f,i as p,n as m,r as h,t as g}from"./sheet-CKp82pOA.js";var _=r(),v=n(a(),1),y=e();function b(e){let t=(0,_.c)(4),{unit:n}=e,r=u(n),i;if(r.isPending)i=`Wird gelesen …`;else if(r.isError)i=`Das Protokoll lässt sich gerade nicht lesen: ${r.error.message}`;else if(r.data.ok===!1)i=r.data.err||r.data.text||`Das Protokoll lässt sich nicht lesen.`;else{let e;t[0]===r.data.text?e=t[1]:(e=r.data.text?.trim()||`Noch keine Einträge.`,t[0]=r.data.text,t[1]=e),i=e}let a;return t[2]===i?a=t[3]:(a=(0,y.jsx)(`pre`,{className:`ziffern m-0 max-h-[50vh] w-full basis-full overflow-auto rounded-lg border border-linie bg-[#0b0d0f] p-3 text-xs leading-relaxed whitespace-pre-wrap break-all text-text-2`,children:i}),t[2]=i,t[3]=a),a}function x({offen:e,onSchliessen:n}){let r=c(),a=d(),[u,_]=(0,v.useState)(null),[x,S]=(0,v.useState)(null),[C,w]=(0,v.useState)(null);async function T(e){if(!C){S(null),w(e.unit);try{let t=await o(`/api/maintenance/restart`,{service:e.unit});t.ok?l(`erfolg`,`${e.name} ${e.schlaeft?`wird geweckt`:`startet neu`}.`):l(`fehler`,`${e.name} ließ sich nicht starten: ${s(t)}`),r.invalidateQueries({queryKey:[`dienste`]})}catch(e){l(`fehler`,e.message)}finally{w(null)}}}let E;return E=a.isPending?(0,y.jsx)(`p`,{role:`status`,className:`px-4 text-[15px] text-text-2`,children:`Dienste werden gelesen …`}):a.isError&&!a.data?(0,y.jsxs)(`p`,{role:`alert`,className:`px-4 text-[15px] text-rot-text`,children:[`Die Dienste lassen sich gerade nicht lesen: `,a.error.message]}):a.data?.services.length?(0,y.jsx)(`ul`,{className:`m-0 flex list-none flex-col px-4 pb-4`,children:a.data.services.map(e=>(0,y.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-2 border-t border-linie py-2.5`,children:[(0,y.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,y.jsx)(`span`,{className:t(`size-2.5 shrink-0 rounded-full`,e.ok?`bg-gruen`:e.schlaeft?`bg-text-3`:`bg-rot`),"aria-hidden":!0}),(0,y.jsxs)(`span`,{className:`min-w-0`,children:[(0,y.jsx)(`span`,{className:`block text-[15px]`,children:e.name}),(0,y.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[e.unit,` · `,e.ok?`läuft`:e.schlaeft?`schläft (abgeschaltet)`:`antwortet nicht`]})]})]}),(0,y.jsxs)(`span`,{className:`flex flex-wrap gap-2`,children:[(0,y.jsx)(i,{variant:u===e.unit?`info`:`ghost`,size:`sm`,"aria-expanded":u===e.unit,onClick:()=>_(u===e.unit?null:e.unit),children:`Protokoll`}),x===e.unit?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(i,{variant:`gefahr`,size:`sm`,onClick:()=>T(e),children:e.schlaeft?`Wirklich wecken?`:`Wirklich neu starten?`}),(0,y.jsx)(i,{variant:`ghost`,size:`sm`,onClick:()=>S(null),children:`Nein`})]}):(0,y.jsx)(i,{variant:`outline`,size:`sm`,disabled:C!==null,onClick:()=>S(e.unit),children:C===e.unit?`Startet …`:e.schlaeft?`Wecken`:`Neu starten`})]}),u===e.unit&&(0,y.jsx)(b,{unit:e.unit})]},e.unit))}):(0,y.jsx)(`p`,{className:`px-4 text-[15px] text-text-2`,children:`Keine Dienste gefunden.`}),(0,y.jsx)(g,{open:e,onOpenChange:e=>!e&&n(),children:(0,y.jsxs)(m,{side:`right`,className:`gap-3 overflow-y-auto border-linie bg-panel data-[side=right]:w-full data-[side=right]:sm:max-w-2xl`,children:[(0,y.jsxs)(p,{children:[(0,y.jsx)(f,{className:`schild text-lg`,children:`Dienste und Protokolle`}),(0,y.jsx)(h,{className:`text-text-2`,children:`Welcher Dienst läuft, was er zuletzt geschrieben hat.`})]}),E]})})}export{x as Dienste};
import{c as e,i as t,p as n,s as r,t as i,u as a}from"./button-BheHBEml.js";import{H as o,I as s,Q as c,U as l,b as u,s as d}from"./index-CsrOM_oc.js";import{a as f,i as p,n as m,r as h,t as g}from"./sheet-CKp82pOA.js";var _=r(),v=n(a(),1),y=e();function b(e){let t=(0,_.c)(4),{unit:n}=e,r=u(n),i;if(r.isPending)i=`Wird gelesen …`;else if(r.isError)i=`Das Protokoll lässt sich gerade nicht lesen: ${r.error.message}`;else if(r.data.ok===!1)i=r.data.err||r.data.text||`Das Protokoll lässt sich nicht lesen.`;else{let e;t[0]===r.data.text?e=t[1]:(e=r.data.text?.trim()||`Noch keine Einträge.`,t[0]=r.data.text,t[1]=e),i=e}let a;return t[2]===i?a=t[3]:(a=(0,y.jsx)(`pre`,{className:`ziffern m-0 max-h-[50vh] w-full basis-full overflow-auto rounded-lg border border-linie bg-[#0b0d0f] p-3 text-xs leading-relaxed whitespace-pre-wrap break-all text-text-2`,children:i}),t[2]=i,t[3]=a),a}function x({offen:e,onSchliessen:n}){let r=c(),a=d(),[u,_]=(0,v.useState)(null),[x,S]=(0,v.useState)(null),[C,w]=(0,v.useState)(null);async function T(e){if(!C){S(null),w(e.unit);try{let t=await o(`/api/maintenance/restart`,{service:e.unit});t.ok?l(`erfolg`,`${e.name} ${e.schlaeft?`wird geweckt`:`startet neu`}.`):l(`fehler`,`${e.name} ließ sich nicht starten: ${s(t)}`),r.invalidateQueries({queryKey:[`dienste`]})}catch(e){l(`fehler`,e.message)}finally{w(null)}}}let E;return E=a.isPending?(0,y.jsx)(`p`,{role:`status`,className:`px-4 text-[15px] text-text-2`,children:`Dienste werden gelesen …`}):a.isError&&!a.data?(0,y.jsxs)(`p`,{role:`alert`,className:`px-4 text-[15px] text-rot-text`,children:[`Die Dienste lassen sich gerade nicht lesen: `,a.error.message]}):a.data?.services.length?(0,y.jsx)(`ul`,{className:`m-0 flex list-none flex-col px-4 pb-4`,children:a.data.services.map(e=>(0,y.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-2 border-t border-linie py-2.5`,children:[(0,y.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,y.jsx)(`span`,{className:t(`size-2.5 shrink-0 rounded-full`,e.ok?`bg-gruen`:e.schlaeft?`bg-text-3`:`bg-rot`),"aria-hidden":!0}),(0,y.jsxs)(`span`,{className:`min-w-0`,children:[(0,y.jsx)(`span`,{className:`block text-[15px]`,children:e.name}),(0,y.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[e.unit,` · `,e.ok?`läuft`:e.schlaeft?`schläft (abgeschaltet)`:`antwortet nicht`]})]})]}),(0,y.jsxs)(`span`,{className:`flex flex-wrap gap-2`,children:[(0,y.jsx)(i,{variant:u===e.unit?`info`:`ghost`,size:`sm`,"aria-expanded":u===e.unit,onClick:()=>_(u===e.unit?null:e.unit),children:`Protokoll`}),x===e.unit?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(i,{variant:`gefahr`,size:`sm`,onClick:()=>T(e),children:e.schlaeft?`Wirklich wecken?`:`Wirklich neu starten?`}),(0,y.jsx)(i,{variant:`ghost`,size:`sm`,onClick:()=>S(null),children:`Nein`})]}):(0,y.jsx)(i,{variant:`outline`,size:`sm`,disabled:C!==null,onClick:()=>S(e.unit),children:C===e.unit?`Startet …`:e.schlaeft?`Wecken`:`Neu starten`})]}),u===e.unit&&(0,y.jsx)(b,{unit:e.unit})]},e.unit))}):(0,y.jsx)(`p`,{className:`px-4 text-[15px] text-text-2`,children:`Keine Dienste gefunden.`}),(0,y.jsx)(g,{open:e,onOpenChange:e=>!e&&n(),children:(0,y.jsxs)(m,{side:`right`,className:`gap-3 overflow-y-auto border-linie bg-panel data-[side=right]:w-full data-[side=right]:sm:max-w-2xl`,children:[(0,y.jsxs)(p,{children:[(0,y.jsx)(f,{className:`schild text-lg`,children:`Dienste und Protokolle`}),(0,y.jsx)(h,{className:`text-text-2`,children:`Welcher Dienst läuft, was er zuletzt geschrieben hat.`})]}),E]})})}export{x as Dienste};
@@ -1 +1 @@
import{c as e,p as t,t as n,u as r}from"./button-BheHBEml.js";import{H as i,Q as a,U as o,V as s,Z as c,q as l}from"./index-SRwQwEnh.js";import{a as u,i as d,n as f,r as p,t as m}from"./sheet-CKp82pOA.js";var h=t(r(),1),g=e();function _({offen:e,onSchliessen:t}){let r=a(),_=c({queryKey:[`geheimnisse`],queryFn:()=>s(`/api/maintenance/geheimnisse`),enabled:e}),[v,y]=(0,h.useState)(``),[b,x]=(0,h.useState)(!1),[S,C]=(0,h.useState)(!1);async function w(e){if(!b){x(!0),C(!1);try{await i(`/api/maintenance/geheimnisse`,{schluessel:`hf_token`,wert:e}),o(`erfolg`,e?`Hugging-Face-Zugang gespeichert.`:`Hugging-Face-Zugang gelöscht.`),y(``),r.invalidateQueries({queryKey:[`geheimnisse`]})}catch(e){o(`fehler`,e.message)}finally{x(!1)}}}let T=_.data,E;return E=_.isPending?`Wird gelesen …`:T?T.hf_token_gesetzt?`Ist hinterlegt.`:`Fehlt.`:`Lässt sich gerade nicht lesen${_.error?`: ${_.error.message}`:`.`}`,(0,g.jsx)(m,{open:e,onOpenChange:e=>!e&&t(),children:(0,g.jsxs)(f,{side:`right`,className:`gap-3 overflow-y-auto border-linie bg-panel data-[side=right]:w-full data-[side=right]:sm:max-w-lg`,children:[(0,g.jsxs)(d,{children:[(0,g.jsx)(u,{className:`schild text-lg`,children:`Einstellungen`}),(0,g.jsx)(p,{className:`text-text-2`,children:`Was die Box sich merkt.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-3 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hugging-Face-Zugang`}),(0,g.jsxs)(`p`,{className:`text-sm text-text-2`,"aria-live":`polite`,children:[(0,g.jsx)(`span`,{className:!T&&!_.isPending?`text-rot-text`:void 0,children:E}),` Nötig für gesperrte Modelle und schnellere Downloads.`,T?.hf_token_aus_env?` Er kommt aus der Dienst-Einstellung und lässt sich hier nicht löschen.`:``]}),T?.schreibbar===!1&&(0,g.jsx)(`p`,{className:`text-sm text-bernstein`,children:`Die Box kann den Zugang gerade nicht speichern: Ihre Ablage ist nicht beschreibbar.`}),(0,g.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),v.trim()&&w(v.trim())},children:[(0,g.jsx)(`label`,{htmlFor:`hf-token`,className:`sr-only`,children:`Hugging-Face-Zugang`}),(0,g.jsx)(`input`,{id:`hf-token`,type:`password`,autoComplete:`off`,value:v,onChange:e=>y(e.target.value),placeholder:`hf_…`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,g.jsx)(n,{type:`submit`,disabled:!v.trim()||T?.schreibbar===!1||b,children:b?`Speichert …`:`Speichern`})]}),T?.hf_token_gesetzt&&!T.hf_token_aus_env&&(S?(0,g.jsxs)(`span`,{className:`flex flex-wrap gap-2`,children:[(0,g.jsx)(n,{variant:`gefahr`,size:`sm`,disabled:b,onClick:()=>w(null),children:`Wirklich löschen?`}),(0,g.jsx)(n,{variant:`ghost`,size:`sm`,onClick:()=>C(!1),children:`Nein`})]}):(0,g.jsx)(n,{variant:`ghost`,size:`sm`,className:`self-start`,disabled:b,onClick:()=>C(!0),children:`Zugang löschen`}))]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hinweise`}),(0,g.jsx)(`p`,{className:`text-sm text-text-2`,children:`Dringende Hinweise gehen zusätzlich per Telegram raus, alles andere bleibt hier. Einfache Probleme wie einen abgestürzten Dienst behebt der Wächter selbst und schreibt es in den Verlauf.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4 pb-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hermes`}),(0,g.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-11 items-center gap-2 self-start rounded-lg border border-linie-stark bg-erhaben px-4 text-[15px] hover:border-text-3`,children:[(0,g.jsx)(l,{className:`size-4`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),(0,g.jsx)(`p`,{className:`text-xs text-text-3`,children:`Chat, Sitzungen und Cron-Jobs verwaltet Hermes selbst. Es fragt nach seiner eigenen Anmeldung.`})]})]})})}export{_ as Einstellungen};
import{c as e,p as t,t as n,u as r}from"./button-BheHBEml.js";import{H as i,Q as a,U as o,V as s,Z as c,q as l}from"./index-CsrOM_oc.js";import{a as u,i as d,n as f,r as p,t as m}from"./sheet-CKp82pOA.js";var h=t(r(),1),g=e();function _({offen:e,onSchliessen:t}){let r=a(),_=c({queryKey:[`geheimnisse`],queryFn:()=>s(`/api/maintenance/geheimnisse`),enabled:e}),[v,y]=(0,h.useState)(``),[b,x]=(0,h.useState)(!1),[S,C]=(0,h.useState)(!1);async function w(e){if(!b){x(!0),C(!1);try{await i(`/api/maintenance/geheimnisse`,{schluessel:`hf_token`,wert:e}),o(`erfolg`,e?`Hugging-Face-Zugang gespeichert.`:`Hugging-Face-Zugang gelöscht.`),y(``),r.invalidateQueries({queryKey:[`geheimnisse`]})}catch(e){o(`fehler`,e.message)}finally{x(!1)}}}let T=_.data,E;return E=_.isPending?`Wird gelesen …`:T?T.hf_token_gesetzt?`Ist hinterlegt.`:`Fehlt.`:`Lässt sich gerade nicht lesen${_.error?`: ${_.error.message}`:`.`}`,(0,g.jsx)(m,{open:e,onOpenChange:e=>!e&&t(),children:(0,g.jsxs)(f,{side:`right`,className:`gap-3 overflow-y-auto border-linie bg-panel data-[side=right]:w-full data-[side=right]:sm:max-w-lg`,children:[(0,g.jsxs)(d,{children:[(0,g.jsx)(u,{className:`schild text-lg`,children:`Einstellungen`}),(0,g.jsx)(p,{className:`text-text-2`,children:`Was die Box sich merkt.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-3 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hugging-Face-Zugang`}),(0,g.jsxs)(`p`,{className:`text-sm text-text-2`,"aria-live":`polite`,children:[(0,g.jsx)(`span`,{className:!T&&!_.isPending?`text-rot-text`:void 0,children:E}),` Nötig für gesperrte Modelle und schnellere Downloads.`,T?.hf_token_aus_env?` Er kommt aus der Dienst-Einstellung und lässt sich hier nicht löschen.`:``]}),T?.schreibbar===!1&&(0,g.jsx)(`p`,{className:`text-sm text-bernstein`,children:`Die Box kann den Zugang gerade nicht speichern: Ihre Ablage ist nicht beschreibbar.`}),(0,g.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),v.trim()&&w(v.trim())},children:[(0,g.jsx)(`label`,{htmlFor:`hf-token`,className:`sr-only`,children:`Hugging-Face-Zugang`}),(0,g.jsx)(`input`,{id:`hf-token`,type:`password`,autoComplete:`off`,value:v,onChange:e=>y(e.target.value),placeholder:`hf_…`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,g.jsx)(n,{type:`submit`,disabled:!v.trim()||T?.schreibbar===!1||b,children:b?`Speichert …`:`Speichern`})]}),T?.hf_token_gesetzt&&!T.hf_token_aus_env&&(S?(0,g.jsxs)(`span`,{className:`flex flex-wrap gap-2`,children:[(0,g.jsx)(n,{variant:`gefahr`,size:`sm`,disabled:b,onClick:()=>w(null),children:`Wirklich löschen?`}),(0,g.jsx)(n,{variant:`ghost`,size:`sm`,onClick:()=>C(!1),children:`Nein`})]}):(0,g.jsx)(n,{variant:`ghost`,size:`sm`,className:`self-start`,disabled:b,onClick:()=>C(!0),children:`Zugang löschen`}))]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hinweise`}),(0,g.jsx)(`p`,{className:`text-sm text-text-2`,children:`Dringende Hinweise gehen zusätzlich per Telegram raus, alles andere bleibt hier. Einfache Probleme wie einen abgestürzten Dienst behebt der Wächter selbst und schreibt es in den Verlauf.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4 pb-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hermes`}),(0,g.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-11 items-center gap-2 self-start rounded-lg border border-linie-stark bg-erhaben px-4 text-[15px] hover:border-text-3`,children:[(0,g.jsx)(l,{className:`size-4`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),(0,g.jsx)(`p`,{className:`text-xs text-text-3`,children:`Chat, Sitzungen und Cron-Jobs verwaltet Hermes selbst. Es fragt nach seiner eigenen Anmeldung.`})]})]})})}export{_ as Einstellungen};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{c as e,s as t}from"./button-BheHBEml.js";import{G as n,K as r,q as i}from"./index-SRwQwEnh.js";import{a,i as o,n as s,r as c,t as l}from"./sheet-CKp82pOA.js";var u=t(),d=e();function f(e){let t=(0,u.c)(16),{onDienste:f,onEinstellungen:p,onSchliessen:m}=e,h;t[0]===m?h=t[1]:(h=e=>!e&&m(),t[0]=m,t[1]=h);let g;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(g=(0,d.jsxs)(o,{children:[(0,d.jsx)(a,{className:`schild text-lg`,children:`Mehr`}),(0,d.jsx)(c,{className:`sr-only`,children:`Weitere Bereiche`})]}),t[2]=g):g=t[2];let _;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,d.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-base`,children:[(0,d.jsx)(i,{className:`size-5`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),t[3]=_):_=t[3];let v;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,d.jsx)(r,{className:`size-5`,"aria-hidden":!0}),t[4]=v):v=t[4];let y;t[5]===f?y=t[6]:(y=(0,d.jsxs)(`button`,{type:`button`,onClick:f,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[v,` Dienste und Protokolle`]}),t[5]=f,t[6]=y);let b;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,d.jsx)(n,{className:`size-5`,"aria-hidden":!0}),t[7]=b):b=t[7];let x;t[8]===p?x=t[9]:(x=(0,d.jsxs)(`button`,{type:`button`,onClick:p,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[b,` Einstellungen`]}),t[8]=p,t[9]=x);let S;t[10]!==y||t[11]!==x?(S=(0,d.jsxs)(s,{side:`bottom`,className:`border-linie bg-panel pb-[calc(1rem+env(safe-area-inset-bottom))]`,children:[g,(0,d.jsxs)(`div`,{className:`flex flex-col gap-2 px-4`,children:[_,y,x]})]}),t[10]=y,t[11]=x,t[12]=S):S=t[12];let C;return t[13]!==h||t[14]!==S?(C=(0,d.jsx)(l,{open:!0,onOpenChange:h,children:S}),t[13]=h,t[14]=S,t[15]=C):C=t[15],C}export{f as MehrMenue};
import{c as e,s as t}from"./button-BheHBEml.js";import{G as n,K as r,q as i}from"./index-CsrOM_oc.js";import{a,i as o,n as s,r as c,t as l}from"./sheet-CKp82pOA.js";var u=t(),d=e();function f(e){let t=(0,u.c)(16),{onDienste:f,onEinstellungen:p,onSchliessen:m}=e,h;t[0]===m?h=t[1]:(h=e=>!e&&m(),t[0]=m,t[1]=h);let g;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(g=(0,d.jsxs)(o,{children:[(0,d.jsx)(a,{className:`schild text-lg`,children:`Mehr`}),(0,d.jsx)(c,{className:`sr-only`,children:`Weitere Bereiche`})]}),t[2]=g):g=t[2];let _;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,d.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-base`,children:[(0,d.jsx)(i,{className:`size-5`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),t[3]=_):_=t[3];let v;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,d.jsx)(r,{className:`size-5`,"aria-hidden":!0}),t[4]=v):v=t[4];let y;t[5]===f?y=t[6]:(y=(0,d.jsxs)(`button`,{type:`button`,onClick:f,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[v,` Dienste und Protokolle`]}),t[5]=f,t[6]=y);let b;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,d.jsx)(n,{className:`size-5`,"aria-hidden":!0}),t[7]=b):b=t[7];let x;t[8]===p?x=t[9]:(x=(0,d.jsxs)(`button`,{type:`button`,onClick:p,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[b,` Einstellungen`]}),t[8]=p,t[9]=x);let S;t[10]!==y||t[11]!==x?(S=(0,d.jsxs)(s,{side:`bottom`,className:`border-linie bg-panel pb-[calc(1rem+env(safe-area-inset-bottom))]`,children:[g,(0,d.jsxs)(`div`,{className:`flex flex-col gap-2 px-4`,children:[_,y,x]})]}),t[10]=y,t[11]=x,t[12]=S):S=t[12];let C;return t[13]!==h||t[14]!==S?(C=(0,d.jsx)(l,{open:!0,onOpenChange:h,children:S}),t[13]=h,t[14]=S,t[15]=C):C=t[15],C}export{f as MehrMenue};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -7,7 +7,7 @@
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>Homelab Orchestrator</title>
<script type="module" crossorigin src="/assets/index-SRwQwEnh.js"></script>
<script type="module" crossorigin src="/assets/index-CsrOM_oc.js"></script>
<link rel="modulepreload" crossorigin href="/assets/button-BheHBEml.js">
<link rel="stylesheet" crossorigin href="/assets/index-Bpe3m53F.css">
</head>
@@ -27,9 +27,9 @@ function artText(ziel: ZielStand): string {
return nummer ? `${art} ${nummer}` : art
}
/** Bei einem Update „alt → neu“ (steht in kurz), sonst nur, was läuft — ein Pfeil auf dieselbe Version verwirrt. */
function Stand({ b }: { b: BausteinStand }) {
if (b.kurz) return <span className="ziffern">{b.kurz}</span>
if (b.installiert && b.verfuegbar) return <span className="ziffern">{b.installiert} → {b.verfuegbar}</span>
if (b.installiert) return <span className="ziffern">{b.installiert}</span>
return null
}