state

package
v0.43.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package state owns the run state: one small `key value` file per session under ~/.claude/f10/state, keyed by session rather than by repo because two sessions over one checkout are two runs.

This package is the only writer (`f10 state`, `f10 hook`) and holds the rules. The status line's renderer, `bin/f10-state.sh render`, is the other reader: it runs on every refresh, so it stays bash and reads the same format with the same tolerances - unknown keys ignored, a non-numeric timestamp read as stale. The render parity test pins that.

Index

Constants

View Source
const DefaultTTL = 24 * time.Hour

DefaultTTL is how long a run counts as live with nothing reporting: the point past which the badge stops rendering.

View Source
const PipelineSep = " → "

PipelineSep joins a recorded pipeline's steps, as `pipelines:` strings spell them: a step name may hold spaces (`review (local)`).

Variables

View Source
var Phases = []string{"capture", "plan", "ship"}

Phases in the order the badge draws them.

View Source
var Statuses = []string{"pending", "running", "done", "failed", "partial", "skipped", "prior", "blocked"}

Statuses a phase can hold, in the order the usage text lists them.

Functions

func Clear added in v0.36.0

func Clear(dir, session string)

Clear drops a session's state file. Absent is fine.

func Dir

func Dir() string

Dir is where state files live: F10_STATE_DIR, else the default.

func Glyph added in v0.36.0

func Glyph(status string) string

Glyph is the status line's default shape for a status; the renderer's F10_STATE_GLYPHS override applies to the status line only.

func Path

func Path(dir, session string) string

Path is the state file for a session: the id sanitized, since it names a file, the way the renderer sanitizes it.

func Prune added in v0.36.0

func Prune(dir string, now time.Time)

Prune drops the per-session files of long-dead sessions: run state, the conventions marker f10-inject.sh writes, and the session start mark.

func Session

func Session() string

Session is the session this process runs in: the explicit override, then the id Claude Code exports into every Bash tool call. Empty from a plain terminal. A hook names its session in the payload instead.

func SplitPipeline added in v0.42.0

func SplitPipeline(s string) []string

SplitPipeline reads a recorded pipeline back into its steps.

func StartedPath added in v0.36.0

func StartedPath(dir, session string) string

StartedPath is the mark a session's start leaves beside its state file: when the session loaded the plugin, for doctor to compare with the install's update time.

func Stopped

func Stopped(status string) bool

Stopped reports whether the phase status is one a run halts on.

func TTL

func TTL() time.Duration

TTL is how long a run counts as live, from F10_STATE_TTL.

Types

type Run

type Run struct {
	Session string `json:"session"`
	Task    string `json:"task,omitempty"`
	URL     string `json:"url,omitempty"`
	Root    string `json:"root,omitempty"`  // checkout root the run is about
	Skill   string `json:"skill,omitempty"` // the skill that began the run
	Capture string `json:"capture"`
	Plan    string `json:"plan"`
	Ship    string `json:"ship"`
	Leaf    string `json:"leaf,omitempty"`  // the pipeline step running, or stopped on
	Final   string `json:"final,omitempty"` // the ship pipeline's declared last step
	// the ship pipeline's steps as declared, in order
	Pipeline []string  `json:"pipeline,omitempty"`
	Note     string    `json:"note,omitempty"` // why the run stopped
	Next     string    `json:"next,omitempty"` // what unblocks it
	Ask      string    `json:"ask,omitempty"`  // the question a driven run stopped on, options included
	Updated  time.Time `json:"updated"`
}

A Run is one session's state file, read back. Every phase holds one of the Statuses: pending, running, done, failed, partial, skipped, prior, blocked.

func Fresh added in v0.36.0

func Fresh(session string) *Run

Fresh is the run a session has before anything reported: every phase pending.

func List

func List(dir string, now time.Time, ttl time.Duration) ([]*Run, error)

List reads every live run in dir, newest first. A missing directory is an empty list: no run has ever reported on this machine.

func Load

func Load(path string) (*Run, error)

Load reads one state file. A missing file is os.ErrNotExist, unwrapped enough for errors.Is.

func LoadOrFresh added in v0.36.0

func LoadOrFresh(dir, session string) (*Run, bool)

LoadOrFresh reads the session's file, or starts a fresh run when there is none. The bool says whether a file was read.

func (*Run) Backstop added in v0.36.0

func (r *Run) Backstop() bool

Backstop is the Stop hook's promotion, for the most-dropped call: the final `set ship done` after the PR and report. Stop states are left alone. Single-turn capture and plan promote; ship spans many turns, so it promotes only on the declared final step, or when no final or leaf is known (overstating is the cheaper error). It reports whether anything changed.

func (*Run) Live

func (r *Run) Live(now time.Time, ttl time.Duration) bool

Live reports whether the run was updated within ttl of now.

func (*Run) PhaseText

func (r *Run) PhaseText(phase string) string

PhaseText is the status with its step attached where one is known and belongs to that status: `running: implement`, `blocked at judge`. The leaf is a pipeline step, so only ship carries one, but for the judge fetch runs on a stale task before plan.

func (*Run) PlanWritten added in v0.36.0

func (r *Run) PlanWritten(task string)

PlanWritten is the plan step's output landing: plan done, unreported, and the file's name is the task id.

func (*Run) Save added in v0.36.0

func (r *Run) Save(dir string, now time.Time) error

Save writes the run in the format the status line's bash renderer reads, key for key, through a temp file so the polling renderer never sees a torn file. Every value is flattened to one line: a newline would start a new key.

func (*Run) Seed added in v0.36.0

func (r *Run) Seed(skill, args, cwd string) bool

Seed begins a run for a skill invocation and resets the phases, except a chain over one task (plan, then ship) whose argument names the task already held: that carries settled phases forward, or ship would show this session's plan as `skipped`. It reports false for --help, which runs nothing, so the badge keeps the last real run.

func (*Run) Set added in v0.36.0

func (r *Run) Set(phase, status, leaf string) error

Set records a phase's status. A stop state keeps the leaf (the argument, else the last running one): "blocked at judge" is the answer to "ship blocked". A phase running again retires the old note and question.

func (*Run) SetAsk added in v0.36.0

func (r *Run) SetAsk(text string) error

SetAsk records the questionnaire a driven run stopped on, options included: no one is in its pane to answer.

func (*Run) SetFinal added in v0.36.0

func (r *Run) SetFinal(step string) error

SetFinal declares the ship pipeline's last step, for the Stop backstop: a turn ending on it is a dropped `set ship done`; mid-pipeline is a pause.

func (*Run) SetNote added in v0.36.0

func (r *Run) SetNote(reason, next string) error

SetNote records why a run stopped and what unblocks it.

func (*Run) SetPipeline added in v0.42.0

func (r *Run) SetPipeline(steps []string) error

SetPipeline declares the ship pipeline's steps, in order; its last is the final step.

func (*Run) SetTask added in v0.36.0

func (r *Run) SetTask(id, url string) error

SetTask records the task the run is about. A tracker task id means the task predates this run, so an unreported capture becomes `prior`; `done` and `running` stay, since capture reports those itself.

func (*Run) Show added in v0.36.0

func (r *Run) Show(w io.Writer, now time.Time)

Show prints the run one `label value` line per fact, in `f10 status` order. A phase carries its glyph and, for ship, its step.

func (*Run) Status

func (r *Run) Status(phase string) string

Status is the phase's status as recorded.

type UsageError added in v0.36.0

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

A UsageError is a malformed call: an unknown phase or status, a missing argument. It is a typo in step prose, so the command exits 2 rather than leave the badge frozen without a word.

func (*UsageError) Error added in v0.36.0

func (e *UsageError) Error() string

Jump to

Keyboard shortcuts

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