feat: Datei-Symbol am Projekt (auto) + VM-Startparameter im Desktop-Panel

- Brain: /projects/status + /list liefern has_files + file_count pro Projekt
  (Scan /shared/projects/<id>/). Ersetzt das manuelle Code-Flag als primaeren
  Indikator. VM-Liste liefert boot_cmd (lesbarer aria-vm-Startbefehl).
- App: 📄-Symbol (+ Anzahl) an Projekten mit Dateien im ProjectsBrowser.
  DesktopTile zeigt pro VM den Start-Befehl als Wert dahinter.
- Diagnostic: 📄-Symbol (+ Anzahl, Tooltip) an Projekten mit Dateien.

Hinweis (kein Code): der VNC-Stream laeuft komplett durch RVS — der Port ist nur
der interne QEMU-Display-Port, den die Bridge lokal auf dem Host nutzt; die App
oeffnet nie einen Port (firewall-unabhaengig).

py/tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 23:31:31 +02:00
co-authored by Claude Opus 4.8
parent 0efb8d0848
commit e64043dca5
5 changed files with 59 additions and 4 deletions
@@ -225,6 +225,9 @@ export const ProjectsBrowser: React.FC<Props> = ({ visible = true, onClose, onAc
<View style={{ width: 8, height: 8, borderRadius: 4, backgroundColor: dot.color }} />
)}
<Text style={[s.rowName, isActive && { color: '#34C759' }]}>{item.name}</Text>
{item.has_files && (
<Text style={{ fontSize: 12 }} accessibilityLabel="hat Dateien">📄{item.file_count ? ` ${item.file_count}` : ''}</Text>
)}
{hidden && <Text style={s.hiddenBadge}>versteckt</Text>}
{item.status === 'ended' && <Text style={s.statusBadge}>beendet</Text>}
{isActive && <Text style={s.activeBadge}> FOCUS</Text>}
+4
View File
@@ -168,6 +168,9 @@ export interface Project {
// Optionale absolute noVNC-URL (falls der Desktop direkt erreichbar ist,
// sonst laeuft der VNC-Stream als RFB-Bytes durch RVS).
desktop_url?: string;
// Automatisch: hat das Projekt Dateien in /shared/projects/<id>/? → Datei-Symbol.
has_files?: boolean;
file_count?: number;
}
export interface ProjectStatus {
@@ -185,6 +188,7 @@ export interface ProjectVm {
mem: number;
running?: boolean;
vnc_port?: number;
boot_cmd?: string;
created_at?: number;
}
+4 -2
View File
@@ -101,8 +101,9 @@ const DesktopTile: React.FC<Props> = ({ projectId, focused }) => {
<View style={{ flex: 1 }}>
<Text style={styles.vmName}>
<Text style={{ color: vm.running ? '#34C759' : '#555570' }}>●</Text> {vm.name}
<Text style={styles.vmMeta}> {vm.arch} · {vm.running ? 'läuft' : 'gestoppt'}</Text>
</Text>
<Text style={styles.vmMeta}>{vm.arch} · Display :{vm.vnc_display} · {vm.running ? 'läuft' : 'gestoppt'}</Text>
<Text style={styles.vmCmd} numberOfLines={2}>{vm.boot_cmd || `aria-vm boot ${vm.name} --vnc-display ${vm.vnc_display}`}</Text>
</View>
<View style={styles.vmBtns}>
{isBusy ? (
@@ -145,7 +146,8 @@ const styles = StyleSheet.create({
err: { color: '#FF6E6E', fontSize: 13, marginTop: 16 },
vmRow: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#12122A', borderRadius: 10, padding: 12, marginBottom: 8 },
vmName: { color: '#E0E0F0', fontSize: 15, fontWeight: '700' },
vmMeta: { color: '#8888AA', fontSize: 12, marginTop: 3 },
vmMeta: { color: '#8888AA', fontSize: 12, fontWeight: '400' },
vmCmd: { color: '#6A9BD0', fontSize: 11, fontFamily: 'monospace', marginTop: 4 },
vmBtns: { flexDirection: 'row', gap: 6, alignItems: 'center' },
vmBtn: { borderWidth: 1, borderRadius: 8, paddingHorizontal: 10, paddingVertical: 6 },
vmBtnText: { fontSize: 12, fontWeight: '700' },