Documentation
¶
Overview ¶
Package cliwrap re-exports the canonical types from internal/cwtypes via Go type aliases, so the public API surface is unchanged.
Index ¶
- Constants
- Variables
- type ExceedAction
- type LogChunk
- type LogOptions
- type Manager
- func (m *Manager) ChildPIDs() map[string]int
- func (m *Manager) Events() event.Bus
- func (m *Manager) List() []mgmt.ListEntry
- func (m *Manager) ListPersistent() ([]PersistentSessionInfo, error)
- func (m *Manager) LogsSnapshot(id string, stream uint8) []byte
- func (m *Manager) LogsSnapshotFiltered(id string, stream uint8, since time.Time, lines int) []byte
- func (m *Manager) Reattach(ctx context.Context, id string) (ProcessHandle, error)
- func (m *Manager) Register(spec Spec) (ProcessHandle, error)
- func (m *Manager) Shutdown(ctx context.Context) error
- func (m *Manager) StatusOf(id string) (mgmt.ListEntry, error)
- func (m *Manager) Stop(ctx context.Context, id string) error
- func (m *Manager) WatchLogs(processID string) (chunks <-chan LogChunk, unregister func())
- type ManagerOption
- func WithAgentOutboxCapacity(n int) ManagerOption
- func WithAgentPath(path string) ManagerOption
- func WithLogFileDir(dir string) ManagerOption
- func WithLogFileRotation(maxSize int64, maxFiles int) ManagerOption
- func WithLogRingBufferBytes(n int) ManagerOption
- func WithOutboxCapacity(n int) ManagerOption
- func WithPersistentDir(path string) ManagerOption
- func WithRuntimeDir(path string) ManagerOption
- func WithoutWAL() ManagerOption
- type PTYConfig
- type PTYData
- type PersistentSessionInfo
- type ProcessHandle
- type ResourceLimits
- type RestartPolicy
- type SandboxSpec
- type Spec
- type SpecBuilder
- func (b *SpecBuilder) Build() (Spec, error)
- func (b *SpecBuilder) Persistent() *SpecBuilder
- func (b *SpecBuilder) WithEnv(k, v string) *SpecBuilder
- func (b *SpecBuilder) WithLogOptions(o LogOptions) *SpecBuilder
- func (b *SpecBuilder) WithMaxRestarts(n int) *SpecBuilder
- func (b *SpecBuilder) WithPTY(cfg *PTYConfig) *SpecBuilder
- func (b *SpecBuilder) WithResourceLimits(l ResourceLimits) *SpecBuilder
- func (b *SpecBuilder) WithRestart(p RestartPolicy) *SpecBuilder
- func (b *SpecBuilder) WithRestartBackoff(d time.Duration) *SpecBuilder
- func (b *SpecBuilder) WithRingBufferSize(n int) *SpecBuilder
- func (b *SpecBuilder) WithSandbox(s *SandboxSpec) *SpecBuilder
- func (b *SpecBuilder) WithStdin(m StdinMode) *SpecBuilder
- func (b *SpecBuilder) WithStopTimeout(d time.Duration) *SpecBuilder
- func (b *SpecBuilder) WithWorkDir(path string) *SpecBuilder
- type SpecValidationError
- type State
- type Status
- type StdinMode
Constants ¶
const ( RestartNever = cwtypes.RestartNever RestartOnFailure = cwtypes.RestartOnFailure RestartAlways = cwtypes.RestartAlways ExceedWarn = cwtypes.ExceedWarn ExceedThrottle = cwtypes.ExceedThrottle ExceedKill = cwtypes.ExceedKill StdinNone = cwtypes.StdinNone StdinPipe = cwtypes.StdinPipe StdinInherit = cwtypes.StdinInherit StatePending = cwtypes.StatePending StateStarting = cwtypes.StateStarting StateRunning = cwtypes.StateRunning StateStopping = cwtypes.StateStopping StateStopped = cwtypes.StateStopped StateCrashed = cwtypes.StateCrashed StateRestarting = cwtypes.StateRestarting StateFailed = cwtypes.StateFailed )
Re-exported constants.
const DefaultLogRingBufferBytes = 1 << 20 // 1 MiB
DefaultLogRingBufferBytes is the per-(process, stream) log ring buffer capacity used when neither WithLogRingBufferBytes nor the YAML `log.ring_buffer_bytes` key is set.
Variables ¶
var ( ErrProcessNotFound = errors.New("cliwrap: process not found") ErrProcessAlreadyExists = errors.New("cliwrap: process already exists") ErrProcessNotRunning = errors.New("cliwrap: process not running") ErrProcessAlreadyRunning = errors.New("cliwrap: process already running") ErrManagerShuttingDown = errors.New("cliwrap: manager is shutting down") ErrManagerClosed = errors.New("cliwrap: manager is closed") ErrSandboxProviderNotFound = errors.New("cliwrap: sandbox provider not registered") ErrAgentSpawnFailed = errors.New("cliwrap: failed to spawn agent") ErrHandshakeTimeout = errors.New("cliwrap: handshake timeout") ErrStopTimeout = errors.New("cliwrap: stop timeout") // ErrInvalidSpec is re-exported from cwtypes so that // SpecValidationError.Is(ErrInvalidSpec) works across both packages. ErrInvalidSpec = cwtypes.ErrInvalidSpec // PTY-related errors. // ErrPTYUnsupportedByAgent is re-exported from cwtypes so that // errors.Is checks work across both packages. ErrPTYUnsupportedByAgent = cwtypes.ErrPTYUnsupportedByAgent ErrPTYNotConfigured = errors.New("cliwrap: PTY operations require Spec.PTY to be set") // ErrSessionNotFound is returned by Reattach when the session ID has // no metadata directory under WithPersistentDir. ErrSessionNotFound = errors.New("cliwrap: persistent session not found") // ErrSessionAlreadyExists is returned by Spawn (Persistent=true) when // a session with the same ID already exists in WithPersistentDir. // The user must terminate or rm the existing session first; cli-wrapper // does not auto-clean stale dirs. ErrSessionAlreadyExists = errors.New("cliwrap: persistent session already exists") // ErrAgentDead is returned by Reattach when the pid file points to a // dead PID, OR when the agent's MsgHello.startedAt does not match the // recorded meta.json startedAt (PID rollover defense). ErrAgentDead = errors.New("cliwrap: persistent agent is no longer alive") // ErrAlreadyAttached is returned by Reattach when another host is // currently connected to the session. ErrAlreadyAttached = errors.New("cliwrap: persistent session already attached by another host") // ErrIncompatibleAgent is returned by Reattach when the agent's // capability version does not match the host's expectations. ErrIncompatibleAgent = errors.New("cliwrap: incompatible agent version") // ErrPersistenceUnsupportedByAgent is returned at Start time when the // caller passes Persistent=true but the agent did not advertise the // "persistence" capability. ErrPersistenceUnsupportedByAgent = errors.New("cliwrap: agent does not support persistent sessions") )
Sentinel errors.
var ApplyPTYDefaults = cwtypes.ApplyPTYDefaults
ApplyPTYDefaults re-exports cwtypes.ApplyPTYDefaults so callers need only import pkg/cliwrap.
Functions ¶
This section is empty.
Types ¶
type ExceedAction ¶
type ExceedAction = cwtypes.ExceedAction
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type LogChunk ¶ added in v0.2.0
LogChunk is an alias for cwtypes.LogChunk, re-exported so public callers of pkg/cliwrap see a cliwrap.LogChunk type while the canonical definition lives in the leaf cwtypes package (which internal/mgmt can import without creating a cycle).
type LogOptions ¶
type LogOptions = cwtypes.LogOptions
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager is the top-level library entry point.
func NewManager ¶
func NewManager(opts ...ManagerOption) (*Manager, error)
NewManager constructs a Manager with the given options.
func (*Manager) ChildPIDs ¶
ChildPIDs returns a snapshot of running (process ID -> child PID) pairs. Processes that are not in StateRunning are omitted.
func (*Manager) Events ¶
Events returns the Manager's event bus. Subscribers receive lifecycle, log, and reliability events. The bus is lazily created on first call.
func (*Manager) ListPersistent ¶ added in v0.3.0
func (m *Manager) ListPersistent() ([]PersistentSessionInfo, error)
ListPersistent scans WithPersistentDir for valid sessions. Stale entries (Alive=false) are returned but not auto-cleaned; the user removes them via `cliwrap kill <id>` or `rm -rf <dir>/<id>`. Sessions are returned sorted by ID.
CW-G4 Task 13.
func (*Manager) LogsSnapshot ¶ added in v0.2.0
LogsSnapshot is the mgmt API entry that returns the current ring-buffer contents for a (process, stream) pair. Returns nil if no logs have been recorded for that pair yet.
func (*Manager) LogsSnapshotFiltered ¶ added in v0.3.0
LogsSnapshotFiltered returns the snapshot filtered by chunk-arrival timestamp (`since`, zero disables) and trimmed to the trailing `lines` newline-delimited lines (zero disables). When both filters are zero it is byte-equivalent to LogsSnapshot. Backs `cliwrap logs --since` and `--lines`.
func (*Manager) Reattach ¶ added in v0.3.0
Reattach connects to a previously-spawned persistent session by ID. On success, returns a ProcessHandle equivalent to one returned by Manager.Register followed by Start: WriteInput, SubscribePTYData, Signal, Resize, Status, Stop, and Close all behave identically.
SubscribePTYData on a Reattach-derived handle yields the ring buffer snapshot first (as one or more chunks in chronological order), then transitions to live PTY data.
Errors (see spec §"Error Matrix"):
- ErrSessionNotFound: <persistentDir>/<id>/ does not exist (or sock missing)
- ErrAgentDead: pid file points to a dead PID, or Hello.StartedAt does not match meta.json.StartedAt (PID rollover defense)
- ErrAlreadyAttached: another host is currently connected
- ErrIncompatibleAgent: handshake parsing failure
- ctx.Err(): ctx canceled / deadline exceeded
CW-G4 Task 14.
func (*Manager) Register ¶
func (m *Manager) Register(spec Spec) (ProcessHandle, error)
Register validates and registers a process spec.
func (*Manager) WatchLogs ¶ added in v0.2.0
WatchLogs registers a follow-mode subscription. The returned channel receives LogChunk values for every subsequent call to emitLogChunk whose processID matches the filter. An empty processID filter matches every process.
The caller MUST invoke the returned unregister function exactly once when done — this is typically done via defer. Failing to unregister leaks the subscription and the goroutine that reads from it.
The channel is buffered; emit-side fan-out is non-blocking, so slow consumers lose chunks rather than backpressuring the producer.
type ManagerOption ¶
type ManagerOption func(*Manager)
ManagerOption mutates a Manager during construction.
func WithAgentOutboxCapacity ¶ added in v0.4.6
func WithAgentOutboxCapacity(n int) ManagerOption
WithAgentOutboxCapacity sets the IPC outbox slot count INSIDE the agent process. WithOutboxCapacity tunes the host's outbox (host → agent direction); this option tunes the agent's outbox (agent → host direction), where PTY output frames accumulate when the host's SubscribePTYData consumer is slow or backpressured.
Zero or negative values keep the agent's legacy default (1024). Propagated via the CLIWRAP_AGENT_OUTBOX_CAPACITY env var that the spawner sets on every spawned agent; the agent's DefaultConfig honors the variable when its value parses as a positive integer.
For interactive PTY hosts whose terminals briefly stall (window resize, paste, scrollback dump), values of 4096–16384 match the guidance for the host side.
func WithAgentPath ¶
func WithAgentPath(path string) ManagerOption
WithAgentPath sets the absolute path to the cliwrap-agent binary.
func WithLogFileDir ¶ added in v0.3.0
func WithLogFileDir(dir string) ManagerOption
WithLogFileDir enables file-backed log persistence. Each (process, stream) pair gets its own rotated log file at `<dir>/<processID>.<stream>.log`, with `<processID>.<stream>.1.log`, `.2.log`, ... as rotated siblings. Files coexist with the in-memory ring buffer: live snapshots and `cliwrap logs` continue to read from memory; the on-disk copies survive Manager shutdown for postmortem.
Empty path disables file persistence (default). Per-rotator MaxSize and MaxFiles use FileRotator defaults (64 MiB and 7) unless overridden via WithLogFileRotation.
func WithLogFileRotation ¶ added in v0.3.0
func WithLogFileRotation(maxSize int64, maxFiles int) ManagerOption
WithLogFileRotation overrides the per-rotator size cap and retention count used by WithLogFileDir. Zero values fall back to FileRotator defaults (64 MiB, 7 files). No effect when WithLogFileDir is unset.
func WithLogRingBufferBytes ¶ added in v0.3.0
func WithLogRingBufferBytes(n int) ManagerOption
WithLogRingBufferBytes overrides the per-(process, stream) log ring buffer capacity. Smaller values reduce memory at the cost of evicting older log lines sooner. Zero or negative values fall back to DefaultLogRingBufferBytes.
func WithOutboxCapacity ¶ added in v0.4.0
func WithOutboxCapacity(n int) ManagerOption
WithOutboxCapacity overrides the IPC outbox slot count for every session created by this Manager. Zero or negative values fall back to the legacy default (1024). Larger buffers reduce overflow likelihood under bursty traffic at the cost of memory; for interactive PTY hosts values of 4096–16384 are typical.
func WithPersistentDir ¶ added in v0.3.0
func WithPersistentDir(path string) ManagerOption
WithPersistentDir overrides the directory where persistent-session metadata (sock, pid, meta.json, agent.log) is stored. Default: $HOME/.cliwrap/sessions/. The directory is created with mode 0700 lazily on first persistent Spawn; per-session subdirectories are 0700 with files 0600.
Tests should pass t.TempDir() to keep state isolated. CW-G4.
func WithRuntimeDir ¶
func WithRuntimeDir(path string) ManagerOption
WithRuntimeDir sets the directory for per-process state (WAL, logs).
func WithoutWAL ¶ added in v0.4.0
func WithoutWAL() ManagerOption
WithoutWAL disables the disk-backed write-ahead log on the outgoing IPC direction for every session created by this Manager. When set, outbox overflow drops messages instead of fsync-spilling to disk — the host trades the legacy "messages are never lost" guarantee for predictable per-keystroke latency under load.
Recommended for interactive PTY hosts where dropped input is recovered by user retry. Not recommended for batch / persistent / replay-critical workloads.
type PTYConfig ¶ added in v0.3.0
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type PTYData ¶ added in v0.3.0
type PTYData = controller.PTYData
PTYData carries one chunk of PTY output delivered to a SubscribePTYData caller.
type PersistentSessionInfo ¶ added in v0.3.0
type PersistentSessionInfo struct {
// ID is the session identifier (matches Spec.ID).
ID string
// Spec is the original cwtypes.Spec recorded at agent startup.
Spec cwtypes.Spec
// AgentPID is the agent process PID at startup. May be stale; use
// Alive to interpret.
AgentPID int
// StartedAt is the agent's startup time (UTC nanoseconds).
StartedAt time.Time
// Alive is true iff kill -0 AgentPID succeeds. Best-effort: under
// PID rollover, this can be a false positive — the actual Reattach
// performs an additional StartedAt comparison via MsgHello.
Alive bool
// Attached is true iff the .attached flag file exists in the session
// directory (best-effort indicator that another host is currently
// connected). The actual Reattach attempt is the source of truth.
Attached bool
}
PersistentSessionInfo summarizes a persistent session discovered on disk.
CW-G4 §"Public API surface".
type ProcessHandle ¶
type ProcessHandle interface {
ID() string
Spec() Spec
Status() Status
Start(ctx context.Context) error
Stop(ctx context.Context) error
Close(ctx context.Context) error
// WriteInput forwards b as PTY stdin to the running child.
// Returns ErrPTYNotConfigured if Spec.PTY is nil.
WriteInput(ctx context.Context, b []byte) error
// Resize sends a TIOCSWINSZ to the running PTY child.
// Returns ErrPTYNotConfigured if Spec.PTY is nil.
Resize(ctx context.Context, cols, rows uint16) error
// Signal delivers sig to the foreground process group of the PTY child.
// Returns ErrPTYNotConfigured if Spec.PTY is nil.
Signal(ctx context.Context, sig syscall.Signal) error
// SubscribePTYData registers a receiver for PTY output frames.
// If Spec.PTY is nil the returned channel is immediately closed.
// The caller MUST invoke the returned unsubscribe function exactly once.
SubscribePTYData() (<-chan PTYData, func())
// OnStateChange registers cb to be called every time the underlying
// controller transitions to a new state (StateStarting →
// StateRunning → StateStopping/Stopped/Crashed/...). The callback
// fires only on actual transitions; same-value re-stores are
// filtered out. Pass nil to disable. Replacing an existing callback
// is supported and atomic with respect to in-flight transitions.
//
// The callback may be registered before or after Start; in the
// pre-Start case it is buffered until Start wires it onto the
// controller, so even the StateStarting → StateRunning transition
// is observable.
//
// The callback runs on whichever goroutine triggered the transition
// (typically the IPC dispatch loop or the Start/Stop call itself),
// so it MUST NOT block. Hosts that need to do heavy work should
// hand off to a separate goroutine.
//
// The Status passed to the callback reflects the freshly-updated
// state at call time; ChildPID is the value at that instant.
OnStateChange(cb func(Status))
}
ProcessHandle is the user-facing handle to a managed process.
type ResourceLimits ¶
type ResourceLimits = cwtypes.ResourceLimits
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type RestartPolicy ¶
type RestartPolicy = cwtypes.RestartPolicy
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type SandboxSpec ¶
type SandboxSpec = cwtypes.SandboxSpec
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type Spec ¶
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type SpecBuilder ¶
type SpecBuilder struct {
// contains filtered or unexported fields
}
SpecBuilder is a fluent constructor for Spec. Errors surface only from Build.
func NewSpec ¶
func NewSpec(id, cmd string, args ...string) *SpecBuilder
NewSpec starts a new SpecBuilder for the given ID, command, and arguments.
func (*SpecBuilder) Build ¶
func (b *SpecBuilder) Build() (Spec, error)
Build validates and returns the Spec.
func (*SpecBuilder) Persistent ¶ added in v0.3.0
func (b *SpecBuilder) Persistent() *SpecBuilder
Persistent marks the session as CW-G4 persistent: agent + child outlive the host process and are reattachable via Manager.Reattach.
func (*SpecBuilder) WithEnv ¶
func (b *SpecBuilder) WithEnv(k, v string) *SpecBuilder
WithEnv sets a single environment variable.
func (*SpecBuilder) WithLogOptions ¶
func (b *SpecBuilder) WithLogOptions(o LogOptions) *SpecBuilder
WithLogOptions attaches log storage options.
func (*SpecBuilder) WithMaxRestarts ¶
func (b *SpecBuilder) WithMaxRestarts(n int) *SpecBuilder
WithMaxRestarts limits how many restarts will be attempted.
func (*SpecBuilder) WithPTY ¶ added in v0.3.0
func (b *SpecBuilder) WithPTY(cfg *PTYConfig) *SpecBuilder
WithPTY attaches a PTY configuration. If cfg is nil the field is cleared. Call ApplyPTYDefaults on the returned Spec (or let Controller.Start do it) to fill in zero-valued cols/rows.
func (*SpecBuilder) WithResourceLimits ¶
func (b *SpecBuilder) WithResourceLimits(l ResourceLimits) *SpecBuilder
WithResourceLimits attaches resource caps.
func (*SpecBuilder) WithRestart ¶
func (b *SpecBuilder) WithRestart(p RestartPolicy) *SpecBuilder
WithRestart sets the restart policy.
func (*SpecBuilder) WithRestartBackoff ¶
func (b *SpecBuilder) WithRestartBackoff(d time.Duration) *SpecBuilder
WithRestartBackoff sets the initial backoff delay between restarts.
func (*SpecBuilder) WithRingBufferSize ¶ added in v0.3.0
func (b *SpecBuilder) WithRingBufferSize(n int) *SpecBuilder
WithRingBufferSize sets the in-memory PTY ring buffer size (bytes) used for redraw on reattach. Only meaningful when Persistent=true. Default (0) means 256 KiB at agent startup. CW-G4.
func (*SpecBuilder) WithSandbox ¶
func (b *SpecBuilder) WithSandbox(s *SandboxSpec) *SpecBuilder
WithSandbox attaches a sandbox spec.
func (*SpecBuilder) WithStdin ¶
func (b *SpecBuilder) WithStdin(m StdinMode) *SpecBuilder
WithStdin selects how the child's stdin is wired.
func (*SpecBuilder) WithStopTimeout ¶
func (b *SpecBuilder) WithStopTimeout(d time.Duration) *SpecBuilder
WithStopTimeout sets the SIGTERM → SIGKILL grace period.
func (*SpecBuilder) WithWorkDir ¶
func (b *SpecBuilder) WithWorkDir(path string) *SpecBuilder
WithWorkDir sets the working directory for the child process.
type SpecValidationError ¶
type SpecValidationError = cwtypes.SpecValidationError
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.
type State ¶
Type aliases — these are transparent to callers. Users continue to write cliwrap.State, cliwrap.Spec, etc.