# Desktop Modes Tool Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Let the assistant read and set the desktop modes dnd, presentation, nolock and quiet. **Architecture:** One tool file (`mode.toml`) and one script (`mode.sh`) in the existing tool format, calling `statusctl`. No change to `assistant.py`. Spec: `docs/superpowers/specs/2026-10-19-mode-tool-design.md`. **Tech Stack:** bash, statusctl (`~/bin`, on the daemon's PATH). --- ### Task 1: mode.sh with its check **Files:** - Create: `examples/tools/test-mode.sh` - Create: `examples/tools/mode.sh` - [ ] **Step 1: Write the check.** It runs `mode.sh` against a throwaway `XDG_RUNTIME_DIR`, so the real modes are never touched. ```bash #!/bin/bash # test-mode.sh: self-check for mode.sh against a scratch runtime dir. set -u here=$(dirname "$0") export XDG_RUNTIME_DIR=$(mktemp -d) trap 'rm -rf "$XDG_RUNTIME_DIR"' EXIT fail=0 check() { [ "$2" = "$3" ] || { echo "FAIL $1: got '$2', want '$3'"; fail=1; }; } check "read missing" "$("$here/mode.sh" dnd "")" "dnd: off" check "set on" "$("$here/mode.sh" dnd 1)" "dnd: on" check "file written" "$(cat "$XDG_RUNTIME_DIR/status.dnd")" "1" check "set off" "$("$here/mode.sh" dnd 0)" "dnd: off" "$here/mode.sh" dnd yes >/dev/null 2>&1; check "bad value exit" "$?" "1" "$here/mode.sh" bogus 1 >/dev/null 2>&1; check "bad mode exit" "$?" "1" echo 1 > "$XDG_RUNTIME_DIR/status.gaming" check "gaming hold" "$("$here/mode.sh" presentation 0)" \ "presentation: on (held on by a running game; manual setting off)" [ $fail = 0 ] && echo "ok" exit $fail ``` - [ ] **Step 2: Run it, expect failure** (`mode.sh` missing). Run: `bash examples/tools/test-mode.sh` - [ ] **Step 3: Write `examples/tools/mode.sh`** (GPLv2 header as in `playing.sh`). ```bash set -uo pipefail mode=${1:-} on=${2:-} case "$on" in "") ;; 0|1) statusctl "$mode" set "$on" || exit 1 ;; *) echo "on must be 1, 0 or empty, not: $on" >&2; exit 1 ;; esac # Read back rather than echo the request: a set that did not land must not # be reported as done. An unknown mode fails here, in statusctl. v=$(statusctl "$mode" get) || exit 1 [ "$v" = 1 ] && s=on || s=off # statusctl get reads only the manual half of presentation; a running game # holds it on regardless (see statusctl's gaming_on). g=$(tr -d '[:space:]' < "${XDG_RUNTIME_DIR:-/tmp}/status.gaming" 2>/dev/null) if [ "$mode" = presentation ] && [ "$g" = 1 ]; then echo "presentation: on (held on by a running game; manual setting $s)" else echo "$mode: $s" fi ``` - [ ] **Step 4: Run the check, expect `ok`.** Run: `chmod +x examples/tools/mode.sh examples/tools/test-mode.sh && examples/tools/test-mode.sh` ### Task 2: mode.toml **Files:** - Create: `examples/tools/mode.toml` - [ ] **Step 1: Write it**, exactly as in the spec's "Tool" section. - [ ] **Step 2: Self-check still passes:** `python3 assistant.py --test`. - [ ] **Step 3: Commit** `examples/tools/mode.sh`, `test-mode.sh`, `mode.toml`. ### Task 3: Install and live check - [ ] **Step 1:** `cp examples/tools/mode.sh examples/tools/mode.toml ~/.config/desktop-assistant/tools/` then `./assistant.sh restart`. - [ ] **Step 2:** Live, over the socket: 10 phrasings (it/en, on/off/query), note tool call, arguments, reply, and `statusctl get` after. Restore each mode to its starting value afterwards. - [ ] **Step 3:** Set-then-ask after unrelated history: the model calls the tool again. - [ ] **Step 4:** Record results under Findings in `AGENTS.md`, mark the spec implemented, commit.