@wrongstack/desktop 0.280.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/wrongstack-desktop.js +38 -0
- package/dist/main/agent-bridge.js +7 -0
- package/dist/main/agent-bridge.js.map +1 -0
- package/dist/main/chunk-F3LGFYUK.js +239 -0
- package/dist/main/chunk-F3LGFYUK.js.map +1 -0
- package/dist/main/main.js +2293 -0
- package/dist/main/main.js.map +1 -0
- package/dist/preload/preload.cjs +90 -0
- package/dist/preload/preload.cjs.map +1 -0
- package/dist/preload/webui-preload.cjs +84 -0
- package/dist/preload/webui-preload.cjs.map +1 -0
- package/dist/renderer/assets/index-BAP2wfHP.css +1 -0
- package/dist/renderer/assets/index-Cq-Fc_6i.js +395 -0
- package/dist/renderer/assets/index-Cq-Fc_6i.js.map +1 -0
- package/dist/renderer/index.html +13 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-Cq-Fc_6i.js","names":[],"sources":["../../../src/renderer/src/i18n.ts","../../../src/renderer/src/renderer.ts"],"sourcesContent":["/**\n * Desktop renderer i18n — lightweight vanilla-TS translation layer.\n * No react-i18next (the desktop shell is pure DOM manipulation).\n *\n * The display language is sourced from the SHARED machine config\n * (`~/.wrongstack/config.json` → `Config.uiLocale`): the main process reads it\n * at boot and pushes it here over the `desktop:locale-changed` IPC channel\n * (and re-pushes on any cross-process config change). localStorage is kept\n * only as a fast-boot cache so the first paint isn't blank; it is reconciled\n * to the config value the moment main sends it. Falls back to 'en'.\n *\n * Usage: import { t } from './i18n'; t('openProject')\n */\n\nexport type DesktopLocale = 'en' | 'tr' | 'de' | 'fr' | 'it' | 'es' | 'pt-BR';\n\nconst STORAGE_KEY = 'wrongstack.desktop.locale';\n\n/** Push a renderer-initiated locale change to main (which persists it to the\n * shared config). No-op outside the desktop shell. */\nfunction pushLocaleToMain(locale: DesktopLocale): void {\n try {\n (window as unknown as { wrongstackDesktop?: { setLocale?: (l: string) => void } })\n .wrongstackDesktop?.setLocale?.(locale);\n } catch { /* bridge not available (e.g. unit tests) */ }\n}\n\nfunction readLocale(): DesktopLocale {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored && stored in CATALOGS) return stored as DesktopLocale;\n } catch { /* localStorage unavailable */ }\n return 'en';\n}\n\nlet currentLocale: DesktopLocale = readLocale();\n\n/**\n * Apply a locale. `propagate: true` (default) also pushes the change to main so\n * it lands in the shared config; `propagate: false` is for main-originated\n * changes (the `onLocaleChanged` listener) so we don't echo back (loop).\n */\nexport function setLocale(locale: DesktopLocale, opts: { propagate?: boolean } = {}): void {\n if (locale === currentLocale) return;\n currentLocale = locale;\n try { localStorage.setItem(STORAGE_KEY, locale); } catch { /* ignore */ }\n if (opts.propagate !== false) pushLocaleToMain(locale);\n for (const cb of localeChangeListeners) cb();\n}\n\nexport function getLocale(): DesktopLocale {\n return currentLocale;\n}\n\nconst localeChangeListeners = new Set<() => void>();\n/** Subscribe to locale changes (user picker or a config push from main).\n * Returns an unsubscribe. The desktop shell uses this to re-render its DOM. */\nexport function onLocaleChange(cb: () => void): () => void {\n localeChangeListeners.add(cb);\n return () => {\n localeChangeListeners.delete(cb);\n };\n}\n\nexport const SUPPORTED_LOCALES: DesktopLocale[] = ['en', 'tr', 'de', 'fr', 'it', 'es', 'pt-BR'];\n\ntype Catalog = Record<string, string>;\n\nconst en: Catalog = {\n desktopNavAria: 'Desktop navigation',\n openProjectFolderTitle: 'Open project folder',\n dismiss: 'Dismiss',\n active: 'Active',\n globalSettingsWorkspace: 'Global settings workspace',\n newSession: 'New Session',\n revealProjectFolder: 'Reveal project folder',\n registerProjectFolder: 'Register project folder',\n findProject: 'Find project',\n clearProjectSearch: 'Clear project search',\n register: 'Register',\n projectLists: 'Project lists',\n removeFromRegistry: 'Remove from project registry',\n none: 'None',\n quickView: 'Quick view',\n openChat: 'Open chat',\n openTerminal: 'Open terminal',\n term: 'Term',\n openFiles: 'Open files',\n files: 'Files',\n openInBrowser: 'Open in browser',\n closeSession: 'Close session',\n runtimeError: 'Runtime Error',\n openProject: 'Open Project',\n restoring: 'Restoring',\n workspace: 'Workspace',\n projects: 'Projects',\n quick: 'Quick',\n quickActions: 'Quick actions',\n all: 'All',\n recent: 'Recent',\n registered: 'Registered',\n globalSettings: 'Global Settings',\n settings: 'Settings',\n webui: 'WebUI',\n webuiCommands: 'WebUI commands',\n webuiReady: 'WebUI ready',\n webuiLoading: 'WebUI loading',\n webuiError: 'WebUI error',\n webuiIdle: 'WebUI idle',\n noActiveWebui: 'No active WebUI',\n chat: 'Chat',\n terminal: 'Terminal',\n newTerm: 'New Term',\n prompt: 'Prompt',\n command: 'Command',\n compact: 'Compact',\n yolo: 'YOLO',\n ready: 'Ready',\n loading: 'Loading',\n idle: 'Idle',\n error: 'Error',\n offline: 'Offline',\n running: 'Running',\n starting: 'Starting',\n stopped: 'Stopped',\n noProject: 'No project',\n noMatchingProjects: 'No matching projects',\n noRegisteredProjects: 'No registered projects',\n noOpenProjectSessions: 'No open project sessions',\n unknownError: 'Unknown error',\n next: 'Next',\n collapseSidebar: 'Collapse desktop sidebar',\n expandSidebar: 'Expand desktop sidebar',\n gs: 'GS',\n sessions: 'Sessions',\n runtimes: 'Runtimes',\n launcherError: 'The active WebUI did not handle that launcher command. Try Reload if the view is still starting.',\n sessionLauncherError: 'That session WebUI did not handle the command yet. Try Reload if it is still starting.',\n operationFailed: 'Operation failed.',\n};\n\nconst tr: Catalog = {\n desktopNavAria: 'Masaüstü navigasyon',\n openProjectFolderTitle: 'Proje klasörünü aç',\n dismiss: 'Kapat',\n active: 'Aktif',\n globalSettingsWorkspace: 'Genel ayarlar çalışma alanı',\n newSession: 'Yeni Oturum',\n revealProjectFolder: 'Proje klasörünü göster',\n registerProjectFolder: 'Proje klasörünü kaydet',\n findProject: 'Proje bul',\n clearProjectSearch: 'Proje aramasını temizle',\n register: 'Kaydet',\n projectLists: 'Proje listeleri',\n removeFromRegistry: 'Proje kaydından kaldır',\n none: 'Yok',\n quickView: 'Hızlı görünüm',\n openChat: 'Sohbeti aç',\n openTerminal: 'Terminali aç',\n term: 'Term',\n openFiles: 'Dosyaları aç',\n files: 'Dosyalar',\n openInBrowser: 'Tarayıcıda aç',\n closeSession: 'Oturumu kapat',\n runtimeError: 'Çalışma Zamanı Hatası',\n openProject: 'Proje Aç',\n restoring: 'Geri yükleniyor',\n workspace: 'Çalışma alanı',\n projects: 'Projeler',\n quick: 'Hızlı',\n quickActions: 'Hızlı eylemler',\n all: 'Tümü',\n recent: 'Son',\n registered: 'Kayıtlı',\n globalSettings: 'Genel Ayarlar',\n settings: 'Ayarlar',\n webui: 'WebUI',\n webuiCommands: 'WebUI komutları',\n webuiReady: 'WebUI hazır',\n webuiLoading: 'WebUI yükleniyor',\n webuiError: 'WebUI hatası',\n webuiIdle: 'WebUI boşta',\n noActiveWebui: 'Etkin WebUI yok',\n chat: 'Sohbet',\n terminal: 'Terminal',\n newTerm: 'Yeni Terminal',\n prompt: 'İstem',\n command: 'Komut',\n compact: 'Sıkışık',\n yolo: 'YOLO',\n ready: 'Hazır',\n loading: 'Yükleniyor',\n idle: 'Boşta',\n error: 'Hata',\n offline: 'Çevrimdışı',\n running: 'Çalışıyor',\n starting: 'Başlatılıyor',\n stopped: 'Durduruldu',\n noProject: 'Proje yok',\n noMatchingProjects: 'Eşleşen proje yok',\n noRegisteredProjects: 'Kayıtlı proje yok',\n noOpenProjectSessions: 'Açık proje oturumu yok',\n unknownError: 'Bilinmeyen hata',\n next: 'İleri',\n collapseSidebar: 'Masaüstü kenar çubuğunu daralt',\n expandSidebar: 'Masaüstü kenar çubuğunu genişlet',\n gs: 'GA',\n sessions: 'Oturumlar',\n runtimes: 'Çalışma zamanları',\n};\n\nconst de: Catalog = {\n desktopNavAria: 'Desktop-Navigation',\n openProjectFolderTitle: 'Projektordner öffnen',\n dismiss: 'Verwerfen',\n active: 'Aktiv',\n globalSettingsWorkspace: 'Globale Einstellungen-Workspace',\n newSession: 'Neue Sitzung',\n revealProjectFolder: 'Projektordner anzeigen',\n registerProjectFolder: 'Projektordner registrieren',\n findProject: 'Projekt finden',\n clearProjectSearch: 'Projektsuche löschen',\n register: 'Registrieren',\n projectLists: 'Projektlisten',\n removeFromRegistry: 'Aus Projekt-Registry entfernen',\n none: 'Keine',\n quickView: 'Schnellansicht',\n openChat: 'Chat öffnen',\n openTerminal: 'Terminal öffnen',\n term: 'Term',\n openFiles: 'Dateien öffnen',\n files: 'Dateien',\n openInBrowser: 'Im Browser öffnen',\n closeSession: 'Sitzung schließen',\n runtimeError: 'Laufzeitfehler',\n openProject: 'Projekt öffnen',\n restoring: 'Wiederherstellen',\n workspace: 'Workspace',\n projects: 'Projekte',\n quick: 'Schnell',\n quickActions: 'Schnellaktionen',\n all: 'Alle',\n recent: 'Zuletzt',\n registered: 'Registriert',\n globalSettings: 'Globale Einstellungen',\n settings: 'Einstellungen',\n webui: 'WebUI',\n webuiCommands: 'WebUI-Befehle',\n webuiReady: 'WebUI bereit',\n webuiLoading: 'WebUI lädt',\n webuiError: 'WebUI-Fehler',\n webuiIdle: 'WebUI inaktiv',\n noActiveWebui: 'Kein aktives WebUI',\n chat: 'Chat',\n terminal: 'Terminal',\n newTerm: 'Neues Terminal',\n prompt: 'Prompt',\n command: 'Befehl',\n compact: 'Kompakt',\n yolo: 'YOLO',\n ready: 'Bereit',\n loading: 'Lädt',\n idle: 'Inaktiv',\n error: 'Fehler',\n offline: 'Offline',\n running: 'Läuft',\n starting: 'Startet',\n stopped: 'Gestoppt',\n noProject: 'Kein Projekt',\n noMatchingProjects: 'Keine passenden Projekte',\n noRegisteredProjects: 'Keine registrierten Projekte',\n noOpenProjectSessions: 'Keine offenen Projektsessions',\n unknownError: 'Unbekannter Fehler',\n next: 'Weiter',\n collapseSidebar: 'Desktop-Seitenleiste einklappen',\n expandSidebar: 'Desktop-Seitenleiste ausklappen',\n gs: 'GE',\n sessions: 'Sessions',\n runtimes: 'Runtimes',\n};\n\nconst fr: Catalog = {\n desktopNavAria: 'Navigation du bureau',\n openProjectFolderTitle: 'Ouvrir le dossier du projet',\n dismiss: 'Fermer',\n active: 'Actif',\n globalSettingsWorkspace: 'Espace des paramètres globaux',\n newSession: 'Nouvelle session',\n revealProjectFolder: 'Révéler le dossier du projet',\n registerProjectFolder: 'Enregistrer le dossier du projet',\n findProject: 'Rechercher un projet',\n clearProjectSearch: 'Effacer la recherche de projet',\n register: 'Enregistrer',\n projectLists: 'Listes de projets',\n removeFromRegistry: 'Retirer du registre des projets',\n none: 'Aucun',\n quickView: 'Vue rapide',\n openChat: 'Ouvrir le chat',\n openTerminal: 'Ouvrir le terminal',\n term: 'Term',\n openFiles: 'Ouvrir les fichiers',\n files: 'Fichiers',\n openInBrowser: 'Ouvrir dans le navigateur',\n closeSession: 'Fermer la session',\n runtimeError: \"Erreur d'exécution\",\n openProject: 'Ouvrir un projet',\n restoring: 'Restauration',\n workspace: 'Espace de travail',\n projects: 'Projets',\n quick: 'Rapide',\n quickActions: 'Actions rapides',\n all: 'Tous',\n recent: 'Récents',\n registered: 'Enregistrés',\n globalSettings: 'Paramètres globaux',\n settings: 'Paramètres',\n webui: 'WebUI',\n webuiCommands: 'Commandes WebUI',\n webuiReady: 'WebUI prêt',\n webuiLoading: 'WebUI charge',\n webuiError: 'Erreur WebUI',\n webuiIdle: 'WebUI inactif',\n noActiveWebui: 'Pas de WebUI actif',\n chat: 'Chat',\n terminal: 'Terminal',\n newTerm: 'Nouveau terminal',\n prompt: 'Invite',\n command: 'Commande',\n compact: 'Compact',\n yolo: 'YOLO',\n ready: 'Prêt',\n loading: 'Chargement',\n idle: 'Inactif',\n error: 'Erreur',\n offline: 'Hors ligne',\n running: 'En cours',\n starting: 'Démarrage',\n stopped: 'Arrêté',\n noProject: 'Aucun projet',\n noMatchingProjects: 'Aucun projet correspondant',\n noRegisteredProjects: 'Aucun projet enregistré',\n noOpenProjectSessions: 'Aucune session de projet ouverte',\n unknownError: 'Erreur inconnue',\n next: 'Suivant',\n collapseSidebar: 'Réduire la barre latérale',\n expandSidebar: 'Agrandir la barre latérale',\n gs: 'PG',\n sessions: 'Sessions',\n runtimes: 'Runtimes',\n};\n\nconst it: Catalog = {\n desktopNavAria: 'Navigazione desktop',\n openProjectFolderTitle: 'Apri cartella progetto',\n dismiss: 'Chiudi',\n active: 'Attivo',\n globalSettingsWorkspace: 'Workspace impostazioni globali',\n newSession: 'Nuova sessione',\n revealProjectFolder: 'Rivela cartella progetto',\n registerProjectFolder: 'Registra cartella progetto',\n findProject: 'Trova progetto',\n clearProjectSearch: 'Cancella ricerca progetto',\n register: 'Registra',\n projectLists: 'Elenchi progetti',\n removeFromRegistry: 'Rimuovi dal registro progetti',\n none: 'Nessuno',\n quickView: 'Vista rapida',\n openChat: 'Apri chat',\n openTerminal: 'Apri terminale',\n term: 'Term',\n openFiles: 'Apri file',\n files: 'File',\n openInBrowser: 'Apri nel browser',\n closeSession: 'Chiudi sessione',\n runtimeError: 'Errore di runtime',\n openProject: 'Apri progetto',\n restoring: 'Ripristino',\n workspace: 'Workspace',\n projects: 'Progetti',\n quick: 'Rapido',\n quickActions: 'Azioni rapide',\n all: 'Tutti',\n recent: 'Recenti',\n registered: 'Registrati',\n globalSettings: 'Impostazioni globali',\n settings: 'Impostazioni',\n webui: 'WebUI',\n webuiCommands: 'Comandi WebUI',\n webuiReady: 'WebUI pronto',\n webuiLoading: 'WebUI carica',\n webuiError: 'Errore WebUI',\n webuiIdle: 'WebUI inattivo',\n noActiveWebui: 'Nessun WebUI attivo',\n chat: 'Chat',\n terminal: 'Terminale',\n newTerm: 'Nuovo terminale',\n prompt: 'Prompt',\n command: 'Comando',\n compact: 'Compatto',\n yolo: 'YOLO',\n ready: 'Pronto',\n loading: 'Caricamento',\n idle: 'Inattivo',\n error: 'Errore',\n offline: 'Offline',\n running: 'In corso',\n starting: 'Avvio',\n stopped: 'Fermato',\n noProject: 'Nessun progetto',\n noMatchingProjects: 'Nessun progetto corrispondente',\n noRegisteredProjects: 'Nessun progetto registrato',\n noOpenProjectSessions: 'Nessuna sessione di progetto aperta',\n unknownError: 'Errore sconosciuto',\n next: 'Avanti',\n collapseSidebar: 'Comprimi barra laterale',\n expandSidebar: 'Espandi barra laterale',\n gs: 'IG',\n sessions: 'Sessioni',\n runtimes: 'Runtime',\n};\n\nconst es: Catalog = {\n desktopNavAria: 'Navegación de escritorio',\n openProjectFolderTitle: 'Abrir carpeta del proyecto',\n dismiss: 'Cerrar',\n active: 'Activo',\n globalSettingsWorkspace: 'Espacio de ajustes globales',\n newSession: 'Nueva sesión',\n revealProjectFolder: 'Revelar carpeta del proyecto',\n registerProjectFolder: 'Registrar carpeta del proyecto',\n findProject: 'Buscar proyecto',\n clearProjectSearch: 'Borrar búsqueda de proyecto',\n register: 'Registrar',\n projectLists: 'Listas de proyectos',\n removeFromRegistry: 'Quitar del registro de proyectos',\n none: 'Ninguno',\n quickView: 'Vista rápida',\n openChat: 'Abrir chat',\n openTerminal: 'Abrir terminal',\n term: 'Term',\n openFiles: 'Abrir archivos',\n files: 'Archivos',\n openInBrowser: 'Abrir en el navegador',\n closeSession: 'Cerrar sesión',\n runtimeError: 'Error de ejecución',\n openProject: 'Abrir proyecto',\n restoring: 'Restaurando',\n workspace: 'Espacio de trabajo',\n projects: 'Proyectos',\n quick: 'Rápido',\n quickActions: 'Acciones rápidas',\n all: 'Todos',\n recent: 'Recientes',\n registered: 'Registrados',\n globalSettings: 'Ajustes globales',\n settings: 'Ajustes',\n webui: 'WebUI',\n webuiCommands: 'Comandos WebUI',\n webuiReady: 'WebUI listo',\n webuiLoading: 'WebUI cargando',\n webuiError: 'Error de WebUI',\n webuiIdle: 'WebUI inactivo',\n noActiveWebui: 'Sin WebUI activo',\n chat: 'Chat',\n terminal: 'Terminal',\n newTerm: 'Nuevo terminal',\n prompt: 'Indicación',\n command: 'Comando',\n compact: 'Compacto',\n yolo: 'YOLO',\n ready: 'Listo',\n loading: 'Cargando',\n idle: 'Inactivo',\n error: 'Error',\n offline: 'Desconectado',\n running: 'En ejecución',\n starting: 'Iniciando',\n stopped: 'Detenido',\n noProject: 'Sin proyecto',\n noMatchingProjects: 'Sin proyectos coincidentes',\n noRegisteredProjects: 'Sin proyectos registrados',\n noOpenProjectSessions: 'Sin sesiones de proyecto abiertas',\n unknownError: 'Error desconocido',\n next: 'Siguiente',\n collapseSidebar: 'Contraer barra lateral',\n expandSidebar: 'Expandir barra lateral',\n gs: 'AG',\n sessions: 'Sesiones',\n runtimes: 'Runtimes',\n};\n\nconst ptBR: Catalog = {\n desktopNavAria: 'Navegação do desktop',\n openProjectFolderTitle: 'Abrir pasta do projeto',\n dismiss: 'Dispensar',\n active: 'Ativo',\n globalSettingsWorkspace: 'Espaço de configurações globais',\n newSession: 'Nova sessão',\n revealProjectFolder: 'Revelar pasta do projeto',\n registerProjectFolder: 'Registrar pasta do projeto',\n findProject: 'Encontrar projeto',\n clearProjectSearch: 'Limpar busca de projeto',\n register: 'Registrar',\n projectLists: 'Listas de projetos',\n removeFromRegistry: 'Remover do registro de projetos',\n none: 'Nenhum',\n quickView: 'Vista rápida',\n openChat: 'Abrir chat',\n openTerminal: 'Abrir terminal',\n term: 'Term',\n openFiles: 'Abrir arquivos',\n files: 'Arquivos',\n openInBrowser: 'Abrir no navegador',\n closeSession: 'Fechar sessão',\n runtimeError: 'Erro de execução',\n openProject: 'Abrir projeto',\n restoring: 'Restaurando',\n workspace: 'Workspace',\n projects: 'Projetos',\n quick: 'Rápido',\n quickActions: 'Ações rápidas',\n all: 'Todos',\n recent: 'Recentes',\n registered: 'Registrados',\n globalSettings: 'Configurações globais',\n settings: 'Configurações',\n webui: 'WebUI',\n webuiCommands: 'Comandos WebUI',\n webuiReady: 'WebUI pronto',\n webuiLoading: 'WebUI carregando',\n webuiError: 'Erro WebUI',\n webuiIdle: 'WebUI inativo',\n noActiveWebui: 'Sem WebUI ativo',\n chat: 'Chat',\n terminal: 'Terminal',\n newTerm: 'Novo terminal',\n prompt: 'Prompt',\n command: 'Comando',\n compact: 'Compacto',\n yolo: 'YOLO',\n ready: 'Pronto',\n loading: 'Carregando',\n idle: 'Inativo',\n error: 'Erro',\n offline: 'Offline',\n running: 'Em execução',\n starting: 'Iniciando',\n stopped: 'Parado',\n noProject: 'Sem projeto',\n noMatchingProjects: 'Sem projetos correspondentes',\n noRegisteredProjects: 'Sem projetos registrados',\n noOpenProjectSessions: 'Sem sessões de projeto abertas',\n unknownError: 'Erro desconhecido',\n next: 'Próximo',\n collapseSidebar: 'Recolher barra lateral',\n expandSidebar: 'Expandir barra lateral',\n gs: 'CG',\n sessions: 'Sessões',\n runtimes: 'Runtimes',\n};\n\nconst CATALOGS: Record<DesktopLocale, Catalog> = { en, tr, de, fr, it, es, 'pt-BR': ptBR };\n\n/** Translate a key, falling back to the key itself if not found. */\nexport function t(key: string): string {\n return CATALOGS[currentLocale]?.[key] ?? CATALOGS.en[key] ?? key;\n}\n\n// Follow the shared config language: the main process pushes the config-backed\n// locale here on boot and whenever another surface changes it. propagate:false\n// so adopting the config value never echoes back to main (loop). No-op outside\n// the desktop shell (e.g. unit tests with no bridge).\ntry {\n (\n window as unknown as {\n wrongstackDesktop?: { onLocaleChanged?: (cb: (locale: string) => void) => () => void };\n }\n ).wrongstackDesktop?.onLocaleChanged?.((locale: string) => {\n if (locale && locale in CATALOGS) setLocale(locale as DesktopLocale, { propagate: false });\n });\n} catch {\n /* bridge not available */\n}\n","import type {\n DesktopProjectEntry,\n DesktopRuntimeRecord,\n DesktopStateSnapshot,\n DesktopWebuiStatusSnapshot,\n DesktopWebuiCommand,\n} from '../../shared/types.js';\nimport { getLocale, onLocaleChange, setLocale, SUPPORTED_LOCALES, t } from './i18n.js';\nimport './styles.css';\n\n/** Locale code → endonym (shown untranslated so a user finds their language in\n * any UI language, same principle as the WebUI LANGUAGES list). */\nconst LOCALE_ENDONYMS: Record<string, string> = {\n en: 'English',\n tr: 'Türkçe',\n de: 'Deutsch',\n fr: 'Français',\n it: 'Italiano',\n es: 'Español',\n 'pt-BR': 'Português',\n};\n\nconst appRootElement = document.querySelector<HTMLDivElement>('#app');\nif (!appRootElement) throw new Error('Missing #app root');\nconst appRoot = appRootElement;\n\nlet state: DesktopStateSnapshot = {\n activeRuntimeId: null,\n runtimes: [],\n recentProjects: [],\n registeredProjects: [],\n restoring: false,\n};\nlet webuiStatus: DesktopWebuiStatusSnapshot = { runtimeId: null, status: 'idle' };\nlet busy = false;\nlet shellError: string | null = null;\nconst RUNTIME_GROUP_STORAGE_KEY = 'wrongstack.desktop.runtimeGroups';\nconst SHELL_SIDEBAR_STORAGE_KEY = 'wrongstack.desktop.sidebarCollapsed';\nconst DESKTOP_PANEL_STORAGE_KEY = 'wrongstack.desktop.panel';\nconst PROJECT_TAB_STORAGE_KEY = 'wrongstack.desktop.projectTab';\nconst ICON_NAMES = [\n 'agents',\n 'branch',\n 'chart',\n 'check',\n 'checklist',\n 'chevron',\n 'chip',\n 'clock',\n 'collab',\n 'command',\n 'compress',\n 'cursor',\n 'debug',\n 'document',\n 'download',\n 'external',\n 'files',\n 'folder',\n 'folder-plus',\n 'gallery',\n 'git',\n 'history',\n 'kanban',\n 'keyboard',\n 'list',\n 'mail',\n 'map',\n 'message',\n 'monitor',\n 'phase',\n 'plan',\n 'plus',\n 'project',\n 'pulse',\n 'refresh',\n 'search',\n 'settings',\n 'shield',\n 'skill',\n 'spark',\n 'target',\n 'tasks',\n 'terminal',\n 'wand',\n 'x',\n] as const;\ntype IconName = (typeof ICON_NAMES)[number];\ntype DesktopPanel = 'workspace' | 'projects' | 'quick';\ntype ProjectPickerTab = 'recent' | 'registered' | 'all';\ntype ProjectPickerVariant = 'dock' | 'full' | 'embedded';\nlet runtimeGroupState = readRuntimeGroupState();\nlet shellSidebarCollapsed = readShellSidebarCollapsed();\nlet desktopPanel: DesktopPanel = readDesktopPanel();\nlet projectPickerTab: ProjectPickerTab = readProjectPickerTab();\nlet projectSearch = '';\nlet launcherFeedback: LauncherFeedback | null = null;\nlet launcherFeedbackSeq = 0;\n\ninterface LauncherFeedback {\n id: number;\n state: 'pending' | 'success' | 'error';\n label: string;\n commandKey?: string | undefined;\n message?: string | undefined;\n}\n\ninterface RuntimeProjectGroup {\n key: string;\n name: string;\n root: string;\n kind: DesktopRuntimeRecord['kind'];\n sessions: DesktopRuntimeRecord[];\n}\n\nfunction activeRuntime(): DesktopRuntimeRecord | undefined {\n return state.runtimes.find((runtime) => runtime.id === state.activeRuntimeId);\n}\n\nfunction render(): void {\n const active = activeRuntime();\n appRoot.innerHTML = `\n <div class=\"desktop-shell ${shellSidebarCollapsed ? 'shell-collapsed' : ''}\">\n <aside class=\"sidebar\">\n ${renderDesktopRail()}\n ${shellSidebarCollapsed ? '' : renderSidebarPane(active)}\n </aside>\n\n <main class=\"stage ${active?.status === 'running' ? 'stage-mounted' : ''}\">\n ${renderStage(active)}\n </main>\n </div>\n `;\n}\n\nfunction renderDesktopRail(): string {\n return `\n <nav class=\"desktop-rail\" aria-label=\"${t('desktopNavAria')}\">\n <div class=\"rail-brand\" title=\"WrongStack Desktop\">WS</div>\n <div class=\"rail-section\">\n <button class=\"rail-button accent\" title=\"${t('openProjectFolderTitle')}\" data-action=\"open-project\" ${busy ? 'disabled' : ''}>\n ${iconSvg('folder-plus')}\n </button>\n ${renderDesktopPanelButton(t('workspace'), 'monitor', 'workspace')}\n ${renderDesktopPanelButton(t('projects'), 'folder', 'projects', projectCountLabel())}\n ${renderDesktopPanelButton(t('quickActions'), 'command', 'quick')}\n </div>\n ${renderCollapsedRuntimeButtons()}\n <div class=\"rail-spacer\"></div>\n <select\n class=\"rail-locale-select\"\n data-action=\"set-locale\"\n title=\"${t('settings')}\"\n aria-label=\"${t('settings')}\"\n >\n ${SUPPORTED_LOCALES.map(\n (code) =>\n `<option value=\"${code}\"${code === getLocale() ? ' selected' : ''}>${LOCALE_ENDONYMS[code] ?? code}</option>`,\n ).join('')}\n </select>\n <button class=\"rail-button\" title=\"${t('globalSettings')}\" data-action=\"open-settings\" ${busy ? 'disabled' : ''}>\n ${iconSvg('settings')}\n </button>\n <button\n class=\"rail-button rail-toggle\"\n title=\"${shellSidebarCollapsed ? t('expandSidebar') : t('collapseSidebar')}\"\n data-action=\"toggle-shell-sidebar\"\n aria-label=\"${shellSidebarCollapsed ? t('expandSidebar') : t('collapseSidebar')}\"\n aria-pressed=\"${shellSidebarCollapsed ? 'true' : 'false'}\"\n >\n ${iconSvg('chevron')}\n </button>\n </nav>\n `;\n}\n\nfunction renderDesktopPanelButton(\n label: string,\n icon: IconName,\n panel: DesktopPanel,\n badge?: string,\n): string {\n const active = desktopPanel === panel;\n return `\n <button\n class=\"rail-button ${active ? 'active' : ''}\"\n title=\"${escapeAttr(label)}\"\n data-action=\"select-desktop-panel\"\n data-panel=\"${escapeAttr(panel)}\"\n aria-pressed=\"${active ? 'true' : 'false'}\"\n >\n ${iconSvg(icon)}\n ${badge ? `<span class=\"rail-badge\">${escapeHtml(badge)}</span>` : ''}\n </button>\n `;\n}\n\nfunction renderCollapsedRuntimeButtons(): string {\n if (state.runtimes.length === 0) return '';\n return `\n <div class=\"rail-divider\"></div>\n <div class=\"rail-runtime-list\">\n ${state.runtimes.map(renderCollapsedRuntimeButton).join('')}\n </div>\n `;\n}\n\nfunction renderCollapsedRuntimeButton(runtime: DesktopRuntimeRecord): string {\n const active = runtime.id === state.activeRuntimeId;\n return `\n <button\n class=\"rail-runtime ${active ? 'active' : ''}\"\n title=\"${escapeAttr(`${runtime.name} · ${runtime.root}`)}\"\n data-action=\"activate\"\n data-runtime=\"${escapeAttr(runtime.id)}\"\n >\n <span class=\"status-dot status-${runtime.status}\"></span>\n <span>${escapeHtml(runtimeInitials(runtime))}</span>\n </button>\n `;\n}\n\nfunction renderSidebarPane(active: DesktopRuntimeRecord | undefined): string {\n return `\n <section class=\"sidebar-pane\">\n ${renderPaneHeader(active)}\n ${renderPaneBody(active)}\n </section>\n `;\n}\n\nfunction renderPaneHeader(active: DesktopRuntimeRecord | undefined): string {\n const title =\n desktopPanel === 'projects' ? t('projects') : desktopPanel === 'quick' ? t('quick') : t('workspace');\n const subtitle =\n desktopPanel === 'projects'\n ? `${projectCountLabel()} projects`\n : desktopPanel === 'quick'\n ? active?.status === 'running'\n ? t('webuiCommands')\n : t('noActiveWebui')\n : active\n ? active.name\n : state.restoring\n ? t('restoring')\n : t('noProject');\n return `\n <header class=\"pane-header\">\n <div class=\"pane-title-block\">\n <div class=\"pane-kicker\">WrongStack</div>\n <div class=\"pane-title\">${escapeHtml(title)}</div>\n </div>\n <div class=\"pane-subtitle\" title=\"${escapeAttr(subtitle)}\">${escapeHtml(subtitle)}</div>\n </header>\n `;\n}\n\nfunction renderPaneBody(active: DesktopRuntimeRecord | undefined): string {\n if (desktopPanel === 'projects') {\n return `\n <div class=\"pane-body pane-body-scroll\">\n ${renderShellError()}\n ${renderProjectsMenu()}\n </div>\n `;\n }\n if (desktopPanel === 'quick') {\n return `\n <div class=\"pane-body pane-body-scroll\">\n ${renderShellError()}\n ${renderLauncher(active)}\n ${renderActiveProject(active)}\n </div>\n `;\n }\n return `\n <div class=\"pane-body workspace-pane\">\n <div class=\"workspace-main\">\n ${renderShellError()}\n ${renderActiveProject(active)}\n ${renderRuntimeList()}\n </div>\n <div class=\"workspace-projects\">\n ${renderProjectPicker('dock')}\n </div>\n </div>\n `;\n}\n\nfunction renderProjectsMenu(): string {\n return `\n <div class=\"projects-menu-stack\">\n ${renderLauncherFeedback()}\n ${renderProjectSessionTree()}\n ${renderProjectPicker('embedded')}\n </div>\n `;\n}\n\nfunction renderShellError(): string {\n if (!shellError) return '';\n return `\n <div class=\"shell-error\" role=\"alert\">\n <div class=\"shell-error-copy\">${escapeHtml(shellError)}</div>\n <button class=\"icon-button\" title=\"${t('dismiss')}\" data-action=\"clear-error\">\n ${iconSvg('x')}\n </button>\n </div>\n `;\n}\n\nfunction renderActiveProject(active: DesktopRuntimeRecord | undefined): string {\n if (!active) {\n return `\n <section class=\"panel active-panel\">\n <header class=\"panel-header\">\n <span>${t('active')}</span>\n <span class=\"status-chip idle\">${state.restoring ? t('restoring') : t('idle')}</span>\n </header>\n <div class=\"project-empty\">${state.restoring ? `${t('restoring')}...` : t('noProject')}</div>\n </section>\n `;\n }\n\n return `\n <section class=\"panel active-panel\">\n <header class=\"panel-header\">\n <span>${t('active')}</span>\n <span class=\"status-chip ${active.status}\">${escapeHtml(runtimeStatusLabel(active))}</span>\n </header>\n <div class=\"active-project\">\n <div class=\"active-title\">${escapeHtml(active.name)}</div>\n ${active.kind === 'global-settings' ? `<div class=\"runtime-kind\">${t('globalSettingsWorkspace')}</div>` : ''}\n <div class=\"active-path\">${escapeHtml(active.root)}</div>\n <div class=\"active-meta\">\n <span>HTTP ${active.httpPort}</span>\n <span>WS ${active.wsPort}</span>\n </div>\n ${renderWebuiStatus(active)}\n ${\n active.error\n ? `<div class=\"runtime-error\">${escapeHtml(active.error)}</div>`\n : ''\n }\n ${renderRuntimeLogs(active)}\n </div>\n <div class=\"action-row project-action-row ${active.kind === 'project' ? '' : 'compact-actions'}\">\n ${\n active.kind === 'project'\n ? `<button class=\"secondary-action project-session-action\" data-action=\"new-project-session\" data-runtime=\"${escapeAttr(active.id)}\">\n ${iconSvg('plus')}<span>${t('newSession')}</span>\n </button>`\n : ''\n }\n <button class=\"icon-tool-button\" title=\"${t('revealProjectFolder')}\" data-action=\"reveal-root\" data-runtime=\"${escapeAttr(active.id)}\">\n ${iconSvg('folder')}\n </button>\n <button class=\"icon-tool-button\" title=\"${t('openInBrowser')}\" data-action=\"open-browser\" data-runtime=\"${escapeAttr(active.id)}\">\n ${iconSvg('external')}\n </button>\n <button class=\"icon-tool-button\" title=\"${t('refresh')}\" data-action=\"reload-webui\" data-runtime=\"${escapeAttr(active.id)}\">\n ${iconSvg('refresh')}\n </button>\n </div>\n </section>\n `;\n}\n\nfunction renderWebuiStatus(active: DesktopRuntimeRecord): string {\n const status = effectiveWebuiStatus(active);\n const pending =\n webuiStatus.runtimeId === active.id && webuiStatus.pendingCommands\n ? ` · ${webuiStatus.pendingCommands} queued`\n : '';\n const prefs = renderWebuiPrefBadges(active);\n const label = status === 'ready' ? t('webuiReady') : status === 'loading' ? t('webuiLoading') : status === 'error' ? t('webuiError') : t('webuiIdle');\n return `\n <div class=\"webui-state\">\n <span class=\"status-dot status-${status === 'ready' ? 'running' : status === 'error' ? 'error' : status === 'loading' ? 'starting' : 'stopped'}\"></span>\n <span>${escapeHtml(`${label}${pending}${prefs}`)}</span>\n ${webuiStatus.error && webuiStatus.runtimeId === active.id ? `<span class=\"webui-error\">${escapeHtml(webuiStatus.error)}</span>` : ''}\n </div>\n `;\n}\n\nfunction renderWebuiPrefBadges(active: DesktopRuntimeRecord): string {\n if (webuiStatus.runtimeId !== active.id || !webuiStatus.prefs) return '';\n const labels: string[] = [];\n if (webuiStatus.prefs.yolo === true) labels.push(t('yolo'));\n if (webuiStatus.prefs.nextPrediction === true) labels.push(t('next'));\n if (webuiStatus.prefs.contextAutoCompact === true) labels.push(t('compact'));\n return labels.length > 0 ? ` · ${labels.join(' · ')}` : '';\n}\n\nfunction renderRuntimeLogs(active: DesktopRuntimeRecord): string {\n const logs = active.recentLogs?.filter((line) => line.trim()) ?? [];\n if (logs.length === 0) return '';\n return `\n <details class=\"runtime-log-details\" ${active.status === 'error' ? 'open' : ''}>\n <summary>WebUI output <span>${logs.length}</span></summary>\n <pre>${logs.map(escapeHtml).join('\\n')}</pre>\n </details>\n `;\n}\n\nfunction renderLauncher(active: DesktopRuntimeRecord | undefined): string {\n const enabled = Boolean(\n active && active.status === 'running' && effectiveWebuiStatus(active) !== 'error',\n );\n const disabled = enabled ? '' : 'disabled';\n const yoloActive = Boolean(\n active && webuiStatus.runtimeId === active.id && webuiStatus.prefs?.yolo === true,\n );\n return `\n <section class=\"panel launcher-panel\">\n <header class=\"panel-header\">\n <span>${t('quick')}</span>\n <span class=\"count\">${enabled ? t('ready') : t('offline')}</span>\n </header>\n ${renderLauncherFeedback()}\n <div class=\"quick-action-grid\">\n ${[\n renderShortcut(t('chat'), 'message', { activity: 'chat', view: 'chat' }, disabled),\n renderShortcut(t('prompt'), 'cursor', { action: 'focus-chat' }, disabled),\n renderShortcut(t('terminal'), 'terminal', { terminal: true }, disabled),\n renderShortcut(t('newTerm'), 'plus', { terminal: 'new' }, disabled),\n renderShortcut(t('yolo'), 'shield', { pref: { key: 'yolo', toggle: true } }, disabled, yoloActive),\n ].join('')}\n </div>\n </section>\n `;\n}\n\nfunction renderProjectPicker(variant: ProjectPickerVariant): string {\n const allProjects = dedupeProjects([...state.recentProjects, ...state.registeredProjects]);\n const recentProjects = dedupeProjects(state.recentProjects);\n const registeredProjects = dedupeProjects(state.registeredProjects);\n const tabProjects =\n projectPickerTab === 'recent'\n ? recentProjects\n : projectPickerTab === 'registered'\n ? registeredProjects\n : allProjects;\n const query = projectSearch.trim();\n const filteredProjects = query\n ? tabProjects.filter((project) => projectMatchesSearch(project, query))\n : tabProjects;\n const limit = variant === 'dock' ? 8 : variant === 'embedded' ? 18 : 48;\n const visibleProjects = filteredProjects.slice(0, limit);\n const visibleTotal = visibleProjects.length;\n const filteredTotal = filteredProjects.length;\n const total = allProjects.length;\n return `\n <section class=\"panel projects-panel projects-panel-${variant}\">\n <header class=\"panel-header projects-header\">\n <span>${t('projects')}</span>\n <span class=\"panel-header-actions\">\n <span class=\"count\">${visibleTotal}/${filteredTotal || total}</span>\n <button class=\"panel-header-button\" title=\"${t('registerProjectFolder')}\" data-action=\"register-project\" ${busy ? 'disabled' : ''}>\n ${iconSvg('folder-plus')}\n </button>\n </span>\n </header>\n <div class=\"project-picker\">\n ${renderProjectTabs(recentProjects.length, registeredProjects.length, allProjects.length)}\n <div class=\"project-search-row\">\n ${iconSvg('search')}\n <input\n class=\"project-search-input\"\n type=\"search\"\n value=\"${escapeAttr(projectSearch)}\"\n placeholder=\"${t('findProject')}\"\n aria-label=\"${t('findProject')}\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n ${\n projectSearch\n ? `<button class=\"project-search-clear\" title=\"${t('clearProjectSearch')}\" data-action=\"clear-project-search\">${iconSvg('x')}</button>`\n : ''\n }\n </div>\n ${\n variant === 'full' || variant === 'embedded'\n ? `<div class=\"project-picker-actions\">\n <button class=\"secondary-action compact-action\" data-action=\"open-project\" ${busy ? 'disabled' : ''}>\n ${iconSvg('folder')}<span>${t('open')}</span>\n </button>\n <button class=\"secondary-action compact-action\" data-action=\"register-project\" ${busy ? 'disabled' : ''}>\n ${iconSvg('folder-plus')}<span>${t('register')}</span>\n </button>\n </div>`\n : ''\n }\n ${\n visibleProjects.length === 0\n ? `<div class=\"empty compact-empty\">${total === 0 ? t('noRegisteredProjects') : t('noMatchingProjects')}</div>`\n : `<div class=\"project-list\">${visibleProjects.map(renderProjectItem).join('')}</div>`\n }\n </div>\n </section>\n `;\n}\n\nfunction renderProjectTabs(recentCount: number, registeredCount: number, allCount: number): string {\n return `\n <div class=\"project-tabs\" role=\"tablist\" aria-label=\"${t('projectLists')}\">\n ${renderProjectTab('recent', t('recent'), recentCount)}\n ${renderProjectTab('registered', t('registered'), registeredCount)}\n ${renderProjectTab('all', t('all'), allCount)}\n </div>\n `;\n}\n\nfunction renderProjectTab(tab: ProjectPickerTab, label: string, count: number): string {\n const active = projectPickerTab === tab;\n return `\n <button\n class=\"project-tab ${active ? 'active' : ''}\"\n data-action=\"set-project-tab\"\n data-project-tab=\"${escapeAttr(tab)}\"\n role=\"tab\"\n aria-selected=\"${active ? 'true' : 'false'}\"\n >\n <span>${escapeHtml(label)}</span>\n <span>${count}</span>\n </button>\n `;\n}\n\nfunction renderProjectItem(project: DesktopProjectEntry): string {\n const openRuntime = state.runtimes.find((runtime) => sameProjectRoot(runtime.root, project.root));\n const title = project.name || basenameFromPath(project.root) || project.root;\n const subtitle = project.lastWorkingDir || project.root;\n return `\n <div class=\"project-item-row ${openRuntime ? 'open' : ''}\">\n <button\n class=\"project-item-main\"\n data-action=\"${openRuntime ? 'activate' : 'open-project-path'}\"\n ${openRuntime ? `data-runtime=\"${escapeAttr(openRuntime.id)}\"` : `data-project-root=\"${escapeAttr(project.root)}\"`}\n title=\"${escapeAttr(project.root)}\"\n >\n ${iconSvg(openRuntime ? 'project' : 'folder')}\n <span class=\"project-item-copy\">\n <span class=\"project-item-title\">${escapeHtml(title)}</span>\n <span class=\"project-item-path\">${escapeHtml(subtitle)}</span>\n </span>\n ${openRuntime ? `<span class=\"project-open-dot\" title=\"${t('open')}\"></span>` : ''}\n </button>\n <button\n class=\"project-remove-button\"\n data-action=\"unregister-project\"\n data-project-root=\"${escapeAttr(project.root)}\"\n title=\"${t('removeFromRegistry')}\"\n aria-label=\"${t('removeFromRegistry')}\"\n >\n ${iconSvg('x')}\n </button>\n </div>\n `;\n}\n\nfunction projectMatchesSearch(project: DesktopProjectEntry, query: string): boolean {\n const haystack = [\n project.name,\n project.root,\n project.slug,\n project.lastWorkingDir,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n return haystack.includes(query.toLowerCase());\n}\n\nfunction renderLauncherFeedback(): string {\n if (!launcherFeedback) return '';\n const icon =\n launcherFeedback.state === 'success'\n ? 'check'\n : launcherFeedback.state === 'error'\n ? 'x'\n : 'pulse';\n const text =\n launcherFeedback.message ??\n (launcherFeedback.state === 'pending'\n ? `Opening ${launcherFeedback.label}...`\n : launcherFeedback.state === 'success'\n ? `${launcherFeedback.label} opened`\n : `${launcherFeedback.label} failed`);\n return `\n <div class=\"launcher-feedback ${launcherFeedback.state}\" role=\"status\">\n ${iconSvg(icon)}\n <span>${escapeHtml(text)}</span>\n </div>\n `;\n}\n\nfunction effectiveWebuiStatus(active: DesktopRuntimeRecord): DesktopWebuiStatusSnapshot['status'] {\n if (webuiStatus.runtimeId === active.id) return webuiStatus.status;\n return active.status === 'running' ? 'loading' : 'idle';\n}\n\nfunction renderShortcut(\n label: string,\n icon: IconName,\n command: DesktopWebuiCommand,\n disabled: string,\n active = false,\n): string {\n const commandKey = launcherCommandKey(command);\n const pending = launcherFeedback?.state === 'pending' && launcherFeedback.commandKey === commandKey;\n const disabledAttr = disabled || pending ? 'disabled' : '';\n return `\n <button\n class=\"shortcut-button ${active ? 'active-shortcut' : ''} ${pending ? 'pending-shortcut' : ''}\"\n data-action=\"webui-command\"\n data-command=\"${escapeAttr(commandKey)}\"\n data-label=\"${escapeAttr(label)}\"\n title=\"${escapeAttr(label)}\"\n aria-pressed=\"${active ? 'true' : 'false'}\"\n aria-busy=\"${pending ? 'true' : 'false'}\"\n ${disabledAttr}\n >\n ${iconSvg(icon)}<span>${escapeHtml(label)}</span>\n </button>\n `;\n}\n\nfunction renderRuntimeList(): string {\n const groups = groupRuntimesByProject(state.runtimes);\n return `\n <section class=\"panel runtime-panel\">\n <header class=\"panel-header\">\n <span>${t('runtimes')}</span>\n <span class=\"count\">${groups.length}/${state.runtimes.length}</span>\n </header>\n <div class=\"runtime-list\">\n ${\n state.runtimes.length === 0\n ? `<div class=\"empty\">${t('none')}</div>`\n : groups.map(renderRuntimeGroup).join('')\n }\n </div>\n </section>\n `;\n}\n\nfunction renderProjectSessionTree(): string {\n const groups = groupRuntimesByProject(state.runtimes).filter((group) => group.kind === 'project');\n return `\n <section class=\"panel runtime-panel project-sessions-panel\">\n <header class=\"panel-header\">\n <span>${t('sessions')}</span>\n <span class=\"count\">${groups.length}/${groups.reduce((sum, group) => sum + group.sessions.length, 0)}</span>\n </header>\n <div class=\"runtime-list project-session-tree\">\n ${\n groups.length === 0\n ? `<div class=\"empty compact-empty\">${state.restoring ? `${t('restoring')}...` : t('noOpenProjectSessions')}</div>`\n : groups.map(renderRuntimeGroup).join('')\n }\n </div>\n </section>\n `;\n}\n\nfunction groupRuntimesByProject(runtimes: DesktopRuntimeRecord[]): RuntimeProjectGroup[] {\n const groups = new Map<string, RuntimeProjectGroup>();\n for (const runtime of runtimes) {\n const key = runtimeProjectKey(runtime);\n const existing = groups.get(key);\n if (existing) {\n existing.sessions.push(runtime);\n continue;\n }\n groups.set(key, {\n key,\n name: runtime.kind === 'global-settings' ? t('globalSettings') : basenameFromPath(runtime.root) || runtime.name,\n root: runtime.root,\n kind: runtime.kind,\n sessions: [runtime],\n });\n }\n return [...groups.values()];\n}\n\nfunction runtimeProjectKey(runtime: DesktopRuntimeRecord): string {\n if (runtime.kind === 'global-settings') return 'global-settings';\n return `${runtime.kind}:${normalizeRuntimeRoot(runtime.root) || runtime.id}`;\n}\n\nfunction normalizeRuntimeRoot(root: string): string {\n return root.replace(/\\\\/g, '/').replace(/\\/+$/g, '').trim().toLowerCase();\n}\n\nfunction sameProjectRoot(left: string, right: string): boolean {\n return normalizeRuntimeRoot(left) === normalizeRuntimeRoot(right);\n}\n\nfunction dedupeProjects(projects: DesktopProjectEntry[]): DesktopProjectEntry[] {\n const seen = new Set<string>();\n const next: DesktopProjectEntry[] = [];\n for (const project of projects) {\n const key = normalizeRuntimeRoot(project.root);\n if (!key || seen.has(key)) continue;\n seen.add(key);\n next.push(project);\n }\n return next;\n}\n\nfunction basenameFromPath(root: string): string {\n const normalized = root.replace(/\\\\/g, '/').replace(/\\/+$/g, '').trim();\n if (!normalized) return root;\n return normalized.split('/').filter(Boolean).pop() ?? normalized;\n}\n\nfunction renderRuntimeGroup(group: RuntimeProjectGroup): string {\n const active = group.sessions.some((runtime) => runtime.id === state.activeRuntimeId);\n const firstSession = group.sessions[0];\n const open = runtimeGroupIsOpen(group);\n const sessionLabel = group.sessions.length === 1 ? '1 session' : `${group.sessions.length} sessions`;\n return `\n <div class=\"runtime-project-group ${active ? 'active' : ''} ${open ? 'open' : 'collapsed'}\" data-runtime-group=\"${escapeAttr(group.key)}\">\n <div class=\"runtime-project-header\">\n <button\n class=\"runtime-project-toggle\"\n data-action=\"toggle-runtime-group\"\n data-runtime-group-key=\"${escapeAttr(group.key)}\"\n aria-expanded=\"${open ? 'true' : 'false'}\"\n title=\"${escapeAttr(group.root)}\"\n >\n <span class=\"runtime-chevron\">${iconSvg('chevron')}</span>\n ${iconSvg(group.kind === 'global-settings' ? 'settings' : 'folder')}\n <span class=\"runtime-project-copy\">\n <span class=\"runtime-name\">${escapeHtml(group.name)}</span>\n <span class=\"runtime-path\">${escapeHtml(group.root)}</span>\n </span>\n ${renderRuntimeGroupStatus(group)}\n <span class=\"runtime-session-count\">${escapeHtml(sessionLabel)}</span>\n </button>\n ${\n group.kind === 'project' && firstSession\n ? `<button class=\"icon-button runtime-add-session\" title=\"${t('newSession')}\" data-action=\"new-project-session\" data-runtime=\"${escapeAttr(firstSession.id)}\">\n ${iconSvg('plus')}\n </button>`\n : ''\n }\n </div>\n ${\n open\n ? `<div class=\"runtime-session-list\">\n ${group.sessions.map((runtime, index) => renderRuntimeSession(runtime, index + 1)).join('')}\n </div>`\n : ''\n }\n </div>\n `;\n}\n\nfunction runtimeGroupIsOpen(group: RuntimeProjectGroup): boolean {\n if (group.sessions.some((runtime) => runtime.id === state.activeRuntimeId)) return true;\n const stored = runtimeGroupState[group.key];\n if (typeof stored === 'boolean') return stored;\n return state.runtimes.length === group.sessions.length;\n}\n\nfunction renderRuntimeGroupStatus(group: RuntimeProjectGroup): string {\n const statuses: DesktopRuntimeRecord['status'][] = ['error', 'starting', 'running', 'stopped'];\n const activeStatuses = statuses.filter((status) =>\n group.sessions.some((runtime) => runtime.status === status),\n );\n return `\n <span class=\"runtime-status-stack\" aria-hidden=\"true\">\n ${activeStatuses\n .map((status) => `<span class=\"status-dot status-${escapeAttr(status)}\"></span>`)\n .join('')}\n </span>\n `;\n}\n\nfunction renderRuntimeSession(runtime: DesktopRuntimeRecord, index: number): string {\n const isActive = runtime.id === state.activeRuntimeId;\n const label = runtime.kind === 'global-settings' ? t('settings') : `Session ${index}`;\n const meta = runtime.status === 'error'\n ? runtime.error ?? t('error')\n : `HTTP ${runtime.httpPort} · WS ${runtime.wsPort}`;\n const disabled = runtime.status === 'running' ? '' : 'disabled';\n return `\n <div class=\"runtime-session-row ${isActive ? 'active' : ''}\">\n <button class=\"runtime-session-main\" data-action=\"activate\" data-runtime=\"${escapeAttr(runtime.id)}\" title=\"${escapeAttr(runtime.root)}\">\n <span class=\"status-dot status-${runtime.status}\"></span>\n <span class=\"runtime-session-copy\">\n <span class=\"runtime-session-title\">${escapeHtml(label)}</span>\n <span class=\"runtime-session-meta\">${escapeHtml(meta)}</span>\n </span>\n </button>\n <div class=\"runtime-session-actions\" aria-label=\"${escapeAttr(label)} actions\">\n <button class=\"runtime-session-action primary\" title=\"${t('quickView')}\" data-action=\"activate\" data-runtime=\"${escapeAttr(runtime.id)}\">\n ${iconSvg('monitor')}<span>${t('quick')}</span>\n </button>\n <button class=\"runtime-session-action\" title=\"${t('openChat')}\" data-action=\"session-webui-command\" data-runtime=\"${escapeAttr(runtime.id)}\" data-command=\"${escapeAttr(launcherCommandKey({ activity: 'chat', view: 'chat' }))}\" data-label=\"Chat\" ${disabled}>\n ${iconSvg('message')}<span>${t('chat')}</span>\n </button>\n <button class=\"runtime-session-action\" title=\"${t('openTerminal')}\" data-action=\"session-webui-command\" data-runtime=\"${escapeAttr(runtime.id)}\" data-command=\"${escapeAttr(launcherCommandKey({ terminal: 'toggle' }))}\" data-label=\"Terminal\" ${disabled}>\n ${iconSvg('terminal')}<span>${t('term')}</span>\n </button>\n <button class=\"runtime-session-action\" title=\"${t('openFiles')}\" data-action=\"session-webui-command\" data-runtime=\"${escapeAttr(runtime.id)}\" data-command=\"${escapeAttr(launcherCommandKey({ activity: 'files', view: 'files' }))}\" data-label=\"Files\" ${disabled}>\n ${iconSvg('files')}<span>${t('files')}</span>\n </button>\n <button class=\"runtime-session-icon\" title=\"${t('openInBrowser')}\" data-action=\"open-browser\" data-runtime=\"${escapeAttr(runtime.id)}\" ${disabled}>\n ${iconSvg('external')}\n </button>\n <button class=\"runtime-session-icon\" title=\"${t('refresh')}\" data-action=\"session-reload-webui\" data-runtime=\"${escapeAttr(runtime.id)}\" ${disabled}>\n ${iconSvg('refresh')}\n </button>\n <button class=\"runtime-session-icon danger\" title=\"${t('closeSession')}\" data-action=\"close\" data-runtime=\"${escapeAttr(runtime.id)}\">\n ${iconSvg('x')}\n </button>\n </div>\n </div>\n `;\n}\n\nfunction renderStage(active: DesktopRuntimeRecord | undefined): string {\n if (active?.status === 'running') {\n return '<div class=\"mount-shadow\"></div>';\n }\n if (active?.status === 'starting') {\n return `\n <section class=\"stage-card\">\n <div class=\"stage-kicker\">${t('starting')}</div>\n <h1>${escapeHtml(active.name)}</h1>\n <div class=\"stage-path\">${escapeHtml(active.root)}</div>\n </section>\n `;\n }\n if (active?.status === 'error') {\n return `\n <section class=\"stage-card error-card\">\n <div class=\"stage-kicker\">${t('runtimeError')}</div>\n <h1>${escapeHtml(active.name)}</h1>\n <pre>${escapeHtml(active.error ?? t('unknownError'))}</pre>\n ${renderRuntimeLogs(active)}\n </section>\n `;\n }\n return `\n <section class=\"stage-card\">\n <div class=\"stage-kicker\">WrongStack Desktop</div>\n <h1>${state.restoring ? t('restoring') : t('openProject')}</h1>\n <div class=\"stage-actions\">\n <button class=\"primary-action inline\" data-action=\"open-project\" ${busy ? 'disabled' : ''}>\n ${iconSvg('folder-plus')}<span>${t('openProject')}</span>\n </button>\n <button class=\"secondary-action inline\" data-action=\"register-project\" ${busy ? 'disabled' : ''}>\n ${iconSvg('folder')}<span>${t('register')}</span>\n </button>\n <button class=\"secondary-action inline\" data-action=\"open-settings\" ${busy ? 'disabled' : ''}>\n ${iconSvg('settings')}<span>${t('settings')}</span>\n </button>\n </div>\n </section>\n `;\n}\n\nfunction runtimeStatusLabel(runtime: DesktopRuntimeRecord): string {\n if (runtime.status === 'starting') return t('starting');\n if (runtime.status === 'running') return t('running');\n if (runtime.status === 'error') return t('error');\n return t('stopped');\n}\n\nasync function refresh(): Promise<void> {\n const [nextState, nextWebuiStatus] = await Promise.all([\n window.wrongstackDesktop.getState(),\n window.wrongstackDesktop.getWebuiStatus(),\n ]);\n state = nextState;\n webuiStatus = nextWebuiStatus;\n render();\n}\n\nasync function withBusy(fn: () => Promise<void>): Promise<void> {\n if (busy) return;\n busy = true;\n shellError = null;\n render();\n try {\n await fn();\n } catch (err) {\n shellError = toErrorMessage(err);\n console.error(err);\n } finally {\n busy = false;\n render();\n }\n}\n\nwindow.addEventListener('keydown', (event) => {\n const mod = event.ctrlKey || event.metaKey;\n if (mod && event.key.toLowerCase() === 'k') {\n event.preventDefault();\n void window.wrongstackDesktop.navigateWebui({ action: 'open-command-palette' });\n }\n});\n\nappRoot.addEventListener('input', (event) => {\n const target = event.target as HTMLInputElement | null;\n if (!target?.classList.contains('project-search-input')) return;\n const cursor = target.selectionStart ?? target.value.length;\n projectSearch = target.value;\n render();\n focusProjectSearch(cursor);\n});\n\n// Language picker (a <select>, so it fires `change`). setLocale updates the\n// renderer chrome instantly + pushes to main, which persists it to the shared\n// config so every other surface (webui, menu) follows.\nappRoot.addEventListener('change', (event) => {\n const target = event.target as HTMLSelectElement | null;\n if (target?.dataset.action !== 'set-locale') return;\n const match = SUPPORTED_LOCALES.find((c) => c === target.value);\n if (match && match !== getLocale()) {\n setLocale(match);\n render();\n }\n});\n\nappRoot.addEventListener('click', (event) => {\n const target = event.target as HTMLElement | null;\n const actionTarget = target?.closest<HTMLElement>('[data-action]');\n if (!actionTarget) return;\n const action = actionTarget.dataset.action;\n const runtimeId = actionTarget.dataset.runtime;\n\n if (action === 'webui-command') {\n const raw = actionTarget.dataset.command;\n if (!raw) return;\n const label = actionTarget.dataset.label ?? t('command');\n const commandKey = raw;\n try {\n const command = JSON.parse(raw) as DesktopWebuiCommand;\n setLauncherFeedback({\n state: 'pending',\n label,\n commandKey,\n });\n void window.wrongstackDesktop\n .navigateWebui(command)\n .then((ok) => {\n if (ok) {\n setLauncherFeedback({\n state: 'success',\n label,\n commandKey,\n });\n return;\n }\n const message = t('launcherError');\n shellError = message;\n setLauncherFeedback({\n state: 'error',\n label,\n commandKey,\n message,\n });\n });\n } catch {\n /* malformed DOM data should not break the shell */\n }\n return;\n }\n\n if (action === 'session-webui-command') {\n if (!runtimeId) return;\n const raw = actionTarget.dataset.command;\n if (!raw) return;\n const label = actionTarget.dataset.label ?? 'WebUI';\n const commandKey = raw;\n try {\n const command = JSON.parse(raw) as DesktopWebuiCommand;\n setLauncherFeedback({\n state: 'pending',\n label,\n commandKey: `${runtimeId}:${commandKey}`,\n });\n void withBusy(async () => {\n state = await window.wrongstackDesktop.activateRuntime(runtimeId);\n const ok = await window.wrongstackDesktop.navigateWebui(command);\n if (ok) {\n setLauncherFeedback({\n state: 'success',\n label,\n commandKey: `${runtimeId}:${commandKey}`,\n });\n return;\n }\n const message = t('sessionLauncherError');\n shellError = message;\n setLauncherFeedback({\n state: 'error',\n label,\n commandKey: `${runtimeId}:${commandKey}`,\n message,\n });\n });\n } catch {\n /* malformed DOM data should not break the shell */\n }\n return;\n }\n\n if (action === 'clear-error') {\n shellError = null;\n render();\n return;\n }\n\n if (action === 'clear-project-search') {\n projectSearch = '';\n render();\n focusProjectSearch(0);\n return;\n }\n\n if (action === 'toggle-shell-sidebar') {\n shellSidebarCollapsed = !shellSidebarCollapsed;\n writeShellSidebarCollapsed();\n void window.wrongstackDesktop.setShellSidebarCollapsed(shellSidebarCollapsed);\n render();\n return;\n }\n\n if (action === 'select-desktop-panel') {\n const panel = parseDesktopPanel(actionTarget.dataset.panel);\n if (!panel) return;\n desktopPanel = panel;\n writeDesktopPanel();\n render();\n return;\n }\n\n if (action === 'set-project-tab') {\n const tab = parseProjectPickerTab(actionTarget.dataset.projectTab);\n if (!tab) return;\n projectPickerTab = tab;\n writeProjectPickerTab();\n render();\n return;\n }\n\n if (action === 'toggle-runtime-group') {\n const key = actionTarget.dataset.runtimeGroupKey;\n if (!key) return;\n const group = groupRuntimesByProject(state.runtimes).find((item) => item.key === key);\n if (!group) return;\n runtimeGroupState = { ...runtimeGroupState, [key]: !runtimeGroupIsOpen(group) };\n writeRuntimeGroupState();\n render();\n return;\n }\n\n void withBusy(async () => {\n if (action === 'open-project') {\n state = await window.wrongstackDesktop.openProject();\n } else if (action === 'register-project') {\n state = await window.wrongstackDesktop.registerProject();\n } else if (action === 'open-project-path') {\n const root = actionTarget.dataset.projectRoot;\n if (root) state = await window.wrongstackDesktop.openProject(root);\n } else if (action === 'unregister-project') {\n const root = actionTarget.dataset.projectRoot;\n if (root) state = await window.wrongstackDesktop.unregisterProject(root);\n } else if (action === 'new-project-session') {\n state = await window.wrongstackDesktop.openProjectSession(runtimeId);\n } else if (action === 'open-settings') {\n state = await window.wrongstackDesktop.openSettings();\n } else if (action === 'activate' && runtimeId) {\n state = await window.wrongstackDesktop.activateRuntime(runtimeId);\n } else if (action === 'close' && runtimeId) {\n state = await window.wrongstackDesktop.closeRuntime(runtimeId);\n } else if (action === 'open-browser' && runtimeId) {\n await window.wrongstackDesktop.openRuntimeInBrowser(runtimeId);\n } else if (action === 'reveal-root' && runtimeId) {\n await window.wrongstackDesktop.revealRuntimeRoot(runtimeId);\n } else if (action === 'reload-webui' && runtimeId) {\n await window.wrongstackDesktop.reloadWebui();\n } else if (action === 'session-reload-webui' && runtimeId) {\n state = await window.wrongstackDesktop.activateRuntime(runtimeId);\n await window.wrongstackDesktop.reloadWebui();\n }\n });\n});\n\nwindow.wrongstackDesktop.onStateChanged((next) => {\n state = next;\n render();\n});\n\nwindow.wrongstackDesktop.onWebuiStatusChanged((next) => {\n webuiStatus = next;\n render();\n});\n\nwindow.wrongstackDesktop.onShellSidebarCollapsedChanged((collapsed) => {\n shellSidebarCollapsed = collapsed;\n writeShellSidebarCollapsed();\n render();\n});\n\n// Re-render whenever the locale changes — user picker OR a config push from\n// main (another surface changed the shared language).\nonLocaleChange(() => render());\n\nvoid refresh();\nvoid window.wrongstackDesktop.setShellSidebarCollapsed(shellSidebarCollapsed);\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nfunction escapeAttr(value: string): string {\n return escapeHtml(value).replace(/'/g, ''');\n}\n\nfunction toErrorMessage(value: unknown): string {\n if (value instanceof Error) return value.message;\n if (typeof value === 'string') return value;\n return t('operationFailed');\n}\n\nfunction readRuntimeGroupState(): Record<string, boolean> {\n return readBooleanRecord(RUNTIME_GROUP_STORAGE_KEY);\n}\n\nfunction readShellSidebarCollapsed(): boolean {\n try {\n return window.localStorage.getItem(SHELL_SIDEBAR_STORAGE_KEY) === 'true';\n } catch {\n return false;\n }\n}\n\nfunction writeShellSidebarCollapsed(): void {\n try {\n window.localStorage.setItem(SHELL_SIDEBAR_STORAGE_KEY, String(shellSidebarCollapsed));\n } catch {\n /* best-effort UI preference */\n }\n}\n\nfunction readDesktopPanel(): DesktopPanel {\n return parseDesktopPanel(readLocalStorageValue(DESKTOP_PANEL_STORAGE_KEY)) ?? 'workspace';\n}\n\nfunction writeDesktopPanel(): void {\n try {\n window.localStorage.setItem(DESKTOP_PANEL_STORAGE_KEY, desktopPanel);\n } catch {\n /* best-effort UI preference */\n }\n}\n\nfunction readProjectPickerTab(): ProjectPickerTab {\n return parseProjectPickerTab(readLocalStorageValue(PROJECT_TAB_STORAGE_KEY)) ?? 'recent';\n}\n\nfunction writeProjectPickerTab(): void {\n try {\n window.localStorage.setItem(PROJECT_TAB_STORAGE_KEY, projectPickerTab);\n } catch {\n /* best-effort UI preference */\n }\n}\n\nfunction readLocalStorageValue(key: string): string | null {\n try {\n return window.localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction parseDesktopPanel(value: unknown): DesktopPanel | null {\n return value === 'workspace' || value === 'projects' || value === 'quick' ? value : null;\n}\n\nfunction parseProjectPickerTab(value: unknown): ProjectPickerTab | null {\n return value === 'recent' || value === 'registered' || value === 'all' ? value : null;\n}\n\nfunction readBooleanRecord(key: string): Record<string, boolean> {\n try {\n const raw = window.localStorage.getItem(key);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {};\n const next: Record<string, boolean> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value === 'boolean') next[key] = value;\n }\n return next;\n } catch {\n return {};\n }\n}\n\nfunction writeRuntimeGroupState(): void {\n writeBooleanRecord(RUNTIME_GROUP_STORAGE_KEY, runtimeGroupState);\n}\n\nfunction writeBooleanRecord(key: string, value: Record<string, boolean>): void {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* best-effort UI preference */\n }\n}\n\nfunction launcherCommandKey(command: DesktopWebuiCommand): string {\n return JSON.stringify(command);\n}\n\nfunction runtimeInitials(runtime: DesktopRuntimeRecord): string {\n const source = runtime.kind === 'global-settings' ? t('gs') : runtime.name || basenameFromPath(runtime.root);\n const words = source\n .replace(/[_-]+/g, ' ')\n .split(/\\s+/)\n .filter(Boolean);\n const initials =\n words.length >= 2 ? `${words[0]?.[0] ?? ''}${words[1]?.[0] ?? ''}` : source.slice(0, 2);\n return initials.toUpperCase();\n}\n\nfunction projectCountLabel(): string {\n return String(dedupeProjects([...state.recentProjects, ...state.registeredProjects]).length);\n}\n\nfunction setLauncherFeedback(next: Omit<LauncherFeedback, 'id'>): void {\n launcherFeedbackSeq += 1;\n const id = launcherFeedbackSeq;\n launcherFeedback = { id, ...next };\n render();\n if (next.state === 'pending') return;\n window.setTimeout(() => {\n if (launcherFeedback?.id !== id) return;\n launcherFeedback = null;\n render();\n }, next.state === 'success' ? 1_250 : 3_000);\n}\n\nfunction focusProjectSearch(cursor: number): void {\n window.requestAnimationFrame(() => {\n const input = document.querySelector<HTMLInputElement>('.project-search-input');\n if (!input) return;\n input.focus();\n const bounded = Math.max(0, Math.min(cursor, input.value.length));\n input.setSelectionRange(bounded, bounded);\n });\n}\n\nconst ICON_PATHS: Record<IconName, string> = {\n agents:\n '<path d=\"M16 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2\"></path><circle cx=\"9.5\" cy=\"7\" r=\"4\"></circle><path d=\"M22 21v-2a4 4 0 0 0-3-3.9\"></path><path d=\"M16 3.1a4 4 0 0 1 0 7.8\"></path>',\n branch:\n '<circle cx=\"6\" cy=\"6\" r=\"3\"></circle><circle cx=\"18\" cy=\"6\" r=\"3\"></circle><circle cx=\"18\" cy=\"18\" r=\"3\"></circle><path d=\"M9 6h6\"></path><path d=\"M18 9v6\"></path><path d=\"M6 9v3a6 6 0 0 0 6 6h3\"></path>',\n chart:\n '<path d=\"M3 3v18h18\"></path><rect x=\"7\" y=\"12\" width=\"3\" height=\"5\"></rect><rect x=\"12\" y=\"8\" width=\"3\" height=\"9\"></rect><rect x=\"17\" y=\"5\" width=\"3\" height=\"12\"></rect>',\n check: '<path d=\"M20 6L9 17l-5-5\"></path>',\n checklist:\n '<path d=\"M9 6h11\"></path><path d=\"M9 12h11\"></path><path d=\"M9 18h11\"></path><path d=\"M4 6l1 1 2-2\"></path><path d=\"M4 12l1 1 2-2\"></path><path d=\"M4 18l1 1 2-2\"></path>',\n chevron: '<path d=\"M9 18l6-6-6-6\"></path>',\n chip:\n '<rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"2\"></rect><path d=\"M4 9h3\"></path><path d=\"M4 15h3\"></path><path d=\"M17 9h3\"></path><path d=\"M17 15h3\"></path><path d=\"M9 4v3\"></path><path d=\"M15 4v3\"></path><path d=\"M9 17v3\"></path><path d=\"M15 17v3\"></path>',\n clock:\n '<circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 7v5l3 2\"></path>',\n command:\n '<path d=\"M7 7h.01\"></path><path d=\"M12 7h.01\"></path><path d=\"M17 7h.01\"></path><path d=\"M7 12h.01\"></path><path d=\"M12 12h.01\"></path><path d=\"M17 12h.01\"></path><path d=\"M7 17h.01\"></path><path d=\"M12 17h.01\"></path><path d=\"M17 17h.01\"></path>',\n collab:\n '<circle cx=\"8\" cy=\"8\" r=\"3\"></circle><circle cx=\"16\" cy=\"8\" r=\"3\"></circle><path d=\"M3 20a5 5 0 0 1 10 0\"></path><path d=\"M11 20a5 5 0 0 1 10 0\"></path>',\n compress:\n '<path d=\"M8 3v6H2\"></path><path d=\"M16 3v6h6\"></path><path d=\"M8 21v-6H2\"></path><path d=\"M16 21v-6h6\"></path>',\n cursor: '<path d=\"M4 4l9 17 2-7 7-2L4 4z\"></path>',\n debug:\n '<path d=\"M8 2h8\"></path><path d=\"M9 2v4\"></path><path d=\"M15 2v4\"></path><path d=\"M5 10h14\"></path><path d=\"M7 10v4a5 5 0 0 0 10 0v-4\"></path><path d=\"M3 14h4\"></path><path d=\"M17 14h4\"></path><path d=\"M4 20l3-3\"></path><path d=\"M20 20l-3-3\"></path>',\n document:\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><path d=\"M14 2v6h6\"></path><path d=\"M8 13h8\"></path><path d=\"M8 17h6\"></path>',\n download:\n '<path d=\"M12 3v12\"></path><path d=\"M7 10l5 5 5-5\"></path><path d=\"M5 21h14\"></path>',\n external:\n '<path d=\"M15 3h6v6\"></path><path d=\"M10 14L21 3\"></path><path d=\"M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5\"></path>',\n files:\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><path d=\"M14 2v6h6\"></path>',\n folder:\n '<path d=\"M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"></path>',\n 'folder-plus':\n '<path d=\"M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"></path><path d=\"M12 11v5\"></path><path d=\"M9.5 13.5h5\"></path>',\n git:\n '<path d=\"M7 7h10\"></path><path d=\"M7 12h10\"></path><path d=\"M7 17h10\"></path><path d=\"M4 7h.01\"></path><path d=\"M4 12h.01\"></path><path d=\"M4 17h.01\"></path>',\n gallery:\n '<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"></rect><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"></circle><path d=\"M21 15l-5-5L5 21\"></path>',\n history: '<path d=\"M3 12a9 9 0 1 0 3-6.7\"></path><path d=\"M3 4v6h6\"></path><path d=\"M12 7v5l3 2\"></path>',\n kanban:\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"></rect><path d=\"M9 4v16\"></path><path d=\"M15 4v16\"></path><path d=\"M6 8h.01\"></path><path d=\"M12 12h.01\"></path><path d=\"M18 9h.01\"></path>',\n keyboard:\n '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M7 9h.01\"></path><path d=\"M11 9h.01\"></path><path d=\"M15 9h.01\"></path><path d=\"M19 9h.01\"></path><path d=\"M7 13h.01\"></path><path d=\"M11 13h.01\"></path><path d=\"M15 13h.01\"></path><path d=\"M7 17h10\"></path>',\n list:\n '<path d=\"M8 6h13\"></path><path d=\"M8 12h13\"></path><path d=\"M8 18h13\"></path><path d=\"M3 6h.01\"></path><path d=\"M3 12h.01\"></path><path d=\"M3 18h.01\"></path>',\n mail:\n '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M3 7l9 6 9-6\"></path>',\n map:\n '<path d=\"M9 18l-6 3V6l6-3 6 3 6-3v15l-6 3-6-3z\"></path><path d=\"M9 3v15\"></path><path d=\"M15 6v15\"></path>',\n message: '<path d=\"M21 15a4 4 0 0 1-4 4H8l-5 3V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z\"></path>',\n monitor:\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M8 21h8\"></path><path d=\"M12 18v3\"></path><path d=\"M7 13l3-3 2 2 4-5 1 3\"></path>',\n phase:\n '<path d=\"M4 7h6\"></path><path d=\"M14 7h6\"></path><path d=\"M4 17h6\"></path><path d=\"M14 17h6\"></path><circle cx=\"12\" cy=\"7\" r=\"2\"></circle><circle cx=\"12\" cy=\"17\" r=\"2\"></circle><path d=\"M12 9v6\"></path>',\n plan:\n '<rect x=\"4\" y=\"3\" width=\"16\" height=\"18\" rx=\"2\"></rect><path d=\"M8 8h8\"></path><path d=\"M8 12h8\"></path><path d=\"M8 16h5\"></path>',\n plus: '<path d=\"M12 5v14\"></path><path d=\"M5 12h14\"></path>',\n project:\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"></rect><path d=\"M8 4v16\"></path><path d=\"M8 9h13\"></path>',\n pulse:\n '<path d=\"M3 12h4l2-6 4 12 2-6h6\"></path>',\n refresh:\n '<path d=\"M21 12a9 9 0 0 1-15.4 6.4\"></path><path d=\"M3 12A9 9 0 0 1 18.4 5.6\"></path><path d=\"M18 2v5h-5\"></path><path d=\"M6 22v-5h5\"></path>',\n search:\n '<circle cx=\"11\" cy=\"11\" r=\"7\"></circle><path d=\"M21 21l-4.3-4.3\"></path>',\n settings:\n '<path d=\"M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z\"></path><path d=\"M4 12a8 8 0 0 1 .2-1.8l-2-1.5 2-3.4 2.4 1a8 8 0 0 1 3-1.7L10 2h4l.4 2.6a8 8 0 0 1 3 1.7l2.4-1 2 3.4-2 1.5A8 8 0 0 1 20 12a8 8 0 0 1-.2 1.8l2 1.5-2 3.4-2.4-1a8 8 0 0 1-3 1.7L14 22h-4l-.4-2.6a8 8 0 0 1-3-1.7l-2.4 1-2-3.4 2-1.5A8 8 0 0 1 4 12z\"></path>',\n shield:\n '<path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"></path><path d=\"M9 12l2 2 4-5\"></path>',\n skill:\n '<path d=\"M12 2l2.5 6.5L21 11l-6.5 2.5L12 20l-2.5-6.5L3 11l6.5-2.5L12 2z\"></path>',\n spark:\n '<path d=\"M12 3l1.7 5.3L19 10l-5.3 1.7L12 17l-1.7-5.3L5 10l5.3-1.7L12 3z\"></path><path d=\"M19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8L19 16z\"></path>',\n target:\n '<circle cx=\"12\" cy=\"12\" r=\"9\"></circle><circle cx=\"12\" cy=\"12\" r=\"5\"></circle><circle cx=\"12\" cy=\"12\" r=\"1\"></circle>',\n tasks:\n '<path d=\"M4 6h2\"></path><path d=\"M4 12h2\"></path><path d=\"M4 18h2\"></path><path d=\"M10 6h10\"></path><path d=\"M10 12h10\"></path><path d=\"M10 18h10\"></path>',\n terminal: '<path d=\"M4 17l6-5-6-5\"></path><path d=\"M12 19h8\"></path>',\n wand:\n '<path d=\"M15 4l5 5\"></path><path d=\"M14 5l-9 9 5 5 9-9\"></path><path d=\"M5 3v4\"></path><path d=\"M3 5h4\"></path><path d=\"M19 17v4\"></path><path d=\"M17 19h4\"></path>',\n x: '<path d=\"M18 6L6 18\"></path><path d=\"M6 6l12 12\"></path>',\n};\n\nfunction iconSvg(name: IconName): string {\n return `<svg class=\"svg-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${ICON_PATHS[name]}</svg>`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>WrongStack Desktop</title>
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-Cq-Fc_6i.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BAP2wfHP.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="app"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wrongstack/desktop",
|
|
3
|
+
"version": "0.280.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "WrongStack Desktop - Electron shell for managing multiple local WrongStack runtimes.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"wrongstack",
|
|
8
|
+
"desktop",
|
|
9
|
+
"electron",
|
|
10
|
+
"ai",
|
|
11
|
+
"coding-agent"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/WrongStack/WrongStack.git",
|
|
16
|
+
"directory": "apps/desktop"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/WrongStack/WrongStack#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/WrongStack/WrongStack/issues"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/main/main.js",
|
|
24
|
+
"bin": {
|
|
25
|
+
"wrongstack-desktop": "./bin/wrongstack-desktop.js",
|
|
26
|
+
"wstack-desktop": "./bin/wrongstack-desktop.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"bin",
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"electron": "^43.0.0",
|
|
34
|
+
"ws": "^8.21.0",
|
|
35
|
+
"@wrongstack/webui": "0.280.0",
|
|
36
|
+
"@wrongstack/core": "0.280.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^26.0.1",
|
|
40
|
+
"@types/ws": "^8.18.1",
|
|
41
|
+
"tsup": "^8.5.1",
|
|
42
|
+
"typescript": "^6.0.3",
|
|
43
|
+
"vite": "^8.1.0"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "pnpm --filter @wrongstack/tools build && pnpm --filter @wrongstack/webui build && tsup && vite build",
|
|
50
|
+
"dev": "pnpm run build && electron .",
|
|
51
|
+
"start": "electron .",
|
|
52
|
+
"test": "vitest run --config vitest.config.ts",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|
|
55
|
+
}
|
|
56
|
+
}
|