execsegment

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package execsegment splits a Codex command script into its top-level segments and instruments them for per-segment tracking. The helper that runs inside the command shell and the router that displays it share this split, so their segment indices always agree.

Index

Constants

View Source
const (
	Hello  = "hello"
	Begin  = "b"
	Output = "o"
	End    = "e"
	Done   = "d"
	// Lossy reports that the helper stopped reporting output to stay within
	// its bound; statuses continue.
	Lossy = "lossy"
)

Message types.

View Source
const Guard = "MEKUGI_EXEC_TRACK"

Guard marks a shell that already decided whether to track its command, so nested command shells started by that command are never tracked.

View Source
const Protocol = 3

Protocol is the helper-to-router message version.

View Source
const ShTrackerEnvironment = "MEKUGI_SH_TRACKER"

Variables

This section is empty.

Functions

func Hook

func Hook(tracker string) string

Hook is Bash startup source, read from BASH_ENV, that tracks the command script Codex passed with -c. It decides before any segment runs: only when the helper plans the script and the router matches it to a live Codex command does the shell run the rewrite in place of the script and exit. Otherwise it returns and Bash runs the original script itself, so the command never runs twice.

Codex's own snapshot scripts, including the wrapper that re-executes the command shell, pass through without setting the guard: the snapshot would otherwise record it for every later command.

func OpenPreparedReport added in v0.2.0

func OpenPreparedReport(work string, timeout time.Duration) (report, reply *os.File, directory string, err error)

OpenPreparedReport opens router-created resources requested earlier by dash.

func OpenReport added in v0.2.0

func OpenReport(channel, directory string, timeout time.Duration) (report, reply *os.File, work string, err error)

OpenReport sends an atomic request through an existing FIFO, followed by router-created FIFOs. The sandboxed helper only opens files; it creates no filesystem objects. Report has one writer, so output messages need no shared-pipe framing.

func ReportDirectory added in v0.2.0

func ReportDirectory(directory, id string) (string, bool)

ReportDirectory validates a request ID before resolving its private files.

func RequestReport added in v0.2.0

func RequestReport(channel, id string) error

RequestReport asks the router to create one invocation's existing resources.

func Rewrite

func Rewrite(script string, segments []Segment) string

Rewrite wraps each segment in hooks that report its start and exit status. Each wrapper runs in the current shell and returns the segment's status, so && and || chains, $?, and shell state behave as in the original. A hook passes a nonzero status on as the operand of an && list, where errexit ignores it: under set -e, only the segment's own command can end the shell.

func ShOriginal added in v0.2.0

func ShOriginal(script string) string

ShOriginal recognizes only an exact envelope produced by ShScript. Removing its inline boundaries keeps authored newlines and shell error line numbers.

func ShScript added in v0.2.0

func ShScript(tracker, script string) string

ShScript adds a portable startup call and the existing segment rewrite. Bash's startup hook recognizes this envelope before its DEBUG trap replaces the script. Other shells retain their own execution and no-op boundaries.

func ShTracker added in v0.2.0

func ShTracker(helper, channel, directory string) string

ShTracker runs in dash itself. Only transport differs from Bash: dash has no coprocess, so the existing router also supplies control and ack FIFOs.

func Tracker

func Tracker(helper, channel, directory string) string

Tracker is the Bash source that runs a tracked script. The helper runs as a coprocess: the shell sends it segment boundaries and waits for each acknowledgment, so the helper has relayed a segment's output before the next segment starts. Output reaches Codex unchanged through the helper, which alone keeps the original descriptors. A terminal cannot be relayed without changing what programs detect, so terminal commands report status only.

The rewrite does not run from the startup file, whose errors differ from the script's: a fatal expansion error there would abandon the startup file and run the original script as well. A one-time DEBUG trap instead runs it in place of the script's first command, so error messages, line numbers, and fatal errors behave as in the original. Split accepts only scripts whose first command fires that trap before it has any effect.

Types

type Message

type Message struct {
	Timing   Timing   `json:"timing,omitzero"`
	Type     string   `json:"t"`
	Version  int      `json:"v,omitzero"`
	Thread   string   `json:"thread,omitempty"`
	Script   string   `json:"script,omitempty"`
	Segments []string `json:"segments,omitempty"`
	Terminal bool     `json:"tty,omitzero"`
	Index    int      `json:"i,omitzero"`
	Data     string   `json:"d,omitempty"`
	Code     *int     `json:"c,omitempty"`
}

Message is one line of the helper's report. Hello opens a report and the router answers with Reply; the rest follow in the order the shell and its output produced them.

type Reply

type Reply struct {
	OK bool `json:"ok"`
}

Reply accepts or declines a hello.

type Segment

type Segment struct {
	Start, End int    // Script byte span, excluding terminators and heredoc bodies.
	Source     string // Display source, including any heredoc body.
}

Segment is one top-level command of a list: a statement, or an operand of a top-level && or || chain. Pipelines and compound commands stay whole.

func Split

func Split(script string) ([]Segment, bool)

Split returns the script's segments when every segment can be tracked without changing the script's behavior. Single commands are observed in place, without a rewrite. It reports false for lists whose first command runs before the shell's DEBUG trap can replace the script, and for scripts whose semantics depend on the shell state the instrumentation touches: job control, traps, top-level returns, process replacement, command tracing, and variables naming the current command.

type Timing

type Timing struct {
	Started   time.Time `json:"started,omitzero"`
	Ended     time.Time `json:"ended,omitzero"`
	ElapsedNS int64     `json:"elapsed_ns,omitzero"`
}

Timing records helper-observed command boundaries. ElapsedNS is measured with the helper's monotonic clock, independently of wall-clock adjustments.

Jump to

Keyboard shortcuts

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