evo

package module
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

README

Evident Output

Go presentation library for CLI state, progress, evidence, changes, plans, and conclusions. Application code owns execution; package evo owns presentation — so the same call sites render correctly whether stdout is a real terminal or a log file, and the exit code always matches what the screen just said.

Install

go get github.com/zachbornheimer/evident-output@v0.5.2

Requires Go 1.25+. License: Apache-2.0.

Quickstart

import (
    evo "github.com/zachbornheimer/evident-output"
)

func main() {
    evo.Init(evo.Config{Title: "bpp-csharp"}) // first statement — arms first paint before any I/O
    evo.Main(run) // exits the process itself; evo.Run(run) if you need the code without exiting
}

func run() error {
    // Start as casually as fmt — then promote to structure when useful.
    evo.Println("Reading configuration")
    evo.Printf("Found %d packages\n", 18)

    evo.Task("working tree").Done()
    evo.Task("branches").Block(
        "local-only branch",
        evo.Detail("commit or stash before continuing"),
    )

    evo.Task("cleanup").Delete("stale local branch", func() error {
        return removeStaleBranches()
    }, evo.Affected(2)) // singular object, ledger renders "2 stale local branches"

    for pkg, task := range evo.Group("install").Each(packages) {
        task.Define(func() error { return install(pkg) })
    }
    return nil // Block is a presentation outcome, not a Go error
}

On a real terminal, install draws an in-place, colored, animated progress line while it runs — no extra code. Piped (prog > log.txt, CI, an agent harness), the same call sites fall back to plain, durable lines:

Reading configuration
Found 18 packages
✓ working tree
⊘ branches      local-only branch
   └─ commit or stash before continuing
◐ install  0/2
◐ install  1/2  a
◐ install  2/2  b
✓ cleanup
✓ install

[changed] cleanup  deleted 2 stale local branches

[blocked]  bpp-csharp

Exit code 1 — see the table below. Try the live, colored version: go run ./examples/repo-status/.

Conclusion band → exit code

The trailing [state] band and the process exit code always agree — never read one without checking the other. · partial and · warned are modifiers on the state, not a state of their own.

Band Exit code Meaning
[changed] 0 A mutation verb (Delete/Create/…) recorded outside DryRun
[planned] 0 A mutation verb recorded under Config.DryRun (would, not did)
[ready] 0 Every task resolved Done; no mutation verb recorded
[blocked] 1 At least one Block, and nothing Failed
[failed] 2 At least one Fail, or a caller-supplied misuse
[cancelled] 130 Cancel or an interrupt ended the run early
any of the above + · partial unchanged The run also left an unresolved task — same exit code as the state above
any of the above + · warned unchanged At least one Warn annotated a task without otherwise changing the headline — Warn never resolves the task itself; Done/Fail/Block/… still must

Pick the entity

Shape Use when
Task One atomic unit — a check/gate resolved directly (Done/Warn/Block/Fail/Skipped) or work submitted with Define / a mutation verb
Group Independent collection of atomic tasks (state is derived); the scheduler may overlap eligible children; Group.Each for homogeneous items
Sequence Ordered dependency of tasks (state is derived); a failed child auto-resolves later siblings to NotStarted; both nest via .Sequence/.Group

Learn more

Documentation

Overview

Package evo is Evident Output: a presentation library for CLI state, progress, evidence, changes, plans, messages, actions, and conclusions.

Application code owns execution. Evo owns presentation.

func main() {
    evo.Init(evo.Config{Title: "repo"}) // first statement — arms first paint before any I/O
    evo.Main(run)
}

func run() error {
    evo.Println("Reading configuration")
    evo.Task("working tree").Done()
    t := evo.Task("fetch")
    cmd.Stdout = t.Writer()
    cmd.Stderr = t.Writer()
    return nil // Block is a presentation outcome, not a Go error
}

Adoption ladder (guess-driven defaults — the naive spelling is the correct one):

  1. evo.Init(Config) once in main, before any I/O; evo.Main(run) — dry-run wording, empty-case, and exit codes are all owned; run returns only error.
  2. Print / Printf / Println / Verbose — start as casually as fmt.
  3. evo.Task(name) for everything — a check/gate resolved directly (Done/Warn/Block/Fail/Skip, no Doing/Progress call) renders as a fact row; work with Doing/Progress or a mutation verb (Add/Delete/Create/Update/Remove/Write/Push/Record/RecordName) shows a spinner while running — the verb picks [planned] vs [changed] from Config.DryRun; no call site ever flips its own tense. name is a printf format whenever args follow it (evo.Task("build %s", ref)); no args leaves name untouched. Define(fn) or a mutation verb submits work; Done is only for already-resolved work with no callback.
  4. evo.Group(name).Each(items) / evo.Sequence(name).Each(items) for collection progress. Each item is an atomic Task; Define or a mutation verb submits it. The range waits for submitted work before control proceeds. cmd.Stdout = task.Writer() so a talkative child's last line becomes the live doing-text. A failed item Fails that child Task — not a second Task declared inside the loop body for the same item.
  5. evo.Task(name).Skipped(evo.Reason("...")) / .Kept(evo.Reason("...")) — taxonomy counted and summed, never a bare "skipped N". evo.Reason(name) is a get-or-create lookup on the default instance: the same string at every call site merges into one bucket, so an inline evo.Reason("protected") is always legal — lifting it to a package var is optional, never required for correctness. Individual names render under Config.Verbosity: VerbosityVerbose (see doc there); at the default VerbosityNormal the human line stays the aggregated "! skipped N (...)" count. The names are never dropped — they always live on TaskSnapshot.Skipped/Kept (Output.Snapshot / TaskHandle.Snapshot); the wire JSON document does not carry them.
  6. evo.Confirm(question, ...) — owns the whole ask-decide-resolve gate (prompt, quiesce, Done/Blocked resolution, exit code). question is verbatim text, not a printf format like Task/Sequence/Reason/Doing/Skip's text — use fmt.Sprintf to build a dynamic question first. Confirm is the one entity-text spelling that stays non-printf (release-gate round 6 finding 4).
  7. evo.Sequence(name) for named children with derived, auto-lifecycle state.
  8. task.Fail(summary) / task.Block(summary) are statements — no return value, so a bare call is errcheck-clean. `return task.Failf("schema mismatch: %w", err)` (task declared as evo.Task("validate manifest")) builds and returns one error in a single line: a trailing ": %w"/", %w" splits the formatted text into the rendered summary and an evidence line for the wrapped error; Blockf is the same for Block. The summary states WHAT went wrong, not the task's own name again — the rendered row already carries the task label, so a summary of "validate manifest: %w" would just repeat it back. Warn, and success/skip verbs, stay void too — this is never fluent chaining. Done/Warn/Task/Sequence/Reason/Doing/Skip are printf-variadic themselves (fmt.Sprintf semantics when args follow); there is no separate Donef/Warnf/Taskf/Reasonf/Doingf/ Skipf (C6). Output.Failf stays void rather than mirroring TaskHandle.Failf's *Failure return (release-gate round 4 finding 5): every call site uses it as a bare statement, a returned error would fail errcheck at each of them with no lint-config exception on this repo, and there is no per-call Next chain for an output-level failure to attach to the way TaskHandle.Failf's *Failure attaches to its task (Output.Next already covers the output-level case). Documented asymmetry, not an oversight.
  9. Config{Debug: evo.DebugConfig{Level: evo.LevelDebug}} selects the journal threshold for Debug/Capture mirrors and the slog bridge. evo.LogLevel is its own type, distinct from stdlib slog.Level — SlogHandler translates between the two internally, but Config.Debug.Level itself never takes a slog.Level value. LevelUnset (the zero value) resolves to LevelInfo; LevelTrace/LevelDebug are the two levels that surface Debug journal lines. Package-level evo.SlogHandler() journals to the default instance, the same default-instance sugar evo.Task/evo.Verbose already offer.

Ordinary surface: evo.Init/evo.Main, Print*, evo.Task/evo.Group/evo.Sequence, Task.Define / mutation verbs / Task.Writer, Task.Fail / Task.Failf / Task.Block / Task.Blockf, evo.Confirm, evo.Reason, slog via SlogHandler (level from Config.Debug.Level).

Advanced surface, for testing and tooling call sites that need a hosted instance instead of the package-level default: Config.Isolated returns an independent *Output that never touches package state; Output.Run(run func(*Output) error) seals it (the hosted counterpart of Main's run func() error, called on the *Output itself instead of the default instance); Config.Options is the raw-Option escape hatch for exact writer/ terminal/clock wiring. Plan/Changes for the would/did split without a Task, session evidence, terminal drivers, and testkit.

Example (BeginnerAPI)

Example_beginnerAPI proves the beginner shape compiles and renders real rows, not an empty // Output: that only proves compile (evo-dialect-axes- report.md axis 2: "the example discards stdout and asserts nothing"). Sequence (declaration order, one Running child at a time) keeps the two child rows deterministic across runs; Group.Each would be correct too but collapses an all-success aggregate into a single summary line.

package main

import (
	"bytes"
	"fmt"
	"io"

	evo "github.com/zachbornheimer/evident-output"
)

func main() {
	var buf bytes.Buffer
	out := evo.Init(evo.Config{Stdout: &buf, Stderr: io.Discard, Plain: true})
	check := func(string) error { return nil }
	worktrees := out.Sequence("worktrees")
	for _, path := range []string{"repo-a", "repo-b"} {
		task := worktrees.Task(path)
		task.Define(func() error { return check(path) })
	}
	if err := out.Finish(); err != nil {
		fmt.Println(err)
	}
	fmt.Print(buf.String())
}
Output:
✓ worktrees
   ✓ repo-a
   ✓ repo-b

Index

Examples

Constants

View Source
const (
	ExitOK        = core.ExitOK
	ExitBlocked   = core.ExitBlocked
	ExitFailed    = core.ExitFailed
	ExitCancelled = core.ExitCancelled
)

Default exit codes from architecture §26.

View Source
const (
	// GlyphsAuto detects the vocabulary from locale and TTY interactivity.
	GlyphsAuto = txt.GlyphsAuto
	// GlyphsUnicode forces the Unicode vocabulary regardless of locale.
	GlyphsUnicode = txt.GlyphsUnicode
	// GlyphsASCII forces the ASCII vocabulary regardless of locale.
	GlyphsASCII = txt.GlyphsASCII
)
View Source
const (
	Pending    = core.Pending
	Running    = core.Running
	Done       = core.Done
	Blocked    = core.Blocked
	Failed     = core.Failed
	Skipped    = core.Skipped
	Cancelled  = core.Cancelled
	Empty      = core.Empty
	Incomplete = core.Incomplete
	// NotStarted marks a group task that never ran because an earlier sibling
	// already failed or was cancelled — rendered "-  <name>  not started" and
	// excluded from the conclusion (the group's verdict comes from the
	// failed/cancelled sibling, not from its unstarted followers).
	NotStarted = core.NotStarted
)

EntityState values — see the type doc comment above for the naming rationale (no State* prefix on this block).

View Source
const (
	StateReady     = core.StateReady
	StateChanged   = core.StateChanged
	StateWarning   = core.StateWarning
	StateBlocked   = core.StateBlocked
	StateFailed    = core.StateFailed
	StateCancelled = core.StateCancelled
	StatePlanned   = core.StatePlanned
)

ConclusionState values — the trailing "[state]" band a run can end in.

View Source
const (
	Indeterminate = core.Indeterminate
	Determinate   = core.Determinate
	BytesKind     = core.BytesKind
)

ProgressKind values — which measurement a task's Progress reports.

View Source
const (
	// VisibilityNormal messages always project at VerbosityNormal (C11:
	// prefixed consistently with VisibilityVerbose — the two enum members
	// previously disagreed on their own naming convention).
	VisibilityNormal = core.VisibilityNormal
	// VisibilityVerbose messages project only when Config.Verbosity is VerbosityVerbose.
	VisibilityVerbose = core.VisibilityVerbose
)
View Source
const (
	ColorAuto   = engine.ColorAuto
	ColorAlways = engine.ColorAlways
	ColorNever  = engine.ColorNever
)
View Source
const (
	FormatHuman    = engine.FormatHuman
	FormatData     = engine.FormatData
	FormatExternal = engine.FormatExternal
)
View Source
const (
	VerbosityNormal  = engine.VerbosityNormal
	VerbosityVerbose = engine.VerbosityVerbose
)
View Source
const (
	ProjectionHuman      = engine.ProjectionHuman
	ProjectionPlain      = engine.ProjectionPlain
	ProjectionJSON       = engine.ProjectionJSON
	ProjectionJSONL      = engine.ProjectionJSONL
	ProjectionStreamJSON = engine.ProjectionStreamJSON
)
View Source
const (
	LevelUnset = engine.LevelUnset
	LevelTrace = engine.LevelTrace
	LevelDebug = engine.LevelDebug
	LevelInfo  = engine.LevelInfo
	LevelWarn  = engine.LevelWarn
	LevelError = engine.LevelError
)
View Source
const (
	DebugPresentationHistory = engine.DebugPresentationHistory
	DebugPresentationPane    = engine.DebugPresentationPane
)
View Source
const (
	EvidenceStreamCombined = engine.EvidenceStreamCombined
	EvidenceStreamStdout   = engine.EvidenceStreamStdout
	EvidenceStreamStderr   = engine.EvidenceStreamStderr
)
View Source
const DefaultVisibleNames = engine.DefaultVisibleNames
View Source
const EventSchemaVersion = core.EventSchemaVersion

EventSchemaVersion is the durable event schema version. Tracks the 0.2 contract series (pre-1.0 wire format may still evolve).

View Source
const JSONSchemaVersion = render.JSONSchemaVersion

JSONSchemaVersion is the final JSON document schema version. Tracks the 0.3 contract series (pre-1.0 wire format may still evolve). Bumped from 0.2: "items" no longer exists as a separate wire kind — the item/task fold means every entity (including a fact-check resolved without ever running) is a "tasks" row (CHANGELOG "Unreleased").

View Source
const PublishedRelease = "v0.5.2"

PublishedRelease is the single source of truth for the current published module and MCP pin used in install guidance.

Maintenance class this protects (v0.2.10 hygiene, generalized):

  • skills / integrations / README disagree on which tag to install
  • MCP config generator falls back to a stale hardcoded tag
  • portable docs recommend @latest or a personal-machine clone path
  • signed tags ship with stale README pins (next patch, never rewrite history)

When cutting a release:

  1. Promote CHANGELOG ## Unreleased → ## [X.Y.Z] (Keep a Changelog).
  2. Set PublishedRelease to the new tag (e.g. "v0.2.11").
  3. Prefer: mise run test && mise run cut-release (cut-release syncs pins, stages CHANGELOG, refuses Unreleased drift).
  4. Tag that commit; do not move prior tags.

version_drift_test.go enforces the portable surface stays synchronized.

Variables

View Source
var (
	ErrClosed              = engine.ErrClosed
	ErrAlreadyResolved     = engine.ErrAlreadyResolved
	ErrUnresolvedTask      = engine.ErrUnresolvedTask
	ErrInvalidProgress     = engine.ErrInvalidProgress
	ErrProgressRegression  = engine.ErrProgressRegression
	ErrDuplicateKey        = engine.ErrDuplicateKey
	ErrInvalidConfig       = engine.ErrInvalidConfig
	ErrRenderer            = engine.ErrRenderer
	ErrLimitExceeded       = engine.ErrLimitExceeded
	ErrReasonSkipOnly      = engine.ErrReasonSkipOnly
	ErrReasonWrongTask     = engine.ErrReasonWrongTask
	ErrConcurrentRunning   = engine.ErrConcurrentRunning
	ErrDryRunDeclaredLate  = engine.ErrDryRunDeclaredLate
	ErrTerminalWithoutSink = engine.ErrTerminalWithoutSink
	ErrNotStarted          = engine.ErrNotStarted
	ErrWaitDeadlock        = engine.ErrWaitDeadlock
)

Functions

func Confirm added in v0.3.0

func Confirm(question string, opts ...ConfirmOption) bool

Confirm asks question on the default instance and returns whether the user accepted.

func Delay added in v0.2.7

func Delay(d time.Duration) *time.Duration

func EncodeEventJSON added in v0.5.0

func EncodeEventJSON(e Event) ([]byte, error)

EncodeEventJSON encodes one journal event as a single JSON object (no newline).

func EncodeJSON

func EncodeJSON(s Snapshot) ([]byte, error)

EncodeJSON encodes a snapshot as final JSON (§25.1 / §25.4).

func EncodeJSONL

func EncodeJSONL(events []Event) ([]byte, error)

EncodeJSONL encodes durable events as JSON Lines (§25.2 / §25.4).

func Fact added in v0.4.0

func Fact(name, value string)

func IsCharDevice

func IsCharDevice(w io.Writer) bool

func Main

func Main(run func() error)

Main executes run and os.Exit's with the conclusion code.

func MainWith added in v0.4.0

func MainWith(out *Output, run func(*Output) error)

MainWith executes run against out and os.Exit's with the conclusion code.

Superseded by Main (default instance) and Output.Run (hosted instance).

func Pluralize added in v0.3.0

func Pluralize(quantity int64, singular string) string

func Print added in v0.3.0

func Print(args ...any)

Print formats like fmt.Sprint and enqueues human-facing text on the default instance.

func Printf added in v0.3.0

func Printf(format string, args ...any)

Printf formats like fmt.Sprintf and enqueues human-facing text on the default instance.

func Println added in v0.3.0

func Println(args ...any)

Println formats like fmt.Sprintln and enqueues a complete line on the default instance.

func RenderPlain

func RenderPlain(s Snapshot, opts PlainOptions) ([]byte, error)

func Run added in v0.4.0

func Run(run func() error) int

Run executes run, finishes the default Output, and returns the conclusion exit code.

func SetDefault added in v0.3.0

func SetDefault(out *Output)

SetDefault installs out as the package-level default Output.

func SlogHandler added in v0.3.0

func SlogHandler() slog.Handler

SlogHandler returns a slog.Handler journaling to the default instance.

func TruncateNames added in v0.2.16

func TruncateNames(names []string, visible int) string

func Warn added in v0.4.0

func Warn(summary string)

Types

type Action

type Action = core.Action

Action is a recommended next step for the user.

Aliased into internal/core alongside the rest of the data model — see Snapshot's doc comment (snapshot.go) for why.

func Command

func Command(executable string, args ...string) Action

Command builds an action with an executable and arguments. Display-bound strings are sanitized at construction.

func Label added in v0.3.0

func Label(text string) Action

Label builds a plain-text recommended next step with no executable command (e.g. a policy hint like "pass --yes to confirm non-interactively").

type Attachment added in v0.3.0

type Attachment = core.Attachment

Attachment is an additional label/value problem attachment.

Named Attachment (not Evidence) because Evidence names the retained process-output sink (see Evidence in capture.go) — this is a single labeled fact attached to a Problem, a different concept from that sink.

type ChangesSnapshot

type ChangesSnapshot = core.ChangesSnapshot

ChangesSnapshot is an immutable changes section.

type ColorMode added in v0.2.0

type ColorMode = engine.ColorMode

type CommandSpec

type CommandSpec = core.CommandSpec

CommandSpec is an executable plus argv (never a shell string).

type Conclusion

type Conclusion = core.Conclusion

Conclusion is the multidimensional meaning of a finished command.

Aliased into internal/core alongside the rest of the data model — see Snapshot's doc comment (snapshot.go) for why, and EVIDENT_OUTPUT_ARCHITECTURE_SPEC_v0.5.md §38 for the full layout.

type ConclusionJSON

type ConclusionJSON = render.ConclusionJSON

ConclusionJSON is JSON-friendly conclusion.

type ConclusionState

type ConclusionState = core.ConclusionState

ConclusionState is the human headline for a finished output.

type Config

type Config = engine.Config

func DefaultConfig added in v0.2.0

func DefaultConfig() Config

type ConfirmOption added in v0.3.0

type ConfirmOption = engine.ConfirmOption

func AssumeYes added in v0.3.0

func AssumeYes(v bool) ConfirmOption

func ConfirmDetail added in v0.3.0

func ConfirmDetail(lines ...string) ConfirmOption

func Destructive added in v0.3.0

func Destructive() ConfirmOption

func PolicyFlag added in v0.3.0

func PolicyFlag(flag string) ConfirmOption

func PolicyHint added in v0.3.0

func PolicyHint(command string, args ...string) ConfirmOption

type DebugConfig added in v0.2.0

type DebugConfig = engine.DebugConfig

type DebugPaneOption

type DebugPaneOption = engine.DebugPaneOption

func NewestFirst

func NewestFirst() DebugPaneOption

func OldestFirst

func OldestFirst() DebugPaneOption

func PaneHeight

func PaneHeight(lines int) DebugPaneOption

func PreserveDebugTail

func PreserveDebugTail() DebugPaneOption

type DebugPresentation

type DebugPresentation = engine.DebugPresentation

type EffectRecord

type EffectRecord = core.EffectRecord

EffectRecord is one semantic change or plan row.

type EntityOption added in v0.2.3

type EntityOption = engine.EntityOption

func ID added in v0.2.3

func ID(id string) EntityOption

ID sets a stable machine key. Superseded: Task is name-only.

func StartPhase added in v0.3.0

func StartPhase(text string) EntityOption

StartPhase sets a task's first doing-text at declare time. Superseded: call Doing.

type EntityState

type EntityState = core.EntityState

EntityState is the lifecycle state of an item or task.

C11 naming sweep: these members stay bare (Done, Failed, Blocked, ...) rather than gaining a State* prefix to match ConclusionState below — prefixing would collide outright with ConclusionState's own StateFailed/ StateBlocked/StateCancelled/StateWarning constants (same package, same identifiers, different types is still a duplicate declaration in Go). Renaming ConclusionState's constants instead would ripple into the JSON wire (schema 0.3, frozen this release) and every existing golden — this is the "document instead" branch the census decision allows.

Aliased into internal/core alongside the rest of the data model — see Snapshot's doc comment (snapshot.go) for why.

type Event

type Event = core.Event

Event is an immutable journal record.

Aliased into internal/core alongside the rest of the data model — see Snapshot's doc comment (snapshot.go) for why.

type EventJSON

type EventJSON = render.EventJSON

EventJSON is a JSON Lines event record (§25.2).

type Evidence

type Evidence = engine.Evidence

type EvidenceOption added in v0.3.0

type EvidenceOption = engine.EvidenceOption

func KeepLastLines added in v0.1.2

func KeepLastLines(n int) EvidenceOption

func MaxEvidenceBytes added in v0.3.0

func MaxEvidenceBytes(n int) EvidenceOption

func MirrorToDebug added in v0.2.2

func MirrorToDebug() EvidenceOption

func MirrorToDiagnostics added in v0.2.2

func MirrorToDiagnostics() EvidenceOption

type EvidenceStream added in v0.3.0

type EvidenceStream = engine.EvidenceStream

type FactRecord added in v0.4.0

type FactRecord = core.Fact

FactRecord is a discovered name/value annotation — information, not work (user-13-problems.md Problem 8). Named FactRecord, not Fact, because Fact is the evo.Fact/TaskHandle.Fact verb (EffectRecord sets the naming precedent: the verb keeps the plain name, its stored shape gets Record). See TaskHandle.Fact and Output.Fact.

Aliased into internal/core alongside the rest of the data model — see Snapshot's doc comment (snapshot.go) for why.

type Failure added in v0.3.0

type Failure struct {
	// contains filtered or unexported fields
}

func (*Failure) Error added in v0.3.0

func (f *Failure) Error() string

func (*Failure) Next added in v0.3.0

func (f *Failure) Next(actions ...Action) *Failure

func (*Failure) NextCommand added in v0.3.0

func (f *Failure) NextCommand(executable string, args ...string) *Failure

func (*Failure) Unwrap added in v0.3.0

func (f *Failure) Unwrap() error

type Field

type Field = core.Field

Field is a structured diagnostic or log field.

type FixedClock

type FixedClock = engine.FixedClock

type Format added in v0.2.0

type Format = engine.Format

type GlyphProfile added in v0.3.0

type GlyphProfile = txt.GlyphProfile

GlyphProfile selects which glyph vocabulary state markers render in (evo-rec.md "Tightened glyph vocabulary", rule GLYPH-001: glyph selection via capability profile, cell-width measurement not rune counts).

The zero value, GlyphsAuto, keeps today's Unicode vocabulary off a TTY (a non-interactive stream can't show a human mojibake, so there is nothing to guard against) and on any TTY whose locale already advertises UTF-8. It downgrades to the ASCII vocabulary only on an interactive terminal without UTF-8 locale support — the one case where the status column would otherwise render as mojibake.

Aliased into internal/text (glyph tables and the rendering primitives that select from them live there — see EVIDENT_OUTPUT_ARCHITECTURE_SPEC_v0.5.md §38).

type GroupHandle added in v0.3.0

type GroupHandle struct {
	// contains filtered or unexported fields
}

func Group added in v0.3.0

func Group(name string) *GroupHandle

func (*GroupHandle) Each added in v0.5.0

func (g *GroupHandle) Each(items []string) iter.Seq2[string, *TaskHandle]

func (*GroupHandle) Group added in v0.5.0

func (g *GroupHandle) Group(name string) *GroupHandle

func (*GroupHandle) Sequence added in v0.5.0

func (g *GroupHandle) Sequence(name string) *SequenceHandle

func (*GroupHandle) Snapshot added in v0.3.0

func (g *GroupHandle) Snapshot() TasksSnapshot

func (*GroupHandle) Summary added in v0.3.0

func (g *GroupHandle) Summary(text string) *GroupHandle

func (*GroupHandle) Task added in v0.3.0

func (g *GroupHandle) Task(name string) *TaskHandle

type JSONAction

type JSONAction = render.JSONAction

JSONAction is a wire-format action.

type JSONChanges

type JSONChanges = render.JSONChanges

JSONChanges is wire-format changes.

type JSONCollection

type JSONCollection = render.JSONCollection

JSONCollection is a wire-format task collection with child IDs (§25.1).

type JSONCommand

type JSONCommand = render.JSONCommand

JSONCommand is argv for display.

type JSONDocument

type JSONDocument = render.JSONDocument

JSONDocument is the final machine projection (§25.1).

Aliased into internal/render alongside the JSON encoding machinery that produces it — see EVIDENT_OUTPUT_ARCHITECTURE_SPEC_v0.5.md §38.

type JSONEffectRecord

type JSONEffectRecord = render.JSONEffectRecord

JSONEffectRecord is a change/plan row.

type JSONMessage added in v0.2.0

type JSONMessage = render.JSONMessage

JSONMessage is a wire-format user-facing message.

type JSONOutputMeta

type JSONOutputMeta = render.JSONOutputMeta

JSONOutputMeta identifies the output instance.

type JSONPlan

type JSONPlan = render.JSONPlan

JSONPlan is wire-format plan.

type JSONProblem

type JSONProblem = render.JSONProblem

JSONProblem is a wire-format problem (no raw Cause by default).

type JSONProgress

type JSONProgress = render.JSONProgress

JSONProgress is wire-format progress.

type JSONTask

type JSONTask = render.JSONTask

JSONTask is a wire-format task.

type LiveSurface

type LiveSurface = engine.LiveSurface

type LogLevel

type LogLevel = engine.LogLevel

type LogRecord added in v0.2.4

type LogRecord = engine.LogRecord

type MessageSnapshot added in v0.2.0

type MessageSnapshot = core.MessageSnapshot

MessageSnapshot is one logical user-facing message in the canonical model.

type MutationOption added in v0.5.0

type MutationOption = engine.MutationOption

func Affected added in v0.4.0

func Affected(n int) MutationOption

type NoopRedactor

type NoopRedactor = engine.NoopRedactor

type Option

type Option = engine.Option

func AlsoWrite

func AlsoWrite(w io.Writer) Option

func Clock

func Clock(ts TimeSource) Option

func DataProjection

func DataProjection() Option

func DebugAddSource added in v0.3.0

func DebugAddSource() Option

func DebugHistory

func DebugHistory() Option

func DebugLevel

func DebugLevel(level LogLevel) Option

func DebugPane

func DebugPane(opts ...DebugPaneOption) Option

func Diagnostics

func Diagnostics(w io.Writer) Option

func DryRun added in v0.3.0

func DryRun() Option

func ExternalProjection

func ExternalProjection() Option

func Glyphs added in v0.3.0

func Glyphs(p GlyphProfile) Option

Glyphs selects the glyph capability profile (default GlyphsAuto).

func MaxEntities

func MaxEntities(n int) Option

func MaxEvents

func MaxEvents(n int) Option

func MaxFrameRate

func MaxFrameRate(framesPerSecond int) Option

func NoColor

func NoColor() Option

func Plain

func Plain() Option

func Redact

func Redact(r Redactor) Option

func ResultStream added in v0.2.3

func ResultStream(w io.Writer) Option

func Stdin added in v0.3.0

func Stdin(r io.Reader) Option

func Strict

func Strict() Option

func Terminal

func Terminal(driver TerminalDriver) Option

func Title added in v0.2.7

func Title(subject string) Option

func To

func To(w io.Writer) Option

func VisibilityDelay

func VisibilityDelay(delay time.Duration) Option

func Width

func Width(columns int) Option

type Output

type Output struct {
	// contains filtered or unexported fields
}

Output, TaskHandle, and the other presentation handles are wrappers, not aliases: engine test helpers must not appear in go doc or the rec surface.

func Default added in v0.3.0

func Default() *Output

Default returns the package-level default Output, lazily creating one with a zero Config the first time it's needed.

func Init added in v0.3.0

func Init(configs ...Config) *Output

Init is the sole Output constructor. It builds an Output from cfg, installs it as the package-level default, and arms first paint — call once, in main, before any I/O.

func (*Output) Cancel

func (o *Output) Cancel(reason string)

func (*Output) Close

func (o *Output) Close() error

func (*Output) Conclusion

func (o *Output) Conclusion() Conclusion

func (*Output) Confirm added in v0.3.0

func (o *Output) Confirm(question string, opts ...ConfirmOption) bool

func (*Output) Context added in v0.5.0

func (o *Output) Context() context.Context

func (*Output) Err

func (o *Output) Err() error

func (*Output) Fact added in v0.4.0

func (o *Output) Fact(name, value string)

func (*Output) Fail

func (o *Output) Fail(summary string, options ...ProblemOption)

func (*Output) Failf added in v0.3.0

func (o *Output) Failf(format string, args ...any)

func (*Output) Finish

func (o *Output) Finish() error

func (*Output) Group added in v0.3.0

func (o *Output) Group(name string) *GroupHandle

func (*Output) Next

func (o *Output) Next(actions ...Action)

func (*Output) NextCommand

func (o *Output) NextCommand(executable string, args ...string)

func (*Output) Print added in v0.2.0

func (o *Output) Print(args ...any)

func (*Output) Printf added in v0.2.0

func (o *Output) Printf(format string, args ...any)

func (*Output) Println added in v0.2.0

func (o *Output) Println(args ...any)

func (*Output) ResultWriter added in v0.2.3

func (o *Output) ResultWriter() io.Writer

func (*Output) Run added in v0.3.0

func (o *Output) Run(run func(*Output) error) int

func (*Output) Sequence added in v0.4.0

func (o *Output) Sequence(name string) *SequenceHandle

func (*Output) Snapshot

func (o *Output) Snapshot() Snapshot

func (*Output) Suspend

func (o *Output) Suspend(fn func() error) error

func (*Output) Task

func (o *Output) Task(name string) *TaskHandle

func (*Output) Warn added in v0.4.0

func (o *Output) Warn(summary string)

func (*Output) Writer added in v0.2.0

func (o *Output) Writer() io.Writer

type PlainOptions

type PlainOptions = engine.PlainOptions

type PlanSnapshot

type PlanSnapshot = core.PlanSnapshot

PlanSnapshot is an immutable plan section.

type Printer added in v0.2.0

type Printer struct {
	// contains filtered or unexported fields
}

func Verbose added in v0.2.0

func Verbose() *Printer

Verbose returns a Printer scoped to Verbose visibility on the default instance.

func (*Printer) Print added in v0.2.0

func (p *Printer) Print(args ...any)

func (*Printer) Printf added in v0.2.0

func (p *Printer) Printf(format string, args ...any)

func (*Printer) Println added in v0.2.0

func (p *Printer) Println(args ...any)

func (*Printer) Writer added in v0.2.0

func (p *Printer) Writer() io.Writer

type Problem

type Problem = core.Problem

Problem is structured evidence explaining a negative item or task outcome.

Aliased into internal/core alongside the rest of the data model — see Snapshot's doc comment (snapshot.go) for why.

type ProblemOption

type ProblemOption = engine.ProblemOption

ProblemOption configures a problem constructed by Block/Warn/Fail helpers.

func Code

func Code(value string) ProblemOption

Code sets a stable problem code.

func Count

func Count(value int64, unit ...string) ProblemOption

Count sets a quantity and optional unit.

func Detail

func Detail(text string) ProblemOption

Detail sets user-visible detail text (strings only).

func Location

func Location(path string, line, column int) ProblemOption

Location sets a source location on a Problem (renamed from At — C5: a free-function At collided in name, though not in call syntax, with Output.At(visibility), confusing autocomplete and readers alike).

func Next

func Next(action Action) ProblemOption

Next attaches actions to a problem.

func NextCommand

func NextCommand(executable string, args ...string) ProblemOption

NextCommand attaches a recommended command action.

func On

func On(subject string) ProblemOption

On sets the problem subject.

type Progress

type Progress = core.Progress

Progress is absolute measurement for a task.

type ProgressKind

type ProgressKind = core.ProgressKind

ProgressKind classifies task measurement.

type Projection added in v0.5.0

type Projection = engine.Projection

type ReasonOption added in v0.3.0

type ReasonOption = engine.ReasonOption

func ForSkip added in v0.3.0

func ForSkip() ReasonOption

func OnTask added in v0.3.0

func OnTask(taskName string) ReasonOption

type Redactor

type Redactor = engine.Redactor

type SequenceHandle added in v0.4.0

type SequenceHandle struct {
	// contains filtered or unexported fields
}

func Sequence added in v0.4.0

func Sequence(name string) *SequenceHandle

Sequence declares (or, for a repeated name, returns) a self-managing, ordered task container on the default instance.

func (*SequenceHandle) Each added in v0.5.0

func (s *SequenceHandle) Each(items []string) iter.Seq2[string, *TaskHandle]

func (*SequenceHandle) Group added in v0.5.0

func (s *SequenceHandle) Group(name string) *GroupHandle

func (*SequenceHandle) Sequence added in v0.4.0

func (s *SequenceHandle) Sequence(name string) *SequenceHandle

func (*SequenceHandle) Snapshot added in v0.4.0

func (s *SequenceHandle) Snapshot() TasksSnapshot

func (*SequenceHandle) Summary added in v0.4.0

func (s *SequenceHandle) Summary(text string) *SequenceHandle

func (*SequenceHandle) Task added in v0.4.0

func (s *SequenceHandle) Task(name string) *TaskHandle

type Snapshot

type Snapshot = core.Snapshot

Snapshot is an immutable complete presentation state at a version.

Declared as a type alias into internal/core (the repo's data-model package — see EVIDENT_OUTPUT_ARCHITECTURE_SPEC_v0.5.md §38): rendering and evidence-capture machinery import core, never this root package, so the data model has to live where they can reach it without an import cycle back through the behavioral facades (Output, TaskHandle, evidence) that stay declared here. pkg.go.dev cannot expand an aliased type's fields (internal/core is never rendered) — see docs/reference.md for the full field-level reference this doc comment summarizes.

type SourceLocation added in v0.3.0

type SourceLocation = core.SourceLocation

SourceLocation is a path-based source position. Named SourceLocation (not Location) so the Location(...) ProblemOption constructor below can keep that name without colliding with its own return type.

type SystemClock

type SystemClock = engine.SystemClock

type TaskHandle added in v0.3.0

type TaskHandle struct {
	// contains filtered or unexported fields
}

func Task

func Task(name string) *TaskHandle

Task declares (or, for a repeated name, returns) a Task on the default instance.

func (*TaskHandle) Add added in v0.3.0

func (t *TaskHandle) Add(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) After added in v0.5.0

func (t *TaskHandle) After(preds ...any) *TaskHandle

func (*TaskHandle) Block added in v0.3.0

func (t *TaskHandle) Block(summary string, options ...ProblemOption)

func (*TaskHandle) Blockf added in v0.3.0

func (t *TaskHandle) Blockf(format string, args ...any) *Failure

func (*TaskHandle) Bytes added in v0.3.0

func (t *TaskHandle) Bytes(completed, total int64) *TaskHandle

func (*TaskHandle) Cancel added in v0.3.0

func (t *TaskHandle) Cancel(reason string)

func (*TaskHandle) Context added in v0.5.0

func (t *TaskHandle) Context() context.Context

func (*TaskHandle) Create added in v0.3.0

func (t *TaskHandle) Create(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) Define added in v0.5.0

func (t *TaskHandle) Define(fn func() error)

func (*TaskHandle) Delete added in v0.3.0

func (t *TaskHandle) Delete(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) Doing added in v0.4.0

func (t *TaskHandle) Doing(text string, args ...any) *TaskHandle

func (*TaskHandle) Done added in v0.3.0

func (t *TaskHandle) Done(args ...any)

func (*TaskHandle) Fact added in v0.4.0

func (t *TaskHandle) Fact(name, value string)

func (*TaskHandle) Fail added in v0.3.0

func (t *TaskHandle) Fail(summary string, options ...ProblemOption)

func (*TaskHandle) Failf added in v0.3.0

func (t *TaskHandle) Failf(format string, args ...any) *Failure

func (*TaskHandle) Kept added in v0.3.0

func (t *TaskHandle) Kept(reason TaxonomyReason)

func (*TaskHandle) Next added in v0.3.0

func (t *TaskHandle) Next(actions ...Action) *TaskHandle

func (*TaskHandle) NextCommand added in v0.3.0

func (t *TaskHandle) NextCommand(executable string, args ...string) *TaskHandle

func (*TaskHandle) Progress added in v0.3.0

func (t *TaskHandle) Progress(completed, total int) *TaskHandle

func (*TaskHandle) Push added in v0.3.0

func (t *TaskHandle) Push(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) Record added in v0.3.0

func (t *TaskHandle) Record(verb string, quantity int, object string)

func (*TaskHandle) RecordLabel added in v0.3.0

func (t *TaskHandle) RecordLabel(label string, quantity int, object string)

func (*TaskHandle) RecordName added in v0.3.0

func (t *TaskHandle) RecordName(verb, object string)

func (*TaskHandle) Remove added in v0.3.0

func (t *TaskHandle) Remove(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) Skipped added in v0.3.0

func (t *TaskHandle) Skipped(reason TaxonomyReason)

func (*TaskHandle) Snapshot added in v0.3.0

func (t *TaskHandle) Snapshot() TaskSnapshot

func (*TaskHandle) Step added in v0.3.0

func (t *TaskHandle) Step(completed, total int, name string) *TaskHandle

func (*TaskHandle) Update added in v0.3.0

func (t *TaskHandle) Update(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) Wait added in v0.5.0

func (t *TaskHandle) Wait() error

func (*TaskHandle) Warn added in v0.3.0

func (t *TaskHandle) Warn(summary string)

func (*TaskHandle) Write added in v0.3.0

func (t *TaskHandle) Write(object string, fn func() error, opts ...MutationOption)

func (*TaskHandle) Writer added in v0.4.0

func (t *TaskHandle) Writer() io.Writer

type TaskSnapshot

type TaskSnapshot = core.TaskSnapshot

TaskSnapshot is an immutable task view.

type TasksSnapshot

type TasksSnapshot = core.TasksSnapshot

TasksSnapshot is an immutable collection view.

type TaxonomyReason added in v0.3.0

type TaxonomyReason struct {
	// contains filtered or unexported fields
}

func Reason added in v0.3.0

func Reason(name string) TaxonomyReason

Reason returns a get-or-create taxonomy Reason by name on the default instance.

func (TaxonomyReason) Name added in v0.3.0

func (r TaxonomyReason) Name() string

type TaxonomyRecord added in v0.3.0

type TaxonomyRecord = core.TaxonomyRecord

TaxonomyRecord is one accumulated (reason, name) disposition entry — recorded by TaskHandle.Skipped or TaskHandle.Kept, never assembled by hand.

type TerminalDriver

type TerminalDriver = engine.TerminalDriver

type TimeSource

type TimeSource = engine.TimeSource

type Verbosity added in v0.2.0

type Verbosity = engine.Verbosity

type Visibility added in v0.2.0

type Visibility = core.Visibility

Visibility selects whether a message is ordinary or verbose user detail. Zero is VisibilityNormal.

Directories

Path Synopsis
cmd
evident-output command
Command evident-output provides review/preview/explain CLI parity with MCP tools.
Command evident-output provides review/preview/explain CLI parity with MCP tools.
evident-output-mcp command
Command evident-output-mcp is the stdio MCP server.
Command evident-output-mcp is the stdio MCP server.
examples
data-command command
Command data-command: domain JSON on stdout, human presentation on stderr.
Command data-command: domain JSON on stdout, human presentation on stderr.
debug-history command
Command debug-history demos a short sequential probe.
Command debug-history demos a short sequential probe.
debug-pane command
Command debug-pane demos a sequential audit with an optional blocker.
Command debug-pane demos a sequential audit with an optional blocker.
doctor command
Command doctor is an environment/health check CLI.
Command doctor is an environment/health check CLI.
install-pipeline command
Command install-pipeline demos Tasks, Progress, Capture, and Main.
Command install-pipeline demos Tasks, Progress, Capture, and Main.
internal/demo
Package demo is reserved for advanced example utilities.
Package demo is reserved for advanced example utilities.
live-progress command
Command live-progress is the ordinary multi-progress demo (user API only).
Command live-progress is the ordinary multi-progress demo (user API only).
migrate command
Command migrate demonstrates the mutation-verb effect boundary (Add/Create/Write, ...): the same call site records a planned effect under --dry-run (evo.DryRun) or a committed one when it actually runs, and evo derives Changed/Ready/Planned from what happened — the caller never chooses which ledger a mutation lands in.
Command migrate demonstrates the mutation-verb effect boundary (Add/Create/Write, ...): the same call site records a planned effect under --dry-run (evo.DryRun) or a committed one when it actually runs, and evo derives Changed/Ready/Planned from what happened — the caller never chooses which ledger a mutation lands in.
print command
Command print is the first adoption rung: Print/Printf/Println like fmt.
Command print is the first adoption rung: Print/Printf/Println like fmt.
repo-status command
Command repo-status is a realistic "is this repo safe to retire?" check.
Command repo-status is a realistic "is this repo safe to retire?" check.
scope-plugin command
Command scope-plugin demos named Tasks for host and plugin work.
Command scope-plugin demos named Tasks for host and plugin work.
terminal-driver command
Command terminal-driver is an advanced teaching surface: custom TerminalDriver, frame-by-frame logging, and explicit renderer knobs.
Command terminal-driver is an advanced teaching surface: custom TerminalDriver, frame-by-frame logging, and explicit renderer knobs.
verbose command
Command verbose shows Normal vs Verbose message visibility.
Command verbose shows Normal vs Verbose message visibility.
internal
agent/adopt
Package adopt inventories non-evo CLI output in an existing codebase and proposes a migration plan keyed to the adoption ladder (Init/Main → Task/Done → effects → facts/warnings → confirm/dry-run).
Package adopt inventories non-evo CLI output in an existing codebase and proposes a migration plan keyed to the adoption ladder (Init/Main → Task/Done → effects → facts/warnings → confirm/dry-run).
agent/catalog
Package catalog is the task-oriented guidance catalog for agent assistance.
Package catalog is the task-oriented guidance catalog for agent assistance.
agent/harness
Package harness evaluates agent-assistance scenarios (§30.9, MCP-022/049).
Package harness evaluates agent-assistance scenarios (§30.9, MCP-022/049).
agent/preview
Package preview generates multi-profile plain previews from snapshots.
Package preview generates multi-profile plain previews from snapshots.
agent/review
Package review provides deterministic static review of Evident Output usage.
Package review provides deterministic static review of Evident Output usage.
agent/rules
Package rules is the stable review-rule registry (Appendix C namespaces).
Package rules is the stable review-rule registry (Appendix C namespaces).
agent/sections
Package sections is the full-docs counterpart to catalog: catalog holds hand-curated, token-budgeted guidance snippets; sections serves the whole authoritative doc corpus (reference, development, MCP wiring, the adoption ladder, and the per-concept guides catalog already owns) through one list/get pair, mirroring the Svelte MCP's list-sections / get-documentation shape.
Package sections is the full-docs counterpart to catalog: catalog holds hand-curated, token-budgeted guidance snippets; sections serves the whole authoritative doc corpus (reference, development, MCP wiring, the adoption ladder, and the per-concept guides catalog already owns) through one list/get pair, mirroring the Svelte MCP's list-sections / get-documentation shape.
core
Package core owns evident-output's data model: the immutable, fields-only value types a finished or in-flight run presents (Snapshot, Problem, Conclusion, and peers) plus the pure functions that derive one from another (InferConclusion, SanitizeProblem, ...).
Package core owns evident-output's data model: the immutable, fields-only value types a finished or in-flight run presents (Snapshot, Problem, Conclusion, and peers) plus the pure functions that derive one from another (InferConclusion, SanitizeProblem, ...).
modpin
Package modpin parses a go.mod for the evident-output require pin and replace directive so MCP update and the usage-audit share one parser.
Package modpin parses a go.mod for the evident-output require pin and replace directive so MCP update and the usage-audit share one parser.
render
Package render is evident-output's presentation machinery: plain, structured (JSON/JSONL), and interactive (live) projection of a internal/core Snapshot.
Package render is evident-output's presentation machinery: plain, structured (JSON/JSONL), and interactive (live) projection of a internal/core Snapshot.
text
Package text is repo-owned CLI text machinery: sanitization, terminal cell width measurement, truncation, glyph-safe pluralization/conjugation.
Package text is repo-owned CLI text machinery: sanitization, terminal cell width measurement, truncation, glyph-safe pluralization/conjugation.
wireschema
Package wireschema validates a rendered JSON document against evo's own published JSON Schema (schema/output.v1.json) — the facade that makes the schema file an enforced gate instead of prose nobody checks (P8: "today nothing references that file — make it a gate").
Package wireschema validates a rendered JSON document against evo's own published JSON Schema (schema/output.v1.json) — the facade that makes the schema file an enforced gate instead of prose nobody checks (P8: "today nothing references that file — make it a gate").
Package terminal provides production terminal drivers for Evident Output.
Package terminal provides production terminal drivers for Evident Output.
Package testkit provides deterministic clocks, screens, and assertions for evo tests.
Package testkit provides deterministic clocks, screens, and assertions for evo tests.
tools
gensections command
Command gensections copies the docs the MCP server's list_sections / get_documentation tools serve into internal/agent/sections/embedded, the only directory go:embed can reach from that package.
Command gensections copies the docs the MCP server's list_sections / get_documentation tools serve into internal/agent/sections/embedded, the only directory go:embed can reach from that package.
scripts/evo-usage-audit command
Command evo-usage-audit scans a Go repository for uses of github.com/zachbornheimer/evident-output (and its subpackages) and prints a markdown usage inventory: one heading per file that uses evo, one fenced code block per top-level declaration that uses it, tagged with how.
Command evo-usage-audit scans a Go repository for uses of github.com/zachbornheimer/evident-output (and its subpackages) and prints a markdown usage inventory: one heading per file that uses evo, one fenced code block per top-level declaration that uses it, tagged with how.
scripts/sync-release-pins command
Command sync-release-pins rewrites install pins on portable surfaces to match evo.PublishedRelease.
Command sync-release-pins rewrites install pins on portable surfaces to match evo.PublishedRelease.
scripts/traceability-check command
Command traceability-check verifies every expected §31 ID is present, and that every .go file TRACEABILITY.md's Test(s) column names still exists (a moved or renamed test file that nobody updated the table for used to pass silently — IDs-present-only checking let the table rot green).
Command traceability-check verifies every expected §31 ID is present, and that every .go file TRACEABILITY.md's Test(s) column names still exists (a moved or renamed test file that nobody updated the table for used to pass silently — IDs-present-only checking let the table rot green).

Jump to

Keyboard shortcuts

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