# CLI reference

The command list below is emitted by the native CLI built with this wiki. Start with `check`, use `format` to inspect canonical text, and add `--write` only when you want to save it.

```text
scorescript — the ScoreScript toolchain

USAGE
    scorescript docs [<chapter>|--list]
    scorescript import <file.musicxml|file.mxl> [-o <out>]
    scorescript musicxml <file> [-o <out>] [--movement <id|number>] [--concert]
    scorescript check  <file> [--severity error|warning|info]
                              [--format text|json] [--delta <baseline.jsonl>]
    scorescript format <file> [--write] [--durations numbers|letters]
                              [--no-align] [--compact]
                              [--normalize <pass>[,<pass>...]]
    scorescript format --list
    scorescript render <file> [-o <out>] [--movement <id|number>] [--staff-space <n>] [--width <n>] [--transposed] [--layout <name>]
    scorescript pdf    <file> [-o <out>] [--page letter|a4] [--part <name>] [--concert|--transposed]
                              [--book] [--movement <id|number>] [--layout <name>] [--save-layout <name>]
    scorescript parts  <file>
    scorescript layouts <file>
    scorescript geometry <file> [--flowing] [--systems]
    scorescript to-grid  <file> [-o <out>] [--by measures|systems|rehearsals]
    scorescript to-parts <file> [-o <out>]
    scorescript part get <file> "<name>" [-o <out>]
    scorescript part put <file> "<name>" <edited> [--write]
    scorescript expand <file> --part "<name>" --bars <a>[-<b>] [--write]
    scorescript midi   <file> [-o <out>] [--movement <id|number>]
    scorescript play   <file> [--movement <id|number>]
    scorescript jam    <file> [--loop m9-16] [--part <name>] [--mute <name>] [--program [<name>=]<n>]
                              [--movement <id|number>] [--soundfont <path>] [--audio-driver <name>]
                              [--render <path>] [--for <seconds>] [--dry-run] [--tick <ms>]
                              [--view code|score|none] [--score] [--gfx kitty|braille|blocks|none]
    scorescript view   <file> [--port <n>] [--no-open]
    scorescript install-desktop [--uninstall]
    scorescript lsp

COMMANDS
    docs     read a wiki chapter offline as Markdown; --list prints chapter names.
             Uses the same teaching documents as the website and MCP resources.
    import   read MusicXML and print the canonical ScoreScript it becomes
             (stdout when no -o). Everything the language cannot hold is a
             diagnostic on stderr, named and counted. Compressed .mxl follows
             META-INF/container.xml and is opened with bounded decompression.
    musicxml write uncompressed MusicXML 4.0 (stdout when no -o) — the door
             out, so a score is never hostage to this toolchain. Each part is
             written at the pitch its player READS, with a <transpose> saying
             how to reach concert; --concert writes the sounding score with no
             transposition instead. A two-staff piano is ONE part with two
             staves, as the format means it. Anything that cannot make the
             crossing is named on stderr as `not exported: …`, never dropped.
    check    print diagnostics as file:line:col: severity[code]: message — teaches
             (exit 1 when any of them is an error). --severity prints that tier
             and everything more serious, and --severity error skips the
             layout-borne alignment check, so it is parse + analyze only.
             --format json prints one object per line — severity, code,
             message, file, line, column, part, bar, range — with no teaching
             prose and a trailing {"summary"} line. --delta <baseline.jsonl>
             prints only what a previous --format json run did not have, keyed
             on (code, part, bar, message) so an edit that shifts lines
             reports nothing.
    format   print the canonical spelling; --write rewrites the file in place.
             A source with errors is left untouched and its errors are printed.
             The three skin flags re-spell the same music without changing it:
             --durations letters writes q e h w s t instead of 4 8 2 1 16 32,
             --no-align stops padding the grid's columns, and --compact drops
             the indentation and the blank lines as well. Every skin re-reads
             as the same score, and every one of them is idempotent.
             --normalize runs named passes from the normalization menu on top
             of the canonical form (hoist-breaks, key=open, chromatic,
             strip-dev-text, jargon-lint …); what each pass did is reported on
             stderr as file:line:col. `format --list` prints the whole menu.
    render   write a self-contained SVG, one long page (stdout when no -o).
    pdf      write a paginated PDF (stdout when no -o). --part prints one
             player's part, laid out for that part alone AND transposed to the
             pitch that player reads; it still carries the tempo, the rehearsal
             marks and the repeats, wherever they were written. Nothing is
             embedded: notation is vector outlines and words use the standard
             PDF faces.
    parts    print the parts' printed names, one per line — what --part accepts.
    layouts  print this score's layout configurations, one per line, from the
             sidecar beside it (<stem>.layouts.json). A score with no sidecar
             prints the built-in configuration and how to write one. `*` marks
             the one a viewer opens on.
    geometry print where every event landed on the printed pages, one per
             line: id, page (1-based), then x y w h in that page's own
             coordinates — one unit per staff space, the origin at the top-left
             of the sheet. The pages are the ones `pdf` prints and the ids are
             the ones `play` sounds, so this is the map a click, a selection
             and a playhead are built from. --flowing measures the OTHER
             layout instead — the one tall picture `render` draws — because
             the two put a note in different places. --systems prints the
             system bands rather than the events: system, page, x y w h, and
             how many events the band holds, which is the vertical extent a
             playhead spans and the region a click resolves into.
    to-grid  print the same program as editable measure blocks: one row per
             part. --by measures uses compact structural ranges, --by systems
             follows authored \n / \p cuts, and --by rehearsals follows rehearsal
             sections. Each is one formatting of the same score.
    to-parts print the same program part-first: one `Part { … }` group each,
             with compact `mN-M { … }` ranges that can span mapped changes.
             Both directions are checked by
             analysing before and after — the music may not move.
    part get print ONE part as a score of its own, carrying the tempo, the key
             changes, the rehearsal marks and the repeats that were written on
             other players' lines. Edit that file, then:
    part put re-weave the edited part into the score and print the result
             (--write rewrites the score). It moves NOTES: a different bar
             count, meter, key or tempo is refused by name, never reconciled.
    expand   print the ScoreScript one player would carry if they wrote a
             shared line's bars out themselves — the head's music with their
             interval and register applied, as the block that overrides it
             (--write splices it in). A head is taken WHOLE, because a part
             that writes one of its bars stops reading all of them, so the
             bars it covers are usually more than were asked for; the
             whole-document form is `format --normalize expand`.
    midi     write a Standard MIDI File (stdout when no -o).
    play     say what the performance contains, and how to hear it. There is
             no audio engine in this toolchain, by design — `jam` sequences an
             external one rather than becoming one.
    jam      the live session: loop a bar range and keep playing while you
             write. On every save the file is recompiled; a clean save is
             swapped in AT THE NEXT BARLINE without the clock stopping, and a
             broken one prints its diagnostics and keeps the last good take
             sounding. A typo never causes silence. --loop takes a bar range
             (m9-16); --part solos and --mute excludes, both repeatable, so
             'play me just the strings' is one flag. Sound is fluidsynth's,
             driven over a pipe on our clock; --dry-run prints the loop and
             starts nothing. While it plays the terminal shows YOUR SOURCE,
             and the notes light up in it as they sound — the loop's lines,
             with the currently sounding events in reverse video. It is pure
             ANSI, so every terminal gets it. --view score instead engraves
             the loop's bars and sweeps a playhead over real notation (kitty
             graphics where the terminal has them, braille cells everywhere
             else; --gfx forces a tier), and --view none draws neither.
    view     open the file as a living page: real sheets on a dark desk, a
             Play button, and a redraw within half a second of ANY editor
             saving the file. A local server on 127.0.0.1, GET only; stop it
             with Ctrl-C or by visiting /quit.
    install-desktop
             register the file type with the desktop, so a double-click opens
             the viewer: writes ~/.local/share/mime/packages (the MIME type
             text/x-scorescript for *.scorescript, *.ss and *.score) and
             ~/.local/share/applications (the launcher), and nothing else.
             --uninstall removes exactly those two files.
    lsp      speak the Language Server Protocol over stdio.

OPTIONS
    -w, --write          format / part put: rewrite the file instead of printing
        --durations <k>  format: numbers (default, canonical) or letters
        --no-align       format: leave the grid's cells unpadded
        --compact        format: no indentation, no padding, no blank lines
    -o, --output <path>  render/pdf/midi/to-grid/to-parts/part get: write here
                         instead of stdout
        --movement <id>  render/pdf/midi/play: select one authored movement
        --by <landmark>  to-grid: measures, systems, or rehearsals
        --staff-space <n>  render: pixels per staff space (default 8)
        --width <n>        render: the width systems wrap inside, in pixels
        --page <size>      pdf: letter (default) or a4, 0.75in margins
        --part <name>      pdf: one part, by printed name ("Flute 1") or by
                           instrument key when it names only one part
        --transposed       render/pdf: the transposed-score view — every part
                           at the pitch its player reads. The text is concert
                           pitch, so a score is concert unless you ask.
        --concert          pdf: keep concert pitch, even for --part
        --layout <name>    render/pdf: draw this score the way the named
                           configuration says — paper, margins, staff size,
                           spacing, the engraving flags, concert or written,
                           and its part if it has one. It IS the page decision,
                           so it is refused alongside the flags it would
                           overrule. `scorescript layouts <file>` lists them.
        --save-layout <name>
                           pdf: store this command line as a configuration in
                           the sidecar, creating it if there is none — the
                           other knobs start at the engine's defaults, and the
                           file is yours to edit. The PDF is still printed.
    -p, --port <n>       view: listen here (default 4321; a port in use moves
                         to the next free one)
        --no-open        view: print the URL instead of opening a browser
        --uninstall      install-desktop: remove the two files it wrote
    -h, --help           print this
    -V, --version        print the tool and spec versions

```

Read [checking and fixing mistakes](checking.md) for the normal workflow.
