process

package
v0.0.20 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package process provides cross-platform process-group teardown: it kills a process together with its descendants (KillProcessGroup) so agent process trees do not survive the tmux session that launched them.

Index

Constants

This section is empty.

Variables

View Source
var ErrPortRangeExhausted = errors.New("port allocator exhausted")

ErrPortRangeExhausted reports that no valid, non-overlapping port range remains.

View Source
var ErrScriptsChangedSincePrompt = errors.New("project scripts changed since trust prompt")

ErrScriptsChangedSincePrompt is returned when a user approves script content after the repo config changed from the content that originally triggered the prompt.

View Source
var ErrScriptsNotTrusted = errors.New("project scripts not trusted")

ErrScriptsNotTrusted is returned (wrapped) when a repo's .amux/workspaces.json supplies commands but the user has not approved the current content of that file. It is the sentinel callers test with errors.Is to distinguish a trust skip from a genuine setup failure.

Functions

func CommandIsUnresolvable added in v0.0.20

func CommandIsUnresolvable(cmd string) bool

CommandIsUnresolvable reports whether cmd contains constructs (variable expansion, command substitution, globs) that prevent static reference detection, so callers can warn that the command may reference files this detector cannot see. It is a coarse signal, not a parser: any occurrence of $, backtick, *, or ? anywhere in the string trips it.

func ForceKillProcess added in v0.0.14

func ForceKillProcess(pid int) error

ForceKillProcess sends SIGKILL to the process group led by pid.

func IsReservedScriptEnvKey added in v0.0.20

func IsReservedScriptEnvKey(key string) bool

IsReservedScriptEnvKey reports whether key is one of the reserved AMUX_*/ROOT_* names BuildEnv/BuildEnvMap inject (see isReservedScriptEnvKey below for the exact list). It is exported so callers outside this package -- namely the workspace environment-variable editor -- can exclude reserved keys before they are ever shown or persisted, without duplicating or drifting from this list.

func KillProcessGroup added in v0.0.6

func KillProcessGroup(leaderPID int, opts KillOptions) error

KillProcessGroup sends SIGTERM to a process group, waits for the grace period, then sends SIGKILL if processes are still running. The leaderPID parameter is the process ID of the group leader.

func ReferencesInRepoFiles added in v0.0.20

func ReferencesInRepoFiles(cmd, repoRoot string) []string

ReferencesInRepoFiles best-effort detects paths inside repoRoot that a shell command string appears to reference (e.g. "bash ./scripts/dev.sh"). It is intentionally conservative: it reports likely references, never claims to be complete, and is used to WARN, not to authorize. It returns repo-relative paths that exist as regular files under repoRoot.

It does NOT parse the shell. It splits on whitespace, strips surrounding quotes, skips tokens containing shell metacharacters that make resolution unreliable, and confirms each remaining path-like token resolves to an existing file that stays within repoRoot (no ".." escapes). An empty result means "no in-repo file reference was detected", which is NOT a guarantee that the command runs no repo files; use CommandIsUnresolvable to detect the constructs that hide references from this scan.

func SetProcessGroup added in v0.0.6

func SetProcessGroup(cmd *exec.Cmd)

SetProcessGroup configures a command to run in its own process group.

Types

type EnvBuilder

type EnvBuilder struct {
	// contains filtered or unexported fields
}

EnvBuilder builds environment variables for script execution

func NewEnvBuilder

func NewEnvBuilder(ports *PortAllocator) *EnvBuilder

NewEnvBuilder creates a new environment builder

func (*EnvBuilder) BuildEnv

func (b *EnvBuilder) BuildEnv(ws *data.Workspace) []string

BuildEnv creates environment variables for a workspace

func (*EnvBuilder) BuildEnvMap

func (b *EnvBuilder) BuildEnvMap(ws *data.Workspace) map[string]string

BuildEnvMap creates a map of environment variables

type KillOptions added in v0.0.6

type KillOptions struct {
	// GracePeriod is how long to wait for SIGTERM before sending SIGKILL.
	// Default: 200ms
	GracePeriod time.Duration
}

KillOptions configures process group termination behavior.

type PortAllocator

type PortAllocator struct {
	// contains filtered or unexported fields
}

PortAllocator manages port allocation for workspaces

func NewPortAllocator

func NewPortAllocator(start, rangeSize int) *PortAllocator

NewPortAllocator creates a new port allocator

func (*PortAllocator) AllocatePort

func (p *PortAllocator) AllocatePort(workspaceRoot string) int

AllocatePort allocates a port range for a workspace

func (*PortAllocator) GetPort

func (p *PortAllocator) GetPort(workspaceRoot string) (int, bool)

GetPort returns the allocated port for a workspace

func (*PortAllocator) PortRange

func (p *PortAllocator) PortRange(workspaceRoot string) (port, rangeEnd int)

PortRange returns the port and range size for a workspace

func (*PortAllocator) ReleasePort

func (p *PortAllocator) ReleasePort(workspaceRoot string)

ReleasePort releases the port allocation for a workspace so the base can be reused.

type ScriptRunner

type ScriptRunner struct {
	// contains filtered or unexported fields
}

ScriptRunner manages script execution for workspaces

func NewScriptRunner

func NewScriptRunner(portStart, portRange int) *ScriptRunner

NewScriptRunner creates a new script runner

func (*ScriptRunner) IsRunning

func (r *ScriptRunner) IsRunning(ws *data.Workspace) bool

IsRunning checks if a script is running for a workspace

func (*ScriptRunner) LoadConfig

func (r *ScriptRunner) LoadConfig(repoPath string) (*WorkspaceConfig, error)

LoadConfig loads the workspace configuration from the repo

func (*ScriptRunner) PortAllocated added in v0.0.20

func (r *ScriptRunner) PortAllocated(ws *data.Workspace) (int, bool)

PortAllocated reports the port base allocated for the workspace, and whether one is currently held. It mirrors PortAllocator.GetPort so callers (and the delete path's tests) can observe release without reaching into the allocator.

func (*ScriptRunner) ReleaseWorkspace added in v0.0.20

func (r *ScriptRunner) ReleaseWorkspace(ws *data.Workspace)

ReleaseWorkspace releases the workspace's port allocation once no script is running for it, so a deleted workspace's port-range entry does not leak in the allocator's map for the lifetime of the process. It is a no-op while a script is still running so a release can never strand a live script's port; the caller (workspace delete) tears scripts down first. The allocator is keyed by the raw ws.Root (see EnvBuilder.PortRange), so release uses ws.Root directly.

func (*ScriptRunner) RunScript

func (r *ScriptRunner) RunScript(ws *data.Workspace, scriptType ScriptType) (*exec.Cmd, error)

RunScript runs a script for a workspace

func (*ScriptRunner) RunSetup

func (r *ScriptRunner) RunSetup(ws *data.Workspace) error

RunSetup runs the setup scripts for a workspace

func (*ScriptRunner) Stop

func (r *ScriptRunner) Stop(ws *data.Workspace) error

Stop stops the running script for a workspace

func (*ScriptRunner) StopAll

func (r *ScriptRunner) StopAll()

StopAll stops all running scripts

func (*ScriptRunner) TrustRepoScripts added in v0.0.20

func (r *ScriptRunner) TrustRepoScripts(repoPath string) error

TrustRepoScripts records the current content of repoPath's .amux/workspaces.json as approved, so subsequent RunSetup/RunScript calls execute its repo-supplied commands. Approval is content-bound: any later edit to the file re-gates execution until the user trusts it again. A repo with no config file is a no-op (nothing to trust).

func (*ScriptRunner) TrustRepoScriptsIfHash added in v0.0.20

func (r *ScriptRunner) TrustRepoScriptsIfHash(repoPath, expectedHash string) error

TrustRepoScriptsIfHash records trust only if the repo config still matches the content hash that originally triggered the user approval prompt.

type ScriptTrust added in v0.0.20

type ScriptTrust struct {
	// contains filtered or unexported fields
}

ScriptTrust is the per-user registry of repos whose .amux/workspaces.json content the user has explicitly approved. It maps a normalized repo path to the hex SHA-256 of the config content that was approved, so any later edit to the repo's config invalidates the approval (the hash no longer matches). That hash pins only the .amux/workspaces.json content itself; it does not pin other repo files that an approved command may execute.

The security property it enforces: repo-supplied executable config keys (config.SetupWorkspace / config.RunScript / config.ArchiveScript loaded from .amux/workspaces.json) never execute unless IsTrusted returns true. It is fail-closed — a missing or corrupt registry yields "not trusted". If a future change adds new repo-supplied executable config keys, they must go through the same IsTrusted check.

func NewScriptTrust added in v0.0.20

func NewScriptTrust(dir string) *ScriptTrust

NewScriptTrust returns a registry whose backing file lives in dir.

func (*ScriptTrust) IsTrusted added in v0.0.20

func (t *ScriptTrust) IsTrusted(repoPath string, configContent []byte) bool

IsTrusted reports whether the user has approved the current content of repoPath's .amux/workspaces.json. It is fail-closed: a missing or corrupt registry, or any content change since approval, yields false.

func (*ScriptTrust) Trust added in v0.0.20

func (t *ScriptTrust) Trust(repoPath string, configContent []byte) error

Trust records configContent as the approved content for repoPath, writing the registry atomically (temp + fsync + rename) the same way the workspace store persists its JSON state.

type ScriptType

type ScriptType string

ScriptType identifies the type of script

const (
	ScriptSetup   ScriptType = "setup"
	ScriptRun     ScriptType = "run"
	ScriptArchive ScriptType = "archive"
)

type ScriptsNotTrustedError added in v0.0.20

type ScriptsNotTrustedError struct {
	Repo       string
	Command    string
	ConfigHash string
}

ScriptsNotTrustedError carries the hash of the repo config content that was blocked, so the UI can bind a later approval to the exact reviewed content.

func (*ScriptsNotTrustedError) Error added in v0.0.20

func (e *ScriptsNotTrustedError) Error() string

func (*ScriptsNotTrustedError) Unwrap added in v0.0.20

func (e *ScriptsNotTrustedError) Unwrap() error

type WorkspaceConfig added in v0.0.5

type WorkspaceConfig struct {
	SetupWorkspace []string `json:"setup-workspace"`
	RunScript      string   `json:"run"`
	ArchiveScript  string   `json:"archive"`
}

WorkspaceConfig holds per-project workspace configuration

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL