Documentation
¶
Overview ¶
Package tui — bridge-event adapter for the unified pipeline TUI.
BridgeObserver implements pipeline.Observer and the small handful of bridge-runtime callbacks the interactive exec mode needs. Each callback sends a tea.Msg to the program — the unified pipelineModel ingests them through the same throttle path as stream-json events under PLAN-7 / FC.
Index ¶
- func NewPipelineModel(spec *pipeline.Spec, cancel context.CancelFunc, projectRoot string, ...) pipelineModel
- type BootstrapConfig
- type BridgeObserver
- func (o *BridgeObserver) AwaitPending()
- func (o *BridgeObserver) AwaitResolved()
- func (o *BridgeObserver) HookEventFromBridge(h orchestrator.HookEvent)
- func (o *BridgeObserver) OnStageEnd(stage string, dur time.Duration, err error)
- func (o *BridgeObserver) OnStageStart(stage string)
- func (o *BridgeObserver) OnStepEnd(stage string, idx int, step pipeline.Step, dur time.Duration, output string, ...)
- func (o *BridgeObserver) OnStepLine(string, int, string)
- func (o *BridgeObserver) OnStepStart(stage string, idx int, step pipeline.Step)
- func (o *BridgeObserver) PipelineDone(err error)
- type EventKind
- type EventSource
- type PipelineModelOption
- type PipelineTUIObserver
- func (o *PipelineTUIObserver) Done(err error)
- func (o *PipelineTUIObserver) OnStageEnd(stage string, dur time.Duration, err error)
- func (o *PipelineTUIObserver) OnStageStart(stage string)
- func (o *PipelineTUIObserver) OnStepEnd(stage string, idx int, step pipeline.Step, dur time.Duration, output string, ...)
- func (o *PipelineTUIObserver) OnStepLine(stage string, idx int, line string)
- func (o *PipelineTUIObserver) OnStepStart(stage string, idx int, step pipeline.Step)
- type RenderedEvent
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewPipelineModel ¶
func NewPipelineModel(spec *pipeline.Spec, cancel context.CancelFunc, projectRoot string, opts ...PipelineModelOption) pipelineModel
NewPipelineModel returns a tea.Model wired to a pipeline spec. The model starts with every stage in the pending state; stages and their chains transition as Observer messages arrive.
cancel is invoked when the user confirms quit while the pipeline is running; it should cancel the context that runner.Run is using, so exec.CommandContext can tear down the in-flight claude subprocess. A nil cancel is tolerated (e.g. for tests) — the quit modal still renders, but confirmed quit just exits the TUI without touching the subprocess.
projectRoot is the absolute path of the user's project — used by the event renderer to display tool-call file paths relative to the project root (PLAN-2 / F6). Empty string disables relativization.
opts customize the model further — typically WithEventSource and WithAwaitReplySender for the interactive-mode path (PLAN-7 / FA).
Types ¶
type BootstrapConfig ¶
BootstrapConfig holds the result of the TUI session.
func RunBootstrap ¶
func RunBootstrap(catalog *trait.Catalog) (*BootstrapConfig, error)
RunBootstrap launches the TUI and returns the user's selections.
type BridgeObserver ¶ added in v0.0.12
type BridgeObserver struct {
// contains filtered or unexported fields
}
BridgeObserver adapts bridge hook events and pipeline lifecycle events into tea.Msgs sent to the unified pipelineModel. Renamed from PLAN-6's InteractiveObserver as part of PLAN-7 / FC — the rename signals it's no longer interactive-specific; any consumer driven by the bridge hook-event source uses it.
func NewBridgeObserver ¶ added in v0.0.12
func NewBridgeObserver(p *tea.Program) *BridgeObserver
NewBridgeObserver wires the observer to a running tea.Program.
func (*BridgeObserver) AwaitPending ¶ added in v0.0.12
func (o *BridgeObserver) AwaitPending()
AwaitPending sends an awaitPendingMsg to the tea program. Called from the BridgeRuntime subscriber goroutine when a parked await_message tool call surfaces.
func (*BridgeObserver) AwaitResolved ¶ added in v0.0.12
func (o *BridgeObserver) AwaitResolved()
AwaitResolved sends an awaitResolvedMsg to the tea program.
func (*BridgeObserver) HookEventFromBridge ¶ added in v0.0.12
func (o *BridgeObserver) HookEventFromBridge(h orchestrator.HookEvent)
HookEventFromBridge forwards a HookEvent into the tea program as a hookEventMsg. The unified model routes it to the correct stage via stageFromHookStep, renders it through RenderHookEvent, and queues it into the throttle path. PLAN-7 / FC.
func (*BridgeObserver) OnStageEnd ¶ added in v0.0.12
func (o *BridgeObserver) OnStageEnd(stage string, dur time.Duration, err error)
OnStageEnd sends a stageEndMsg.
func (*BridgeObserver) OnStageStart ¶ added in v0.0.12
func (o *BridgeObserver) OnStageStart(stage string)
OnStageStart sends a stageStartMsg.
func (*BridgeObserver) OnStepEnd ¶ added in v0.0.12
func (o *BridgeObserver) OnStepEnd(stage string, idx int, step pipeline.Step, dur time.Duration, output string, err error)
OnStepEnd forwards step ends to the model as stepEndMsg, paired with OnStepStart above so per-step endedAt is stamped and runningStepIdx resets cleanly. PLAN-7 follow-up.
func (*BridgeObserver) OnStepLine ¶ added in v0.0.12
func (o *BridgeObserver) OnStepLine(string, int, string)
OnStepLine is a no-op on the bridge-event source — chain steps share the claude session, so the stdout-line stream has no clean per-step delineation to observe (PLAN-6 / Phase E rationale). Hook events carry the displayable per-step content instead.
func (*BridgeObserver) OnStepStart ¶ added in v0.0.12
func (o *BridgeObserver) OnStepStart(stage string, idx int, step pipeline.Step)
OnStepStart forwards step starts to the model as stepStartMsg — runner-side step boundaries don't depend on the stdout stream, so the same forwarding the programmatic observer does is valid here. The unified model uses them to stamp per-step startedAt for elapsed-time display (PLAN-7 follow-up).
func (*BridgeObserver) PipelineDone ¶ added in v0.0.12
func (o *BridgeObserver) PipelineDone(err error)
PipelineDone signals pipeline.Run returned. The unified model's pipelineDoneMsg branch drains any pending events, transitions to phaseCompleted, and presents the final-report row (PLAN-2 / F7).
type EventKind ¶ added in v0.0.7
type EventKind int
EventKind classifies one rendered event for color/style mapping in the TUI layer. The caller (pipelineModel) maps kind to a lipgloss.Style; the renderer itself stays presentation-agnostic so tests don't depend on lipgloss internals.
const ( // EventSuppressed indicates this line should not be displayed. // Returned for noise (successful Read/Edit/Write tool_results, // system pings, etc). Callers must skip such entries. EventSuppressed EventKind = iota // EventText is an assistant text block (the model's prose // thinking out loud). Glyph "✎", default color. EventText // EventTool is a tool_use call (Read, Edit, Bash, ...). Glyph // "🔧", cyan. EventTool // EventToolResult is a non-trivial tool_result with success // content worth surfacing (e.g. Bash output, WebFetch summary). // Glyph "↳", dim. EventToolResult // EventToolError is a tool_result with is_error=true. Glyph "↳", // red. EventToolError // EventSuccess is a top-level "result" event with success status. // Glyph "✓", green. EventSuccess // EventFailure is a top-level "result" event with error status. // Glyph "✗", red. EventFailure // EventSystem covers system messages (init, ping, etc) that we // surface as low-importance background info. Glyph "·", dim. EventSystem // EventUnknown is the schema-drift fallback: the line parsed as // JSON but didn't match any known shape, OR didn't parse at all // (and we forward it raw). Glyph "?", dim. EventUnknown )
type EventSource ¶ added in v0.0.12
type EventSource int
EventSource selects which input the pipeline model ingests for its per-stage event feed. PLAN-7 / FA — single-model unification.
- SourceStreamJSON consumes stepLineMsg from a `claude -p` stream-json subprocess (the programmatic exec mode).
- SourceHookEvents consumes hookEventMsg from the bridge's hook fan-out (the interactive REPL exec mode), routed through RenderHookEvent.
Both sources produce the same RenderedEvent shape, so all panel / scroll / render-style machinery is source-agnostic. The default is SourceStreamJSON — existing call sites are unchanged.
const ( // SourceStreamJSON is the PLAN-1 / I4b stream-json line source — // the default for `--tui -P` and `--web -P`. SourceStreamJSON EventSource = iota // SourceHookEvents is the PLAN-7 / FC bridge-hook source — used // by `--tui` interactive mode where no stream-json is available. SourceHookEvents )
type PipelineModelOption ¶ added in v0.0.12
type PipelineModelOption func(*pipelineModel)
PipelineModelOption applies an optional configuration to NewPipelineModel. The default constructor (no opts) reproduces the PLAN-2 behavior exactly — SourceStreamJSON, no await modal — keeping every pre-PLAN-7 call site unchanged.
func WithAwaitReplySender ¶ added in v0.0.12
func WithAwaitReplySender(fn awaitReplySender) PipelineModelOption
WithAwaitReplySender wires the await-message reply path. When set, the model accepts awaitPendingMsg and renders the textinput modal; pressing Enter inside the modal invokes the sender with the input content. Nil (the default) keeps the modal unreachable — the path is dead code in programmatic mode. PLAN-7 / FA.
func WithEventSource ¶ added in v0.0.12
func WithEventSource(s EventSource) PipelineModelOption
WithEventSource selects the event-ingestion source. Default is SourceStreamJSON. PLAN-7 / FA.
type PipelineTUIObserver ¶
type PipelineTUIObserver struct {
// contains filtered or unexported fields
}
PipelineTUIObserver implements pipeline.Observer by sending tea.Msgs to the program. Returned by NewPipelineTUIObserver. The program owner is responsible for calling Done() once Run() returns so the model receives pipelineDoneMsg and quits.
func NewPipelineTUIObserver ¶
func NewPipelineTUIObserver(p *tea.Program) *PipelineTUIObserver
func (*PipelineTUIObserver) Done ¶
func (o *PipelineTUIObserver) Done(err error)
func (*PipelineTUIObserver) OnStageEnd ¶
func (o *PipelineTUIObserver) OnStageEnd(stage string, dur time.Duration, err error)
func (*PipelineTUIObserver) OnStageStart ¶
func (o *PipelineTUIObserver) OnStageStart(stage string)
func (*PipelineTUIObserver) OnStepLine ¶ added in v0.0.7
func (o *PipelineTUIObserver) OnStepLine(stage string, idx int, line string)
func (*PipelineTUIObserver) OnStepStart ¶
func (o *PipelineTUIObserver) OnStepStart(stage string, idx int, step pipeline.Step)
type RenderedEvent ¶ added in v0.0.7
RenderedEvent is one display row produced from one stream-json line. Callers concatenate Glyph + " " + Body and apply the style mapped from Kind. Raw is the original NDJSON line — populated by RenderEventWithRoot so PLAN-2 / F3's raw / both render styles can surface it without re-parsing.
func RenderEvent ¶ added in v0.0.7
func RenderEvent(line string) RenderedEvent
RenderEvent parses one stream-json line and returns its display representation. Never panics on malformed input: any failure to parse falls through to EventUnknown with the raw line in Body.
Equivalent to RenderEventWithRoot(line, "") — paths in tool events render absolute. Callers that know their project root should prefer the with-root variant so PLAN-2 / F6 strips the prefix and keeps the informative tail of long paths visible.
func RenderEventWithRoot ¶ added in v0.0.8
func RenderEventWithRoot(line, projectRoot string) RenderedEvent
RenderEventWithRoot is RenderEvent with a project-root path prefix that path-shaped tool arguments are made relative to (PLAN-2 / F6). When projectRoot is empty, behavior is identical to RenderEvent — no relativization is attempted. Tokens that don't share the prefix (system paths, $HOME-relative, framework files) render as-is.
func RenderHookEvent ¶ added in v0.0.12
func RenderHookEvent(h orchestrator.HookEvent, projectRoot string) RenderedEvent
RenderHookEvent converts a bridge HookEvent into a RenderedEvent matching the shape produced by RenderEventWithRoot. The renderer keeps no state; PLAN-7 / FB.
Mapping (cross-ref plan-7_unified-pipeline-tui.md § FB):
UserPromptSubmit → EventText "?" prompt first line PreToolUse → EventTool "🔧" tool_name + first path arg PostToolUse (ok) → EventToolResult "↳" tool_response first line PostToolUse (err) → EventToolError "↳" "⚠ " + tool_response first line Stop → EventSuccess "✓" "skill complete" (+ summary if available) Notification → EventSystem "·" message (anything else) → EventSuppressed — —
projectRoot is stripped from path-shaped tool arguments (same rule the stream-json path uses via PLAN-2 / F6); empty disables.
func (RenderedEvent) IsDisplayable ¶ added in v0.0.7
func (r RenderedEvent) IsDisplayable() bool
IsDisplayable reports whether the event should be rendered at all. Callers typically: r := RenderEvent(line); if !r.IsDisplayable() { continue }