Skip to main content

thinking-desk

Interact with the user's desk display device (Thinking Desk) over LAN. Supports pairing, sending notifications with plain text, rich layout (positioned text, shapes, progress bars), and buzzer sounds. Sends task-done notification + usage data when Claude completes a task. Lets the user tune the usage-warning threshold by voice. Triggers: "pair my display", "show on my screen", "notify my display", "ping my display when done", "send to my screen", "show my usage on display", "unpair my display", "change my usage threshold", "warn me earlier", "set warning threshold to N".

الانتقال إلى التثبيت

معلومات المصدر

المستودع
autonomous-ai/autonomous-desk
آخر نشاط في المصدر
٨ سبتمبر ٢٠٢٦ في ٠٩:٣٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٩
التفرعات
١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
15 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
thinking-desk
description
Interact with the user's desk display device (Thinking Desk) over LAN. Supports pairing, sending notifications with plain text, rich layout (positioned text, shapes, progress bars), and buzzer sounds. Sends task-done notification + usage data when Claude completes a task. Lets the user tune the usage-warning threshold by voice. Triggers: "pair my display", "show on my screen", "notify my display", "ping my display when done", "send to my screen", "show my usage on display", "unpair my display", "change my usage threshold", "warn me earlier", "set warning threshold to N".
allowed-tools
Bash(*)
# Thinking Desk Display Skill Discover, pair, and send notifications to a Thinking Desk display on the local network. After pairing, Claude proactively sends a task-done notification + usage data when completing a task. ## Config Path: `~/.config/autonomous-lcd.json` ```json { "devices": [ { "device_id": "lcd-bd4a14", "label": "My Display", "last_known_ip": "192.168.1.42", "last_seen_at": "2026-05-18T10:30:00Z" } ], "default_device_id": "lcd-bd4a14" } ``` Device ID format: `lcd-<6 lowercase hex digits>` (from last 3 bytes of MAC address). --- ## 1. Discover Find devices on the LAN using the bundled discovery script. **When to use:** during pairing, or when a notification fails with connection error/timeout. ### Run discovery ```bash python3 ${CLAUDE_PLUGIN_ROOT}/scripts/discover.py ``` **Output:** JSON array of found devices, e.g.: ```json [{"device_id": "lcd-bd4a14", "ip": "192.168.1.42"}] ``` **How it works (automatic):** 1. Cache check — tries cached IPs from config (instant) 2. Parallel scan — runs mDNS browse + UDP subnet sweep simultaneously (~10s) 3. Returns all found devices, deduplicated by device_id **On failure:** exits with code 1, stderr contains `{"error": "not_found"}`. Suggest: device powered on? Same WiFi? --- ## 2. Pair One-time setup to register a new device. Uses OTP code displayed on the device screen — no need to read device ID stickers. **When to use:** "pair my display", "add a screen", "set up device". ### User-facing messages Only show simple, non-technical messages to the user during pairing: 1. "Scanning your network..." (while discovery runs) 2. "Found N device(s). Check your display for a pairing code." (after discovery) 3. "What code do you see on your device?" (ask user) 4. "Paired successfully! Your display should now show a confirmation." (after done) **Do NOT show** to user: device IDs, IP addresses, config paths, HTTP status codes, raw JSON, error tracebacks, or internal debug info. These are implementation details. **Bash output:** All bash commands in the pair flow should redirect stdout to `/dev/null` or use a wrapper that only prints a single friendly message (e.g. `"done"` or `"ok"`). Never let raw JSON, device IDs, or HTTP responses appear in the transcript. Pipe discovery output into a variable and process silently within the same script. ### Procedure 1. Tell user: **"Scanning your network..."** 2. Run discovery (section 1) to find **all** devices on the network. 3. If no devices found → tell user: "No devices found. Make sure your display is powered on and connected to the same WiFi." 4. Tell user: **"Found N device(s). Check your display for a pairing code."** 5. For each discovered device, generate a random **4-digit code** (1000–9999, unique per device). 6. Send each device its code as a notification, using the request in **section 4.3** — the `X-Device-ID` header is required and the display answers **403** without it. Do this silently; don't show HTTP results to the user. Alternatively just run `python3 scripts/pair.py start` and `python3 scripts/pair.py complete <code>`, which handle steps 2 and 5–10 for you. Payload: ```json { "play_sound": 20, "items": [ { "type": "text", "text": "Pairing", "x": 0, "y": 0, "width": 220, "align": "center", "size": 3, "color": "#7eb8da" }, { "type": "text", "text": "<CODE>", "x": 0, "y": 35, "width": 220, "align": "center", "size": 4, "color": "#e8dcc8" }, { "type": "text", "text": "Enter this code", "x": 0, "y": 85, "width": 220, "align": "center", "size": 2, "color": "#9a9488" } ] } ``` Skip devices that fail to respond — don't mention them to the user. 7. Ask user: **"What code do you see on your device?"** — match input to a device. 8. Label defaults to **"My Display"** (skip asking). 9. Write to `~/.config/autonomous-lcd.json`: - New device → append to `devices[]` - Existing device ID → update entry - First device → set as `default_device_id` - Set file permission `0600` 10. Send confirmation notification: `{"text": "Paired with Claude", "color": "green", "play_sound": 20}` 11. Tell user: **"Paired successfully! Your display should now show a confirmation."** Re-pairing same device ID is an update, not an error. --- ## 3. Unpair Remove a device. **When to use:** "unpair my display", "remove my display", "stop display updates". ### Procedure 1. Identify which device to unpair (default if not specified). 2. Remove device from `~/.config/autonomous-lcd.json`. 3. If removed device was `default_device_id`, clear it (or set to next device if any remain). 4. Report success. --- ## 4. Notify Send a notification to a paired device. This is the most frequently used operation. **When to use:** "show on my screen", "notify my display", "ping my display when done". Also use proactively at end of long tasks (build, test, deploy). ### 4.1 Pick device - Use device ID the user specified, OR - Use `default_device_id` from config, OR - Error if neither available. If no config or no devices → tell user to pair first. ### 4.2 Build payload **Legacy text mode** — simple notification: ```json { "text": "Build passed in 3m 12s", "size": 2, "color": "green", "play_sound": 20 } ``` - `text` (required) — max 500 chars, strip markdown to plain text - `size` (optional) — 1 to 4, default 2 - `color` (optional) — `red`, `green`, `blue`, `yellow`, `white`, or hex `#RRGGBB` - `play_sound` — always include **20** (`claude_style`) unless user specifies otherwise **Rich layout mode** — positioned items: ```json { "play_sound": 20, "items": [ { "type": "text", "text": "Title", "x": 12, "y": 0, "width": 196, "size": 4, "color": "#ffffff" }, { "type": "rect", "x": 6, "y": 34, "width": 208, "height": 72, "radius": 10, "color": "#171d18" }, { "type": "progress", "x": 18, "y": 78, "width": 184, "height": 14, "radius": 4, "value": 50, "color": "#9bad67", "bg_color": "#2f2f2f" } ] } ``` When `items[]` has at least one valid item, rich layout is used and `text` is ignored. **Coordinate system:** - Viewport: **220 x 117** pixels (inner content area, not full 240x135 screen) - Origin `(0, 0)` = top-left of content area - Last usable point: `(219, 116)` **Limits:** - Max **6** items (extra ignored) - Item text max **95** chars - `value`: 0..100, `radius`: 0..50, `stroke_width`: 1..32 **Text width budget (avoid clipping):** each character is ~`6 × size` px wide, so a string only fits if `len(text) × 6 × size ≤ box width`. At the **220px** viewport that means a `size 4` title fits ~9 chars, `size 3` ~12, `size 2` ~18. Keep big titles short, or drop a size — e.g. `"Task Done"` (9 chars) is already at the edge at size 4, so render it at size 3. Vertically, keep text above **y≈90**; lower text gets clipped at the bottom. ### 4.3 Send ```python import json, urllib.request # Tag the card with the sending agent — the firmware ignores unknown keys on # older builds, and newer firmware forwards it to the backend. payload = json.dumps({**<json_payload>, "source": "claude-code"}).encode() req = urllib.request.Request( "http://<last_known_ip>:3000/lcd", data=payload, headers={ "Content-Type": "application/json", "X-Device-ID": "<device_id>", }, method="POST", ) with urllib.request.urlopen(req, timeout=3) as resp: print(f"HTTP {resp.status}") print(resp.read().decode()) ``` ### 4.4 Handle response | Status | Action | |--------|--------| | **200** | Success. Update `last_seen_at` in config. | | **400** | Malformed payload. Check JSON. | | **403** | Device ID mismatch. Run rediscovery. | | **413** | Text >500 chars. Truncate to 497 + `"..."`, retry once. | | **Connection error/timeout** | Cached IP stale. Run rediscovery (section 1), retry once. | ### 4.5 Dry run If user asks for dry run, show the payload and target URL without sending. --- ## 5. Task Done Notification Handled automatically by the `Stop` hook (`scripts/on-stop-done.py`). Every time Claude finishes a response, the hook: 1. Sends a "Task Done" notification with sound #20. 2. Fetches current usage from the API. 3. If **either** 5-hour or 7-day utilization `>=` the configured threshold → sends usage section 1 (5-hour) after 5s, then usage section 2 (7-day) after another 5s. 4. If both are below threshold → stops after Task Done. Rate-limited to once per 2 seconds. No action needed from Claude — the hook runs automatically. ### Waiting-on-you ping (`Notification` hook) Handled automatically by the `Notification` hook (`scripts/on-notify.py`). Claude Code fires this when it needs your approval to run a tool (a yes/no prompt) or when the input has been left idle. The hook pings the display with sound **#1 (`triple_ping`)** — deliberately different from the Task Done cue (#20) — and shows a compact card: - Tool approval → **`Approve?`** + the tool name (MCP names are shortened, e.g. `mcp__…__authenticate` → `authenticate`) - Idle / waiting for input → **`Your turn`** + `waiting for you` Rate-limited to once per 8 seconds. Fails silently if no display is paired. ### Config: `usage_threshold` Set `usage_threshold` (integer, 0–100) in `~/.config/autonomous-lcd.json` to control when usage is shown after Task Done. Default: **80**. ```json { "devices": [...], "default_device_id": "...", "usage_threshold": 80 } ``` ### 5.1 Adjust Threshold (voice command) Let the user retune the auto-warning threshold in plain language — no need to edit JSON by hand. **When to use:** "change my usage threshold", "warn me earlier", "set warning threshold to 60", "only warn me near the limit", "show usage sooner", "I want alerts at 90%". **Procedure:** 1. Parse the target percentage from the request. - Explicit number ("set threshold to 60") → use it. - "warn me earlier" / "sooner" → lower it (e.g. 60). "only near the limit" / "at the brink" → raise it (e.g. 90). - If no number can be inferred, ask: "What percentage should I warn you at? (0–100)" 2. Validate: integer **0–100**. Reject anything outside the range and ask again. 3. Read `~/.config/autonomous-lcd.json` (if missing → tell the user to pair a display first). 4. Set `usage_threshold` to the new value, preserving all other keys (`devices`, `default_device_id`, etc.). Write back as valid JSON with file permission `0600`. 5. Confirm to the user in plain language, e.g. **"Done — I'll pop your usage on the display once you hit 60% in either window."** Note: `usage_threshold` only controls **when usage auto-displays** after a task. The progress-bar colors (green <60, orange 60–79, red ≥80) are independent and do not change with this value. ### 5.2 Toggle notifications & sound (voice command) Let the user turn the automatic notifications and buzzer on/off in plain language — no JSON editing. All three keys default to **on/true** (so existing setups are unchanged) and live at the top level of `~/.config/autonomous-lcd.json`: | Key | Default | Controls | |-----|---------|----------| | `sounds_enabled` | `true` | Master buzzer switch. When `false`, cards still appear on screen but **silently** (`play_sound: 0`). | | `task_done_enabled` | `true` | The "Task Done" card after each response. When `false`, it is not sent (usage alerts still fire if over threshold). | | `notify_enabled` | `true` | The waiting-on-you ping (`Approve?` / `Your turn`). When `false`, no ping is sent. | **When to use & how to map the request:** - "mute the display" / "turn off the sounds" / "stop beeping" / "im lặng đi" → `sounds_enabled = false`
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub