Skip to content

Repository files navigation

effect-herdr

A typed Effect SDK for herdr, the terminal-native agent multiplexer. Script sibling panes, split workspaces, and react to focus changes — all as composable, typed Effects.

Install

bun add effect-herdr effect

Quickstart

Run this from inside a herdr-managed pane (HERDR_ENV=1):

import { BunFileSystem } from "@effect/platform-bun"
import { Effect, Option } from "effect"
import { currentPane, runInPane, splitPane, HerdrSession } from "effect-herdr"

const program = Effect.gen(function* () {
  const pane = yield* currentPane
  if (Option.isNone(pane)) return yield* Effect.log("not running inside herdr")

  const sibling = yield* splitPane(pane.value, { direction: "right" })
  yield* runInPane(sibling, "echo hello from effect-herdr")
})

program.pipe(
  Effect.provide(HerdrSession.Live),
  Effect.provide(BunFileSystem.layer),
  Effect.runPromise,
)

HerdrSession.Live resolves the socket path the same way the herdr CLI itself does (env var, then ~/.config/herdr/herdr.sock) and fails loud at startup if nothing is listening there — no silent no-ops. BunFileSystem is the one platform layer this quickstart needs; see Platform runtime below for why.

A full runnable version of this — split, run a command, wait, close — is examples/parrot.ts:

bun run examples/parrot.ts   # run from inside a herdr pane

What's here

  • HerdrSession — the ergonomic entry point. One Layer, sound defaults.
  • Pane controlsplitPane, focusPane, closePane, runInPane (batch string or streaming Stream<string> input), waitForOutput (blocks on a substring/regex match, returned as a Stream).
  • Focus trackingactivePane/activeTab (per-container, always resolves), focusedPane/focusedTab/focusedWorkspace (global, Option-wrapped), focusedPaneRef (a live SubscriptionRef that updates as focus changes anywhere in herdr).
  • Identity vs. statePane/Tab/Workspace are stable references you can hold onto, built with makePane/makeTab/makeWorkspace (they carry a kind tag, so a Pane can never be mistaken for the Tab it structurally contains, plus Equal/Hash so they work as HashMap keys); PaneSnapshot/TabSnapshot/WorkspaceSnapshot are point-in-time reads with their own capturedAt.
  • Resource livenessclaim/withClaim tie a resource to a Scope: if herdr closes it out from under you, the claiming fiber is interrupted instead of failing on some later RPC. disconnectPolicy: "destroy" also closes the resource when the scope ends.
  • Kind-polymorphic opsclose/focus/rename accept a pane, tab, or workspace and dispatch on its kind, alongside the per-kind primitives.
  • Raw protocol escape hatch — every ergonomic combinator is built on HerdrConnection's typed rpc client. Drop to session.rpc["workspace.list"]() whenever the service layer doesn't cover your case; there's no hidden state that makes mixing the two incoherent.

Not every herdr RPC method has an ergonomic wrapper yet — see TODO.md for the coverage gap and other known limitations (real-time pane-output tailing, pane.send_input's combined text+keys form).

Platform runtime

effect-herdr uses Effect's platform primitives (FileSystem, ChildProcessSpawner, Crypto, Socket) instead of Node/Bun stdlib calls directly, so it works the same way under Bun or Node. Provide whichever platform layer matches your runtime once, at your program's entrypoint — e.g. @effect/platform-bun's BunServices.layer.

Development

bun install
bun run typecheck
bun run test            # unit tests, packages/core only
bun run test:e2e        # E2E, spins private herdr servers per test
bun run test:all        # both
bun run schema:refresh  # re-capture scripts/herdr-schema.json after upgrading herdr

The E2E suite shells out to a real herdr binary to spawn isolated named-session servers — the SDK-under-test is never in that bootstrap path. Requires herdr on PATH.

Release

Versioning and publishing go through Changesets: run bun run changeset to describe a change, merge it, and CI opens a release PR that publishes to npm on merge. bun run build produces the published dist/ output (ESM + .d.ts) via tsdown.

About

Typed Effect-TS SDK for the herdr terminal-native agent multiplexer

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages