-
Notifications
You must be signed in to change notification settings - Fork 1
Architecture
Finnegan's Owner edited this page Feb 28, 2026
·
4 revisions
Launcher is a Tauri v2 desktop application with a Rust backend and a Nuxt 4 / Vue 3 frontend.
launcher/
├── app/ # Frontend (Nuxt 4)
│ ├── assets/css/main.css # Tailwind CSS v4 design tokens
│ ├── components/ # Vue components
│ │ ├── BriefServerInfo.vue # Server row in the list
│ │ ├── ConnectionInput.vue # Reusable form input
│ │ ├── InsertableDropdown.vue # Dropdown with inline creation
│ │ └── TrustCertModal.vue # Certificate trust dialog
│ ├── composables/ # Vue composables
│ │ ├── useConfirmRejectModal.ts # Imperative modal mounting
│ │ └── useZoom.ts # Keyboard zoom (Cmd/Ctrl +/-/0)
│ ├── pages/ # File-based routing
│ │ ├── index.vue # Main server list
│ │ ├── connections/[id].vue # Connection editor
│ │ └── settings.vue # Settings (placeholder)
│ └── types.d.ts # TypeScript interfaces
├── src-tauri/ # Backend (Rust)
│ ├── src/
│ │ ├── main.rs # Tauri commands and app setup
│ │ ├── connection.rs # ConnectionStore, persistence, cert trust
│ │ ├── webstart.rs # JNLP parsing, JAR downloading, Java process
│ │ ├── verify.rs # JAR signature verification (CMS/PKCS#7)
│ │ └── errors.rs # VerificationError types
│ ├── lib/java-console.jar # Bundled Java console
│ ├── capabilities/default.json # Tauri permission declarations
│ ├── Cargo.toml # Rust dependencies
│ └── tauri.conf.json # Tauri app configuration
└── nuxt.config.ts # Nuxt configuration
Commands are the IPC bridge between frontend and backend. They use rename_all = "snake_case", so the JavaScript side must use snake_case parameter names.
| Command | Returns | Description |
|---|---|---|
launch |
Result<String, String> |
Downloads JARs, verifies signatures, launches Java process |
save |
Result<String, String> |
Saves a connection entry |
delete |
Result<String, String> |
Deletes a connection |
import |
Result<String, String> |
Imports connections from a JSON file |
load_connections |
String |
Returns all connections as JSON array |
load_single_connection |
Result<Value, String> |
Returns one connection by ID |
get_default_connectionentry |
Result<Value, String> |
Returns a default connection template |
get_all_groups |
Result<Value, String> |
Returns all group names |
trust_cert |
Result<String, String> |
Adds a certificate to the trust store |
get_launcher_info |
String |
Returns app version info |
- Frontend calls
launchwith connection ID and a progressChannel - Backend downloads JNLP from server address
- Parses JNLP for JAR URLs and main class
- Downloads JARs (with progress updates via Channel)
- Optionally verifies JAR signatures (CMS/PKCS#7)
- If untrusted cert found, returns cert info to frontend for user approval
- Launches Java process with classpath and connection arguments
- Optionally pipes stdout to a Java console process
-
ConnectionStoremanages all connections in aMutex<HashMap<String, Arc<ConnectionEntry>>> - Persisted to
~/.launcher/launcher-data.json - Trusted certs persisted to
~/.launcher/launcher-trusted-certs.json - JAR cache stored in
~/.launcher/cache/
- TLS certificate validation is intentionally disabled (
danger_accept_invalid_certs) because integration engine servers commonly use self-signed certificates - JAR signature verification is the actual trust boundary — JARs are verified against CMS/PKCS#7 signatures before execution
- Users explicitly approve untrusted certificates through the trust dialog
Tailwind CSS v4 with @theme design tokens in app/assets/css/main.css:
| Token | Value | Usage |
|---|---|---|
surface-0 |
#24272e |
Page background |
surface-1 |
#2c2f37 |
Cards, inputs |
surface-2 |
#353840 |
Hover, selected states |
surface-3 |
#3e414a |
Highest elevation |
accent |
#4f7df7 |
Primary actions |
text-primary |
#e2e5eb |
Main text |
text-secondary |
#9ca3b0 |
Supporting text |
Icons use Phosphor Icons via the ph: prefix with the @nuxt/icon module.
-
Channel API:
launchusestauri::ipc::Channelfor streaming progress updates from Rust to the frontend -
Imperative modals:
useConfirmRejectModalmounts Vue components programmatically for the cert trust dialog, returning a Promise -
Module-level state:
useZoomuses a module-scopedreffor app-wide singleton zoom state
-
Rust: Prefer
?operator and.map_err()over.unwrap(). Return errors to frontend viaResult<T, String>. Use.expect("descriptive message")only for mutex locks (poisoning is unrecoverable). -
Frontend: Wrap
invokecalls in try/catch and display errors inline.