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
- func AcceptanceHuman(w io.Writer, st Style, cs []domain.Criterion)
- func AcceptanceJSON(w io.Writer, slug string, cs []domain.Criterion) error
- func AuditInfoHuman(w io.Writer, st Style, record core.LoadedRecord[core.AuditWithBody], ...)
- func AuditInfoJSON(w io.Writer, record core.LoadedRecord[core.AuditWithBody], path string) error
- func AuditMutationJSON(w io.Writer, a domain.Audit, body string, dryRun bool, ws wire.WorkspaceJSON) error
- func AuditShowHuman(w io.Writer, st Style, record core.LoadedRecord[core.AuditWithBody], ...) error
- func AuditShowJSON(w io.Writer, record core.LoadedRecord[core.AuditWithBody]) error
- func AuditsHuman(w io.Writer, st Style, audits []core.LoadedRecord[domain.Audit]) error
- func AuditsJSON(w io.Writer, audits []core.LoadedRecord[domain.Audit], ...) error
- func AuditsReadHuman(w io.Writer, st Style, audits []core.LoadedRecord[domain.Audit]) error
- func BoardHuman(w io.Writer, st Style, b core.Board) error
- func BoardJSON(w io.Writer, b core.Board) error
- func ConfigHuman(w io.Writer, st Style, snapshot core.ConfigurationSnapshot)
- func ConfigJSON(w io.Writer, snapshot core.ConfigurationSnapshot) error
- func ConfigMigrationHuman(w io.Writer, st Style, migration core.ConfigurationMigration)
- func ConfigMigrationJSON(w io.Writer, migration core.ConfigurationMigration, ...) error
- func CreatedHuman(w io.Writer, st Style, path string, dryRun bool)
- func CreatedJSON(w io.Writer, kind, id, slug, status, path string, dryRun bool, ...) error
- func CreatedSlugNote(w io.Writer, st Style, title, slug string)
- func DependencyMutationHuman(w io.Writer, st Style, receipt core.DependencyMutationReceipt) error
- func DependencyMutationJSON(w io.Writer, receipt core.DependencyMutationReceipt, ...) error
- func DoctorHuman(w io.Writer, st Style, problems []DoctorProblem, registry wire.DoctorRegistry)
- func DoctorJSON(w io.Writer, root string, problems []DoctorProblem, ...) error
- func EpicMutationJSON(w io.Writer, epic domain.Epic, dryRun bool, ws wire.WorkspaceJSON) error
- func EpicShowHuman(w io.Writer, st Style, es core.EpicSummary, tasks []domain.Task, body string) error
- func EpicShowJSON(w io.Writer, detail core.EpicDetail) error
- func EpicsHuman(w io.Writer, st Style, epics []core.EpicSummary) error
- func EpicsJSON(w io.Writer, epics []core.EpicSummary, problems []core.LoadProblem) error
- func FindingCreationJSON(w io.Writer, receipt core.FindingCreationReceipt, ws wire.WorkspaceJSON) error
- func FindingsHuman(w io.Writer, st Style, fs []core.AuditFinding) error
- func FindingsJSON(w io.Writer, fs []core.AuditFinding, problems []core.LoadProblem) error
- func FixHuman(w io.Writer, st Style, results []domain.FixResult, remaining []core.LintResult, ...)
- func FixJSON(w io.Writer, results []domain.FixResult, problems []core.LoadProblem, ...) error
- func IDsQuiet(w io.Writer, ids []string)
- func InitJSON(w io.Writer, e InitEnvelope) error
- func InitRegistration(r core.SpaceRegistrationReceipt) *wire.InitRegistrationJSON
- func InitRegistrationHuman(w io.Writer, st Style, r core.SpaceRegistrationReceipt)
- func LintHuman(w io.Writer, st Style, results []core.LintResult, noun string)
- func LintJSON(w io.Writer, results []core.LintResult, problems []core.LoadProblem) error
- func LintProblemsHuman(w io.Writer, st Style, problems []core.LoadProblem)
- func MovesHuman(out, errw io.Writer, st Style, results []MoveResult, dryRun bool)
- func MovesJSON(w io.Writer, results []MoveResult, dryRun bool, ws wire.WorkspaceJSON) error
- func PathJSON(w io.Writer, path string) error
- func ProblemsHuman(w io.Writer, st Style, problems []domain.FileProblem)
- func ProjectedListJSON[T any](w io.Writer, listKey string, cols []Column[T], items []T, ...) error
- func ProjectedListJSONWithProblems[T, P any](w io.Writer, listKey string, cols []Column[T], items []T, problems []P) error
- func RenderBody(st Style, body string, style func() string, raw bool) string
- func ResearchHuman(w io.Writer, st Style, docs []domain.Research) error
- func ResearchJSON(w io.Writer, docs []core.LoadedRecord[domain.Research], ...) error
- func ResearchMutationJSON(w io.Writer, r domain.Research, body string, dryRun bool, ...) error
- func ResearchReadHuman(w io.Writer, st Style, docs []core.LoadedRecord[domain.Research]) error
- func ResearchShowHuman(w io.Writer, st Style, r domain.Research, body string) error
- func ResearchShowJSON(w io.Writer, record core.LoadedRecord[core.ResearchWithBody]) error
- func SchemaHuman(w io.Writer, st Style, c SchemaContract) error
- func SchemaJSON(w io.Writer, c SchemaContract) error
- func SchemaKindHuman(w io.Writer, st Style, ks KindSchema) error
- func SchemaKindJSON(w io.Writer, ks KindSchema) error
- func SpaceMutationHuman(w io.Writer, st Style, mutation core.SpaceMutation, verb string)
- func SpaceMutationJSON(w io.Writer, mutation core.SpaceMutation) error
- func SpacesHuman(w io.Writer, st Style, groups []core.SpaceGroup)
- func SpacesJSON(w io.Writer, spaces []core.SpaceEntryPoint) error
- func StatusAllHuman(w io.Writer, st Style, overview core.SpaceOverview) error
- func StatusAllJSON(w io.Writer, overview core.SpaceOverview) error
- func SummaryHuman(w io.Writer, st Style, s core.Summary) error
- func SummaryJSON(w io.Writer, s core.Summary) error
- func TaskBlockersHuman(w io.Writer, st Style, result core.TaskBlockersResult) error
- func TaskBlockersJSON(w io.Writer, result core.TaskBlockersResult) error
- func TaskEligibilityFailure(failure *core.TaskEligibilityError) wire.TaskEligibilityFailureJSON
- func TaskGraphRepairHuman(w io.Writer, st Style, receipt core.TaskGraphRepairReceipt, ...) error
- func TaskGraphRepairJSON(w io.Writer, receipt core.TaskGraphRepairReceipt, workspace wire.WorkspaceJSON) error
- func TaskInfoHuman(w io.Writer, st Style, t domain.Task, ac domain.ACCount, path string)
- func TaskInfoJSON(w io.Writer, record core.LoadedRecord[core.TaskWithBody], ac domain.ACCount, ...) error
- func TaskMutationJSON(w io.Writer, t domain.Task, body string, dryRun bool, ws wire.WorkspaceJSON) error
- func TaskRenameJSON(w io.Writer, receipt core.TaskRenameReceipt, ws wire.WorkspaceJSON) error
- func TaskShowHuman(w io.Writer, st Style, t domain.Task, body string) error
- func TaskShowJSON(w io.Writer, record core.LoadedRecord[core.TaskWithBody]) error
- func TaskUnblocksHuman(w io.Writer, st Style, result core.TaskUnblocksResult) error
- func TaskUnblocksJSON(w io.Writer, result core.TaskUnblocksResult) error
- func TasksHuman(w io.Writer, st Style, tasks []domain.Task) error
- func TasksJSON(w io.Writer, tasks []core.LoadedRecord[domain.Task], ...) error
- func TasksReadHuman(w io.Writer, st Style, tasks []core.LoadedRecord[domain.Task]) error
- func TemplateShowHuman(w io.Writer, st Style, info TemplateInfo, body string)
- func TemplateShowJSON(w io.Writer, info TemplateInfo, body string) error
- func TemplatesHuman(w io.Writer, st Style, ts []TemplateInfo)
- func TemplatesJSON(w io.Writer, ts []TemplateInfo) error
- func ThemePreviewHuman(w io.Writer, st Style, name, variant string, pal design.Palette)
- func ThemePreviewJSON(w io.Writer, name, variant string, pal design.Palette) error
- func ThemesHuman(w io.Writer, st Style, themes []wire.ThemeEntry)
- func ThemesJSON(w io.Writer, themes []wire.ThemeEntry) error
- func ThreadApplyComposeJSON(w io.Writer, plan core.ThreadApplyPlan, planPath string, dryRun bool, ...) error
- func ThreadApplyHuman(w io.Writer, st Style, receipt core.ThreadApplyReceipt)
- func ThreadApplyJSON(w io.Writer, receipt core.ThreadApplyReceipt, planPath string, ...) error
- func ThreadCreatedHuman(w io.Writer, st Style, receipt core.ThreadCreationReceipt, path string)
- func ThreadFrontierHuman(w io.Writer, st Style, view core.ThreadView) error
- func ThreadFrontierJSON(w io.Writer, view core.ThreadView) error
- func ThreadGraphJSON(w io.Writer, projection core.ThreadGraphProjection) error
- func ThreadMutationHuman(w io.Writer, st Style, receipt core.ThreadMutationReceipt, path string)
- func ThreadMutationJSON(w io.Writer, receipt core.ThreadCreationReceipt, path string, ...) error
- func ThreadPlanHuman(w io.Writer, st Style, projection core.ThreadGraphProjection) error
- func ThreadPlanJSON(w io.Writer, projection core.ThreadGraphProjection) error
- func ThreadProblemsHuman(w io.Writer, st Style, problems []core.ThreadReadProblem)
- func ThreadShowHuman(w io.Writer, st Style, view core.ThreadView, body string) error
- func ThreadShowJSON(w io.Writer, view core.ThreadView, body string) error
- func ThreadUpdateJSON(w io.Writer, receipt core.ThreadMutationReceipt, path string, ...) error
- func ThreadsHuman(w io.Writer, st Style, list core.ThreadListView) error
- func ThreadsJSON(w io.Writer, list core.ThreadListView, problems []core.ThreadReadProblem) error
- func VersionHuman(w io.Writer, st Style, version string)
- func VersionJSON(w io.Writer, version string) error
- func WorkspaceHuman(w io.Writer, st Style, ws wire.WorkspaceJSON)
- func WorkspaceJSON(w io.Writer, ws wire.WorkspaceJSON) error
- func WriteCSV[T any](w io.Writer, cols []Column[T], items []T) error
- func WriteTablePlain[T any](w io.Writer, cols []Column[T], items []T)
- type Column
- func AuditColumns() []Column[domain.Audit]
- func AuditReadColumns() []Column[core.LoadedRecord[domain.Audit]]
- func EpicColumns() []Column[core.EpicSummary]
- func FindingColumns() []Column[core.AuditFinding]
- func ResearchColumns() []Column[domain.Research]
- func ResearchReadColumns() []Column[core.LoadedRecord[domain.Research]]
- func SelectColumns[T any](all []Column[T], names []string) ([]Column[T], error)
- func TaskColumns() []Column[domain.Task]
- func TaskReadColumns() []Column[core.LoadedRecord[domain.Task]]
- func ThreadColumns() []Column[core.ThreadView]
- type ColumnSpec
- type DoctorProblem
- type InitEnvelope
- type KindSchema
- type MoveResult
- type SchemaCommand
- type SchemaContract
- type SchemaExitCode
- type SchemaField
- type SchemaStatus
- type Style
- func (s Style) AuditPercent(pct int) string
- func (s Style) Bar(pct, width int) string
- func (s Style) Bold(t string) string
- func (s Style) Bucket(b string) string
- func (s Style) CriterionState(state string) string
- func (s Style) Dim(t string) string
- func (s Style) FindingStatus(status string) string
- func (s Style) Green(t string) string
- func (s Style) Link(text, url string) string
- func (s Style) Percent(pct int) string
- func (s Style) Priority(p string) string
- func (s Style) Red(t string) string
- func (s Style) SegmentBar(done, active, dropped, total, width int) string
- func (s Style) Status(st domain.Status) string
- func (s Style) Warn(t string) string
- func (s Style) WithPalette(p design.Palette) Style
- func (s Style) WithTrueColor(tc bool) Style
- func (s Style) WithWidth(w int) Style
- type TemplateInfo
Constants ¶
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 ¶
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 ¶
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 ¶
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 BoardHuman ¶
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 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 ¶
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 ¶
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
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 ¶
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 ¶
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 ¶
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 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
func InitRegistration(r core.SpaceRegistrationReceipt) *wire.InitRegistrationJSON
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 ¶
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 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 ¶
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 ¶
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 ResearchShowHuman ¶
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
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
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 ¶
SummaryHuman renders the at-a-glance dashboard.
func SummaryJSON ¶
SummaryJSON writes the dashboard as a versioned envelope.
func TaskBlockersHuman ¶ added in v0.18.0
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 ¶
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 ¶
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
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 ¶
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
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 ¶
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 ¶
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 ThreadFrontierHuman ¶ added in v0.18.0
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 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 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 ThreadShowJSON ¶ added in v0.18.0
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 ThreadsJSON ¶ added in v0.18.0
func ThreadsJSON(w io.Writer, list core.ThreadListView, problems []core.ThreadReadProblem) error
func VersionHuman ¶
VersionHuman prints the CLI version.
func VersionJSON ¶
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 ¶
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.
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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) Bucket ¶
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
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) FindingStatus ¶
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) Link ¶
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) SegmentBar ¶
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 ¶
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) WithPalette ¶
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 ¶
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.
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.