Skip to content

Add agents - #15

Merged
geodro merged 2 commits into
lerd-env:mainfrom
prabowosd:agents-plugin
Nov 2, 2026
Merged

geodro merged 2 commits into
lerd-env:mainfrom
prabowosd:agents-plugin

Conversation

@prabowosd

@prabowosd prabowosd commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Adds agents (https://github.com/prabowosd/lerd-agents at a7c2e052de672aa11c6d0d902bf2d26205b57352), a plugin that shows the coding agents herdr and Orca run in each site and its worktrees, and opens any checkout in either tool. It works with whichever of the two is running and skips the other.

  1. Adds a site tab and Overview card "Agents", site commands "Open in herdr" and "Open in Orca", commands agents:status and agents:watch, hooks on worktree.added and worktree.removed, an MCP tool agents_status with a skill, and two endpoints: status (GET) and open (POST, loopback_only, the folder checked against the site's own checkouts).
  2. Reads Lerd's /api/sites, git worktree list in the site's folder, and the JSON output of the local herdr and orca commands. No .env, keys or secrets.
  3. Changes only herdr workspaces and Orca terminals it is asked to open, the site's repository in Orca (added when missing, set to show worktrees Orca did not create), and herdr-workspaces.json in its data folder. The worktree.removed hook closes only a workspace the hook created, never one with a working or blocked agent. Lerd itself is never changed.
  4. Sends nothing over the network. Notifications are declared and sent only by agents:watch, when an agent finishes or waits for input.
  5. Needs git and Node, lerd: ">=1.38", Linux and macOS. herdr and Orca are optional, so they are not under requires.
  6. The catalog has no fitting category yet, so the entry proposes AI; happy to change it.

The Agents tab, demo data

  • The repository is public and has an open source license.
  • The README says what the plugin adds, reads, changes and sends.
  • plugin.yaml declares lerd as a lower bound, and platforms if it runs on only one.
  • Everything it runs is readable source in the commit, in shell, Python, Node or similar but not PHP: no binaries, no minified code without its source, nothing downloaded and run.
  • It asks for no privilege and writes only to its own folder, its data folder and the sites it is run against, changing Lerd only through its API.
  • It reads no secrets it has no stated need for, and a site's .env only when the README says why.
  • Lerd's token never leaves the machine and is never written outside the plugin's data folder.
  • Hooks finish quickly and fail without leaving a site, service or database half changed.
  • Nothing leaves the machine without an opt-in the user turns on, and there are no analytics, tracking, ads or mining.
  • Any notifications are declared in plugin.yaml and only tell the user something they need to know or act on.
  • Pages bundle their own assets, nothing loads from third-party servers, and page scripts talk only to the plugin's own endpoints.
  • No services, so no images to pin.
  • No services or frameworks, so no name clashes.
  • The name, description and images describe what it actually does.
  • The images show the plugin itself, are mine to publish, and are at most 6, each a PNG, JPEG or WebP under 1 MB and at most 2560 px wide.

@prabowosd
prabowosd requested a review from a team as a code owner November 2, 2026 16:10

@geodro geodro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, it reads cleanly and the README matches what the code does. I went through every file at e068573 and ran it in a throwaway Ubuntu 26.04 desktop VM on lerd 1.38.0 against a Laravel site. Nothing leaves the machine, it asks for no privilege, it writes only its hooks.log and herdr-workspaces.json in its data folder, and lerd's config and sites were unchanged afterwards. Hostile input (a branch named with quotes, $(...) and markup, ../ and /etc as the folder, bad JSON) was refused or escaped everywhere, the tab and card escape what they draw, and open stays loopback only and checks the folder against the site's own checkouts. Nice work on that part.

One thing has to change before it can be listed. On Linux, Orca's desktop app installs its CLI as orca-ide, because GNOME's Orca screen reader already owns the name orca, and Ubuntu and Fedora desktops ship that screen reader at /usr/bin/orca. The plugin looks up plain orca, so on those machines every status poll from the tab or card (every five seconds), every agents:watch tick, the Open in Orca command and the worktree.added hook run the screen reader instead. It reads its arguments with parse_known_args, so it ignores worktree ps --json, prints "The following are not valid", and starts up for real when it has a display, which lerd's dashboard service has on a desktop session. Under a virtual display I saw it register on the accessibility bus, probe the braille API, write ~/.local/share/orca and dconf, and stay running until the 8 second timeout killed it. Without a display it segfaults in about a second, which is the 1.2s you see on Open in Orca.

The fix I'd suggest: on Linux look for orca-ide first (and ORCA_BIN), never fall back to a bare orca there, and only treat a binary as Orca once it answers with Orca's {"ok": ...} JSON. The README and DOCS should name orca-ide on Linux and link Orca's repository the way they link herdr.

A smaller one: the worktree.added hook can make up to six tool calls with 5 to 15 second timeouts each, which can pass lerd's fixed 30 second hook limit when herdr or Orca is slow to answer. Nothing is left half done when it is cut off, since the workspace record is written right after the create, but shorter timeouts in the hook would keep it inside the limit.

The category is free text in the catalog so AI works, happy to keep it.

agents:watch sends its notifications fine, but it drops the answer, so a 403 after the user switched them off goes unseen; lerd's plugin guide asks for a line on stderr in that case.

With herdr 0.9.5 running, everything on the herdr side did what the README says: Open in herdr created a workspace and focused it the second time, the tab listed the agent and its button focused the right workspace, agents:watch notified on working to idle and on blocked, and the hooks recorded the workspaces they made, kept the one with a busy agent on removal and closed the idle one. I could not run Orca itself, so its repo add and set and terminal paths are untested. Once the Orca lookup is fixed, push it and point the entry here at the new commit and I'll go through the diff.

@prabowosd

Copy link
Copy Markdown
Member Author

Thanks for running it through the VM, that screen reader catch was a good one. The entry now points at a7c2e052de672aa11c6d0d902bf2d26205b57352 (version 0.1.1), diff from e068573573bcd36efb00b0e13651ae2c252fc2bb: prabowosd/lerd-agents@e068573...a7c2e05

  1. On Linux the plugin looks up orca-ide only (or ORCA_BIN / ORCA_CLI_COMMAND) and never runs a bare orca. On either platform a binary counts as Orca only once status --json answers with JSON carrying a boolean ok, checked once per process. A stand-in that prints "The following are not valid" is reported as not found, and Open in Orca says so.
  2. The worktree.added hook caps every call with a 25 second deadline. With both herdr and Orca stubbed to hang, it finished in 13 seconds and logged both as skipped.
  3. agents:watch now writes a line on stderr when lerd answers 403 (with the command to turn notifications on) or anything other than 204.
  4. README and DOCS name orca-ide on Linux and link Orca's repository.

Orca's repo add, set and terminal paths are exercised here on macOS with Orca 1.4.214; I have no Linux desktop with Orca to run them on.

@geodro
geodro merged commit 0f8593c into lerd-env:main Nov 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants