From 3295e1ea0ee3ff500a9af867e0c6b64164c9a9f4 Mon Sep 17 00:00:00 2001 From: robotica4us-collab Date: Fri, 27 Mar 2026 21:35:51 -0500 Subject: [PATCH] fix(skills): sync packaged soundclaw SKILL.md with asset source (fixes #72) (#74) The embedded SOUNDCLAW_SKILL_MD string in packaged.ts was missing the 'OpenClaw Gateway Skill Contract' section that was added to the asset source file in #67. Re-synced the packaged constant from the canonical assets/skills/soundclaw/SKILL.md. Co-authored-by: Neo (subagent) --- src/lib/skills/packaged.ts | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/lib/skills/packaged.ts b/src/lib/skills/packaged.ts index 89043e9..7e25cca 100644 --- a/src/lib/skills/packaged.ts +++ b/src/lib/skills/packaged.ts @@ -185,6 +185,54 @@ When this skill is activated, the agent should walk to the office jukebox before - Reply on the same active channel or session that received the request. - If playback cannot start but a matching track, album, or playlist is found, send back the best Spotify link instead of failing silently. - If multiple matches are plausible, ask a clarifying question instead of guessing. + +--- + +## OpenClaw Gateway Skill Contract + +> This section is for developers implementing the backend skill handler in OpenClaw. +> The Claw3D UI handles authentication via Spotify PKCE OAuth in the browser. +> The gateway skill handles agent-driven requests via the \`soundclaw.*\` RPC namespace. + +### Authentication model + +The user authenticates directly in the browser (PKCE, no secret required). +The access token is stored in browser \`localStorage\` under the key \`soundclaw_token\`. + +For **agent-driven** playback (e.g. "play Jazz for me"), the gateway skill should either: +- Use a server-side Spotify app token (Client Credentials) for search-only actions, or +- Instruct the agent to tell the user to use the jukebox panel for actual playback + +### RPC methods the gateway skill should expose + +\`\`\`ts +// Search for tracks. Returns a list of { name, artist, album, uri, spotifyUrl }. +soundclaw.search({ query: string }): SpotifySearchResult[] + +// Get a shareable Spotify link for a query (for Telegram/chat replies). +soundclaw.getLink({ query: string }): { url: string; title: string } + +// Report current playback state (reads from Spotify API). +soundclaw.playerStatus(): PlayerStatus | null + +// Request playback of a URI (requires user to be authenticated in browser). +soundclaw.play({ uri: string }): { ok: boolean; message?: string } + +// Pause / resume / skip. +soundclaw.pause(): void +soundclaw.resume(): void +soundclaw.next(): void +soundclaw.previous(): void +\`\`\` + +### Agent workflow + +1. Agent receives a music request ("play some jazz", "find this song", etc.) +2. Agent walks to the jukebox (\`movement.target: "jukebox"\`) +3. Agent calls \`soundclaw.search\` to find the best match +4. If the request came from a chat channel (Telegram, etc.): call \`soundclaw.getLink\` and reply with the link +5. If the request came from the office UI: call \`soundclaw.play\` to start playback +6. Agent reports back what was played or linked `; const PACKAGED_SKILL_FILES: Record = {