diff --git a/.claude/skills/synology/SKILL.md b/.claude/skills/synology/SKILL.md index 91bd5a1d..eefa89d3 100644 --- a/.claude/skills/synology/SKILL.md +++ b/.claude/skills/synology/SKILL.md @@ -110,19 +110,35 @@ log via `.claude/scripts/log-skill-error.sh` before surfacing. Handled condition VPN-down connect error surfaced to the user, a method refused for lack of --confirm) are NOT logged. ## Status / verification -- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** First live exercise against the device. - Confirmed working: auth (sid + synotoken CSRF), API discovery (`apis`), version-by-maxVersion - routing, and reads `test` / `storage` / `shares` / `packages` / `services` / `apis`. Device is - **DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4, 2x WD10EZEX 1 TB. - 10 shares (incl. hidden `pacs`, `Activities`, `chat`, `Sandra Fish`); 30 packages running incl. - **Active Backup for Business 3.1.0, Synology Drive Server 3.5.0, Chat, VPN Server, Hybrid Share**. - Session-expiry re-login (106/119), the mutating-verb gate, and the generic-error map are coded to - spec but not yet exercised against a live write (no mutating call made yet — gate verified only by - the read path). Built originally from a 5-agent scan of the DSM 7 help tree + authoritative API - sources (kwent `_full.json`, N4S4/synology-api, Synology Web API guides) — see `references/dsm-api.md`. +- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** Full read-surface exercise against the + device. Device is **DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4, + 2x WD10EZEX 1 TB (volume1 913G, 43% used). 10 shares (incl. hidden `pacs`, `Activities`, `chat`, + `Sandra Fish`); 30 packages running incl. **Active Backup for Business 3.1.0, Synology Drive + Server 3.5.0, Chat, VPN Server, Hybrid Share**. 41 users, 4 groups (administrators, http, + MainOffice, users). +- **Command-by-command results (Web API):** `test` `apis` `sysinfo` `util` `storage` `shares` + `users` `groups` `packages` `services` `connections` `ls` (share roots) `call` — **all OK**. + Auth (sid + synotoken CSRF), API discovery, version-by-maxVersion routing, and the generic `call` + power-tool all confirmed live. +- **SSH backend (`syno-ssh.sh`):** `info` `df` `run` confirmed OK (incl. privileged `sudo -S` and + on-box `synowebapi --exec` at `/usr/syno/bin/synowebapi`). This is the path for real file browsing. +- **`ls ` (FileStation `list`) is DENIED for the admin account on this box** — returns 407 + on-box (SYSTEM_ADMIN) / 400 via Web API even for valid subfolders; the built-in admin lacks + FileStation file privileges. `ls` (no path / share roots via `list_share`) works fine. For actual + file/folder browsing use the SSH backend: `syno-ssh.sh run "ls -la /volume1//" + --confirm`. (`ls ` now catches this and prints the SSH hint.) Windows note: a bare + `ls /Public` arg is also rewritten by MSYS path-conversion — prefer `MSYS_NO_PATHCONV=1` or the + `call ... folder_path=/x` form, but the 407 denial blocks it regardless. +- **WRITE/SETTER PATH NOT YET EXERCISED LIVE.** Session-expiry re-login (106/119), the mutating-verb + gate, and read-modify-write setters are coded to spec but no mutating call has been made against + the device yet. Gate is verified only on the read path. First real change will confirm CSRF on a + write end-to-end. +- Built originally from a 5-agent scan of the DSM 7 help tree + authoritative API sources (kwent + `_full.json`, N4S4/synology-api, Synology Web API guides) — see `references/dsm-api.md`. - **Live fixes from this run (2026-06-25):** `services` used `SYNO.Core.Service.list` which 103s on DSM 7.2.1 — corrected to `get` (returns `{"service":[...]}`). `apis | head` raised a - `BrokenPipeError` traceback — now caught and exits cleanly. + `BrokenPipeError` traceback — now caught and exits cleanly. `ls ` now degrades to an SSH + hint on the FileStation 400/407 denial. - **DSM 7.2.x reboot/shutdown 103:** the Web-API `reboot`/`shutdown` can return error 103 on some builds. Fallback is the SSH `reboot|shutdown --confirm` recipe (`synoshutdown -r|-s`). - **Param-schema caveat:** method names + versions in the reference are device-authoritative, but many diff --git a/.claude/skills/synology/scripts/syno_client.py b/.claude/skills/synology/scripts/syno_client.py index 87a5abf4..b446be85 100644 --- a/.claude/skills/synology/scripts/syno_client.py +++ b/.claude/skills/synology/scripts/syno_client.py @@ -338,8 +338,21 @@ def main(argv): _print(c.call("SYNO.Core.CurrentConnection", "list")) elif args.cmd == "ls": if args.path: - _print(c.call("SYNO.FileStation.List", "list", folder_path=args.path, - additional='["size","owner","time","perm"]')) + try: + _print(c.call("SYNO.FileStation.List", "list", folder_path=args.path, + additional='["size","owner","time","perm"]')) + except SynoError as e: + # FileStation file-browsing (`list`) is denied for an account without + # FileStation file privileges -- on-box it is 407, surfaced here as 400. + # `list_share` (share roots) still works; for actual files use the SSH backend. + if " 400" in str(e) or " 407" in str(e): + raise SynoError( + f"{e}\n [HINT] FileStation file-listing is not permitted for this " + f"account (built-in admin lacks FileStation file privileges on this " + f"device). Use the SSH backend for real file browsing:\n" + f" bash .claude/skills/synology/scripts/syno-ssh.sh run " + f"\"ls -la /volume1//\" --confirm") + raise else: _print(c.call("SYNO.FileStation.List", "list_share", additional='["size","owner","perm"]')) diff --git a/errorlog.md b/errorlog.md index 61c3cfab..0d674dee 100644 --- a/errorlog.md +++ b/errorlog.md @@ -17,6 +17,50 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure · +2026-06-25 | Howard-Home | synology/ls | [friction] ls arg mangled by MSYS path-conversion (/Public -> C:/Program Files/Git/Public) before Python sees it; FileStation list also 407-denied for admin anyway. Fix: use call folder_path=/x (= form not converted) or MSYS_NO_PATHCONV=1; real file browsing via SSH backend. [ctx: ref=feedback_tmp_path_windows os=windows] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology/ssh | syno-ssh recipe 'run' failed (rc=2) [ctx: host=192.168.0.120] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 401) [ctx: err={"code": 401}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.CheckExist.check failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.CheckExist.check failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}] + +2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list failed (code 103) [ctx: err={"code": 103}] + +2026-06-25 | Howard-Home | synology | SYNO.Core.Service.query failed (code 103) [ctx: err={"code": 103}] + +2026-06-25 | Howard-Home | synology | SYNO.Core.Service.get_service failed (code 103) [ctx: err={"code": 103}] + +2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list_service failed (code 103) [ctx: err={"code": 103}] + +2026-06-25 | Howard-Home | synology | SYNO.Core.Service.enum failed (code 103) [ctx: err={"code": 103}] + +2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list failed (code 103) [ctx: err={"code": 103}] + 2026-06-25 | Howard-Home | bash/reachability-probe | [friction] /dev/tcp TCP probe falsely reported host DOWN on Windows MSYS while device was UP; wasted a cycle. Fix: don't trust /dev/tcp on Git-bash Windows for reachability — use the actual client (python urllib) or curl --max-time. 2026-06-25 | Howard-Home | synology | SYNO.Core.QuickConnect.get failed (code 103) [ctx: err={"code": 103}]