Qiaomu Suno Master
Create commercial-grade Suno lyrics, then use the selected Suno execution lane to generate and optionally download the music. It also includes a local music genre finder so vague moods can become precise Suno style tags.
Suno login state is short-lived. Treat Chrome's logged-in Suno web session as
the source of truth, and treat the CLI as the fast path only. If the CLI reports
auth_expired, JWT expired, 401, 403, captcha failures, or cannot find a
browser session, immediately use the Suno web UI fallback instead of retrying the
same CLI request.
Style Tag Selection Contract
When the user asks for Suno style tags, genre combinations, genre discovery, or style sharpening, treat the local genre finder as mandatory evidence, not an optional helper.
- Read
references/genre-selection.mdbefore answering. - Run
python3 scripts/find_music_genres.pyfrom the skill directory. For style-only requests or broad briefs, run at least three focused queries that sample different axes of the brief: the user's original phrase, one or more adjacent genre families, and one or more production/texture/rhythm angles. A single query is acceptable only when the user gives a very narrow style and asks for minimal output. - Build a candidate palette from the database results first. Prefer genre tags that appeared in the finder output or are direct, obvious parents/children of those results.
- Compose each Suno style string as 1-3 genre tags plus 2-5 vocal, instrument, tempo, production, or mood tags. Do not answer from taste alone, and do not dump a long related-genre list into one prompt.
- For style-only requests, do not write lyrics or run Suno generation unless
the user explicitly asks. Return useful combinations, the best starters, and
exclude_styleswhen helpful. - If the finder fails or the database is unavailable, say that clearly and continue with a best-effort fallback instead of implying the tags were database-backed.
Generation Execution Contract
This skill must prefer a deterministic lane over open-ended exploration.
Honor explicit lane requests as a hard lock.
- If the user explicitly asks for Computer Use, the whole generation task stays on the Computer Use lane from form submission through visible link capture and browser download attempts. Do not switch to CLI, CDP, Browser plugin, raw API calls, or captcha-assisted CLI generation to "make progress".
- Treat "全程用 Computer Use", "直接用 Computer use", "用电脑操作", and follow-up corrections about route mixing as a Computer Use hard lock. Once this lock is active, every Suno-facing action for that request must happen through the visible Suno UI controlled by Computer Use.
- In a Computer Use-locked task, shell commands may prepare lyrics,
manifests, inspect files, move browser-downloaded files, resolve captured
share links, and validate assets. They must not submit Suno generation,
refresh generation auth, run
suno generate, or drive CDP/CLI captcha helpers. - In a Computer Use-locked task, do not run CDP preflights, launch a
CDP-enabled Chrome, call the Browser plugin, or use
download_clips.shas a hidden fallback. If visible UI download fails, report the blocker with the captured links instead of switching lanes. - If Computer Use cannot proceed because the user is actively using the same browser, the page requires login/security/captcha action, or the desktop UI is unavailable, stop at that state and ask for that blocker to be cleared. Do not silently fall back to another generation lane.
- The same lock-in rule applies to any other lane the user explicitly names: use that lane end to end, or stop and report the blocker.
Make the CLI path work first. Use this only when the user did not explicitly request another lane.
- Ensure the installed
sunoCLI exists and runsuno config check. - Refresh auth from the real Chrome Suno session; if refresh fails, run
suno auth --login --quiet. - Run
scripts/generate_with_suno.shonce with the default captcha-backed path. - Retry CLI at most one more time only for the narrow hCaptcha/CDP-launch
failure class, using either
--no-captchaor a user-provided--token "$HCAPTCHA_TOKEN".
- Ensure the installed
If CLI generation is blocked, Codex controls the browser. Use this only when the task is not locked to a different lane.
- Use the Codex Browser plugin when available. If it is not exposed in the current session, use Chrome/Computer Use against the logged-in Suno page.
- Open
https://suno.com/create, fill title, lyrics, styles, model, and options from the prepared local files, click Create, wait for the generated rows, and capture song IDs/links. - Only ask the user to intervene for actions automation cannot legally or reliably complete, such as human login, account security checks, or a live captcha challenge.
Stop forbidden exploration.
- Do not hand-craft Suno generate POST requests, inject copied browser cookies into throwaway profiles, replay captured payloads, or repeatedly test captcha variants unless the user explicitly asks to debug Suno itself.
- If the user provides existing Suno song URLs or clip IDs, skip generation and continue the stable download and LRC validation path.
- If the user asks to upload or publish to Qiaomu Music, delegate that
publishing step to
qiaomu-music-publisher; do not implement Qiaomu Music upload inside this skill. - Never report generation success until real Suno song links or clip IDs have been captured.
When To Use
Use this skill when the user wants:
- A new song from a theme, article, story, mood, or keywords
- Suno-ready lyrics with sections such as
[Verse],[Chorus], and[Bridge] - Music generated through the local Rust
sunoCLI, with web UI fallback - A completed song file downloaded locally
- Existing Suno clip IDs exported as audio, video/MTV, timed LRC, SRT, clean SRT, or Markdown lyrics
- Music genre/style recommendations before lyric writing or generation
- Timestamped
.lrclyrics for any song that will be uploaded to a music player or published as a playable web track
Do not use this skill for pure music theory, ordinary poetry not intended for Suno, or non-Suno audio editing.
Do not use this skill for Qiaomu Music upload execution; use
qiaomu-music-publisher after MP3/LRC assets are ready.
Inputs To Resolve
Infer these from the user request when possible:
title: short, memorable song titlelyrics: complete Suno-ready lyrics with structural tagslrc_required: default yes when generating/downloading music for upload, publishing, or a music-player websitestyle_description: comma-separated Suno style tagsexclude_styles: comma-separated styles, instruments, or moods to avoidgenre_candidates: optional recommended genres fromscripts/find_music_genres.pytitle_options: three concise title candidates before choosing the final titlemodel: defaultv5.5vocal: optionalmaleorfemaleoutput_dir: default to~/Documents/Suno/<song-title>/unless the user gives a foldersong_manifest: default to$OUTPUT_DIR/song.manifest.jsongenerate: whether to run Suno immediately; default yes when the user asks to generate music
If the user only asks for lyrics, produce the requested creative output without running suno.
Workflow
- Analyze the song brief: theme, audience, language, mood, style, vocal, tempo, and any forbidden elements.
- If style is missing, vague, worth sharpening, or the user specifically asks for style/tag recommendations, follow the Style Tag Selection Contract.
- Choose 1-3 fitting genre tags plus a small set of vocal, instrument, tempo, and mood tags. Keep
style_descriptionfocused. - For style-only requests, stop after delivering style combinations and any
useful
exclude_styles; do not continue to lyrics or generation unless asked. - Read
references/lyric-craft.mdand apply the lyric quality rules. - Produce:
title_options- selected
title - optional
genre_candidates style_descriptionexclude_styleslyrics
- Treat Suno-ready lyrics and LRC as separate deliverables:
lyricsis the creative input sent to Suno and may use[Verse],[Chorus],[Bridge], etc..lrcis the timed output fetched after generation from Suno aligned lyrics.- Never upload or publish plain Suno lyrics as music-player synced lyrics.
- Music-player cover art is a separate generated design asset, not the Suno source cover.
- Save lyrics to
$OUTPUT_DIR/lyrics.txtwhen generating. Prefer a file over shell-quoting long multiline lyrics. Unless the user explicitly gives a folder,$OUTPUT_DIRmust be~/Documents/Suno/<song-title>/. Do not use the current repo/workspace directory as the default output location. For a Computer Use-locked task, this same directory is also the final place for browser-downloaded MP3 files after they are moved out of~/Downloads. - Use the manifest-first workflow for generation, download, LRC validation,
and later publishing handoff. Read
references/manifest-workflow.mdwhen creating or updating a song manifest:
python3 scripts/run_workflow.py init \
--manifest "$OUTPUT_DIR/song.manifest.json" \
--title "$TITLE" \
--style "$STYLE_DESCRIPTION" \
--exclude "$EXCLUDE_STYLES" \
--lyrics-file "$LYRICS_FILE" \
--output-dir "$OUTPUT_DIR"
If the user provides existing Suno clip IDs or song URLs, include them with
--ids during init and skip generation. For this existing-clip path, style
and lyrics file may be omitted.
For a Computer Use-locked task, use init only to create durable local metadata
and then immediately follow references/computer-use-workflow.md. Skip
run_workflow.py generate, run_workflow.py download, CDP session checks,
CLI auth refresh, CLI generation, and CLI/browser-helper downloads unless the
user explicitly approves leaving Computer Use.
- Before any generation or download step, run the non-destructive preflight:
python3 scripts/suno_doctor.py --output-dir "$OUTPUT_DIR"
For a Computer Use-locked task, this is the only preflight allowed by default. Do not run the CDP/Chrome session checks below for that locked task.
Before submitting generation, verify that a real Chrome Suno web session exists:
bash scripts/ensure_suno_chrome_session.sh --timeout 12
If no CDP endpoint exists and Chrome is not already running, launch a CDP-enabled Chrome session:
bash scripts/launch_suno_cdp_chrome.sh
If Chrome is already running without remote debugging, quit it fully before
relaunching with CDP flags, or use --dedicated-profile and log into Suno once
there. If Chrome shows a native debugging confirmation, pause for the user to
accept it once. Do not assume page-level CDP injection can dismiss native Chrome
security UI. Do not keep retrying the CLI against an expired JWT.
- Before any CLI step, ensure the Rust CLI exists:
bash scripts/ensure_suno_cli.sh
Auth is handled automatically by both generate_with_suno.sh and
download_clips.sh when the CLI accepts Chrome's session. Only call manually for
export_suno_assets.py:
suno auth --refresh --quiet 2>/dev/null || suno auth --login --quiet
- Generate/download/LRC default path:
python3 scripts/run_workflow.py generate \
--manifest "$OUTPUT_DIR/song.manifest.json"
This wrapper writes suno-meta.env, preserves generate.result.json, extracts
clip IDs, downloads MP3s, fetches LRC, validates LRC, updates
song.manifest.json, and writes workflow.log.
This default path is forbidden for Computer Use-locked tasks. For those tasks,
Computer Use must fill the Suno form, click Create, capture share links, use
the visible row menu to choose Download -> MP3 Audio, and only then use
shell commands to move the browser-downloaded files into
~/Documents/Suno/<song-title>/.
Use dry-run when preparing or debugging without consuming Suno credits:
python3 scripts/run_workflow.py generate \
--manifest "$OUTPUT_DIR/song.manifest.json" \
--dry-run
If the manifest status becomes generation_blocked, or the wrapper emits
GENERATION_BLOCKED, follow references/browser-fallback.md as the Codex
browser-generation lane. Do not attempt raw Suno API calls after a blocked
generation.
- Existing-ID download path:
python3 scripts/run_workflow.py download \
--manifest "$OUTPUT_DIR/song.manifest.json" \
--ids "ID1 ID2"
For any song that will be uploaded to a music player, a website, or any
user-facing playable catalog, LRC is mandatory and run_workflow.py requires it
by default. If LRC is pending, do not upload/publish the track yet. Retry later:
python3 scripts/run_workflow.py validate-lrc \
--manifest "$OUTPUT_DIR/song.manifest.json"
- Low-level debug commands:
Keep the separate generate_with_suno.sh, generate_download_lrc.sh, and
download_clips.sh commands for debugging, browser-fallback recovery, or
partial retries. These commands are not allowed during a Computer Use-locked
task unless the user explicitly approves leaving the Computer Use lane.
Generation only, returning JSON with clip IDs:
bash scripts/generate_with_suno.sh --meta-file "$META_FILE" --output-dir "$OUTPUT_DIR"
End-to-end shell wrapper:
bash scripts/generate_download_lrc.sh --meta-file "$META_FILE" --output-dir "$OUTPUT_DIR"
Download fast path with browser-first downloader:
bash scripts/download_clips.sh --ids "ID1 ID2" --output-dir "$OUTPUT_DIR"
For any song that will be uploaded to a music player, a website, or any user-facing playable catalog, LRC is mandatory. Request and validate LRC at download time:
bash scripts/download_clips.sh --ids "ID1 ID2" --output-dir "$OUTPUT_DIR" \
--lyrics --lyrics-format lrc --require-lrc
Or pipe directly from generate:
bash scripts/generate_with_suno.sh --meta-file "$META_FILE" --output-dir "$OUTPUT_DIR" \
| bash scripts/download_clips.sh --output-dir "$OUTPUT_DIR" \
--lyrics --lyrics-format lrc --require-lrc
If --require-lrc fails, do not upload/publish the track yet. Retry aligned
lyrics after Suno finishes processing:
python3 scripts/export_suno_assets.py ID1 ID2 --format lrc --output "$OUTPUT_DIR"
python3 scripts/validate_lrc.py "$OUTPUT_DIR"
download_clips.sh features:
- Waits 5s for CDN propagation before first attempt
- Retries up to 3 times with 10s delay between attempts
- Auto-refreshes auth from Chrome
- Uses Chrome/CDP browser download first when
websocket-clientis available, otherwise skips that attempt and goes straight tosuno download - Can fetch timestamped
.lrclyrics throughsuno timed-lyrics --require-lrcfails the workflow unless a real timestamped.lrcis present- Accepts IDs via
--idsflag or piped JSON from generate
- LRC gate before upload/publish:
Before uploading to music.qiaomu.ai or any music player, verify the .lrc
file exists and contains real [mm:ss.xx] timestamps:
python3 scripts/validate_lrc.py "$OUTPUT_DIR"
Use the validated .lrc file as the track lyrics payload. Do not use the
original .txt Suno prompt lyrics unless the destination explicitly asks for
unsynced plain lyrics.
- Publishing handoff:
If the destination is Qiaomu Music (music.qiaomu.ai,
qiaomu-music-player-web, "乔木音乐", "上传到乔木音乐", or "发布到乔木音乐"),
handoff to qiaomu-music-publisher after MP3 and timestamped LRC are ready:
python3 ~/.agents/skills/qiaomu-music-publisher/scripts/publish_suno_to_qiaomu_music.py \
--ids "ID1 ID2" \
--output-dir "$OUTPUT_DIR"
qiaomu-music-publisher owns site-specific login, cover handling, multipart
upload, and publication status. Keep this Suno skill focused on creation,
download, and LRC validation. Use song.manifest.json as the source of truth
for IDs, asset paths, and LRC status even if the publisher still takes explicit
CLI arguments.
- Generic music-player cover gate before upload/publish:
For non-Qiaomu music-player uploads, generate a fresh square album cover with
qiaomu-image-generator from the song title, style, and validated lyrics unless
the destination explicitly wants the Suno source cover.
Use the album_cover template with:
style:album-mondo-coverby default, ornegative-space-posterfor sparse/ambient/psychological songsaspect_ratio:1:1description: one symbolic visual distilled from the lyrics, with Mondo-style limited palette, single focal point, andno textfilename: a stable slug ending in-cover.png
Minimum generation shape:
{
"template": "album_cover",
"cover": {
"enabled": true,
"filename": "song-slug-cover.png",
"style": "album-mondo-cover",
"aspect_ratio": "1:1",
"description": "1:1 square album cover, no text. ... distilled lyric imagery ..."
},
"defaults": {
"provider": "jimeng",
"style": "album-mondo-cover",
"aspect_ratio": "1:1"
}
}
Generate with:
python3 ~/.agents/skills/qiaomu-image-generator/scripts/generate.py "$VISUAL_CONFIG" \
--workers 1 --no-insert --output "$OUTPUT_DIR/cover.result.json"
Verify the cover before upload:
file "$OUTPUT_DIR"/*-cover.png
sips -g pixelWidth -g pixelHeight "$OUTPUT_DIR"/*-cover.png
The cover must be square and must be uploaded as the cover multipart field
together with the MP3 and validated LRC.
- Codex browser generation lane:
Read references/browser-fallback.md and use it when:
- the user explicitly asks for reliable Suno generation
- the CLI auth has expired or is rejected
- captcha automation stalls
- a generated clip is visible in the Suno web list but CLI download fails
- the user explicitly asks to use Computer Use
If the user explicitly asks for Computer Use, the Computer Use lane lock applies to generation and browser download attempts. Do not use CLI/CDP generation or CLI/browser download helpers unless the user explicitly approves leaving that lane.
This is not a passive handoff. Codex should control the browser:
- Open
https://suno.com/createin the logged-in Chrome profile. - Switch to Advanced mode and model
v5.5unless the user requested another model. - Fill Lyrics, Styles, and Song Title from the local files/meta.
- Click
Create, wait for the two generated rows to appear, and record both song links. - When rows become playable, click each row's menu/download controls in the web
UI. For non-locked browser fallback only,
download_clips.sh --ids ... --browseris allowed if IDs are visible.
If browser automation cannot complete login, captcha, or Create submission because the page requires a human security action, pause at that exact browser state and ask the user to complete only that action. After it is complete, Codex continues capturing IDs, downloading, validating LRC, and handing off any site-specific publishing step to the appropriate publisher skill.
For direct Computer Use generation and download, read
references/computer-use-workflow.md. This lane should open Suno Create,
submit through the visible web UI, copy share links from the generated rows,
resolve share links to clip IDs, download audio through the visible Suno web UI
when possible, then use local post-processing only for file organization,
timed-lyrics export, LRC validation, and manifest updates. Do not run
run_workflow.py generate, run_workflow.py download, suno generate, or
CDP/captcha helpers in a Computer Use-locked task unless the user explicitly
approves switching lanes.
- Send to Feishu (only in bridge context with
chat_id):
cd "$OUTPUT_DIR"
lark-cli config bind --source lark-channel --identity bot-only
for f in *.mp3; do
lark-cli im +messages-send --as bot --chat-id "$CHAT_ID" --file "./$f"
done
- Report the output directory, manifest path, downloaded file paths, LRC validation status, generated cover path, published track URL, and/or Suno song links.
Never save generated songs, subtitles, videos, or exported lyric files inside the skill directory or incidental current repo. Use ~/Documents/Suno/<song-title>/ by default.
CLI Notes
- The upstream CLI is
paperfoot/suno-cli, installed as thesunocommand. - If
sunois missing, runbash scripts/ensure_suno_cli.shbefore continuing. The script installs from the upstream project, tries Homebrew first, and falls back to Cargo if Homebrew fails. - Verify with
suno --versionafter install. - Prefer
python3 scripts/run_workflow.py generate --manifest "$OUTPUT_DIR/song.manifest.json"for ordinary generation tasks. It wraps generation, download, LRC validation, asset discovery, and status tracking. - Run
python3 scripts/suno_doctor.py --output-dir "$OUTPUT_DIR"before generation to check local prerequisites without spending credits. - Auth is synced from Chrome's logged-in Suno session (
suno auth --refreshorsuno auth --login), but Suno can reject the CLI JWT even when the web UI remains logged in. In that case the web UI is authoritative. - Prefer
bash scripts/generate_with_suno.shfor generation only as the fast path. It auto-refreshes auth and defaults to the captcha-backed submit path, but must not be retried repeatedly after auth/captcha rejection. - CLI retry budget is two total generation attempts: default captcha-backed once, then one targeted retry only for hCaptcha/CDP launch failure with
--no-captchaor a provided--token. - Latest verified path on 2026-05-25:
suno 0.5.7default captcha-backed generation solved hCaptcha, submitted v5.5, returned two complete IDs, thendownload_clips.sh --require-lrcdownloaded MP3 and validated LRC. Do not add--no-captchaby default. - IMPORTANT: Do NOT use
--downloadon generate. CDN needs time to propagate. Always use the separatedownload_clips.shafter generation completes. - Use
scripts/download_clips.shfor ordinary CLI/non-locked browser fallback downloads — it handles retry logic and CDN delay. In Computer Use-locked tasks, attempt browser UI downloads first and do not switch to CLI download without explicit user approval. - For generated songs that will be uploaded or published through the
ordinary CLI/non-locked fallback path, always add
--lyrics --lyrics-format lrc --require-lrctodownload_clips.sh. - For songs uploaded to Qiaomu Music, invoke
qiaomu-music-publisherafter MP3 and LRC are ready. Site-specific login/upload logic belongs there. - If clip IDs are visible in the web list during a non-locked fallback task,
download_clips.sh --ids "ID1 ID2" --browseris the preferred download retry because it asks Chrome to fetch the audio through the browser pipeline first. - Use
scripts/export_suno_assets.pywhen the user wants SRT/LRC/timed lyrics, clean MTV subtitles, audio download, or video/MTV download from existing clip IDs. - Use
scripts/validate_lrc.py "$OUTPUT_DIR"before any music-player upload. A file with only[Verse]/[Chorus]markers is plain lyrics, not LRC. - Use
scripts/clean_srt_for_mtv.pyto remove Suno structural markers such as[Verse]and[Chorus]from subtitle files. - If Suno's captcha solver is flaky in a given browser session, fall back to
--no-captchaonly when you have another valid submission path or a manual--token.
Genre Finder
This skill vendors joeseesun/music-genre-finder data in references/genre-finder/.
Use:
python3 scripts/find_music_genres.py "深夜 空灵 梦幻" --limit 5
python3 scripts/find_music_genres.py "raw energetic punk" --limit 5
python3 scripts/find_music_genres.py "世界音乐 鼓 长笛" --json
For Suno, convert recommendations into concise style tags. Prefer 1-3 genre tags plus vocal, instrument, tempo, and mood tags. Avoid dumping many related subgenres into one prompt. For style-only or broad recommendation requests, run multiple focused finder queries and synthesize from the returned palette before answering.
Asset Export
For existing clip IDs:
python3 scripts/export_suno_assets.py <clip-id> --format lyrics --clean-srt
Without --output, assets are saved under ~/Documents/Suno/<clip-title>/.
Useful formats:
audio: download MP3/audiovideo: download Suno video/MTV asset when availablejson: save timed lyrics JSONlrc: save music-player lyricssrt: save subtitle filemd: save AI-readable timestamped lyrics Markdownlyrics: shortcut forjson,lrc,srt,mdall: shortcut foraudio,video,json,lrc,srt,md
To retry timed lyrics from existing clip IDs, use the Rust suno CLI export path:
python3 scripts/export_suno_assets.py <clip-id> --format lrc --output "$OUTPUT_DIR"
python3 scripts/export_suno_assets.py <clip-id1> <clip-id2> --format lyrics --output "$OUTPUT_DIR"
For MTV:
python3 scripts/export_suno_assets.py <clip-id> --output "$OUTPUT_DIR" --format video,lyrics --clean-srt
Chrome CDP Auth Assist
This skill vendors a lightweight Chrome DevTools Protocol helper from pasky/chrome-cdp-skill as scripts/cdp.mjs.
Use it only when the user wants to reuse an existing Chrome login or debug Suno browser state. Chrome must have remote debugging enabled. If CDP is unavailable, fall back to suno auth --login or the browser-generation lane. Keep all CDP checks bounded with --timeout; a native Chrome debugging confirmation can otherwise stall automation before page scripts run.
To start a CDP-enabled Chrome session:
bash scripts/launch_suno_cdp_chrome.sh
Useful environment knobs:
SUNO_CDP_TIMEOUT=12bounds the pre-generation CDP probe.SUNO_SKIP_CHROME_SESSION_CHECK=1skips the pre-generation CDP probe when it is known to trigger a native Chrome confirmation.SUNO_CDP_PORT=9222controls the Chrome remote debugging port.
This machine has liaocaoxuezhe/chrome-devtools-auto-allow installed at
/Users/joetech/.local/share/chrome-devtools-auto-allow. Its LaunchAgent is
com.local.cdp-auto-allow, app path is
/Users/joetech/.local/share/chrome-devtools-auto-allow/CDP Auto Allow.app, and
logs are written to /tmp/cdp-auto-allow.debug.log. If the log says
不允许辅助访问, the user must enable the app in macOS Accessibility settings.
Known issue: the upstream suno CLI captcha auto-solver may open a piloted
Chrome and fail with CDP Runtime.evaluate ws err: Connection reset....
Another common failure is auth_expired even after suno auth --login succeeds.
When either happens, switch to references/browser-fallback.md immediately.
Output Style
For lyrics-only requests where the user asks to use this creator prompt, output only Markdown code blocks in this order:
```lyrics
...
style-description-tags
exclude-style-tags
1. ...
2. ...
3. ...
For generated music, keep the final response brief:
- mention that generation completed or where it stopped
- include the output folder
- include the next command only if the user needs to authenticate or retry