yardsort

The ys command line

ys drives Yardsort from a terminal. It reads the same database as the app, so a workspace made with ys appears in the window and a workspace made in the window appears in ys. It does not need the app to be running.

An agent started by ys belongs to the daemon, not to the command — so it keeps working after ys returns, and you can open Yardsort later to watch it. That is the whole point of it.

Installing

ys comes with the app. Every copy of Yardsort carries it next to its own executable, built from the same commit, so the two always agree about the database. Whether it is on your PATH depends on how you installed Yardsort:

How you installed YardsortWhere ys isHow it is updated
.deb, .rpm, or the AUR package/usr/bin/ys, installed with the app. Nothing to do.By your package manager, with the app.
Homebrew caskLinked onto your PATH by Homebrew.With the app.
macOS app (.dmg)Install ys makes /usr/local/bin/ys, a link into Yardsort.app. macOS asks for your password when that folder needs it.With the app: the link points into it. Signed and notarized with it, too.
Linux AppImageInstall ys copies it to ~/.local/bin/ys. An AppImage is mounted somewhere new every time it starts, so a link would stop working.When Yardsort starts and finds an older copy there, it replaces it.
Windows installer (-setup.exe, .msi)Install ys copies it to %LOCALAPPDATA%\dev.yardsort.app\bin\ys.exe and adds that folder to your user PATH. Terminals opened afterwards find it; ones already open do not.When Yardsort starts and finds an older copy there, it replaces it. A ys.exe that is running at that moment is renamed aside and removed next time.

Install ys is in Settings → General → Command line. The first-run checklist on the welcome screen has it too, while ys is missing or out of date. Both say where your terminal finds ys and which version it is. It is optional: nothing in the app needs ys.

  • Something else is called ys. If there is already a file at the install location and it is not Yardsort's ys, Yardsort asks before replacing it; Cancel leaves it alone. A ys already there, of any version, is replaced without asking. So is a broken link left by a Yardsort.app that has since moved; a broken link to anything else counts as something else.
  • Another ys comes first. If your terminal finds a ys somewhere else — one you unpacked by hand, say — the panel names it. Installing then puts Yardsort's own copy at the install location, but the other one keeps winning until you remove it.
  • ~/.local/bin is not on your PATH. Most Linux distributions add it when it exists, but not all. The panel says so; add it in your shell's startup file (for example export PATH="$HOME/.local/bin:$PATH") and press Check again.
  • macOS says to move Yardsort first. A link into an app that is still on its disk image, or that macOS is running from a temporary copy, would break. Drag Yardsort into Applications and open it from there.

To remove it, delete the file or link at the install location, and on Windows the folder's entry in your user PATH.

Without the app

ys is also a separate download: a single binary in the assets of each release. Put it anywhere on your PATH.

# Linux
tar -xzf ys-*-linux-x86_64.tar.gz && sudo install ys /usr/local/bin/

# macOS (universal)
tar -xzf ys-*-macos-universal.tar.gz && sudo install ys /usr/local/bin/

On Windows, unzip ys-*-windows-x86_64.zip and put ys.exe in a folder on your PATH.

This copy of ys is not signed or notarized on macOS, unlike the one inside the app. A copy downloaded with a browser is therefore quarantined and refused on first run. Either download it with curl, or clear the flag:

xattr -d com.apple.quarantine ys

A copy installed this way does not update itself.

Commands

Run ys --help, or ys <command> --help, for the full list. Every command takes --json, which prints a machine-readable version instead of a table.

ys project list

The repositories Yardsort knows about, with how many workspaces each has.

NAME       WORKSPACES  PATH
yardsort   3           /home/you/projects/yardsort

Projects are added in the app; ys does not create them.

ys workspace list

Every workspace, including each project's own local checkout. --project <name> narrows it to one project and --all includes archived ones. With --json each entry carries a kind, which is local for a project's own checkout and worktree for one Yardsort made.

ys workspace new <project> "<prompt>"

The main one. Creates a branch and a worktree, then starts an agent in it with your prompt as its first message — the same thing the composer does in the app.

ys workspace new yardsort "fix the flaky login test"
created  fix-the-flaky-login-test
  branch ys/fix-the-flaky-login-test
  path   /home/you/yardsort/yardsort/fix-the-flaky-login-test
  agent  claude (a49add8f)

It keeps working after this command returns. Open Yardsort to watch.
OptionWhat it does
--base <branch>Branch to start from. Default: the repository's default branch.
--harness <id>Which agent to run. Default: the first one found on your PATH.
--model <model>Model, for harnesses that take one.
--effort <level>Effort or thinking level, for harnesses that take one.
--no-agentCreate the branch and worktree and start nothing.

The project can be named or given by id. If the harness you asked for is not configured or not installed, nothing is created at all — no branch, no folder, no record.

ys workspace delete <workspace>

Removes the folder and forgets the workspace, including its session history. The branch is kept — commits are never thrown away, same as Delete workspace in the app. Delete the branch yourself with git if you want it gone. A project's own local checkout cannot be deleted.

ys workspace delete fix-the-flaky-login-test
deleted  fix-the-flaky-login-test
  branch ys/fix-the-flaky-login-test (kept)
  path   /home/you/yardsort/yardsort/fix-the-flaky-login-test

The workspace can be a name or an id from ys workspace list --json. A name that matches more than one workspace is refused, and the ids are printed so you can say which one. Archived workspaces are included: deleting one removes it for good.

Uncommitted changes and untracked files are refused, and nothing is removed. They live only in the folder, so there is no way back to them. --force is the confirmation that they should go:

ys workspace delete fix-the-flaky-login-test --force

A process that is already running in the workspace is not stopped. That is what lets a harness delete the workspace it is standing in and still finish; the folder disappears underneath it and the command returns. The branch is there either way. ys steps out of the folder before removing it. On Windows a folder that is still some other program's current directory — the agent or shell that launched the command — cannot be removed, and nothing is deleted.

ys workspace handoff <workspace>

Prints the handoff packet for a workspace: what Yardsort recorded there — the task, where the branch stands and who wrote each changed file, what each agent run did, and what is not known — written as the next agent's first message. The same text the app's Hand off… button starts from (see handing work to another agent), without Assist's ordering of the files, which the command line has no key for.

ys workspace handoff fix-the-flaky-login-test
ys workspace handoff fix-the-flaky-login-test > handoff.md

The workspace can be named or given by id. --json gives { "text", "runs", "events" }. Nothing is started: pipe the text where you want it, or paste it as an agent's first message.

ys session list

Agent conversations. Running ones by default; --all includes those that have ended, and --workspace <name> narrows it to one.

ID        WORKSPACE                 HARNESS  STATE    TITLE
6051993d  fix-the-flaky-login-test  claude   running  fix the flaky login test

The state column compares two things, because they can disagree:

StateMeaning
runningThe record says running and the daemon confirms the process is there.
goneThe record says running but the process is not — it died with nobody watching. Yardsort settles the record the next time it starts.
running?The record says running and there is no daemon to ask.
endedThe conversation finished, and the record says so.

ys attach [target]

Puts a running session on your terminal: the screen is repainted where it got to, and what you type goes to the agent. Ctrl-] detaches, and the agent carries on — detaching is not stopping, exactly as closing the Yardsort window is not stopping.

ys attach                      # when only one thing is running
ys attach fix-the-flaky-login-test
ys attach 6051993d             # the start of an id from `ys session list`

With nothing named it attaches to the only running session, and asks which one you meant if there is more than one. A shell has no workspace name, so reach it by id.

Attaching matches the session to your terminal's size, and follows it if you resize the window. If the app has the same session open in a tab, that tab's size and yours are the same setting — whichever changed last wins, and the app sets it again when you next focus the tab. --no-resize leaves the size alone, at the cost of a program drawing to a width you cannot see.

You can attach to a session the app also has open; both see the same output, and either can type. Only sessions that are still running can be attached to.

ys logs [target]

Prints what a session has on its screen, without taking the terminal over — including sessions that have finished, which is the one thing attach will not do.

ys logs                        # the only session, if there is one
ys logs fix-the-flaky-login-test
ys logs --lines 20             # just the end of it
ys logs --json                 # the text as a JSON field, for scripts
ys logs --raw                  # escape sequences and colours, exactly as the app would repaint

Without --raw the screen is replayed through a terminal emulator and handed back as plain text, so it can be read, grepped or piped. Scrollback comes too, as far back as the session kept it.

Screens live in the background process, not in the database. It stops once nothing is connected and nothing is running — so a finished agent's last screen is readable while Yardsort is open, or while other agents are still working, and gone a short while after the last of them stops. ys logs says so rather than reporting an empty screen. Nothing is written to disk: a screen can hold anything the agent printed, and Yardsort does not keep a copy of that.

ys activity list

The newest recorded activity: when each agent, shell or run command started in a workspace and how it ended, newest first. --workspace <name> narrows it to one workspace, --limit <N> changes how many rows (50 by default), and --json prints the same rows as a JSON array with the event's full payload.

WHEN                  WORKSPACE      EVENT            SOURCE              DETAILS
2026-09-24 20:44:15Z  fix-the-login  process.exited   yardsort/lifecycle  exit 0, via spool
2026-09-24 20:44:02Z  fix-the-login  tool.completed   claude/hook         Edit src/login.rs, 12 ms
2026-09-24 20:43:59Z  add-a-footer   usage.reported   codex/session_file  29842 tokens
2026-09-24 20:43:41Z  rename-the-cli tool.completed   opencode/plugin     write src/main.rs
2026-09-24 20:43:12Z  tidy-the-tests approval.resolved grok/session_file  run_terminal_command, allow, waited 4210 ms
2026-09-24 20:43:05Z  add-a-footer   turn.completed   omp/extension       19963 tokens
2026-09-24 20:42:50Z  rename-the-cli file.reported_write cursor/hook      src/main.rs
2026-09-24 20:43:58Z  fix-the-login  process.started  yardsort/lifecycle  claude, opus, reporting via hook

Rows from claude/hook, codex/session_file, opencode/plugin, grok/session_file, omp/extension, pi/extension and cursor/hook are what the agents themselves reported or recorded, when capture is on for them; the rest is what Yardsort saw.

Any ys command that reads the daemon first takes the exits it kept while nothing was connected into the database, so a session list after an agent finished on its own says ended rather than gone.

ys memory

A project's memory: short lessons for its agents, which you approve in the app. Meant as much for the agents Yardsort starts as for you — any of them can run it.

ys memory list                          # approved entries, newest first
ys memory search timezone tests         # approved entries containing every word
ys memory propose "The tests need TZ=UTC."

Run inside a workspace, it is about that workspace's project; elsewhere, name it with --project <project>. list and search answer only in a project that shares its memory with its agents — the switch in the Memory view — and say so otherwise; propose works either way. propose adds a proposal for you to review in the Memory view and says so; when an agent Yardsort started runs it, the proposal records which agent and which workspace. There is no command to approve, edit, reject or revoke: those are yours, in the app, because an agent can run anything ys offers. --json works as everywhere.

ys workflow

The workflows Yardsort knows: the built-in ones and the files in your profile's workflows folder.

ys workflow list                 # every workflow, whether it is ready, and where it comes from
ys workflow show code-review     # the file that would be used, then any problems on stderr
ys workflow copy code-review     # your own copy to edit, used instead of the built-in
ys workflow validate fix-ci.yaml # each problem as file:line:column: message; exit 1 if any
ys workflow validate -           # the same, reading the file from standard input
ys workflow run ping --workspace fix-login --input note=hi   # queue a run; Yardsort must be open
ys workflow runs                 # runs, newest first; --run <id> shows one step by step
ys workflow cancel 3f2a9c1e      # stop a run; agents it started keep running

copy writes into the workflows folder and never overwrites; --as <new-id> makes a second workflow instead of a replacement. validate needs no profile, so it works on any machine, in CI, or on a file an agent has just written. list also prints where the workflows folder is.

run checks the workflow, the workspace and every input before it queues anything, and refuses while Yardsort is closed, because the app is what carries runs out. Inside a workspace's folder, or in an agent's terminal there, --workspace can be left out. It prints the run's id and returns at once. A workflow that uses the pull request needs the GitHub CLI (gh), logged in, and an open pull request for the workspace's branch. A run id can be shortened to its first characters, as runs prints it. --json works as everywhere. See Running a workflow and Requesting a code review.

ys activity export

Every recorded event as NDJSON on stdout — one JSON object per line, oldest first, with the same fields --json shows. --workspace <name> narrows it. Pipe it wherever you like; nothing else exports it.

ys doctor

Where ys is looking and whether it can get there: the data directory, the database, the daemon, which agents are on your PATH, how much activity is recorded, and where the exit spool and the agents' inbox are and whether anything is waiting in them. The first thing to run when ys and the app seem to disagree.

Profiles

ys looks for the same data directory the app uses. --data-dir <dir> points it at another one, which is how you reach a throwaway profile:

ys --data-dir /tmp/ys project list

YARDSORT_DATA_DIR works too, as it does for the app.

ys never creates a database. If it cannot find one it says which path it tried, rather than starting an empty one and telling you that you have no projects — see Troubleshooting.