-
Notifications
You must be signed in to change notification settings - Fork 4
CLI Music
ed music is two things behind one noun. It is transport control for whichever
music player is actually playing on this Mac, Spotify, Apple Music or Edith's
own library player, and it is the file manager for Edith's library folder:
listing, moving, renaming and trashing tracks. Reach for it to see what is
playing without switching apps, to drive playback from a script or a hotkey, and
to keep the library tidy from a shell.
The group answers to ed music, ed nowplaying and ed np. A bare ed music
runs ed music status, and flags meant for status may be given straight to
it, so ed np --json and ed music --player spotify both work.
| Command | What it does |
|---|---|
ed music status |
What is playing right now, on whichever player. The default subcommand. |
ed music play |
Resume playback on the active player. |
ed music pause |
Pause the active player. |
ed music stop |
Stop the active player and reset its position to zero. |
ed music toggle |
Toggle play and pause. Aliased playpause. |
ed music next |
Skip to the next track. |
ed music previous |
Go back to the previous track. Aliased prev. |
ed music volume |
Set the active player's volume, from 0 to 1. |
ed music players |
Every player Edith can see, and which one is active. |
ed music open-current |
Open the active player, including Edith's Music page. |
ed music reveal-current |
Reveal the current library track, or open its external player. |
ed music library |
Choose the folder Edith uses as its local music library. |
ed music ls |
List the library, a folder at a time. Aliased list. |
ed music mkdir |
Make a folder in the library. Aliased newfolder. |
ed music mv |
Move a track into a folder. Aliased move. |
ed music rename |
Rename a track or a folder. |
ed music rm |
Move a track or folder to the Trash. |
ed music start |
Play one track out of the library, or a whole folder. |
ed music seek |
Jump to a point in the current track, from 0 to 1. |
ed music shuffle |
Turn shuffle on or off, or report it. |
ed music repeat |
Turn repeat on or off, or report it. Aliased loop. |
ed music rescan |
Read the music folder again after changing it outside Edith. |
ed music favorite <track> |
Add a track to favourites. Aliased favourite. |
ed music unfavorite <track> |
Remove a track from favourites. Aliased unfavourite. |
ed music reveal <track> |
Reveal a track in Finder. |
ed music open |
Open the music library in Finder. |
There are exactly three players, and they are named builtin, spotify and
apple. builtin is Edith's own library player, which lives in the menu bar
app and shows up as Edith in human output.
Each is reached a different way, which is why some commands need Edith running and others do not.
-
spotifyandappleare driven straight over AppleScript:edpipes a script into/usr/bin/osascriptand waits up to 6 seconds. Edith does not have to be running for this, and never sees the command. -
builtinis driven over the app's own notification bus. Reading its state postsrequestMusicStateand waits up to 2 seconds for amusicStatereply; changing it postsmusicCommand. It counts as reachable only when the menu bar app is running and thetabMusicEnabledextension is on.
Every AppleScript starts with a System Events check for the player's process,
so a player that is not already open is reported as not running rather than
launched. Transport commands never open Spotify or Apple Music for you.
open-current and the external fallback of reveal-current can bring an
already-running player forward after that same eligibility check.
Choosing the active player. With no --player, ed takes a snapshot of all
three and scores each one: not running scores 0, running scores 1, plus 2 if it
has a track loaded and plus 4 if it is actually playing. The highest score wins.
Ties are broken first toward the player you last drove from the command line,
which ed remembers in the cliActivePlayer shared default after every
successful transport command, and otherwise toward the earlier player in the
fixed order builtin, spotify, apple. When the best score is still 0,
nothing is running and the command exits 4:
$ ed music pause
error: no music player is running
hint: open Spotify or Apple Music, or turn on Edith's Music extension
Forcing one. --player <name> skips the scoring, probes only that player,
and fails if it is not running. The spellings are generous and
case-insensitive:
| Player | Accepted spellings |
|---|---|
builtin |
builtin, built-in, edith, internal
|
spotify |
spotify |
apple |
apple, applemusic, apple-music, music, itunes
|
Anything else exits 3 with no player named <text> and the three canonical
names as the hint. A named player that is closed exits 4 and says which:
$ ed music next --player spotify
error: Spotify is not running
hint: open Spotify, then retry
--player exists on ten commands: status, play, pause, stop, toggle,
next, previous, volume, open-current and reveal-current. players
always looks at all three.
start, seek, shuffle and repeat always mean Edith's own player, because
they drive the library queue rather than a generic transport.
The command line, Music page, menu bar player, notch controls and media keys use
the same transport requests. A request therefore keeps the same play, pause,
stop, track, folder, seek, volume, shuffle and repeat semantics regardless of
which surface sent it. Scripts can use the commands above noninteractively and
add --json whenever they need stable structured output.
The Music page and command line also use the same library content operations for
listing and rescanning the library, making folders, moving tracks, renaming
tracks or folders, and moving either kind of item to the Trash. The app confirms
Trash actions in its sheets. ed music rm prints the exact path and track count
without changing anything until --yes is present, in plain text or as one JSON
document.
Folder selection is shared too. ed music library ~/Music performs the same
path expansion, directory validation, external-storage confirmation, stale-state
reset, cache invalidation and live notification as the Music page picker.
ed music statused music played music pauseed music stoped music toggleed music nexted music previoused music volumeed music playersed music open-currented music reveal-currented music libraryed music lsed music mkdired music mved music renameed music rmed music started music seeked music shuffleed music repeated music rescaned music favoriteed music unfavoriteed music revealed music open
| Code | What produced it |
|---|---|
| 0 | The command did what it says. Also the dry run of ed music rm without --yes, and ed music status --json when no player is running. |
| 1 | A library operation the filesystem refused: a blank name, a destination that already exists, a Trash that failed, or trashing the library root. Also shuffle or repeat given a word that is neither on nor off. |
| 2 |
volume or seek outside 0 to 1, a level or position that is not a number, an unknown flag, a missing argument. |
| 3 | An unknown --player spelling, a track query that matches nothing, a track query that matches more than one track, a library folder selection that does not exist or is not a directory, a folder that does not exist. |
| 4 | No player is running, or the forced player is not; no music folder is set; start or seek with the menu bar app closed; Edith's own player unreachable because the app is closed, the Music extension is off, or it did not answer in time; osascript refused, timed out, or macOS has not granted this command line Automation access. |
ed music status with no --player probes all three players in the order
builtin, spotify, apple, one after another. The built-in probe is skipped
instantly when the app is closed or the extension is off, and the AppleScript
probes return quickly when the player is not open, so the worst case is a slow
answer rather than a hang: 2 seconds for the built-in reply and 6 for each
script. --player cuts it to a single probe.
Automation failures are swallowed on the way in. Reading a player's state drops
any osascript error and treats the player as not running, and every transport
command probes before it sends, so with Automation denied ed music status
exits 4 with no music player is running and ed music pause --player spotify
exits 4 with Spotify is not running rather than naming the real cause. The
osascript error is reported verbatim only when the send itself fails after a
probe that worked: then ed exits 4 with
macOS has not granted this command line Automation access and points at
System Settings. That grant belongs to your terminal, not to Edith, and is
separate from anything ed permissions reports.
The last player you successfully drove is remembered in the cliActivePlayer
shared default and used only to break a tie between two players with the same
score. status and players read it; they never write it.
Every library content command needs a confirmed folder and exits 4 with
no music folder is set when there is none, even though the commands do not
need the app. Set it with ed music library ~/Music or from the Music page.
Both routes standardize the path and confirm external folders before any content
command can use them. A raw restored /Volumes value without that confirmation
is treated as unset instead of silently reading a fallback folder.
Track queries are matched against the relative path and the derived title, never
against file tags, and the first exact relative-path hit wins before any
substring matching happens. That makes ed music mv Chill/beta-tune.mp3 Focus
unambiguous even when beta matches several files.
Favourites follow a rename or a move, including a folder rename, because the
stored relative paths are repointed as part of the move. They do not follow a
trash: ed music rm leaves the old path sitting in musicFavourites.
ed music rename --folder "" <name> is rejected because the empty path is the
library root. The root can only be changed through ed music library <path>,
which updates confirmation and live state together.
shuffle and repeat write to the standard defaults domain, matching the
.standard scope those two settings declare in the config catalog, so
ed config get musicShuffling and ed music shuffle always agree.
Library mutations announce themselves on the app's notification bus:
mkdir, mv, rename, rm and rescan all post musicFolderChanged, and
mv and rename additionally post a renamed command so a running player
follows the file. None of them wait for an acknowledgement.
Every command in this group emits exactly one JSON document per invocation, with
object keys sorted, and prints diagnostics on stderr only. There is no streaming
mode here, so --json output is always pretty-printed.
-
ed configsetsmusicVolume,musicShuffling,musicLoopingand the rest of the generalmusicpreferences. -
ed extensionsturns themusicextension on, which is what makes the built-in player reachable at all. -
ed permissionscovers the grants that belong to the Edith bundle, which are not the Automation grant this group needs. -
ed downloadis how tracks get into the library in the first place. - All command groups
Auto-generated from docs/, edit the docs in the repo, not the wiki.
CLI reference
Companion
- Deploy
- Concepts
- Concepts Memory
- Concepts Ingestion
- Concepts Search
- Concepts Chat
- Concepts Learning
- Concepts Brain
- Concepts Friend
- Hosts
- Stack
- Status
- Doctor
- Search
- Index
- Ingest
- Episodes
- Sync
- Observations
- Reflect
- Beliefs
- Ask
- Extract
- Claims
- Corroborate
- Runs
- Chat
- Conversations
- Forget
- Export
- Import
- Erase
- Wipe
- Episode
- Nightly
- Reason
- Personas
- Council
- Lenses
- Core
- Why
- Hypotheses
- Predictions
- Commitments
- Discrepancies
- Calibration
- Inquire
- Entities
- Eval
- Standup
- Machines
- Baselines
- Connectors
- Facts
- Correct
- Weekly
- Db
Guides