timeline

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package timeline builds the unified task-detail timeline consumed by both the TUI and the Web UI. It imports orchestrator only — no api dependency — so web/templates can import it without creating an import cycle with internal/api (which pulls in web/templates for rendering).

The builder takes fully-resolved inputs: the task, its actions, and a list of JobInfo records. Each caller adapts from its own Job shape (api.Job / dispatcher job model) via ConvertAPIJob-style helpers.

Index

Constants

View Source
const (
	JobStatusRunning   = "running"
	JobStatusCompleted = "completed"
	JobStatusFailed    = "failed"
)

JobStatus mirrors the string values used by api.JobStatus so timeline renderers don't need to import api to discriminate running / completed / failed states. Callers pass these strings through.

Variables

This section is empty.

Functions

func BuildActionLabel

func BuildActionLabel(a *orchestrator.Action) string

BuildActionLabel returns the display label for a timeline action. State transitions: "<type> → <to_status>". Progress actions: "進捗: <message>" (extracted from JSON payload).

func BuildJobLabel

func BuildJobLabel(j *JobInfo) string

BuildJobLabel returns the display label for a job.

  • completed: "[role] <name> ✓ <duration>" (name omitted when empty)
  • failed: "[role] <name> ✗ <duration>"
  • running: "[role] <elapsed> ago"
  • other: "[role] <name><status>"

DisplayName is used when set; otherwise HandlerID is used as fallback. When role is "hook", the "[hook]" prefix is omitted — the handler name alone identifies the hook sufficiently.

func FormatElapsed

func FormatElapsed(t time.Time) string

FormatElapsed returns a short MM:SS (or HH:MM:SS) elapsed string since t. Matches the TUI helper so that TUI display is unchanged after shared-timeline migration. Exported so the Web UI can compute the initial server-side value for a running job's live-ticking elapsed counter.

func IsProgressAction

func IsProgressAction(a *orchestrator.Action) bool

IsProgressAction reports whether an action is a non-transitioning progress note.

func IsStateTransition

func IsStateTransition(a *orchestrator.Action) bool

IsStateTransition reports whether an action moves the task to a different status.

func JobDuration

func JobDuration(j *JobInfo) string

JobDuration returns a human-readable duration for a completed/failed job. Returns "?" when the job has no UpdatedAt or UpdatedAt is not after CreatedAt.

Types

type Event

type Event struct {
	Time    time.Time
	HasTime bool
	Kind    EventKind
	Label   string
	Action  *orchestrator.Action
	Job     *JobInfo
}

Event is a single row in the unified timeline. Exactly one of Action / Job is populated, matching Kind.

func SelectableEvents

func SelectableEvents(groups []StatusGroup) []Event

SelectableEvents returns the flat event list from all groups in order. Used by TUI for cursor clamping and enter-key drilldown.

type EventKind

type EventKind string

EventKind distinguishes action rows from job rows.

const (
	KindAction EventKind = "action"
	KindJob    EventKind = "job"
)

type JobInfo

type JobInfo struct {
	ID          string
	Role        string
	HandlerID   string
	DisplayName string // optional; shown instead of HandlerID when non-empty
	Status      string // one of JobStatusRunning / Completed / Failed (or other)
	ExitCode    int
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

JobInfo is the minimum job data needed to place a job on the timeline and render its label / status icon / link target. Callers convert from their native job type (api.Job for TUI / Web).

type StatusGroup

type StatusGroup struct {
	Status       string
	EnteredAt    time.Time
	HasEnteredAt bool
	Events       []Event
}

StatusGroup groups events under a single task-status visit. Repeated visits to the same status produce distinct groups in order.

func Build

func Build(task *orchestrator.Task, actions []*orchestrator.Action, jobs []*JobInfo) []StatusGroup

Build groups filtered events by the task-status visit in which they occurred. Only state-transition actions and jobs are included. hook_fired actions are intentionally dropped because the associated job carries the same information (success, handler id, duration) plus output.

Each visit to a status creates a new group so repeated visits (e.g. executing → aborted → pending → executing) produce distinct groups in chronological order instead of collapsing same-status events into one.

Each group's EnteredAt records when the task entered that visit:

  • initial group: task.CreatedAt
  • subsequent groups: the CreatedAt of the transition action that moved into it

Jump to

Keyboard shortcuts

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