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 ¶
- func AreaMissLine(id, actual, requested string) string
- func LastEventSHA(s *scope.Scope, match scope.State) string
- func LookupCommitDateCached(ctx context.Context, root, sha string, cache map[string]string) string
- func NewCmd() *cobra.Command
- func ReadEntityBody(root, relPath string) []byte
- func Run(id, root, format, area string, pretty bool, historyLimit int) int
- type ScopeView
- type ShowAC
- type ShowView
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AreaMissLine ¶ added in v0.17.0
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 ¶
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 ¶
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 ¶
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 ¶
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.
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 ¶
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.