render

package
v0.23.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package render turns typed core results into CLI output. It owns the human presentation (ANSI tables, lipgloss trees) and is a thin io.Writer wrapper over the machine wire contract in internal/wire: each *JSON emit func builds a wire envelope value (wire.ToXEnvelope) and encodes it, so the CLI and a future web adapter serialize identical JSON. The wire format itself — envelopes, DTOs, SchemaVersion, the JSON Schema — lives in wire, not here.

Index

Constants

View Source
const SchemaVersion = wire.SchemaVersion

SchemaVersion re-exports the wire contract's version so existing CLI call sites (exit.go's error envelope, the projection writer in columns.go) keep one import. The canonical value + changelog live in internal/wire.

Variables

This section is empty.

Functions

func AcceptanceHuman

func AcceptanceHuman(w io.Writer, st Style, cs []domain.Criterion)

AcceptanceHuman prints the numbered acceptance checklist ("[x] 1. text"), the list an agent then flips by index. Empty prints a dim note.

A criterion that is not met for a REASON shows that reason inline. Without it the state vocabulary would be invisible on the surface where criteria are actually read, and an unchecked box would go on meaning "not yet", "won't do", and "no longer applies" all at once — the ambiguity the vocabulary exists to remove.

func AcceptanceJSON

func AcceptanceJSON(w io.Writer, slug string, cs []domain.Criterion) error

AcceptanceJSON writes `task ac --list --json`: the task's acceptance criteria.

func AuditInfoHuman

func AuditInfoHuman(w io.Writer, st Style, record core.LoadedRecord[core.AuditWithBody], path string)

AuditInfoHuman prints audit metadata as an aligned key/value block: bucket and the finding disposition tally (the audit analogue of a task's acceptance tally).

func AuditInfoJSON

func AuditInfoJSON(w io.Writer, record core.LoadedRecord[core.AuditWithBody], path string) error

AuditInfoJSON writes the token-cheap audit metadata read (`audit info --json`): path + bucket + finding tally, no body.

func AuditMutationJSON

func AuditMutationJSON(w io.Writer, a domain.Audit, body string, dryRun bool, ws wire.WorkspaceJSON) error

AuditMutationJSON writes the result of `audit append`: the reloaded audit, dry_run (always present — a preview must be distinguishable from a real write), and the resulting body. The audit counterpart to TaskMutationJSON.

func AuditShowHuman

func AuditShowHuman(w io.Writer, st Style, record core.LoadedRecord[core.AuditWithBody], findings []domain.Finding, body string) error

AuditShowHuman prints an audit's metadata, a status-grouped finding tree, and its body. findings is parsed from the raw body by the caller; body is the already-rendered (glamour/raw) markdown.

func AuditShowJSON

func AuditShowJSON(w io.Writer, record core.LoadedRecord[core.AuditWithBody]) error

AuditShowJSON writes an audit plus its body.

func AuditsHuman

func AuditsHuman(w io.Writer, st Style, audits []core.LoadedRecord[domain.Audit]) error

AuditsHuman writes a table of audits with finding counts.

func AuditsJSON

func AuditsJSON(w io.Writer, audits []core.LoadedRecord[domain.Audit], problems []core.LoadProblem) error

AuditsJSON writes a versioned envelope of audits, including any per-file load problems (mirrors LintJSON's `unreadable`).

func AuditsReadHuman added in v0.23.0

func AuditsReadHuman(w io.Writer, st Style, audits []core.LoadedRecord[domain.Audit]) error

func BoardHuman

func BoardHuman(w io.Writer, st Style, b core.Board) error

BoardHuman renders the active-work board: one section per status (with its count), each a table of tasks (slug · priority · description). The active-work counterpart of SummaryHuman's aggregation dashboard.

func BoardJSON

func BoardJSON(w io.Writer, b core.Board) error

BoardJSON writes the active-work board as a versioned envelope.

func ConfigHuman added in v0.17.0

func ConfigHuman(w io.Writer, st Style, snapshot core.ConfigurationSnapshot)

func ConfigJSON added in v0.17.0

func ConfigJSON(w io.Writer, snapshot core.ConfigurationSnapshot) error

func ConfigMigrationHuman added in v0.17.0

func ConfigMigrationHuman(w io.Writer, st Style, migration core.ConfigurationMigration)

func ConfigMigrationJSON added in v0.17.0

func ConfigMigrationJSON(w io.Writer, migration core.ConfigurationMigration, workspace wire.WorkspaceJSON) error

func CreatedHuman

func CreatedHuman(w io.Writer, st Style, path string, dryRun bool)

CreatedHuman prints the path of a newly created file (or, under --dry-run, the path that WOULD be created).

func CreatedJSON

func CreatedJSON(w io.Writer, kind, id, slug, status, path string, dryRun bool, ws wire.WorkspaceJSON) error

CreatedJSON writes a versioned envelope for a newly created item; dry_run marks a preview (nothing was written). status is the new item's status (task status / epic status / audit bucket); path is relative to the planning root, matching the human output.

func CreatedSlugNote

func CreatedSlugNote(w io.Writer, st Style, title, slug string)

CreatedSlugNote surfaces the derived slug on a dim line after the "created …" line, but only when Slugify did something beyond the obvious — a title with a colon, em-dash, arrow, or other dropped character shows where its filename came from, while the everyday "Add retry backoff" → add-retry-backoff stays silent (lowercasing + space→hyphen is no surprise). The JSON envelope already carries the id, so this is human-only. slug is the full filename id (NN-… for an epic, <date>-… for an audit); divergence is judged on the original title/area.

func DependencyMutationHuman added in v0.18.0

func DependencyMutationHuman(w io.Writer, st Style, receipt core.DependencyMutationReceipt) error

DependencyMutationHuman explains every edge outcome and migration prefix.

func DependencyMutationJSON added in v0.18.0

func DependencyMutationJSON(w io.Writer, receipt core.DependencyMutationReceipt, workspace wire.WorkspaceJSON) error

DependencyMutationJSON writes the stable guarded dependency receipt.

func DoctorHuman

func DoctorHuman(w io.Writer, st Style, problems []DoctorProblem, registry wire.DoctorRegistry)

DoctorHuman writes separate linkback and registry sections, then one combined problem footer. Empty planning repos are healthy and therefore absent from registry.Problems.

func DoctorJSON

func DoctorJSON(w io.Writer, root string, problems []DoctorProblem, registry wire.DoctorRegistry) error

DoctorJSON writes the linkback and registry audits. Problem arrays are empty (not null) when healthy, so a consumer can len() them without a nil check.

func EpicMutationJSON

func EpicMutationJSON(w io.Writer, epic domain.Epic, dryRun bool, ws wire.WorkspaceJSON) error

EpicMutationJSON writes the result of an `epic set`: the reloaded epic + dry_run (always present — a preview must be distinguishable from a real write). The epic counterpart to TaskMutationJSON; field-only, so there's no body to echo.

func EpicShowHuman

func EpicShowHuman(w io.Writer, st Style, es core.EpicSummary, tasks []domain.Task, body string) error

EpicShowHuman prints an epic, its tasks, and its body. The rollup arrives on the EpicSummary (computed once by ShowEpic) rather than re-derived here — same rule as epic list / status / the TUI detail (audit M3).

func EpicShowJSON

func EpicShowJSON(w io.Writer, detail core.EpicDetail) error

EpicShowJSON writes an epic, its tasks, and its body.

func EpicsHuman

func EpicsHuman(w io.Writer, st Style, epics []core.EpicSummary) error

EpicsHuman writes a table of epics with task rollup.

func EpicsJSON

func EpicsJSON(w io.Writer, epics []core.EpicSummary, problems []core.LoadProblem) error

EpicsJSON writes a versioned envelope of epics with rollup, including any per-file load problems (mirrors LintJSON's `unreadable`).

func FindingCreationJSON added in v0.23.0

func FindingCreationJSON(w io.Writer, receipt core.FindingCreationReceipt, ws wire.WorkspaceJSON) error

FindingCreationJSON writes the compact receipt for `audit finding new`.

func FindingsHuman

func FindingsHuman(w io.Writer, st Style, fs []core.AuditFinding) error

FindingsHuman writes a scannable table of findings (empty input writes nothing). Title goes last so it's the column that truncates to terminal width.

func FindingsJSON

func FindingsJSON(w io.Writer, fs []core.AuditFinding, problems []core.LoadProblem) error

FindingsJSON writes the structured finding-query result: each parsed finding tagged with its audit slug and bucket, so a cross-audit query stays self-describing. Mirrors the list envelopes' `unreadable` for per-file problems.

func FixHuman

func FixHuman(w io.Writer, st Style, results []domain.FixResult, remaining []core.LintResult, dryRun bool)

FixHuman writes the auto-repairs applied (or proposed under --dry-run), then the leftover lint findings the pass could NOT repair (report-only epic issues, unfixable task issues) — so a human sees the residual breakage `--fix` left behind, not just what it touched. remaining is empty on a dry-run.

func FixJSON

func FixJSON(w io.Writer, results []domain.FixResult, problems []core.LoadProblem, remaining []core.LintResult, dryRun bool, ws wire.WorkspaceJSON) error

FixJSON writes the structured fix report: what was repaired (`fixed`), any files that still can't be read after the pass (`unreadable`), and the per-entity lint findings the pass could NOT repair (`remaining` — report-only epics, unfixable task issues). All three are empty on a dry-run (which writes nothing) — so a --json consumer learns the residual breakage without parsing the prose error.

func IDsQuiet

func IDsQuiet(w io.Writer, ids []string)

IDsQuiet writes one id per line (the `-o name` / `-q` output).

func InitJSON

func InitJSON(w io.Writer, e InitEnvelope) error

InitJSON reports the init result. The caller fills the envelope's named fields (mode/root/planning_repo/linked_back/tracked/created); InitJSON stamps the schema_version and normalizes created to an empty array (not null) so a consumer can len() it.

func InitRegistration added in v0.17.0

InitRegistration converts the reusable application receipt for the init envelope.

func InitRegistrationHuman added in v0.17.0

func InitRegistrationHuman(w io.Writer, st Style, r core.SpaceRegistrationReceipt)

InitRegistrationHuman writes the one-line machine-local registry receipt that follows a fresh topology bootstrap.

func LintHuman

func LintHuman(w io.Writer, st Style, results []core.LintResult, noun string)

LintHuman writes the per-entity lint findings + a count footer. noun names the entity for the footer ("task", "audit") since the same result/render shape backs both `lint` and `audit lint`.

func LintJSON

func LintJSON(w io.Writer, results []core.LintResult, problems []core.LoadProblem) error

LintJSON writes the structured lint report: unreadable files + field issues.

func LintProblemsHuman added in v0.23.0

func LintProblemsHuman(w io.Writer, st Style, problems []core.LoadProblem)

LintProblemsHuman renders portable failed-record diagnostics without assuming every source has a filesystem path. Identity leads when available; an optional repair location remains visible on its own labelled line.

func MovesHuman

func MovesHuman(out, errw io.Writer, st Style, results []MoveResult, dryRun bool)

MovesHuman prints one line per transition outcome ("would move" on a --dry-run preview).

func MovesJSON

func MovesJSON(w io.Writer, results []MoveResult, dryRun bool, ws wire.WorkspaceJSON) error

MovesJSON writes the structured per-task transition report; dry_run marks a preview (nothing was written).

func PathJSON

func PathJSON(w io.Writer, path string) error

PathJSON writes just the resolved absolute path (`task/epic/audit path --json`).

func ProblemsHuman

func ProblemsHuman(w io.Writer, st Style, problems []domain.FileProblem)

ProblemsHuman writes per-file load problems (unreadable frontmatter).

func ProjectedListJSON

func ProjectedListJSON[T any](w io.Writer, listKey string, cols []Column[T], items []T, problems []domain.FileProblem) error

ProjectedListJSON writes a `--json -c …` projection: the standard versioned envelope (schema_version + the entity's listKey + an `unreadable` array only when non-empty, mirroring the full envelope's omitempty) but with each row narrowed to the selected columns as column-named string fields. listKey is the entity's envelope key ("tasks", "epics", …), so a projected list lands under the same key as its full envelope.

This is a string-valued VIEW, NOT the canonical typed envelope: rows omit unselected fields, so projected output does NOT validate against `schema --json-schema` (which describes the full envelopes). Columns that represent wire fields use their canonical keys and source values when selected canonically. Explicit compatibility aliases retain their requested output key but still use the raw projected value. Presentation-only fallbacks are reserved for default or explicitly legacy table/CSV selections. Only bare `--json` is the schema-validated contract.

func ProjectedListJSONWithProblems added in v0.23.0

func ProjectedListJSONWithProblems[T, P any](w io.Writer, listKey string, cols []Column[T], items []T, problems []P) error

ProjectedListJSONWithProblems is the adapter-neutral form of ProjectedListJSON. Most planning entities expose filesystem read failures and use the convenience wrapper above; Threads deliberately expose portable identity-aware diagnostics instead. Keeping the unreadable element generic lets both retain their public diagnostic shape without teaching the shared projection renderer about either adapter.

func RenderBody

func RenderBody(st Style, body string, style func() string, raw bool) string

RenderBody returns body rendered as styled markdown when styling is on and raw is false; otherwise it returns the raw source verbatim. That gate keeps the agent/porcelain contract intact: piped output, `--color=never`, `--json`, and an explicit `--raw` all get the unrendered body, byte-for-byte. A render error never fails a `show` — it falls back to the raw body.

style is a LAZY provider, resolved only on the render path. Resolving the glamour style queries the terminal background (an OSC-11 round-trip that can stall on terminals that don't answer), so it must not run when the result is discarded (raw / color off / empty body) — passing a func instead of a string makes that impossible by construction.

func ResearchHuman

func ResearchHuman(w io.Writer, st Style, docs []domain.Research) error

ResearchHuman prints the research corpus as a date-led table. There is no status or progress column — research has no lifecycle and nothing to be "done" — so the date is the organizing signal and the description carries the meaning.

func ResearchJSON

func ResearchJSON(w io.Writer, docs []core.LoadedRecord[domain.Research], problems []core.LoadProblem) error

ResearchJSON writes a versioned envelope of research docs, including any per-file load problems.

func ResearchMutationJSON

func ResearchMutationJSON(w io.Writer, r domain.Research, body string, dryRun bool, ws wire.WorkspaceJSON) error

ResearchMutationJSON writes the result of `research set` / `research append`: the reloaded doc, dry_run (always present — a preview must be distinguishable from a real write), and the resulting body. The research counterpart to TaskMutationJSON.

func ResearchReadHuman added in v0.23.0

func ResearchReadHuman(w io.Writer, st Style, docs []core.LoadedRecord[domain.Research]) error

func ResearchShowHuman

func ResearchShowHuman(w io.Writer, st Style, r domain.Research, body string) error

ResearchShowHuman prints a research doc's metadata and body. body is the already-rendered (glamour/raw) markdown.

func ResearchShowJSON

func ResearchShowJSON(w io.Writer, record core.LoadedRecord[core.ResearchWithBody]) error

ResearchShowJSON writes one research doc plus its body.

func SchemaHuman

func SchemaHuman(w io.Writer, st Style, c SchemaContract) error

SchemaHuman renders the global contract as readable sections.

func SchemaJSON

func SchemaJSON(w io.Writer, c SchemaContract) error

SchemaJSON writes the global contract envelope.

func SchemaKindHuman

func SchemaKindHuman(w io.Writer, st Style, ks KindSchema) error

SchemaKindHuman renders the per-kind authoring guidance.

func SchemaKindJSON

func SchemaKindJSON(w io.Writer, ks KindSchema) error

SchemaKindJSON writes the per-kind authoring envelope.

func SpaceMutationHuman added in v0.17.0

func SpaceMutationHuman(w io.Writer, st Style, mutation core.SpaceMutation, verb string)

SpaceMutationHuman reports what `space add`/`forget` did. A no-op says so plainly rather than claiming a change, so re-running is legibly idempotent.

func SpaceMutationJSON added in v0.17.0

func SpaceMutationJSON(w io.Writer, mutation core.SpaceMutation) error

SpaceMutationJSON emits the `space add`/`forget --json` envelope.

func SpacesHuman added in v0.17.0

func SpacesHuman(w io.Writer, st Style, groups []core.SpaceGroup)

SpacesHuman lists the registry one logical planning space at a time. A direct checkout, if present, anchors the human tree; the remaining entry points retain registry order.

A broken entry is shown DIMMED alongside the healthy ones rather than hidden or turned into an error. The registry describes what you told it about; a repo that moved is information, and the list is the place you would go to fix it.

func SpacesJSON added in v0.17.0

func SpacesJSON(w io.Writer, spaces []core.SpaceEntryPoint) error

SpacesJSON emits the `space list --json` envelope from the shared core projection.

func StatusAllHuman added in v0.17.0

func StatusAllHuman(w io.Writer, st Style, overview core.SpaceOverview) error

StatusAllHuman renders one compact block per logical planning identity, followed by the cross-space working set. Entry-point diagnoses stay inside their group so a dead checkout is visible without drowning out summaries loaded through healthy alternates.

func StatusAllJSON added in v0.17.0

func StatusAllJSON(w io.Writer, overview core.SpaceOverview) error

StatusAllJSON emits the shared cross-space status envelope.

func SummaryHuman

func SummaryHuman(w io.Writer, st Style, s core.Summary) error

SummaryHuman renders the at-a-glance dashboard.

func SummaryJSON

func SummaryJSON(w io.Writer, s core.Summary) error

SummaryJSON writes the dashboard as a versioned envelope.

func TaskBlockersHuman added in v0.18.0

func TaskBlockersHuman(w io.Writer, st Style, result core.TaskBlockersResult) error

TaskBlockersHuman renders a compact explanatory blocker list.

func TaskBlockersJSON added in v0.18.0

func TaskBlockersJSON(w io.Writer, result core.TaskBlockersResult) error

TaskBlockersJSON writes the blocker diagnostic envelope.

func TaskEligibilityFailure added in v0.18.0

func TaskEligibilityFailure(failure *core.TaskEligibilityError) wire.TaskEligibilityFailureJSON

TaskEligibilityFailure preserves the typed start refusal in JSON move rows.

func TaskGraphRepairHuman added in v0.20.0

func TaskGraphRepairHuman(w io.Writer, st Style, receipt core.TaskGraphRepairReceipt, workspace wire.WorkspaceJSON) error

TaskGraphRepairHuman keeps diagnosis terse while making every destructive choice copyable. Exact source paths are preferred over potentially ambiguous duplicate task IDs.

func TaskGraphRepairJSON added in v0.20.0

func TaskGraphRepairJSON(w io.Writer, receipt core.TaskGraphRepairReceipt, workspace wire.WorkspaceJSON) error

TaskGraphRepairJSON writes the guarded source-declaration repair receipt.

func TaskInfoHuman

func TaskInfoHuman(w io.Writer, st Style, t domain.Task, ac domain.ACCount, path string)

TaskInfoHuman prints task metadata as an aligned key/value block (the human face of `task info`): where the file is, the fields an agent triages on, and the acceptance-criteria progress as "checked/total".

func TaskInfoJSON

func TaskInfoJSON(w io.Writer, record core.LoadedRecord[core.TaskWithBody], ac domain.ACCount, path string) error

TaskInfoJSON writes the token-cheap task metadata read (`task info --json`): path + triage fields + the acceptance-criteria tally, no body.

func TaskMutationJSON

func TaskMutationJSON(w io.Writer, t domain.Task, body string, dryRun bool, ws wire.WorkspaceJSON) error

TaskMutationJSON writes the result of a task mutation (`task set`/`append`/`set --body`): the reloaded task, dry_run (always present — a preview must be distinguishable from a real write), and the resulting body for the body-editing commands (empty/omitted for field-only `set`). Distinct from TaskShowEnvelope so the mutation-only dry_run never lands on the `task show` read type.

func TaskRenameJSON added in v0.21.0

func TaskRenameJSON(w io.Writer, receipt core.TaskRenameReceipt, ws wire.WorkspaceJSON) error

TaskRenameJSON writes the guarded rename receipt. Unlike the generic task mutation envelope, it exposes the complete multi-document plan and durable outcome while retaining the resulting task for compatibility.

func TaskShowHuman

func TaskShowHuman(w io.Writer, st Style, t domain.Task, body string) error

TaskShowHuman prints a task's metadata followed by its body.

func TaskShowJSON

func TaskShowJSON(w io.Writer, record core.LoadedRecord[core.TaskWithBody]) error

TaskShowJSON writes a task plus its body.

func TaskUnblocksHuman added in v0.18.0

func TaskUnblocksHuman(w io.Writer, st Style, result core.TaskUnblocksResult) error

TaskUnblocksHuman renders transitive downstream impact without implying counterfactual eligibility.

func TaskUnblocksJSON added in v0.18.0

func TaskUnblocksJSON(w io.Writer, result core.TaskUnblocksResult) error

TaskUnblocksJSON writes the downstream-impact envelope.

func TasksHuman

func TasksHuman(w io.Writer, st Style, tasks []domain.Task) error

TasksHuman writes a scannable table of tasks (empty input writes nothing).

func TasksJSON

func TasksJSON(w io.Writer, tasks []core.LoadedRecord[domain.Task], problems []core.LoadProblem) error

TasksJSON writes a stable, versioned JSON envelope of tasks, including any per-file load problems so a JSON consumer never silently loses unreadable files (mirrors LintJSON's `unreadable`).

func TasksReadHuman added in v0.23.0

func TasksReadHuman(w io.Writer, st Style, tasks []core.LoadedRecord[domain.Task]) error

TasksReadHuman unwraps ordinary task records for presentation only. Source identity remains attached through every machine projection.

func TemplateShowHuman

func TemplateShowHuman(w io.Writer, st Style, info TemplateInfo, body string)

TemplateShowHuman renders a single template: a header line then its body.

func TemplateShowJSON

func TemplateShowJSON(w io.Writer, info TemplateInfo, body string) error

TemplateShowJSON writes the `template show --json` envelope.

func TemplatesHuman

func TemplatesHuman(w io.Writer, st Style, ts []TemplateInfo)

TemplatesHuman renders the template list as a kind / name / description table.

func TemplatesJSON

func TemplatesJSON(w io.Writer, ts []TemplateInfo) error

TemplatesJSON writes the `template list --json` envelope.

func ThemePreviewHuman

func ThemePreviewHuman(w io.Writer, st Style, name, variant string, pal design.Palette)

ThemePreviewHuman renders a palette as a swatch grid: a truecolor block + hex per token, plus a sample gradient bar. When styling is off (piped / --color=never) it degrades to a plain token→hex list + the stripped bar glyphs, so it stays byte-stable like every other surface.

func ThemePreviewJSON

func ThemePreviewJSON(w io.Writer, name, variant string, pal design.Palette) error

ThemePreviewJSON emits a theme's palette swatches as the machine form.

func ThemesHuman

func ThemesHuman(w io.Writer, st Style, themes []wire.ThemeEntry)

ThemesHuman lists the color themes one per line, tagging the default and the active one (the active name is bold).

func ThemesJSON

func ThemesJSON(w io.Writer, themes []wire.ThemeEntry) error

ThemesJSON emits the `theme list --json` envelope.

func ThreadApplyComposeJSON added in v0.18.0

func ThreadApplyComposeJSON(w io.Writer, plan core.ThreadApplyPlan, planPath string, dryRun bool, workspace wire.WorkspaceJSON) error

func ThreadApplyHuman added in v0.18.0

func ThreadApplyHuman(w io.Writer, st Style, receipt core.ThreadApplyReceipt)

func ThreadApplyJSON added in v0.18.0

func ThreadApplyJSON(w io.Writer, receipt core.ThreadApplyReceipt, planPath string, workspace wire.WorkspaceJSON) error

func ThreadCreatedHuman added in v0.18.0

func ThreadCreatedHuman(w io.Writer, st Style, receipt core.ThreadCreationReceipt, path string)

func ThreadFrontierHuman added in v0.18.0

func ThreadFrontierHuman(w io.Writer, st Style, view core.ThreadView) error

func ThreadFrontierJSON added in v0.18.0

func ThreadFrontierJSON(w io.Writer, view core.ThreadView) error

func ThreadGraphJSON added in v0.18.0

func ThreadGraphJSON(w io.Writer, projection core.ThreadGraphProjection) error

func ThreadMutationHuman added in v0.18.0

func ThreadMutationHuman(w io.Writer, st Style, receipt core.ThreadMutationReceipt, path string)

func ThreadMutationJSON added in v0.18.0

func ThreadMutationJSON(w io.Writer, receipt core.ThreadCreationReceipt, path string, workspace wire.WorkspaceJSON) error

func ThreadPlanHuman added in v0.18.0

func ThreadPlanHuman(w io.Writer, st Style, projection core.ThreadGraphProjection) error

func ThreadPlanJSON added in v0.18.0

func ThreadPlanJSON(w io.Writer, projection core.ThreadGraphProjection) error

func ThreadProblemsHuman added in v0.19.0

func ThreadProblemsHuman(w io.Writer, st Style, problems []core.ThreadReadProblem)

ThreadProblemsHuman renders failed portable Thread records without assuming repair context is a filesystem path. Stable identity takes precedence when an adapter supplies both identity and a potentially opaque location.

func ThreadShowHuman added in v0.18.0

func ThreadShowHuman(w io.Writer, st Style, view core.ThreadView, body string) error

func ThreadShowJSON added in v0.18.0

func ThreadShowJSON(w io.Writer, view core.ThreadView, body string) error

func ThreadUpdateJSON added in v0.18.0

func ThreadUpdateJSON(w io.Writer, receipt core.ThreadMutationReceipt, path string, workspace wire.WorkspaceJSON) error

func ThreadsHuman added in v0.18.0

func ThreadsHuman(w io.Writer, st Style, list core.ThreadListView) error

func ThreadsJSON added in v0.18.0

func ThreadsJSON(w io.Writer, list core.ThreadListView, problems []core.ThreadReadProblem) error

func VersionHuman

func VersionHuman(w io.Writer, st Style, version string)

VersionHuman prints the CLI version.

func VersionJSON

func VersionJSON(w io.Writer, version string) error

VersionJSON writes the version in the standard envelope.

func WorkspaceHuman

func WorkspaceHuman(w io.Writer, st Style, ws wire.WorkspaceJSON)

WorkspaceHuman writes the resolved planning tree as aligned key/value lines, leading with the root (the thing you actually want to eyeball) and calling out a pointer resolution explicitly — that is the case where the directory you are standing in is NOT the tree you would change.

func WorkspaceJSON

func WorkspaceJSON(w io.Writer, ws wire.WorkspaceJSON) error

WorkspaceJSON emits the `workspace --json` envelope.

func WriteCSV

func WriteCSV[T any](w io.Writer, cols []Column[T], items []T) error

WriteCSV writes the same projected columns as WriteTablePlain, but as RFC 4180 CSV (encoding/csv quotes any cell containing a comma, quote, or newline) — the `-o csv` format, for spreadsheets. Like the table, an empty result still emits the header row. encoding/csv defaults to LF line endings, matching the rest of our output.

func WriteTablePlain

func WriteTablePlain[T any](w io.Writer, cols []Column[T], items []T)

WriteTablePlain writes the stable tab-separated table for the given columns: a header row of column names, then one tab-separated row per item. No ANSI, no truncation — the documented `-o table` contract.

Types

type Column

type Column[T any] struct {
	Name    string
	Desc    string
	Extract func(T) string
	// contains filtered or unexported fields
}

Column is one projectable field shared by the list formats. Name and Extract retain the stable table/CSV header and display value. projection is an optional canonical wire-contract override for `--json -c`; when present, both the canonical JSON name and the legacy presentation name are accepted as selectors. selectedName records which spelling an explicit projection used so legacy JSON callers keep their key while canonical callers get the wire key. This keeps compatibility without letting a canonical header carry a display fallback. The first column is the concise command handle (slug / epic id), which `-o name` projects; a later column may carry a distinct durable id.

func AuditColumns

func AuditColumns() []Column[domain.Audit]

AuditColumns is the projectable column set for `audit list`. Slug stays first as the human-facing handle projected by `-o name`; the durable id is appended last for explicit selection without shifting established columns.

func AuditReadColumns added in v0.23.0

func AuditReadColumns() []Column[core.LoadedRecord[domain.Audit]]

AuditReadColumns is the source-aware audit list projection.

func EpicColumns

func EpicColumns() []Column[core.EpicSummary]

EpicColumns is the projectable column set for `epic list` (id first; done/total as plain numbers, not the human "2/3 (66%)" cell).

func FindingColumns

func FindingColumns() []Column[core.AuditFinding]

FindingColumns is the projectable column set for `audit findings`. The first column is the addressable id `audit:code` (what `-o name` projects) — unique across audits, unlike a bare finding code which repeats.

func ResearchColumns

func ResearchColumns() []Column[domain.Research]

ResearchColumns are the projectable columns for `research list -o table/csv` and `--json -c`. No status/bucket column exists because research has no lifecycle.

func ResearchReadColumns added in v0.23.0

func ResearchReadColumns() []Column[core.LoadedRecord[domain.Research]]

ResearchReadColumns is the source-aware research list projection.

func SelectColumns

func SelectColumns[T any](all []Column[T], names []string) ([]Column[T], error)

SelectColumns returns the columns named by `names`, in that order; empty `names` returns the established default table columns. An unknown name is a validation error listing the available columns.

func TaskColumns

func TaskColumns() []Column[domain.Task]

TaskColumns is the projectable column set for `task list`. Slug stays first as the human-facing handle projected by `-o name`; the durable id is selectable explicitly and appended last so established columns retain their positions.

func TaskReadColumns added in v0.23.0

func TaskReadColumns() []Column[core.LoadedRecord[domain.Task]]

TaskReadColumns keeps the established list projection while sourcing the durable id from the loaded-record envelope rather than parsed frontmatter.

func ThreadColumns added in v0.23.0

func ThreadColumns() []Column[core.ThreadView]

ThreadColumns is the compact projectable view for `thread list`. It is intentionally not a flattened replacement for the full typed Thread envelope: bare --json retains members, external gates, topology diagnostics, and the nested persisted document. Slug remains first so -o name emits the human command handle; stable identity and explicit progress/health fields are available to agents in any caller-selected order.

type ColumnSpec

type ColumnSpec struct {
	Name    string
	Desc    string
	Aliases []string
}

ColumnSpec is the name+description of a column without the (typed) extractor, so the cli completion/help layer can offer and describe columns without the generic type parameter.

func Specs

func Specs[T any](cols []Column[T]) []ColumnSpec

Specs projects a typed column set to its name/description pairs.

type DoctorProblem

type DoctorProblem = wire.DoctorProblem

DoctorProblem is one linkback inconsistency (the wire type), re-exported so the CLI's doctor command keeps building it through the render package.

type InitEnvelope

type InitEnvelope = wire.InitEnvelope

InitEnvelope is the `init --json` payload (the wire type), re-exported so the CLI's init command keeps building it through the render package.

type KindSchema

type KindSchema = wire.KindSchema

KindSchema is the per-kind authoring guidance (`tskflwctl schema <kind>`): how to compose a well-formed document of that kind.

type MoveResult

type MoveResult = wire.MoveResult

MoveResult is the per-item outcome of a transition (the wire type), re-exported so the CLI's move loop (moves.go) keeps building it through the render package.

func TaskMoveResult added in v0.18.0

func TaskMoveResult(receipt core.TaskLifecycleReceipt) MoveResult

TaskMoveResult maps a guarded lifecycle receipt into the shared move row.

type SchemaCommand added in v0.23.0

type SchemaCommand = wire.SchemaCommand

SchemaCommand is one runnable command and its enforced side-effect capability.

type SchemaContract

type SchemaContract = wire.SchemaContract

SchemaContract is the global machine contract (`tskflwctl schema`): everything an agent needs to drive the tool without parsing --help prose.

type SchemaExitCode

type SchemaExitCode = wire.SchemaExitCode

SchemaExitCode is one active or reserved process exit and its stable meaning.

type SchemaField

type SchemaField = wire.SchemaField

SchemaField is one known frontmatter field and its YAML storage type.

type SchemaStatus

type SchemaStatus = wire.SchemaStatus

SchemaStatus is one task status and whether it is part of the working set.

type Style

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

Style renders optional ANSI styling and carries the output width (0 = no limit). The zero value is disabled (plain) with no width cap — so tests, piped output, and the JSON path are never colored or truncated unless asked.

func NewStyle

func NewStyle(enabled bool) Style

NewStyle returns a Style; enabled controls whether ANSI is emitted. The palette defaults to the project default theme's dark variant; the CLI overrides it with the config-selected theme via WithPalette, and picks truecolor vs the 16-color slot via WithTrueColor.

func (Style) AuditPercent

func (s Style) AuditPercent(pct int) string

AuditPercent colors an audit's fixed-share percent on the same gray/yellow/green tiers as Percent, but labels it "N% settled" (theme.AuditPercentLabel) so the number reads as the share with a terminal disposition — fixed, tracked, or deliberately dropped — rather than as the fixed share alone.

func (Style) Bar

func (s Style) Bar(pct, width int) string

Bar renders a width-char progress bar for pct (0–100) via the shared progressbar package (same constructor + neon gradient the TUI's miniBar uses, so the two surfaces can't drift). The bar always emits lipgloss ANSI, so when styling is off (piped / --json / tests) we strip it back to plain glyphs — keeping the porcelain contract byte-stable.

func (Style) Bold

func (s Style) Bold(t string) string

Bold / Dim style arbitrary text.

func (Style) Bucket

func (s Style) Bucket(b string) string

Bucket renders an audit bucket: a colored glyph + name when styled (the shared theme's shape carries the state), the plain name otherwise — mirroring Status, so the porcelain path stays byte-stable.

func (Style) CriterionState added in v0.18.0

func (s Style) CriterionState(state string) string

CriterionState renders an acceptance criterion's state the way FindingStatus renders a finding's — glyph then word, in the state's own colour. The tokens come from theme.CriterionState, which delegates the shared words to the finding glyphs, so `◌ deferred` is the same mark on a criterion as on a finding.

It replaced a single warn-coloured label used for every state: identical yellow for deferred, wontfix, and n/a, which is the second visual language criterion 8 of let-an-acceptance-criterion-say-more-than-done-or-not-done rules out.

func (Style) Dim

func (s Style) Dim(t string) string

func (Style) FindingStatus

func (s Style) FindingStatus(status string) string

FindingStatus renders an audit finding's status the way Status renders a task status — colored glyph + label when styled, plain label otherwise. An empty status (a finding missing its **Status:**) renders as-is so the table cell stays blank rather than showing a lone glyph.

func (Style) Green

func (s Style) Green(t string) string

Green / Red / Warn style status glyphs and success/error/warning text.

func (s Style) Link(text, url string) string

Link wraps text in an OSC 8 terminal hyperlink to url when styling is on (a TTY), so supporting terminals make it click-to-open; otherwise it returns text unchanged — keeping piped / --color=never / JSON output byte-stable. url should be absolute (e.g. file:///abs/path). Gated on the same `on` flag as color, so it never reaches a pipe or an agent.

func (Style) Percent

func (s Style) Percent(pct int) string

Percent colors a completion percentage: gray <34, yellow <100, green at 100.

func (Style) Priority

func (s Style) Priority(p string) string

Priority colors a priority label.

func (Style) Red

func (s Style) Red(t string) string

func (Style) SegmentBar

func (s Style) SegmentBar(done, active, dropped, total, width int) string

SegmentBar renders an audit's finding breakdown as a stacked bar (done/active/ dropped bands over an open/empty track) via the shared progressbar package — the same renderer the TUI uses, so the surfaces can't drift. Like Bar, it strips the ANSI back to plain (distinct) glyphs when styling is off, keeping porcelain byte-stable.

func (Style) Status

func (s Style) Status(st domain.Status) string

Status renders a status: a colored glyph + label when styled (semantics from the shared theme), the plain label otherwise (so output stays byte-stable).

func (Style) Warn

func (s Style) Warn(t string) string

func (Style) WithPalette

func (s Style) WithPalette(p design.Palette) Style

WithPalette returns a copy that renders with palette p. The CLI passes the active theme's DARK palette: on a truecolor terminal the semantic HEXES render (so the theme shows on every surface); on a 16-color terminal each degrades to its background-independent ANSI slot. The dark hexes assume a dark background, so a light-terminal pass (semantic hexes + the bar gradient) is deferred polish; see the neon-day validation task.

func (Style) WithTrueColor

func (s Style) WithTrueColor(tc bool) Style

WithTrueColor returns a copy that emits the palette's truecolor hues for semantic colors when tc is set (the terminal advertises 24-bit color); otherwise each color degrades to its curated 16-color ANSI slot. Independent of on/off, which stays gated by NewStyle's enabled flag.

func (Style) WithWidth

func (s Style) WithWidth(w int) Style

WithWidth returns a copy capped to a terminal width (0 leaves it uncapped, so piped output keeps full-width rows).

type TemplateInfo

type TemplateInfo = wire.TemplateInfo

TemplateInfo is one body template's listable metadata (kind/name/description), populated by the cli for `template list`/`show`. The wire type, re-exported so the CLI keeps building it through the render package; the rendered body is carried separately (TemplateShow*), since the list view never needs it.

Jump to

Keyboard shortcuts

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