Documentation
¶
Overview ¶
Package rein provides a small, reliable shell layer for AI agents.
rein runs shell commands with timeouts that work, signals that propagate, and process trees that get cleaned up when the context is cancelled. It is designed to be the foundation underneath any agent framework that needs to execute commands.
Index ¶
- type Line
- type Option
- func WithDir(dir string) Option
- func WithEnv(env []string) Option
- func WithGracefulTimeout(d time.Duration) Option
- func WithIdleTimeout(d time.Duration) Option
- func WithLineBuffer(n int) Option
- func WithOverflowPolicy(p OverflowPolicy) Option
- func WithPTY() Option
- func WithTimeout(d time.Duration) Option
- type Options
- type OverflowPolicy
- type Result
- type Session
- func (s *Session) Done() <-chan struct{}
- func (s *Session) Drops() uint64
- func (s *Session) Lines() <-chan Line
- func (s *Session) PID() int
- func (s *Session) Resize(rows, cols int) error
- func (s *Session) Stop() error
- func (s *Session) Wait() (*Result, error)
- func (s *Session) Write(p []byte) (int, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Line ¶
type Line struct {
// Stream is "stdout" or "stderr". With PTY enabled, both are
// merged on a single stream and Stream is always "stdout".
Stream string
// Text is the line content, without the trailing newline.
Text string
}
Line is a single line of output from a Session.
type Option ¶
type Option func(*Options)
Option is a functional option for Run or Start.
func WithEnv ¶
WithEnv sets the environment for the child process. Pass nil to inherit the parent environment.
func WithGracefulTimeout ¶
WithGracefulTimeout sets how long to wait after a graceful signal before sending SIGKILL. Default: 5s. Only takes effect when the command is being stopped.
func WithIdleTimeout ¶
WithIdleTimeout sets the maximum duration of output silence before the process is signalled. Useful for long-running commands like `npm run dev` that should be considered stuck if they stop emitting output. Default: 0 (disabled).
func WithLineBuffer ¶
WithLineBuffer sets the size of the channel that buffers output lines from a Start session. Default: 4096.
func WithOverflowPolicy ¶
func WithOverflowPolicy(p OverflowPolicy) Option
WithOverflowPolicy sets what happens when the line buffer is full. See OverflowPolicy for the options. Default: PolicyBlock.
func WithPTY ¶
func WithPTY() Option
WithPTY allocates a pseudo-terminal for the child. The child sees a real TTY (good for `sudo`, `ssh-add`, colored output, and tools that check isatty). Stderr is merged with stdout on the same line. Default: false.
Only implemented on POSIX in v0.0.1.
func WithTimeout ¶
WithTimeout sets the maximum wall-clock duration of the command. If the command runs longer, the process tree is signalled (see WithGracefulTimeout for the escalation policy).
type Options ¶
type Options struct {
// Timeout is the maximum wall-clock duration before the process
// is signalled. Default: 30s. Zero or negative means no timeout.
Timeout time.Duration
// GracefulTimeout is how long to wait after sending SIGTERM
// before sending SIGKILL. Default: 5s. Only takes effect when
// the command is being stopped (timeout, context cancel, or Stop).
GracefulTimeout time.Duration
// IdleTimeout is the maximum duration of output silence before
// the process is signalled. Useful for long-running commands
// like `npm run dev` that should be considered stuck if they
// stop emitting output. Default: 0 (disabled). Only takes
// effect on Start, not Run.
IdleTimeout time.Duration
// Env is the environment for the child process. If nil, the
// parent environment is inherited.
Env []string
// Dir is the working directory for the child process. If empty,
// the parent's working directory is used.
Dir string
// PTY, if true, allocates a pseudo-terminal for the child. The
// child sees a real TTY (good for `sudo`, `ssh-add`, colored
// output, and tools that check `isatty`). Stderr is merged
// with stdout on the same line. Default: false.
//
// Only implemented on POSIX in v0.0.1.
PTY bool
// LineBuffer is the size of the channel that buffers output
// lines from a Start session before the producer applies
// OverflowPolicy. Default: 4096.
LineBuffer int
// Overflow is the policy applied when LineBuffer is full.
// Default: PolicyBlock.
Overflow OverflowPolicy
}
Options configures a single Run or Start call. Zero values are replaced with sensible defaults; see the Option functions.
type OverflowPolicy ¶
type OverflowPolicy int
OverflowPolicy controls what happens when the line buffer is full and the producer tries to add another line.
const ( // PolicyBlock causes the producer to wait until the consumer // has drained some lines. This is the safest option: no lines // are lost. The downside is that the producer (and the // subprocess) can appear to hang if the consumer is slow. // Default. PolicyBlock OverflowPolicy = iota // PolicyDropNewest causes the producer to silently drop the // new line and increment the drop counter. The consumer sees // only the first N lines of output. The subprocess never // blocks. PolicyDropNewest // PolicyDropOldest causes the producer to drop the oldest // buffered line and add the new one. The consumer always sees // the most recent output. The drop counter is incremented. PolicyDropOldest )
type Result ¶
type Result struct {
// Stdout is the standard output captured during execution.
Stdout string
// Stderr is the standard error captured during execution.
Stderr string
// ExitCode is the process exit code. It is -1 if the process did
// not exit normally (for example, it was killed by a signal).
ExitCode int
// Duration is the wall-clock time from start to exit.
Duration time.Duration
// Err is the terminal error, if any. It is nil on success.
// For non-zero exit codes, Err is set to a non-nil error that
// describes the failure. For timeouts, it indicates how long the
// command ran before being killed.
Err error
}
Result is the outcome of a command run by Run or Start.
Result is always returned, even on failure. Callers should check Err to determine whether the command succeeded.
func Run ¶
Run executes a shell command and waits for it to complete or until the timeout fires.
The command is run via `sh -c <command>`, so shell features (pipes, redirects, globs, env var expansion) work as expected. The process tree is isolated into its own process group so that signals reach every descendant, not just the leader.
Shutdown sequence on timeout or context cancellation:
- SIGTERM is sent to the process group.
- rein waits up to Options.GracefulTimeout for the process to exit on its own.
- If the process is still running, SIGKILL is sent to the process group.
Run always returns a non-nil *Result, even on failure. The returned error is non-nil if and only if result.Err is non-nil.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is a handle to a long-running command started by Start or [StartExec].
A Session streams output line-by-line via Session.Lines, exposes the process lifecycle via Session.Done and Session.Wait, and can be cleanly stopped via Session.Stop.
If the session was started with a PTY (see WithPTY), input can be written to the child's stdin via Session.Write and the terminal window can be resized via Session.Resize.
func Start ¶
Start launches a long-running command and returns a Session.
The command runs in its own process group, so signals propagate to all descendants. Output is streamed line-by-line via Session.Lines. The process is killed on context cancellation, timeout, idle timeout, or Session.Stop.
The shutdown sequence on stop is:
- SIGTERM is sent to the process group.
- rein waits up to Options.GracefulTimeout for the process to exit on its own.
- If the process is still running, SIGKILL is sent to the process group.
For non-PTY sessions, the child's stdin is /dev/null. For PTY sessions (see WithPTY), the child's stdin is the PTY slave and input can be written via Session.Write.
func (*Session) Done ¶
func (s *Session) Done() <-chan struct{}
Done returns a channel that is closed when the process exits.
func (*Session) Drops ¶
Drops returns the number of output lines that have been dropped due to the configured OverflowPolicy. Useful for monitoring back-pressure in long-running consumers.
func (*Session) Lines ¶
Lines returns a channel that emits one Line per line of process output. The channel is closed when the process exits.
The channel is buffered (default 4096 lines; see WithLineBuffer). The OverflowPolicy (see WithOverflowPolicy) controls what happens when the buffer fills:
PolicyBlock (default) — the producer waits.
PolicyDropNewest — the new line is dropped silently.
PolicyDropOldest — the oldest buffered line is dropped to
make room for the new one.
Dropped lines can be detected with Session.Drops.
func (*Session) Resize ¶
Resize resizes the PTY window to rows x cols. Only works for sessions started with WithPTY; for non-PTY sessions it returns an error.
Resize is safe to call from any goroutine.
func (*Session) Stop ¶
Stop sends SIGTERM, waits for the graceful timeout, then SIGKILL. It blocks until the process has exited. Safe to call multiple times; subsequent calls are no-ops that return nil.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
rein
command
Command rein is the CLI for the rein shell-layer library.
|
Command rein is the CLI for the rein shell-layer library. |
|
internal
|
|
|
ndjson
Package ndjson implements the wire protocol used by the rein CLI.
|
Package ndjson implements the wire protocol used by the rein CLI. |
|
procgroup
Package procgroup isolates a child process into its own process group so that signals can be delivered to the entire process tree, not just the leader.
|
Package procgroup isolates a child process into its own process group so that signals can be delivered to the entire process tree, not just the leader. |
|
signal
Package signal sends signals to a child process group.
|
Package signal sends signals to a child process group. |