WappPackage and AppInfo both gain a version field. scan_installed_apps()
reads it from wapp.toml and includes it in InstalledApps responses.
system-ui.html shows it in the title tooltip as 'com.example.app v1.0.0'.
All roundtrip and integration tests updated.
ipc.rs: AppReady { session_id, app_id: String }.
runtime.rs: supervise() passes app_id (already in scope as parameter)
when building the AppReady broadcast message.
main.rs: supervisor integration test updated to use .. to ignore
app_id in the AppReady pattern match.
ipc.rs: LaunchAck gains app_id: String field so callers receive the
app identifier alongside the session handle in a single response.
main.rs: dispatch::LaunchApp constructs LaunchAck { session_id, app_id }
using the app_id that was already in scope.
Tests updated: dispatch_launch_returns_ack now asserts app_id value;
dispatch_terminate_known_returns_stopped and
dispatch_query_app_state_returns_starting use .. to ignore app_id.
ipc.rs:
- Add SessionInfo { session_id: u64, app_id: String } struct.
- Change RunningApps { session_ids: Vec<u64> } to
RunningApps { sessions: Vec<SessionInfo> } so callers can display
meaningful app names without a follow-up QueryAppState round-trip.
- Add session_info_roundtrip test.
main.rs:
- Add SessionEntry { app_id: String, state: AppStateKind } to store
app_id alongside state in SessionRegistry.
- launch() stores app_id in the entry.
- running_sessions() replaces running_ids(); returns Vec<SessionInfo>.
- state() reads from SessionEntry.state.
- set_state() writes to SessionEntry.state.
- QueryRunning dispatch uses running_sessions().
- Test registry_running_ids_reflects_live_sessions renamed to
registry_running_sessions_reflects_live_sessions and updated to
assert both session_id and app_id fields.
- dispatch_query_running test asserts app_id values are present.
system-ui.html:
- RUNNING_APPS handler uses msg.sessions[].{session_id,app_id}.
- ensureTaskbarEntry(sessionId, appId): shows the last component of the
reverse-domain app ID as the taskbar label; sets data-app-id attribute;
tooltip shows full app ID and session number.
- LAUNCH_ACK handler passes null for appId (session ID only available
at launch time; app_id arrives in RUNNING_APPS on reconnect).
Implements the weft-appd WebSocket server that allows the system-ui.html
page running inside Servo to send requests and receive push notifications
without requiring custom SpiderMonkey bindings.
ws.rs — WebSocket connection handler:
- Accepts a tokio TcpStream, performs WebSocket handshake via
tokio-tungstenite accept_async.
- Reads JSON Text frames, deserializes as Request (serde_json), calls
dispatch(), sends Response as JSON Text.
- Subscribes to a broadcast::Receiver<Response> for server-push
notifications (APP_READY, etc.); forwards to client via select!.
- Handles close frames, partial errors, and lagged broadcast gracefully.
main.rs — server changes:
- broadcast::channel(16) created at startup; WebSocket handlers
subscribe for push delivery.
- TcpListener bound on 127.0.0.1:7410 (default) or WEFT_APPD_WS_PORT.
- ws_port() / write_ws_port(): port written to
XDG_RUNTIME_DIR/weft/appd.wsport for runtime discovery.
- WS accept branch added to the main select! loop alongside Unix socket.
ipc.rs — Response and AppStateKind now derive Clone (required by
broadcast::Sender<Response>).
system-ui.html — appd WebSocket client:
- appdConnect(): opens ws://127.0.0.1:<port>/appd with exponential
backoff reconnect (1s → 16s max).
- On open: sends QUERY_RUNNING to populate taskbar with live sessions.
- handleAppdMessage(): maps LAUNCH_ACK and RUNNING_APPS to taskbar
entries; APP_READY shows a timed notification; APP_STATE::stopped
removes the taskbar entry.
- WEFT_APPD_WS_PORT window global overrides the default port.
New deps: tokio-tungstenite 0.24, futures-util 0.3 (sink+std),
serde_json 1.
ipc.rs tests (4 tests):
- request_msgpack_roundtrip: LaunchApp serializes and deserializes with
correct field values.
- response_msgpack_roundtrip: LaunchAck round-trips through MessagePack.
- frame_write_read_roundtrip: write_frame encodes a 4-byte LE length
header + body; read_frame decodes the framed request correctly.
- read_frame_eof_returns_none: empty stream returns None without error.
main.rs tests (5 tests):
- registry_launch_increments_id: each launch returns a strictly
increasing session ID.
- registry_terminate_known_session: terminate returns true and state
transitions to NotFound.
- registry_terminate_unknown_returns_false: terminate on missing ID
returns false.
- registry_running_ids_reflects_live_sessions: running_ids returns all
active sessions; terminated sessions are removed.
- registry_state_not_found_for_unknown: querying an unknown session ID
returns AppStateKind::NotFound.
Also extends scripts/wsl-test.sh to run weft-appd tests alongside
weft-compositor tests.