show

package
v0.26.0 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package show implements the `aiwf show` verb (per-verb subpackage of M-0116; includes the show-scopes helpers moved from show_scopes.go).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AreaMissLine added in v0.17.0

func AreaMissLine(id, actual, requested string) string

AreaMissLine is the one-line text rendered when `aiwf show <id> --area <name>` filters the named entity out because its effective area differs (E-0043, M-0174/AC-3). `show` is single-entity, so the predicate hides the one entity (like an empty list) rather than listing — the line tells the operator the entity exists but lives elsewhere. An untagged entity (actual == "") gets its own wording.

func LastEventSHA

func LastEventSHA(s *scope.Scope, match scope.State) string

LastEventSHA returns the SHA of the latest event in s whose state equals match, or "" when none. Used by ScopeView assembly to look up the ending commit's date (when the scope is ended).

func LookupCommitDateCached

func LookupCommitDateCached(ctx context.Context, root, sha string, cache map[string]string) string

LookupCommitDateCached returns the ISO-8601 author date of the commit at sha, caching results so we never hit `git show` twice for the same SHA in one show call. Errors fall back to an empty string (the caller renders dates as omitempty in JSON).

func NewCmd

func NewCmd() *cobra.Command

NewCmd builds `aiwf show <id>`. Aggregates per-entity state from the existing data sources — frontmatter (entity), git log (history), aiwf check (findings) — into one human-readable view (or one JSON envelope when --format=json). No new state; pure projection.

For composite ids (M-NNN/AC-N), renders just the AC's slice of the parent milestone plus its history.

func ReadEntityBody

func ReadEntityBody(root, relPath string) []byte

ReadEntityBody reads the entity file at root/relPath and returns the body bytes (the prose after the closing `---`). Errors are swallowed — `aiwf show` already emits findings for unreadable / malformed entities via the load-error finding; surfacing the same problem on the body field would double-count. Empty body or missing file produces nil.

Entity.Path is repo-relative (the loader normalizes it that way) so callers must join with root before hitting the filesystem; doing the join in this helper keeps each caller from re-deriving it.

func Run

func Run(id, root, format, area string, pretty bool, historyLimit int) int

Run executes `aiwf show`. Returns one of the cliutil.Exit* codes.

Types

type ScopeView

type ScopeView struct {
	AuthSHA    string `json:"auth_sha"`
	Entity     string `json:"entity"`
	Agent      string `json:"agent"`
	Principal  string `json:"principal"`
	State      string `json:"state"`
	Opened     string `json:"opened,omitempty"`
	EndedAt    string `json:"ended_at,omitempty"`
	EventCount int    `json:"event_count"`
}

ScopeView is one scope's projection on `aiwf show`. It captures the authorization grant's metadata (SHA, agent, principal) and its current FSM state, plus the open/end dates and the count of transitions the scope has gone through.

Auth SHA is the full git SHA of the authorize-opened commit; callers that want a short form truncate. Entity is the scope- entity id at the time the scope was opened (rename-chain resolution lives in the verb gate, not here — show is descriptive, not gating).

func AssembleScopeViews added in v0.23.0

func AssembleScopeViews(
	id string,
	events []history.HistoryEvent,
	ownScopes []*scope.Scope,
	openers map[string]string,
	foreignScopes func(ent string) ([]*scope.Scope, error),
	dateOf func(sha string) string,
) ([]ScopeView, error)

AssembleScopeViews is the pure, git-free core of LoadEntityScopeViews: given an entity's loaded history events, its own scopes (source b), the repo-wide authorize-opener map, a resolver for a foreign scope-entity's scopes (source a), and a commit-date resolver, it assembles the scope-view list. The git-touching gather is the caller's job, so render's single pass (E-0054 / M-0221) assembles byte-identical views from its shared HEAD walk (opener map + replayed scopes + %aI dates) through this exact code path — no fourth copy of the assembly logic.

The M-0223 cost gates live in the caller (LoadEntityScopeViews loads ownScopes / openers only when the events warrant it); Assemble stays gate-free because the gates are pure optimizations — an empty openers map yields no foreign lookups, and empty ownScopes contributes nothing, so the assembled views are identical whether or not the caller gated.

foreignScopes is invoked only for a scope-entity that (a) an aiwf-authorized-by event references and (b) differs from id, so a caller that passes a nil openers map never triggers a foreign resolve. dateOf resolves a commit SHA to its author date (git show for the verb path; a lookup into the shared pass's %aI map for render).

func LoadEntityScopeViews

func LoadEntityScopeViews(ctx context.Context, root, id string) ([]ScopeView, error)

LoadEntityScopeViews returns every scope that ever applied to id — scopes opened ON id (directly), plus scopes from elsewhere that authorized work touching id (via `aiwf-authorized-by:`).

Source (b) — scopes opened directly on id — comes from id's own history via cliutil.LoadEntityScopes, which is width-tolerant: this is both the single source of truth for direct scopes and the fix for the narrow-id omission (a raw-id `ent == id` compare against a canonicalized map value silently dropped `aiwf show E-14`'s table; M-0223).

Source (a) — scopes opened elsewhere that authorized work on id — is the only reason to run the repo-wide authorize-opener grep (cliutil.AuthorizeOpeners), and only when id was actually worked under a foreign scope (history.HasAuthorizedBy). An active direct-scope opener, which has no `aiwf-authorized-by`, resolves entirely from source (b) without the grep (E-0054 read-verb guard).

Empty / pre-aiwf repos return (nil, nil).

type ShowAC

type ShowAC struct {
	ID          string `json:"id"`
	Title       string `json:"title"`
	Status      string `json:"status"`
	TDDPhase    string `json:"tdd_phase,omitempty"`
	Description string `json:"description,omitempty"`
}

ShowAC is one AC's view inside a milestone show. Description carries the prose under the matching `### AC-N — <title>` heading in the milestone body, trimmed of surrounding whitespace; empty when the milestone body has no body section for this AC (e.g. seeded purely via frontmatter).

type ShowView

type ShowView struct {
	ID           string                 `json:"id"`
	Kind         string                 `json:"kind"`
	Title        string                 `json:"title"`
	Status       string                 `json:"status"`
	Path         string                 `json:"path,omitempty"`
	Parent       string                 `json:"parent,omitempty"`
	TDD          string                 `json:"tdd,omitempty"`
	ACs          []ShowAC               `json:"acs,omitempty"`
	Body         map[string]string      `json:"body,omitempty"`
	History      []history.HistoryEvent `json:"history,omitempty"`
	Findings     []check.Finding        `json:"findings,omitempty"`
	ReferencedBy []string               `json:"referenced_by"`
	Scopes       []ScopeView            `json:"scopes,omitempty"`

	// Archived is true when the resolved entity's path lives under a
	// per-kind `archive/` subdirectory per ADR-0004. JSON shape uses
	// `omitempty` so active envelopes don't carry the field at all —
	// downstream tooling treats presence as the indicator. Text
	// rendering appends ` · archived` to the header line (see
	// renderShowText). M-0087/AC-5.
	Archived bool `json:"archived,omitempty"`

	// Composite-id-only fields (when querying M-NNN/AC-N): the AC's
	// own state, populated instead of (not in addition to) the
	// milestone's full ACs slice.
	AC       *ShowAC `json:"ac,omitempty"`
	ParentID string  `json:"parent_id,omitempty"`
}

ShowView is the aggregated per-entity state. Exported for the JSON envelope. Field-set varies by what kind of id was queried; absent fields render as empty / omitted in JSON via omitempty.

ReferencedBy is the inversion of the reference graph — every entity id that names this one as a target. Always emitted in JSON (zero- value `[]`) so downstream consumers never have to check for field presence; populated from tree.Tree.ReverseRefs at view-build time. For composite ids (M-NNN/AC-N), this lists referrers of the AC specifically; the parent milestone's referrers are not rolled in (use `aiwf show M-NNN` for that).

func BuildCompositeShowView

func BuildCompositeShowView(ctx context.Context, root string, t *tree.Tree, loadErrs []tree.LoadError, id string, historyLimit int) (ShowView, bool)

BuildCompositeShowView handles `aiwf show M-NNN/AC-N`. Returns ok=false when the parent or AC doesn't exist.

func BuildShowView

func BuildShowView(ctx context.Context, root string, t *tree.Tree, loadErrs []tree.LoadError, id string, historyLimit int) (ShowView, bool)

BuildShowView assembles the view for id; ok=false when no entity (or AC) matches. Composite ids resolve via the parent milestone's ACs slice.

Jump to

Keyboard shortcuts

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