← Commit history
SKILL.md+6−1
@@ -531,7 +531,9 @@ Fusion launches take 2-4 minutes cold; respect `timeoutSeconds` + `statusVerb` o Two generic CLI commands exist for launching any Windows executable safely — they verify the target exists BEFORE handing it to the OS, so you never trigger a "Windows cannot find" GUI dialog:
 
 - `adom-bridge find_exe '{"name":"..."}'` -- Resolve an exe by absolute path, glob (e.g. `C:/.../webdeploy/production/*/Fusion360.exe` returns newest), bare name (searches PATH + Start Menu `.lnk` targets). Returns `{path, source}`. Does NOT launch.
-- `adom-bridge launch '{"path":"...", "args":[...], "cwd":"...", "detached":true}'` -- Same resolution rules as `find_exe`, then spawns. Fails in terminal (exit 1) with a clear error if the path doesn't exist. **Always prefer this over raw `start`.**
+- `adom-bridge launch '{"path":"...", "args":[...], "cwd":"...", "detached":true, "reason":"..."}'` -- Same resolution rules as `find_exe`, then spawns. Fails in terminal (exit 1) with a clear error if the path doesn't exist. **Always prefer this over raw `start`.**
+
+**Where they run (2.1.143, wiki #210).** With `--target <box>`, or from a container / Linux CLI, both verbs run ON THAT BOX through its ab (mesh first, relay fallback, the same path as `shell_execute`): the path is resolved against the box's filesystem and the app starts there; the reply says `on: "<box>"`. Before 2.1.143 both ran inside the CLI process, so `--target arav-rog launch {path}` answered `find_exe: could not locate` for a file that existed on arav-rog. Only a Windows CLI with no `--target` still resolves and spawns locally. On a box `launch` is a Tier-2 exec verb like `launch_process` (gated the same way, `reason` required); `find_exe` is read-only. A target ab older than 2.1.143 answers unknown verb: use `launch_process {path, args}` there.
 
 For Fusion specifically, use `fusion_start` — it wraps `launch` plus the full startup-picker / add-in-readiness dance.
 - `fusion_import_step` -- Import a STEP/STL/IGES file into Fusion 360
@@ -1259,6 +1261,9 @@ If you don't have the suffix handy, just ask the user. Or if the file you wanted | `desktop_click` | `desktop_mouse_click` |
 | `desktop_double_click` | `desktop_mouse_double_click` |
 | `desktop_right_click` | `desktop_mouse_right_click` |
+| `desktop_mouse_drag` (2.1.143) | `desktop_drag` |
+
+**Drag (2.1.143, wiki #205).** `desktop_mouse_drag {from:{x,y}, to:{x,y}, steps?:12, durationMs?:300, button?:"left", space?:"screen"|"image"|"window", hwnd?|titleContains?, reason}` presses at `from`, moves the real cursor through `steps` interpolated points over `durationMs`, releases at `to`. It is for canvases with no view controls that only react to a drag: orbit a 3D preview (KiCad's Footprint Chooser pane), a splitter, a slider, a lasso. A canvas that tracks motion ignores a teleport, so the pointer really travels; slow canvases want `durationMs` 600+. With `hwnd`/`titleContains` ab raises that window, verifies it is under `from` before pressing (else `target_not_under_cursor`, nothing pressed), and gives the prior foreground back afterwards (`restoreForeground:false` keeps it up). `space:"image"` + `shotId` takes screenshot pixels; `space:"window"` takes window px or `{fx,fy}` fractions of the window rect. The reply lists the `points` actually sent. Same gate and same UIPI limit as `desktop_click`.
 
 An alias is gated exactly like the verb it aliases - it is not a way around the reason requirement below.
 
dist/linux/adom-bridge
⋯ 1 unchanged line ⋯
package.json+1−1
@@ -1,6 +1,6 @@ {
   "slug": "adom-bridge",
-  "version": "2.1.142",
+  "version": "2.1.143",
   "type": "app",
   "brief": "Adom Bridge unleashes your AI onto your full PC: full power, full safety. The AI breaks out of the container it runs in and onto your real machine, managing and running your entire laptop as you: launch apps, move files, drive any window, control KiCad, Fusion 360 or your real signed-in browser. Works with any AI, cloud or local (Claude Desktop, Claude Code, Codex), no Hydrogen required. Bridge and its bridges are an operating system for AI, with managed Node and Python runtimes, and a human-only permission system keeps you in charge of every side-effecting command.",
   "description": "Install this package in a cloud or Hydrogen Desktop container, not on the PC. It delivers two things: the Linux adom-bridge-cli (linked onto PATH) and the Claude skill set that teaches an AI every desktop verb (shell, files, screenshots, windows, notifications, KiCad, Fusion 360, browser automation). The CLI drives the Adom Bridge app running on your Windows PC over the relay; the Windows app itself is the separate installer in the Download box, not part of this package. Run adom-wiki pkg update to keep the CLI and skills current.",
page.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-bridge",-  "version": "2.1.142",+  "version": "2.1.143",   "type": "app",   "description": "Install this package in a cloud or Hydrogen Desktop container, not on the PC. It delivers two things: the Linux adom-bridge-cli (linked onto PATH) and the Claude skill set that teaches an AI every desktop verb (shell, files, screenshots, windows, notifications, KiCad, Fusion 360, browser automation). The CLI drives the Adom Bridge app running on your Windows PC over the relay; the Windows app itself is the separate installer in the Download box, not part of this package. Run adom-wiki pkg update to keep the CLI and skills current.",   "keywords": [
skills/adom-bridge-notify/SKILL.md+2−1
@@ -49,7 +49,8 @@ The click is recorded **durably** (a cross-process file), so both paths work eve A user with several Adom Bridges gets your toast on the box you address, and a copy on the others:
 
 - **No `--target`**: the toast goes to this relay's own box (from a container, the machine that hosts it). That box then MIRRORS a plain toast to every other box of the same account, shown there as `On <box>: <title>` (the receiver's Settings > Notifications > cross-box toasts, default `all`). A BUTTONED prompt (`buttons`, `wait:true`) is mirrored to every box regardless of that setting, and the human can answer it on any of them; the answer travels back to you.
-- **`--target <box>`**: addresses one box directly. With a local ab beside you (a Hydrogen container, a laptop), the CLI hands the call to it and it reaches the box over the mesh first, then the relays (2.1.142+). Without a local ab the call goes through the relay, which only knows the boxes connected to it.
+- **`--target <box>`**: addresses one box directly. With a local ab beside you (a Hydrogen container, a laptop), the CLI hands the call to it and it reaches the box over the mesh first, then the relays (2.1.142+). Without a local ab the call goes through the relay, which only knows the boxes connected to it. Naming the home box itself (`--target AdomLapper` from a container on AdomLapper) runs there directly (2.1.143).
+- **`shownOn`** (2.1.143, wiki #210): every `displayed` reply names the box the toast was shown on. Read it before telling the user "I toasted you": a toast on a box they are not looking at is not a notification. The CLI also stamps `deliveredOn` on a targeted send.
 - **`targets`** lists what is reachable from here and how (`via: relay | mesh`, `path`). `target_not_found` means this relay does not hold that box; it does NOT mean the box is offline, and it does not mean the user never saw your toast (the mirror may have shown it).
 
 So to reach the human where they sit: send a buttoned prompt with no target (it follows them), or `--target` the box `targets` names. Do not conclude "the bridge cannot toast the laptop" from a `target_not_found` on one relay; check `targets` and the mirror first.
skills/adom-bridge-verbs/SKILL.md+1−1
@@ -100,7 +100,7 @@ Every verb below runs via the direct HTTP API - `POST http://127.0.0.1:24680/com 
 ## Shell / WSL / process
 
-- **`find_exe`** — Resolve an executable's absolute path without launching - searches absolute path, webdeploy version globs, Start Menu .lnk targets, then PATH.
+- **`find_exe`** — Resolve an executable's absolute path without launching - searches absolute path, webdeploy version globs, Start Menu .lnk targets, then PATH. 2.1.143 (wiki #210): runs ON the box named by `--target` (or the home box from a container), not on the CLI's own filesystem; `launch` likewise, gated like `launch_process` there.
 - **`launch`** — Launch an executable by absolute path or bare name, verifying it exists first (avoids the Windows 'cannot find' dialog). Args/cwd/detached; returns pid, resolvedPath.
 - **`launch_process`** — Launch a detached fire-and-forget process with an args ARRAY (no shell quoting); env/cwd/window overrides, plus breakawayFromJob/detached flags so the child survives its parent's job-object teardown (installers, updaters). Returns pid immediately; stop with process_kill.
 - **`launch_rdp_client`** — Launch mstsc against an open RDP tunnel's local port with display-aware sizing; first verifies 127.0.0.1:<localPort> is listening, refusing a dead port.
skills/adom-bridge/SKILL.md+6−1
@@ -531,7 +531,9 @@ Fusion launches take 2-4 minutes cold; respect `timeoutSeconds` + `statusVerb` o Two generic CLI commands exist for launching any Windows executable safely — they verify the target exists BEFORE handing it to the OS, so you never trigger a "Windows cannot find" GUI dialog:
 
 - `adom-bridge find_exe '{"name":"..."}'` -- Resolve an exe by absolute path, glob (e.g. `C:/.../webdeploy/production/*/Fusion360.exe` returns newest), bare name (searches PATH + Start Menu `.lnk` targets). Returns `{path, source}`. Does NOT launch.
-- `adom-bridge launch '{"path":"...", "args":[...], "cwd":"...", "detached":true}'` -- Same resolution rules as `find_exe`, then spawns. Fails in terminal (exit 1) with a clear error if the path doesn't exist. **Always prefer this over raw `start`.**
+- `adom-bridge launch '{"path":"...", "args":[...], "cwd":"...", "detached":true, "reason":"..."}'` -- Same resolution rules as `find_exe`, then spawns. Fails in terminal (exit 1) with a clear error if the path doesn't exist. **Always prefer this over raw `start`.**
+
+**Where they run (2.1.143, wiki #210).** With `--target <box>`, or from a container / Linux CLI, both verbs run ON THAT BOX through its ab (mesh first, relay fallback, the same path as `shell_execute`): the path is resolved against the box's filesystem and the app starts there; the reply says `on: "<box>"`. Before 2.1.143 both ran inside the CLI process, so `--target arav-rog launch {path}` answered `find_exe: could not locate` for a file that existed on arav-rog. Only a Windows CLI with no `--target` still resolves and spawns locally. On a box `launch` is a Tier-2 exec verb like `launch_process` (gated the same way, `reason` required); `find_exe` is read-only. A target ab older than 2.1.143 answers unknown verb: use `launch_process {path, args}` there.
 
 For Fusion specifically, use `fusion_start` — it wraps `launch` plus the full startup-picker / add-in-readiness dance.
 - `fusion_import_step` -- Import a STEP/STL/IGES file into Fusion 360
@@ -1259,6 +1261,9 @@ If you don't have the suffix handy, just ask the user. Or if the file you wanted | `desktop_click` | `desktop_mouse_click` |
 | `desktop_double_click` | `desktop_mouse_double_click` |
 | `desktop_right_click` | `desktop_mouse_right_click` |
+| `desktop_mouse_drag` (2.1.143) | `desktop_drag` |
+
+**Drag (2.1.143, wiki #205).** `desktop_mouse_drag {from:{x,y}, to:{x,y}, steps?:12, durationMs?:300, button?:"left", space?:"screen"|"image"|"window", hwnd?|titleContains?, reason}` presses at `from`, moves the real cursor through `steps` interpolated points over `durationMs`, releases at `to`. It is for canvases with no view controls that only react to a drag: orbit a 3D preview (KiCad's Footprint Chooser pane), a splitter, a slider, a lasso. A canvas that tracks motion ignores a teleport, so the pointer really travels; slow canvases want `durationMs` 600+. With `hwnd`/`titleContains` ab raises that window, verifies it is under `from` before pressing (else `target_not_under_cursor`, nothing pressed), and gives the prior foreground back afterwards (`restoreForeground:false` keeps it up). `space:"image"` + `shotId` takes screenshot pixels; `space:"window"` takes window px or `{fx,fy}` fractions of the window rect. The reply lists the `points` actually sent. Same gate and same UIPI limit as `desktop_click`.
 
 An alias is gated exactly like the verb it aliases - it is not a way around the reason requirement below.