guideflow

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: May 7, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package guideflow implements the cinematic `bonsai guide` viewer — a tabbed BubbleTea scroll viewport that renders bundled markdown guides through glamour inside the shared initflow chrome (header + footer + min-size floor). The package is consumed by cmd/guide.go on TTY invocations; non-TTY (piped output) falls back to a static one-shot glamour render in cmd/guide.go.

Topics are supplied by the caller as a pre-ordered slice; the viewer preserves that order on the tab strip. No kanji labels — per Plan 28 Session 2026-04-23 decision D1 the guide surface is English-only.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Topic

type Topic struct {
	Key      string // machine identifier, e.g. "quickstart"
	Label    string // full label, e.g. "QUICKSTART"
	Short    string // narrow-width fallback, e.g. "START"
	Markdown string // raw embedded markdown body
}

Topic is one guide entry shown on a tab. Label is the full-width cell text; Short is the narrow-width fallback rendered when the full strip would exceed the clamp budget. Markdown is the raw embedded content (frontmatter retained — the renderer strips it at render time so the cache key stays pure).

func NewTopics

func NewTopics(rawContents map[string]string) []Topic

NewTopics builds the []Topic slice in canonical order from a rawContents map keyed by machine identifier. Missing keys are silently skipped — the caller (cmd/guide.go) owns the "unknown topic" error path, so the viewer tolerates an incomplete map without panicking.

Order is locked to canonicalOrder regardless of the rawContents iteration order — map iteration is non-deterministic and the tab strip must render the same sequence every invocation.

type ViewerStage

type ViewerStage struct {
	initflow.Stage
	// contains filtered or unexported fields
}

ViewerStage is the BubbleTea model for `bonsai guide`. Four topic tabs across the top, a scrollable glamour-rendered body below, standard initflow chrome wrapping the whole frame. Embeds initflow.Stage with railHidden=true — guide is read-only (no mutation process, no rail segments to walk).

Markdown output is cached per (topicIdx, viewport width) so resize events only re-render when the width actually changes and tab cycles re-use prior renders.

func NewViewer

func NewViewer(topics []Topic, initialKey, version, projectDir string) *ViewerStage

NewViewer constructs a ViewerStage from the given topics + the initial topic key (empty or unknown → idx 0). version and projectDir feed the header chrome; projectDir may be empty if the caller couldn't resolve it (guide doesn't strictly need it).

func (*ViewerStage) Init

func (s *ViewerStage) Init() tea.Cmd

Init implements tea.Model. No-op — the first render is wired up on the first WindowSizeMsg.

func (*ViewerStage) Result

func (s *ViewerStage) Result() any

Result implements harness.Step. Guide is read-only — no payload.

func (*ViewerStage) Title

func (s *ViewerStage) Title() string

Title implements harness.Step.

func (*ViewerStage) Update

func (s *ViewerStage) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model.

Keys:

  • tab / right / l — next topic (wraps)
  • shift+tab / left / h — prev topic (wraps)
  • g / home — viewport top
  • G / end — viewport bottom
  • up/down, j/k, pgup/pgdn, space, u/d — scroll (viewport)
  • q / esc / ctrl+c — quit

func (*ViewerStage) View

func (s *ViewerStage) View() string

View composes the full frame: header + tab strip + viewport + footer. Stage.RenderFrame short-circuits to the min-size floor when the terminal falls below the 70×20 threshold, so the check isn't duplicated here.

Jump to

Keyboard shortcuts

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