Skip to content

Commit 18b92a7

Browse files
docs: teach the composer first and describe what --out actually is
README Quick Start went straight to `generate` with a lyrics file the reader was never told how to produce, and the write section described `--out` as "write the song to a file" — which is what made the composite-document bug easy to miss. Quick Start now leads with write → fill → generate → download, `--out` is documented as the lyric block only, and the redirection-versus- `--out` distinction is stated instead of implied. The skill and CHANGELOG record the same contract, including the envelope change from a `generate` string to `next_action.argv`. Claude-Session: https://claude.ai/code/session_01JpQKiFkvQHL5W1v4chubdR
1 parent 4fabd83 commit 18b92a7

3 files changed

Lines changed: 61 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
# Changelog
22

3+
## v0.8.0 — the composer and the renderer agree about the artifact
4+
5+
One invariant now holds end to end: the file named by the emitted generate command exists, is directly consumable by `--lyrics-file`, contains no unresolved instructions, and reflects every selected control.
6+
7+
**Breaking** (agents reading `write --json`):
8+
9+
- `write --out FILE` writes the **lyric block only**. It previously wrote a composite document (title, Style Prompt, `---` rules, Suno Tags, and in priming mode the Prime-Stack Map and research artefact) that the emitted workflow then handed to `--lyrics-file` — so headers, tags and research metadata were sent to Suno as lyrics and embedded in the MP3. The composite document moved to the new `--project-out FILE`.
10+
- The `generate` string field is replaced by `next_action: {argv, command}`. `argv` is authoritative; `command` is shell-escaped display text. It is `null` when no `--out` file exists, instead of advertising a hardcoded `song.txt` that was never written.
11+
- `write --mode priming` requires `--target`, `--objective` and `--domain` (exit 3 when missing) — priming is consent-based and every run must be auditable. `--domain` and `--subtlety` values are validated.
12+
- `guide` lost the `write` alias (it competed with the `suno write` command).
13+
14+
**Fixes:**
15+
16+
- `--mood` / `--vocal` / `--bpm` / `--instrumental` now drive the Style Prompt, the `[Mood:]`/`[Energy:]`/vocal meta-tags and `suno_tags` from one resolved-controls struct. `--mood "dark and brooding"` no longer emitted `[Mood: Uplifting]` and an "uplifting" tag alongside it.
17+
- `--instrumental` is coherent: no `<...>` fill instructions, `--instrumental` in the emitted command, no vocal-only tags.
18+
- Titles and paths in the emitted command are shell-escaped (`She Said "Go"` produced invalid shell).
19+
- `generate` refuses lyrics containing unresolved `<...>` scaffold placeholders (exit 3, naming the line numbers) so an unfilled draft cannot burn ~70 credits. `--force` overrides.
20+
- The emitted command no longer pins `--model v4.5-all` while help and config advertise v5.5 — it omits `--model` so the configured default applies, and names the cheap-draft option separately.
21+
- New fields: `placeholders_remaining`, `ready_to_generate`, `missing_requirements`, `project_written`.
22+
23+
**Discovery:**
24+
25+
- `write` leads the command list in `--help`; the root example is the full write → fill → generate → download flow, with a one-liner distinguishing write/generate/describe/lyrics. README Quick Start mirrors it.
26+
- `write --help` no longer claims plain text on stdout while the framework sends JSON when piped: shell redirection gets the envelope, `--out` gets the lyrics file.
27+
- `agent-info` gained the `write` output schema, workflow, and mode-specific required fields.
28+
329
## v0.6.0 — framework conformance, captcha preflight, real config
430

531
**Breaking** (agents pinned to the 0.5.x contract must update):

README.md

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# suno
44

5-
**Generate AI music from your terminal — full Suno v5.5 support**
5+
**Write and generate AI music from your terminal — full Suno v5.5 support**
66

77
<br />
88

@@ -86,25 +86,24 @@ suno doctor
8686
# 3. Check your credits
8787
suno credits
8888

89-
# 4. Generate a song with full control
89+
# 4. Write a song — the composer scaffolds it, you fill the <...> lyric slots
90+
suno write --genre "indie rock" --theme "late-night city drives" --vocal male --out song.txt
91+
92+
# 5. Generate the audio from the file you just filled (write prints this exact command)
9093
suno generate \
91-
--title "Weekend Code" \
92-
--tags "indie rock, guitar, upbeat" \
93-
--exclude "metal, heavy" \
94-
--lyrics-file lyrics.txt \
95-
--vocal male \
96-
--weirdness 40 \
97-
--style-influence 65 \
94+
--title "Night Drive" \
95+
--tags "Indie rock, jangly and nostalgic, 110 BPM, warm male vocals, clean guitars, driving drums" \
96+
--lyrics-file song.txt \
9897
--wait --download ./songs/
9998

100-
# 5. Generate with your voice persona
99+
# 6. Generate with your voice persona
101100
suno generate \
102101
--title "My Song" \
103102
--tags "pop, warm" \
104103
--persona e483d2f0-50ca-4a09-8a74-b9e074646377 \
105104
--lyrics "[Verse]\nHello from the CLI"
106105

107-
# 6. Let Suno write the lyrics for you
106+
# 7. Or skip the composer and let Suno write the lyrics from a description
108107
suno describe --prompt "a chill lo-fi track about rainy mornings" --wait
109108
```
110109

@@ -115,14 +114,18 @@ Generation costs ~70 credits per call on v5.5 (35 per clip, 2 clips per call —
115114
`suno write` is the way to compose. It assembles a Suno-ready song scaffold from a genre grammar compiled into the binary — a Style Prompt line, a meta-tagged `[Verse]`/`[Chorus]` skeleton with inline `<...>` lyric placeholders, and a Suno Tags line — then hands you the exact `suno generate` command to run. The grammar is executable, so you never hand-assemble a style prompt: run one command, fill the `<...>` slots, generate.
116115

117116
```bash
118-
# 1. Scaffold the song (free, no credits) — plain text to stdout, or --out to a file
117+
# 1. Scaffold the song (free, no credits) — --out writes the lyric block to a file
119118
suno write --genre "indie rock" --theme "late-night city drives" --vocal male --viral --out song.txt
120119

121-
# 2. Fill the <...> lyric lines in song.txt, then generate the audio
122-
suno generate --title "..." --tags "..." --lyrics-file song.txt --model v4.5-all --wait --download ./songs/
120+
# 2. Fill the <...> lyric lines in song.txt, then run the command `write` printed
121+
suno generate --title "..." --tags "..." --lyrics-file song.txt --wait --download ./songs/
123122
```
124123

125-
Fuzzy genre matching covers ~24 subgenres; an unknown genre is passed through verbatim as a style tag, so `write` never fails on input. In human mode the song is raw plain text on stdout and the ready-to-run `suno generate` command prints to stderr; piped or with `--json` you get a `{title, mode, genre, style_prompt, structure, suno_tags, structure_tags, bpm, vocal, theme, viral, instrumental, generate}` envelope.
124+
`--out` writes the **lyric block only** — no title, no style prompt, no tag list — so the file feeds `generate --lyrics-file` directly and nothing but lyrics reaches the model. The title, Style Prompt and Suno Tags go to stderr (human mode) and into the JSON envelope; `--project-out FILE` additionally saves the full composite document for humans. `suno generate` refuses lyrics that still contain `<...>` scaffold placeholders (exit 3, naming the line numbers), so an unfilled draft can never burn credits — `--force` overrides.
125+
126+
Note that shell redirection (`suno write > song.txt`) receives the JSON envelope, not lyrics: output is a JSON envelope whenever stdout is not a terminal. `--out` is the way to get an editable lyrics file.
127+
128+
Fuzzy genre matching covers ~24 subgenres; an unknown genre is passed through verbatim as a style tag, so `write` never fails on input. Piped or with `--json` you get a `{title, mode, genre, style_prompt, structure, suno_tags, structure_tags, bpm, vocal, theme, viral, instrumental, placeholders_remaining, ready_to_generate, missing_requirements, next_action, written}` envelope. `next_action.argv` is the authoritative handoff — run it as argv, never shell-parse `next_action.command`. It is `null` until `--out` names a real file, and the emitted command omits `--model` so your configured default applies (add `--model v4.5-all` for a ~10-credit draft).
126129

127130
### Priming / research songs
128131

@@ -135,6 +138,8 @@ suno write --mode priming \
135138
--domain marketing --subtlety stealth --out song.txt
136139
```
137140

141+
Priming is consent-based, so `--target`, `--objective` and `--domain` are required: an incomplete request exits 3 with the missing flags named, rather than emitting a scaffold and a ready-to-run command. The objective also seeds the song theme. The Prime-Stack Map and research artefact stay out of the lyrics file — they live in the JSON envelope and `--project-out`.
142+
138143
The deep references live in the built-in guides: `suno guide songwriting` for the full grammar, `suno guide priming` for the consent frame, evidence-graded prime library, and quality gates.
139144

140145
| Flag | What it does | Values |
@@ -145,11 +150,14 @@ The deep references live in the built-in guides: `suno guide songwriting` for th
145150
| `--vocal` | Vocal gender direction | male, female |
146151
| `--bpm` | Tempo | number (else the genre's default) |
147152
| `--viral` | Add earworm/hook meta-tags | flag |
148-
| `--instrumental` | No vocals, no lyric placeholders | flag |
153+
| `--instrumental` | No vocals, no lyric placeholders; adds `--instrumental` to the emitted command | flag |
149154
| `--title` | Song title | free text (else derived from theme) |
150155
| `--mode` | Composition mode | songwriting (default), priming |
151-
| `--target` / `--objective` / `--domain` / `--subtlety` | Priming research fields | `--mode priming` only |
152-
| `--out` | Write the song to a file | path (else stdout) |
156+
| `--target` / `--objective` / `--domain` | Priming research fields | required with `--mode priming` |
157+
| `--subtlety` | Priming subtlety dial | stealth, medium (default), overt |
158+
| `--out` | Write the lyric block to a file (the generation input) | path |
159+
| `--project-out` | Write the composite human document to a file | path |
160+
| `--download` | Download dir baked into the emitted generate command | path (default `./`) |
153161

154162
## Commands
155163

assets/SKILL.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,22 @@ One binary does the whole job — composing the song and rendering the audio. Al
1111

1212
1. Scaffold a Suno-ready song from the built-in grammar:
1313
```bash
14-
suno write --genre "indie rock" --theme "late-night city drives" --vocal male --viral --out song.txt
14+
suno write --genre "indie rock" --theme "late-night city drives" --vocal male --viral --out song.txt --json
1515
```
16-
You get a Style Prompt line, a meta-tagged `[Verse]`/`[Chorus]` skeleton with inline `<...>` lyric placeholders, a Suno Tags line, and the exact `suno generate` command to run next.
17-
2. Fill in the `<...>` lyric lines in `song.txt`.
18-
3. Render the audio:
16+
`--out` writes the **lyric block only** (meta-tagged `[Verse]`/`[Chorus]` skeleton with inline `<...>` placeholders), so the file feeds `generate --lyrics-file` directly. The Style Prompt, Suno Tags and `data.next_action` come back in the JSON envelope. `--project-out FILE` saves the composite human document; never pass that one as lyrics.
17+
2. Fill in the `<...>` lyric lines in `song.txt` — replace every angle-bracket span, keep the `[Section]` tags, repeat the chorus verbatim.
18+
3. Render the audio by running `data.next_action.argv` (authoritative — never shell-parse `next_action.command`):
1919
```bash
20-
suno generate --title "..." --tags "..." --lyrics-file song.txt --model v4.5-all --wait --download ./songs/
20+
suno generate --title "..." --tags "<style_prompt>" --lyrics-file song.txt --wait --download ./songs/
2121
```
22+
`generate` exits 3 if any `<...>` placeholder survives, so an unfilled scaffold can never burn credits. It uses the configured default model; add `--model v4.5-all` for a ~10-credit draft.
2223

2324
## Priming / research songs
2425

2526
```bash
26-
suno write --mode priming --target "..." --objective "..." --domain investment --subtlety stealth --out song.txt
27+
suno write --mode priming --target "..." --objective "..." --domain investment --subtlety stealth --out song.txt --json
2728
```
28-
Adds a chill-lounge low-arousal scaffold plus a Prime-Stack Map and research-artefact block. Then fill the lyrics and `suno generate` as above.
29+
Adds a chill-lounge low-arousal scaffold plus a Prime-Stack Map and research-artefact block (in the envelope, not the lyrics file). Priming is consent-based: `--target`, `--objective` and `--domain` are required and a missing one exits 3. Then fill the lyrics and `suno generate` as above.
2930

3031
## Deep reference & everything else
3132

@@ -35,4 +36,4 @@ Adds a chill-lounge low-arousal scaffold plus a Prime-Stack Map and research-art
3536
- `suno --help` / `suno <command> --help` — usage, tips, real examples
3637
- First run: `suno auth --login`, then `suno doctor` to verify
3738

38-
Piped output is a JSON envelope automatically. `suno write` and `suno lyrics` are free; generation ≈70 credits/call on v5.5.
39+
Piped output is a JSON envelope automatically`suno write > song.txt` gets JSON, not lyrics; use `--out`. `suno write` and `suno lyrics` are free; generation ≈70 credits/call on v5.5.

0 commit comments

Comments
 (0)