# Rust Desk Light Feature

> Implement or modify rust-desk-light features in the repository's established style. Use when work touches the Admin GUI, Server routing, Client behavior, rdl_protocol messages or CommandKind values, remote-management windows, egui UI layout/theme, i18n strings, or end-to-end admin/server/client interactions. Use when this capability is needed.

- Skill: `tomevault-io/rust-desk-light-feature` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/rust-desk-light-feature`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/rust-desk-light-feature/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/rust-desk-light-feature

---


# Rust Desk Light Feature

## Start Here

Work from the existing architecture instead of inventing a parallel path.

- Read the nearby implementation before editing: protocol definitions, Admin event handling, Server routing, Client handling, and the closest UI window.
- Keep changes end-to-end. If a feature crosses Admin, Server, Client, and protocol, update all four in the same pass.
- Preserve user work in the dirty tree. Do not revert unrelated files.
- Prefer small, focused helpers and clear manual validation over broad refactors.
- Keep product/docs language neutral. Do not mention external reference projects in user-facing docs or roadmap entries.

## Code Organization

Choose the owning feature and layer before editing, then keep code close to that owner.

- Put feature-specific parsing, state, UI, workers, commands, and helpers in the feature's own module instead of growing broad generic files.
- Keep generic modules thin. They should coordinate flow, dispatch events, render common scaffolding, or expose truly reusable utilities; they should not accumulate feature-specific business logic.
- Split a feature into child modules when a file grows multiple actions, substantial parsing/rendering, long-running worker state, or several helper groups.
- When operating-system implementations differ beyond small labels or command arguments, use a small cross-platform facade plus OS-specific implementation modules. The facade owns common request parsing, result shape, and dispatch; OS modules own platform APIs, shell commands, fallbacks, and quirks.
- Keep platform-specific code out of unrelated platform branches. A short `cfg` dispatch is fine; substantial Windows, macOS, or Linux behavior belongs behind the feature's platform boundary.
- Promote helpers upward only after unrelated features need them. Otherwise keep helpers private and local to the feature.

## Repository Map

Use these files as anchors:

- `crates/protocol/src/lib.rs`: wire protocol, `PROTOCOL_VERSION`, `Role`, `CommandKind`, `Message`, binary encode/decode logic.
- `crates/server/src/main.rs`: peer registry, role checks, audit logs, routing between Admin and Client.
- `crates/client/src/app.rs`: client message loop and long-running stream workers.
- `crates/client/src/remote_management/`: client-side command implementations.
- `crates/admin/src/app.rs`: Admin state, event dispatch, window storage, command/event handling.
- `crates/admin/src/command_menu.rs`: client context menu commands.
- `crates/admin/src/remote_management/`: dedicated Admin tool windows.
- `crates/admin/src/app/command_result.rs`: shared result-table windows and row actions.
- `crates/admin/src/theme.rs`: colors, sizes, frames, tables, status bars.
- `crates/admin/src/i18n.rs`: `t`, `tf`, command titles, Chinese translations.

## Protocol And Routing

For ordinary request/response commands, follow the `Message::Command` pattern:

- Admin sends `Message::Command { target_id, command, payload }`.
- Server validates the sender role and routes by `target_id`.
- Client executes and replies with `CommandAck` and/or `CommandOutput`.
- Admin maps the returned `client_id`, `command`, and payload into the relevant window.

For interactive streams or bidirectional data, add explicit `Message` variants instead of overloading command output:

- Use `target_id` for Admin-to-Client open/control messages.
- Use `client_id` for Client-to-Admin result/data/close messages.
- Add a stable stream/session id when multiple streams can coexist.
- Server must role-check every direction, keep any required route map, remove routes on close/failure, and send a clear error/result back to Admin when routing fails.
- Client must clean up stream state on close, failed writer, failed reader, or disconnect.

When changing the wire protocol:

- Update `PROTOCOL_VERSION` if old binaries cannot safely understand the new messages.
- Add or update `Message::kind_code`, encoder, decoder, and manual roundtrip validation steps.
- If adding `CommandKind`, update `as_str`, `parse`, `to_code`, `from_code`, `requires_client_gui` if needed, Admin command titles, command menu, client execution, and manual validation steps.

## Admin Windows

Prefer the existing window shape:

- Store per-tool windows in `AdminApp`, render them from `window_dispatch`, and expose `open_window`, `render_windows`, `handle_*`, and `stop_all` style functions for standalone remote-management tools.
- Use `windowing::child_viewport_builder` and `ctx.show_viewport_immediate` for child tool windows.
- Use `Arc<Mutex<_>>` for shared mutable window state and `AtomicBool` request flags for buttons. Process the request flags after the UI closure to avoid egui borrow tangles.
- Do blocking socket, file, or process work on worker threads. Do not block egui rendering.
- Reserve space for status bars before allocating tables or scroll areas.
- For connection/session histories, cap closed historical rows and keep active rows visible.

## UI And Theme

Follow `crates/admin/src/theme.rs`; do not invent one-off dimensions or colors.

- Use `CONTROL_HEIGHT` (`28.0`) for normal controls.
- Use `COMPACT_CONTROL_HEIGHT` (`24.0`) for compact toolbars and table controls.
- Use `PANEL_MARGIN` (`8.0`) and `SECTION_GAP` (`6.0`) for panel spacing.
- Use `TABLE_HEADER_HEIGHT` and `TABLE_ROW_HEIGHT` for tables.
- Use `panel_frame_with_margin`, `page_frame`, `status_frame`, and `clickable_table`.
- Use `palette().text`, `palette().muted`, `COLOR_GOOD`, `COLOR_BAD`, and `COLOR_WARN`; avoid hardcoded ad hoc colors.
- Size action areas from text (`action_area_width`-style helpers) when labels can be translated.
- Reuse existing buttons, table styles, context-menu style, and status-line components.
- Keep operational UIs dense and utilitarian. Avoid landing-page/marketing patterns, decorative cards, nested cards, and oversized headings inside tool windows.
- Use icon/button text only when it matches local conventions. Do not add new visual language to one window.

For tables:

- Use `egui_extras::TableBuilder` through `crate::theme::clickable_table` unless a nearby window uses a different established table helper.
- Keep row/header height stable.
- Use sortable/filterable/cache behavior only when the existing window pattern supports it.
- Do not make rows clickable unless the click performs a visible action; avoid stale selection state.

## I18n

All user-facing text must go through `t()` or `tf()`.

- Use `t("Static Label")` for static labels.
- Use `tf("Message with {name}", &[("name", value)])` for dynamic text.
- Add every new key to `zh()` in `crates/admin/src/i18n.rs`.
- Prefer generic future-proof strings: `Settings saved.` instead of `Theme and language saved.` when the setting group may grow.
- Remove stale i18n keys when UI text is removed and no other code uses them.
- Keep command titles in `command_key`.

## OS-Specific Behavior

Use local OS conventions and manual verification helpers:

- Prefer `cfg!(target_os = "windows")`, `cfg!(target_os = "macos")`, or `std::env::consts::OS` for Admin-side OS-specific strings.
- For Client commands, mirror existing Windows/macOS/Linux branches in `crates/client/src/remote_management`.
- Keep Windows PowerShell/cmd syntax, macOS shell syntax, and Linux shell/systemd behavior distinct.
- When generating copyable terminal commands, produce a command that fits the Admin machine's OS unless the user asks for a remote/client OS command.

## Performance

Avoid unbounded UI and memory growth.

- Cap logs and closed/failed history rows; active sessions should remain visible.
- Separate active state maps from history queues when a feature can run for a long time.
- Avoid sorting/formatting large histories every frame unless the data changed.
- Throttle UI refresh for high-frequency streams.
- Keep binary data off text logs; log summaries or counters instead.

## Validation

Run the smallest relevant checks, then broaden when protocol or shared behavior changes. Temporary local tests are allowed for validation only.

- Always run `cargo fmt --all -- --check`.
- For Admin UI changes, run the relevant Admin build/check commands and manually exercise the changed window or workflow.
- For protocol changes, check all affected packages and manually verify the message flow or encoded payload shape.
- For Admin/Server/Client end-to-end changes, run:
  - `cargo check -p rust-desk-light-admin -p rust-desk-light-server -p rust-desk-light-client`
  - a manual end-to-end scenario covering the changed Admin, Server, and Client path
- Remove any temporary code tests, snapshot tests, or test-only helpers before finalizing, committing, or pushing. Put manual validation notes in the final answer instead.

## Final Checklist

Before finishing:

- Confirm no unused UI text, dead enum variants, stale test references, or stale roadmap wording remain.
- Confirm user-visible docs do not mention private/reference implementation names.
- Confirm the final answer says what changed and what validation passed.

---
> Source: [marlkiller/rust-desk-light](https://github.com/marlkiller/rust-desk-light) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-17 -->

