-
Notifications
You must be signed in to change notification settings - Fork 4
CLI Tools
ed tools answers one question: does this Mac have the command line programs
Edith's extensions shell out to, and where are they? Three tools are in the
catalogue, and the catalogue is fixed in the binary: yt-dlp, which the Music
extension and the whole download queue run, and claude and codex, the agent
CLIs behind Agent Usage.
ls looks for each one and asks it for its version. install reports the tool
when it is already there and otherwise fetches it itself, in this process, the
command line counterpart of the Install button on the tool's row in Settings.
Neither verb needs Edith to be running, neither writes a setting, and neither
can remove a tool: uninstalling stays with Homebrew, npm or rm.
ed tools with nothing after it runs ed tools ls, and ed tools list is the
same command.
| Command | What it does |
|---|---|
ed tools |
Runs ed tools ls, which is the default subcommand. |
ed tools ls |
Lists all three tools with whether each is installed, its version, and why Edith wants it. |
ed tools install <tool> |
Reports the tool when it is already installed, otherwise fetches it here and checks it landed on PATH. |
Every tool ed can report on or install, in the order ls prints them. All
three are listed on every run, whether or not the extension that wants them is
switched on.
id |
Name | Wanted by | Present when |
install fetches it from |
|---|---|---|---|---|
yt-dlp |
yt-dlp | The Music extension, and everything under ed download
|
an executable called yt-dlp is on the assembled PATH |
the official release asset https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos, downloaded with curl --fail --location --progress-bar, made executable, and moved to ~/Library/Application Support/Edith/bin/yt-dlp
|
claude |
Claude Code | The Agent Usage extension | an executable called claude is on the assembled PATH |
brew install --cask claude-code, falling back to npm install -g @anthropic-ai/claude-code
|
codex |
Codex | The Agent Usage extension, and only while codexLimitsEnabled is on, which it is unless you turn it off |
an executable called codex is on the assembled PATH |
brew install --cask codex, falling back to npm install -g @openai/codex
|
The version string in every case is the first line the tool prints for
--version: stdout alone when ls reads it, stdout and stderr together when
install verifies what it just did.
Only yt-dlp lands somewhere Edith owns. The two agent CLIs go wherever
Homebrew or npm puts them, so the path field of ed tools ls --json is the
only reliable answer to which binary is being used. The fallback order is
Homebrew first and npm second: npm is tried both when brew --version fails
and when the brew install itself exits non-zero, and an install with neither
manager available fails with Neither Homebrew nor npm is available for installing Claude Code.
When an install fails, ed prints the tool's manual instruction as the hint,
which is the line to run by hand:
yt-dlp Download yt-dlp_macos from the official yt-dlp release and place it in a folder on PATH.
claude Install with `brew install --cask claude-code` or `npm install -g @anthropic-ai/claude-code`.
codex Install with `brew install --cask codex` or `npm install -g @openai/codex`.
ed does not search your shell's PATH. It builds its own, in this order,
and looks in each directory for a file with the tool's name that the operating
system considers executable:
~/Library/Application Support/Edith/bin
$HOME/.local/bin
~/.local/bin
~/.nvm/current/bin
~/.nvm/versions/node/<version>/bin
/opt/homebrew/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
<every directory already in your PATH, in its own order>
Duplicates are dropped keeping the first occurrence, paths are standardised
before they are compared, the nvm version directories are sorted by name and
then reversed so the lexicographically last one is searched first, and anything
under /Volumes is thrown away because a disk that may not be mounted must not
decide whether a tool exists. The home directory wins that test: a path inside
it is kept even when the home itself sits on an external volume.
$HOME/.local/bin is the same directory as ~/.local/bin unless the
HOME variable in the environment says otherwise, in which case both are
searched. The same assembled PATH is handed to the tool as its environment when
ed runs it, and it is the same one Edith itself uses to run yt-dlp and to
read Codex limits, so what ed tools ls reports is what the app will find.
| Code | When this group produces it |
|---|---|
| 0 | The listing printed; the tool was already installed; the install finished and the tool answered --version. Also --help on the group or on either verb. |
| 2 | The command line was wrong in ArgumentParser's own terms: ed tools install with no tool, an unknown flag, or an extra argument (ed tools ls extra and ed tools bogus both land here, because the unmatched word is offered to the default subcommand ls, which takes none). |
| 3 |
install was given something that is not one of yt-dlp, claude or codex, under either its id or its display name. |
| 4 |
install ran and could not finish: neither Homebrew nor npm available, a curl, chmod, brew or npm that exited non-zero, or a tool that could not be verified afterwards. |
Nothing here exits 1. The only failures are a name that does not resolve and an install that did not land.
-
The PATH
edsearches is assembled, not inherited, soed tools lsand your shell can disagree in both directions. On this Mac yt-dlp is invisible to zsh and perfectly visible toed, because it lives in the directory Edith installs into:$ yt-dlp --version zsh: command not found: yt-dlp $ ed tools ls --json | jq -r '.[] | select(.id == "yt-dlp") | .path' /Users/pulkit/Library/Application Support/Edith/bin/yt-dlpThe reverse also happens: a tool that only exists in a directory under
/Volumesis reported as missing however well it works in your shell. -
lsis not free the first time. It launches every installed tool to read a version, and the standalone macOS build of yt-dlp takes seconds to answer, which dominates the whole command:$ time ed tools ls > /dev/null ed tools ls > /dev/null 0.49s user 0.28s system 9% cpu 8.393 totalEach answer is then kept in
~/Library/Application Support/Edith/tool-versions.jsonagainst that binary's size and modification time, so the next run reads the file and launches nothing:$ time ed tools ls > /dev/null ed tools ls > /dev/null 0.02s user 0.01s system 126% cpu 0.019 totalUpdate or replace a tool and its stamp stops matching, so the next
lsprobes that one again. The three probes run concurrently, so a cold run costs the slowest tool rather than the sum, and there is still no timeout around the call: a tool whose--versionhangs hangsed tools lswith it. -
installedmeans a file with that name is executable on the assembled PATH. It is not a claim that the tool runs. The exit status of--versionis ignored here, while the app's own provisioner treats a non-zero status as missing, so a broken install can readinstalledined tools lsand still show as missing in Settings. -
installis not fire and forget. It runs the download or the package manager itself and does not return until the tool has answered--version, so a zero exit means the tool is there anded tools lswill say so. The Extensions pane, its setup sheet and the onboarding flow drive the sameToolInstallerfrom the app. The app keeps one install per tool at a time;edknows nothing about those, so do not start the same tool from both at once. -
A failure reads twice in a terminal, once as the red
✖row and once as theerror:line. The progress rows are skipped when stderr is not a terminal or when--jsonis passed, and theerror:line never is, so a piped run shows the reason exactly once. -
There is no uninstall and no
--yesguard.installnever touches a tool that is already on PATH, and the only file it removes is a leftover at~/Library/Application Support/Edith/bin/yt-dlpthat the fresh download replaces, so the worst a wrong id can do is exit 3. -
codexLimitsEnableddecides whether the Agent Usage sheet insists oncodexbefore it considers itself set up. It has no effect oned tools, which lists and installs all three regardless. Turning the Music or Agent Usage extension off does not remove anything either: tools stay installed when the extension that wanted them is disabled. -
The relation between tools and extensions is readable from the other side:
ed extensions info music --jsonreports"requiredTools": ["yt-dlp"]anded extensions info usage --jsonreports["claude", "codex"]. -
ed download toolis the second view of the same yt-dlp. It prints the version and path of the binary found on the same assembled PATH, anded download tool --updaterunsyt-dlp -Uon it. The two disagree on tone when the tool is absent:ed tools lsprints amissingrow and exits 0,ed download toolexits 4 withyt-dlp is not installed. -
The
whycolumn is the tool spec's own sentence, not a summary written for the CLI, so it is word for word what the setup sheet shows under the tool's name. The Settings row shows the same sentence until it has checked, then replaces it withInstalled, <version>or with the failure and its manual instruction. -
Completion knows the verbs but not the tools.
ed tools <TAB>offerslsandinstall;ed tools install <TAB>offers nothing at all, because the completion tree marks that argument free rather than pointing it at the catalogue. Type the id. -
Both verbs take
--jsonin its usual form, long only, declared per verb. There is no-j, anded tools --jsonworks only because the bare group falls through tols.
-
ed download, the queue yt-dlp serves, and theed download toolverb for updating it in place. -
ed extensions, which is whererequiredToolscomes from and where turning a feature on can want a tool. -
ed usage, the numbersclaudeandcodexmake possible. -
All
edcommands.
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