Classifies every running child as idle/working/thinking/permission/error using one of three pluggable strategies (output_activity, osc_title_stability, osc_title_status) plus optional regex promoters applied to the tail of recent output. State and last-match reason are exposed via MCP on ProcessInfo and get_process_status. Per-preset configuration lives on a new preset.IdleDetection block with bundled defaults for the first-party claude/codex/opencode presets. OSC title plumbing is exposed as Emulator.Title(), polled from the session pump after each emulator write so title-change activity feeds into the classifier without an extra cgo callback. The MCP timer surface expands to match Solo: timer_set, timer_fire_when_idle_any/all, timer_cancel, timer_pause, timer_resume, timer_list. timer_wait is now a thin wrapper that shares the same manager so it shows up in timer_list while pending. Timer bodies are delivered to the owner process through the existing InjectAsOrchestrator path. Top-level (non-agent) callers can attach timers to a specific process via owner_process_id; omitting it grants universal cancel/pause/resume/list privileges. The sidebar gains a state glyph per process row and appends a nearest-timer indicator when one is pending or paused. Tests: idle_test.go covers the classify() pure function across the three strategies and regex promotion; timers_test.go covers the manager. Harness scenarios cover output_activity, osc_title_stability, osc_title_status, and regex promotion, plus timer_set delivery, cancel, pause/resume, idle_any-on-transition, idle_all-pending, and idle_all-already-satisfied. A new wait_until_mcp harness step type polls an MCP method until an assertion holds.
37 lines
1.8 KiB
Go
37 lines
1.8 KiB
Go
//go:build nocgo
|
|
|
|
// This file provides a stub GhosttyEmulator for `go vet` / `go build`
|
|
// invocations that pass the `nocgo` build tag, so the rest of the Go code can
|
|
// be checked without `libghostty-vt` being installed. The stub fails at
|
|
// construction time — there is no functional emulator in `nocgo` builds.
|
|
|
|
package vt
|
|
|
|
import "errors"
|
|
|
|
type GhosttyEmulator struct{}
|
|
|
|
func NewGhosttyEmulator(cols, rows uint16) (*GhosttyEmulator, error) {
|
|
return nil, errors.New("vt: built with -tags nocgo; libghostty-vt is unavailable")
|
|
}
|
|
|
|
func (e *GhosttyEmulator) Write(p []byte) (int, error) { return 0, errStub }
|
|
func (e *GhosttyEmulator) Resize(cols, rows uint16) error { return errStub }
|
|
func (e *GhosttyEmulator) Size() (uint16, uint16) { return 0, 0 }
|
|
func (e *GhosttyEmulator) PlainText() (string, error) { return "", errStub }
|
|
func (e *GhosttyEmulator) ScreenText() (string, error) { return "", errStub }
|
|
func (e *GhosttyEmulator) SerializeVT() ([]byte, error) { return nil, errStub }
|
|
func (e *GhosttyEmulator) StyledScreenVT() ([]byte, error) { return nil, errStub }
|
|
func (e *GhosttyEmulator) Cursor() (CursorState, error) { return CursorState{}, errStub }
|
|
func (e *GhosttyEmulator) ActiveScreen() (Screen, error) { return 0, errStub }
|
|
func (e *GhosttyEmulator) Title() (string, error) { return "", errStub }
|
|
func (e *GhosttyEmulator) ScrollViewportTop() error { return errStub }
|
|
func (e *GhosttyEmulator) ScrollViewportBottom() error { return errStub }
|
|
func (e *GhosttyEmulator) ScrollViewportDelta(int) error { return errStub }
|
|
func (e *GhosttyEmulator) OnWritePTY(fn func([]byte)) {}
|
|
func (e *GhosttyEmulator) Close() error { return nil }
|
|
|
|
var errStub = errors.New("vt: built with -tags nocgo")
|
|
|
|
var _ Emulator = (*GhosttyEmulator)(nil)
|