Skip to content

feat: a herdr plugin for the sandbox controls (contrib) - #70

Open
TakiTake wants to merge 1 commit into
feat/herdr-method-driftfrom
feat/herdr-plugin
Open

feat: a herdr plugin for the sandbox controls (contrib)#70
TakiTake wants to merge 1 commit into
feat/herdr-method-driftfrom
feat/herdr-plugin

Conversation

@TakiTake

Copy link
Copy Markdown
Owner

Closes #61 — the last of the batch. Stacked on #69 (→ #68#67#66#65#63#62); only the last commit belongs to this PR.

What

contrib/herdr-plugin/ — link it with herdr plugin link contrib/herdr-plugin:

entrypoint kind does
status popup pane the pane's container, image, project, pall8t version, herdr pane + sandbox mode, and how many other sandboxes are running
shell overlay pane pall8t exec into the pane's container — a second shell beside the agent, which keeps running
rebuild / rebuild-no-cache popup pane pall8t build in that sandbox's project directory
stop action pall8t stop for the pane's container

Output-producing entrypoints are panes, not actions: an action's stdout lands in the plugin log, a pane lands in front of the person who asked. stop has nothing to show, so it stays an action.

Design notes

  • Finding the pane's sandbox is the whole trick, and it's why Ship a herdr plugin for pall8t sandbox actions #61 waited on Label pall8t containers and carry the labels through pall8t ls --json #55: the container carries pall8t.herdr.pane, so the plugin looks it up in pall8t ls --json instead of parsing container names. With no pane in the environment it falls back to a single running sandbox, and refuses to choose among several — attaching someone to another agent's container is worse than an error.
  • Thin over the CLI: no socket calls, no reading pall8t's state directory. One contract: ls --json.
  • In contrib/, not its own repo, so it versions with the CLI it drives — a change to ls --json and the plugin that reads it can land in one commit.

Verification

Live, against a real labelled sandbox (HERDR_PANE_ID=%42):

container : pall8t-p8t-plugin-live-cdac8d38-28299
image     : pall8t-p8t-plugin-live-cdac8d38:501-20-557ad54a8e87
project   : /Users/…/p8t-plugin-live
herdr     : pane %42, sandbox full

shell   → inside: dev@pall8t-p8t-plugin-live-cdac8d38-28299   (agent still running)
rebuild → built pall8t-p8t-plugin-live-cdac8d38:501-20-557ad54a8e87
stop    → stopped pall8t-p8t-plugin-live-cdac8d38-28299

Error paths too: no sandbox running, and a pane whose container isn't labelled.

Not verified: invocation by a live herdr server — there's no herdr session on this machine, so the manifest's entrypoint shapes ([[panes]] placements, action contexts) are written against herdr 0.8's documented plugin contract rather than observed. Everything the script itself does is exercised above.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YTFLvjR7dWvxFQfSyBY4Zm

Puts what pall8t knows about a pane's sandbox inside herdr: status, a
second shell in the running container, an image rebuild, a stop. Linked
from a checkout with `herdr plugin link contrib/herdr-plugin`.

It resolves *which* sandbox a pane's is through the `pall8t.herdr.pane`
label rather than by parsing container names — which is why this waited
for labels. Without a pane in the environment it falls back to a single
running sandbox and refuses to choose between several: attaching someone
to another agent's container would be worse than an error.

Output-producing entrypoints are panes, not actions, so results land in
front of the person who asked rather than in the plugin log. Stopping,
which has nothing to show, stays an action.

Lives in contrib/ rather than its own repository so it versions with the
CLI it drives — its only contract is `pall8t ls --json`, and a change to
that shape can land in the same commit as the plugin that reads it.

Verified live against a real labelled sandbox: `status` resolved the
pane's container and printed its image/project/mode; `shell` opened a
second shell inside it (`dev@pall8t-…`) while the agent kept running;
`rebuild` built in the project directory; `stop` stopped it. Error paths
checked too — no sandbox running, and a pane with no labelled container.

Not verified: invocation by a live herdr server (no herdr session here),
so the manifest's entrypoint shapes are written against herdr 0.8's
documented plugin contract rather than observed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YTFLvjR7dWvxFQfSyBY4Zm
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a3d24deb-857c-4f31-97e5-70538b462fb2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant