One-tap remote help from Critical Error Computing — a tiny, calm app a customer runs so a CEC technician can view and control their screen to fix things, like AnyDesk, but over a private peer-to-peer mesh with no central server holding a directory or the session, and with access the customer grants and can revoke at any time.
This repo is the customer-facing client (Windows-first). The remote-control
engine, the technician's app, and the shared CEC crates live in
AllMyStuff; the peer-to-peer substrate
is MyOwnMesh. See
ARCHITECTURE.md and docs/ for the full picture.
- Press for Help. The large, physical-looking headline button. One press
joins the Silent
cecsupport-askingroom; that membership is the raised hand a watching technician sees in their queue. Stopping the request leaves the room. No customer-to-customer or technician-to-technician connection is created just because the hand is raised. - Their support number. Shown too (9 digits, e.g.
123 456 789), with a copy button and "read this to your technician". It's derived from the device's key (allmystuff_cec_protocol::support_id_from_device) and serves as a display/verification label and a fallback: for a customer who'd rather read a number out, or for when the raised-hand queue is too crowded to pick them out, a technician can type the number and the node resolves it to this device on the area. It is not a mesh room. - One shared support area, Silent. On launch the app takes up residence
on the one well-known MyOwnMesh network every CEC node shares
(
HELP_NETWORK_ID=cecsupport-clients). The area is a Silent mesh: the customer is merely present in its signaling room — connected to nobody, connecting to nobody, gossiping nothing. Raising a hand joins a second Silent room (ASK_NETWORK_ID=cecsupport-asking) whose membership IS the technicians' queue; lowering it leaves. A technician's deliberate dial (the device id, straight from the queue or resolved from a read-out number) opens the one direct WebRTC session — CEC infrastructure carries signaling and, at worst, TURN-relayed ciphertext, never a routed session. It connects to a technician only when asked, and only after the customer approves. - Approve or deny. When a technician dials in, a modal appears:
"‹Agent Name› is trying to connect to your computer", with the 6-digit
verification code to check against what the technician reads out, and three
choices — Approve Once, Auto-Approve for 3 hours, Auto-Approve
Forever — plus Deny. The app brings its window to the foreground once
for each new request so the customer sees that a decision is waiting, but it
does not repeatedly steal focus. (These map to
ApprovalScope::Once/ThreeHours/Foreverinallmystuff-cec-consent.) - While connected, the "Who can connect to your computer" list carries the live state: each technician row shows a status dot (connected / connecting / not connected) and, while a session is active, a green "Viewing your screen" (or "Controlling your screen") chip that pulses gently next to the grant's countdown. Each row has one kill-switch — Forget — which disconnects any live session and revokes standing access in the same tap, immediately.
- Tabbed Settings. General holds the friendly computer name; Startup owns
the grant-scoped autostart policy (
while_granted,always, oroff) and background-window behavior; Updates shows the running and pinned versions of CEC Support, AllMyStuff Serve, MyOwnMesh Serve, AMSTerm, Crucible, and any installed service payload. Every row has its own Update or Repair action, so an older shared backend cannot hide behind a current GUI version. - Toolbox. A dedicated window collects safe Windows checks and familiar diagnostics. SFC, DISM, the online CHKDSK scan, and DNS flush run in visible administrator terminals with live progress while other tools remain usable. Windows tools open directly; Show Advanced reveals configuration-changing tools and the bundled Crucible Tests interactive hardware-test console.
It is customer-only. It never browses or dials anyone (that's the technician's AllMyStuff app) — no graph, no fleets, no file browser, no general-purpose remote terminal. Just: press for help, approve/deny, who's connected, revoke, maintenance tools, updates, and autostart.
The client is a thin shell over the AllMyStuff node engine, embedded in "CEC client (customer) mode" and driven over the node control socket — exactly how AllMyStuff's own GUI is a thin client of its node. It reuses three things from AllMyStuff (git dependencies):
allmystuff-node— the node engine + control socket.allmystuff-cec-protocol— the CEC wire contract,SupportId,HELP_NETWORK_ID(the shared support area),ApprovalScope.allmystuff-cec-consent— the three-choice consent store.
Plus its own OS-service installer, crates/cec-support-service (in this
repo), under its own service identity so installing the background service never
touches an AllMyStuff install on the same machine.
The client rides the same per-machine stack an AllMyStuff install runs —
one myownmesh daemon, one allmystuff-serve, shared control sockets, one
machine identity. It reuses a running node or brings the stack up itself, so it
works solo or side by side with AllMyStuff; per-session privacy comes from the
shared area being Silent and hub-mediated plus the customer's per-frame consent,
not from siloing the apps.
Native drive mapping follows that same split. The technician starts it from the remote-control console in AllMyStuff; the authorized customer node supplies or receives the selected folder through the shared node engine, and Windows mounts it as a real drive letter. CEC Support deliberately has no second drive browser or fake in-app mount surface: consent and connection state stay in this customer UI, while the actual mapping lives in the node and the technician's active console.
Clipboard and file-drop behavior follows the same versioned engine boundary: the technician's AllMyStuff console owns the interaction, and the customer's pinned AllMyStuff node receives the authenticated clipboard route. Text, images, copied files, and drag-to-remote transfer are available when both ends run an engine version that supports them; the Updates component table makes that prerequisite visible and can request the pinned node update in place.
The Toolbox is intentionally an allowlist, not a command prompt. The webview
sends a short action id; Rust maps it to one fixed command or Windows program.
Administrator repairs launch through the bundled amst.exe --admin --run path
in a real visible console, while a UTF-8 transcript streams back into the
Toolbox progress cards. Jobs have independent run ids and processes, so a long
SFC or DISM pass does not block Event Viewer, Device Manager, or another repair.
Crucible is bundled as its upstream portable archive, including PresentMon and
LibreHardwareMonitor. The release pins both its version and SHA-256; CEC Support
verifies the archive and materializes the complete runtime under
CEC_SUPPORT_HOME/tools/crucible/<version> before launching it elevated. The
Crucible row in Updates can repair that materialized payload without replacing
the whole app.
CEC Support installs like any other app: the customer downloads the installer
(setup.exe) from support.cec.direct and
double-clicks it. No terminal, no separate downloads, nothing to piece
together. The installer is the Tauri bundle (targets: all → NSIS setup.exe
.msi), and it ships theallmystuff-servenode and themyownmeshdaemon inside it as sidecars (externalBinintauri.conf.json) — one package with everything the client needs.
Reuse, don't clobber happens at runtime, not install time: when the client
comes up it reuses an already-installed AllMyStuff node/daemon if one is present
and new enough, and falls back to its own bundled copies otherwise. The release
build stages the pinned versions into the bundle — the versions pinned in
.myownmesh-rev / .allmystuff-rev, which match the tag = "…" git deps in
gui/src-tauri/Cargo.toml.
The CEC session lifecycle uses these commands on the node's control socket (a sibling agent implements them on the AllMyStuff node):
| Command | Args | Result |
|---|---|---|
cec_status |
{} |
{ number, network_id, role } |
cec_online |
{} |
{ number } (join the shared support area at bring-up) |
cec_ask_help |
{ on } |
— (raise / lower the hand on the area) |
cec_pending |
{} |
[{ tech, agent_name, want_control, session_id, verification_code }] |
cec_approve |
{ tech, scope, session_id, want_control } |
— (scope ∈ once|three_hours|forever) |
cec_deny |
{ tech, session_id } |
— |
cec_revoke |
{ tech } |
— |
cec_grants |
{} |
active grants |
cec_forget_node |
{ node } |
— |
cec_set_label |
{ label } |
— (friendly-name helper, beyond the core dial/approve contract) |
Events re-emitted onto the Tauri bus for the UI:
cec://request { tech, agent_name, want_control, session_id, verification_code }
(drives the modal), cec://session { session_id, state } (the access list's
live dot + "viewing your screen" chip), and cec://grants { grants } (the
access list).
The background service is handled by cec-support-service directly (not the
node), via the service_* Tauri commands.
Component reconciliation also uses the shared node contract: node_version
and mesh_status report what is actually running, while request_update
asks the existing AllMyStuff node to reach at least CEC Support's pin. That is
deliberately a request to the owning process rather than CEC Support silently
replacing another app's live backend.
CECSupport/
├── Justfile one-command ops (`just setup` / `dev` / `check` / `release`)
├── Cargo.toml light root workspace (service crate only)
├── crates/cec-support-service/ the client's OWN OS-service installer
├── gui/ Tauri + Svelte 5 client (its own workspace)
│ ├── package.json, vite.config.ts, tsconfig.json, svelte.config.js
│ ├── src/ App.svelte, tabbed Settings, Toolbox window, store, components
│ └── src-tauri/ Cargo.toml (pinned git deps), main.rs, tauri.conf.json
├── scripts/bump-version.sh version bump used by `just release`
├── .allmystuff-rev / .myownmesh-rev / .crucible-rev pinned bundled components
├── .github/workflows/ ci.yml (service crate + gui check) · release.yml (tag → Windows installer)
├── ARCHITECTURE.md · docs/ design + roadmap
The Justfile wraps all of this — the same recipe set as AllMyStuff, minus the
node-workspace bits it doesn't have. Install just and:
just setup # front-end deps (+ the Tauri prerequisites to install)
just dev # run the app with hot reload
just check # everything CI runs: fmt + clippy + test + gui typecheck/build
just release 0.2.0 # bump versions, commit, push, tagThe individual commands, if you'd rather not use just:
Frontend (this repo's hard validation):
cd gui
pnpm install
pnpm check # svelte-check — 0 errors
pnpm build # vite production build → gui/dist
pnpm dev # browser preview (degrades gracefully with a demo, no backend)Service crate (compiles and tests here):
cargo test # from the repo root — the cec-support-service crateThe full desktop app (gui/src-tauri) needs the AllMyStuff node engine +
CEC crates (git dependencies, now resolvable on published AllMyStuff tags) plus
the Tauri/media toolchain — so it does not build in this repo's headless
Linux sandbox, which lacks that toolchain. On a machine that has it:
cd gui && pnpm tauri dev # or: pnpm tauri buildThe single cec-support binary is both the app and its CLI:
cec-support # open the app (what a customer runs)
cec-support run --service # headless agent — what the OS service runs
cec-support service install # keep it connected across reboots
cec-support id # print this computer's support number
cec-support --version| Piece | Builds in this sandbox? | Why |
|---|---|---|
gui/ frontend (pnpm check/build) |
✅ yes | pure Svelte/TS |
crates/cec-support-service (cargo test) |
✅ yes | no webview/media deps |
gui/src-tauri (cargo build) |
❌ no | needs the heavy media/webview (Tauri) toolchain this headless Linux sandbox lacks |
MIT — see LICENSE.