Add Program to the process package as a lightweight tool-finder and runner. Find() resolves a binary via exec.LookPath (wrapping ErrProgramNotFound), Run() and RunDir() execute the binary and return trimmed combined output. Includes 7 tests covering happy paths, error paths, and the errors.Is contract. Co-Authored-By: Virgil <virgil@lethean.io>
2.4 KiB
2.4 KiB
Plan: Absorb Sail Program
Date: 2026-03-18 Branch: agent/implement-the-plan-at-docs-plans-2026-03
Overview
Add a Program struct to the process package that locates a named binary on PATH and provides lightweight run helpers. This absorbs the "sail program" pattern — a simple way to find and invoke a known CLI tool without wiring the full Core IPC machinery.
API
// Program represents a named executable located on the system PATH.
type Program struct {
Name string // binary name, e.g. "go", "node"
Path string // absolute path resolved by Find()
}
// Find resolves the program's absolute path via exec.LookPath.
func (p *Program) Find() error
// Run executes the program with args in the current working directory.
// Returns combined stdout+stderr output and any error.
func (p *Program) Run(ctx context.Context, args ...string) (string, error)
// RunDir executes the program with args in dir.
// Returns combined stdout+stderr output and any error.
func (p *Program) RunDir(ctx context.Context, dir string, args ...string) (string, error)
Tasks
Task 1: Implement Program in program.go
- Create
program.goin the rootprocesspackage - Add
ErrProgramNotFoundsentinel error usingcoreerr.E - Add
Programstruct with exportedNameandPathfields - Implement
Find() errorusingexec.LookPath; ifNameis empty return error - Implement
RunDir(ctx, dir, args...) (string, error)usingexec.CommandContext- Capture combined stdout+stderr into a
bytes.Buffer - Set
cmd.Dirifdiris non-empty - Wrap run errors with
coreerr.E - Trim trailing whitespace from output
- Capture combined stdout+stderr into a
- Implement
Run(ctx, args...) (string, error)asp.RunDir(ctx, "", args...) - Commit:
feat(process): add Program struct
Task 2: Write tests in program_test.go
- Create
program_test.goin the rootprocesspackage - Test
Find()succeeds for a binary that exists on PATH (echo) - Test
Find()fails for a binary that does not exist - Test
Run()executes and returns output - Test
RunDir()runs in the specified directory (verify viapwdorls) - Test
Run()beforeFind()still works (falls back toName) - Commit:
test(process): add Program tests
Acceptance Criteria
go test ./...passes with zero failures- No
fmt.Errorforerrors.New— onlycoreerr.E Programis in the rootprocesspackage (not exec subpackage)Rundelegates toRunDir— no duplication