Documentation
¶
Index ¶
- Constants
- Variables
- func DefaultPath() string
- func Key(agent, id string) string
- func PruneOld(cfg *Config, maxAge time.Duration, exists func(string) bool)
- func ShortID(id string) string
- func ValidProviderSessionID(id string) bool
- func ValidateProfile(profile Profile) error
- func ValidateProfileName(name string) error
- func ValidateSessionProfileOverrides(overrides SessionProfileOverrides) error
- type Config
- type Mode
- type MousePolicy
- type PRRecord
- type Profile
- type SessionExit
- type SessionProfileOverrides
- type SessionRecord
- type Status
- type Store
- func (s *Store) Load() (Config, error)
- func (s *Store) MarkSessionClosed(sessionName string, exitCode int) error
- func (s *Store) Path() string
- func (s *Store) Save(cfg Config) error
- func (s *Store) SetSessionProbe(exists func(string) bool)
- func (s *Store) TryMarkSessionClosed(sessionName string, exitCode int) (bool, error)
- func (s *Store) TryRecordSessionExit(exit SessionExit) (bool, error)
- func (s *Store) Update(fn func(*Config) error) error
- type UISettings
- type WebProject
- type WebState
Constants ¶
const CurrentSchemaVersion = 4
const (
DefaultAgentName = "opencode"
)
UI defaults and bounds. normalize clamps/coerces out-of-range or unknown on-disk values so a hand-edited or corrupt config can never feed an invalid value downstream (F44).
const SurfaceWeb = "web"
SurfaceWeb marks records owned by the `uam web` service.
Variables ¶
var ErrReadOnly = errors.New("store: config loaded from a newer schema is read-only")
ErrReadOnly is returned by Save/Update when asked to write a config loaded from a newer on-disk schema. Refusing the write prevents an older binary from clobbering fields it does not understand (F33).
Functions ¶
func DefaultPath ¶
func DefaultPath() string
func PruneOld ¶
PruneOld drops long-stale terminal records whose session is gone. Records owned by another surface are never pruned here: their liveness is not a terminal session host, so the probe cannot speak for them.
func ValidProviderSessionID ¶
ValidProviderSessionID is the schema-v3 provider identity grammar. Runtime discovery must use this same boundary so it cannot persist a value that a later load would reject by dropping the containing session record.
func ValidateProfile ¶
func ValidateProfileName ¶
func ValidateSessionProfileOverrides ¶
func ValidateSessionProfileOverrides(overrides SessionProfileOverrides) error
Types ¶
type Config ¶
type Config struct {
SchemaVersion int `json:"schema_version"`
DefaultAgent string `json:"default_agent"`
DefaultProfile string `json:"default_profile"`
Profiles map[string]Profile `json:"profiles"`
Sessions map[string]SessionRecord `json:"sessions"`
UI UISettings `json:"ui"`
// WebProjects holds the web interface's Projects, keyed by Project ID.
WebProjects map[string]WebProject `json:"web_projects,omitempty"`
// ReadOnly is set when the on-disk file declares a SchemaVersion newer than
// this binary understands. The app must not write such a config (doing so
// would drop fields it does not model), so Save/Update refuse it (F33). It
// is in-memory only and never serialized.
ReadOnly bool
// contains filtered or unexported fields
}
func DefaultConfig ¶
func DefaultConfig() Config
func (Config) MarshalJSON ¶
func (*Config) PutSession ¶
func (c *Config) PutSession(key string, rec SessionRecord) bool
PutSession inserts or updates rec under key with a guard against the 8-char ShortID map key collapsing two distinct full IDs into one slot (F22). The short key carries only 32 bits of entropy, so two same-agent sessions can collide; without this guard the second write would silently clobber the first, orphaning a live session whose only handle is that record. It returns true on a successful write (no record, or the same full ID) and false (with a log) when an existing record under key carries a different non-empty full ID.
func (*Config) UnmarshalJSON ¶
type MousePolicy ¶
type MousePolicy string
const ( MousePolicyAuto MousePolicy = "auto" MousePolicyOn MousePolicy = "on" MousePolicyOff MousePolicy = "off" )
type Profile ¶
type Profile struct {
Provider *string `json:"provider,omitempty"`
Mode *Mode `json:"mode,omitempty"`
CommandAlias *string `json:"command_alias,omitempty"`
Mouse *MousePolicy `json:"mouse,omitempty"`
ControlPrefix *string `json:"control_prefix,omitempty"`
BackDetach *bool `json:"back_detach,omitempty"`
ScrollbackLines *int `json:"scrollback_lines,omitempty"`
// contains filtered or unexported fields
}
func (Profile) MarshalJSON ¶
func (*Profile) UnmarshalJSON ¶
type SessionExit ¶
type SessionExit struct {
SessionName string
ProviderSessionID string
ExitCode int
UAMInitiated bool
}
SessionExit describes how a provider process left its native session host. UAMInitiated is true only for an explicit UAM stop/restart request; terminal provider exits and externally delivered signals remain natural exits.
type SessionProfileOverrides ¶
type SessionProfileOverrides struct {
Mode *Mode `json:"mode,omitempty"`
CommandAlias *string `json:"command_alias,omitempty"`
Mouse *MousePolicy `json:"mouse,omitempty"`
ControlPrefix *string `json:"control_prefix,omitempty"`
BackDetach *bool `json:"back_detach,omitempty"`
ScrollbackLines *int `json:"scrollback_lines,omitempty"`
// contains filtered or unexported fields
}
func (SessionProfileOverrides) MarshalJSON ¶
func (o SessionProfileOverrides) MarshalJSON() ([]byte, error)
func (*SessionProfileOverrides) UnmarshalJSON ¶
func (o *SessionProfileOverrides) UnmarshalJSON(data []byte) error
type SessionRecord ¶
type SessionRecord struct {
ID string `json:"id"`
Agent string `json:"agent"`
CommandAlias string `json:"command_alias,omitempty"`
Name string `json:"name"`
Prompt string `json:"prompt,omitempty"`
Mode Mode `json:"mode"`
Workdir string `json:"workdir"`
// SessionName is the backend session name ("uam-<agent>-<id>"). The JSON
// key keeps its historical "tmux_session" spelling so configs written by
// tmux-backed releases load unchanged.
SessionName string `json:"tmux_session"`
CreatedAt time.Time `json:"created_at"`
LastSeenAt time.Time `json:"last_seen_at"`
Pinned bool `json:"pinned"`
Group string `json:"group"`
SortIndex int `json:"sort_index"`
Status Status `json:"status,omitempty"`
// ProviderSessionID is the agent CLI's own session id, recorded when the
// provider lets uam seed it at dispatch (e.g. claude --session-id). A
// resume can then target the exact provider session instead of the
// provider's "most recent" heuristic.
ProviderSessionID string `json:"provider_session_id,omitempty"`
// LastExitCode records the agent process's exit status from the most
// recent close (-1 when it died on a signal). Pointer so records from
// older schemas stay distinguishable from a real exit 0.
LastExitCode *int `json:"last_exit_code,omitempty"`
PR *PRRecord `json:"pr,omitempty"`
Profile string `json:"profile,omitempty"`
ProfileOverrides *SessionProfileOverrides `json:"profile_overrides,omitempty"`
// Surface names the owner of a record. Empty means a terminal session host;
// SurfaceWeb means the web service. Terminal commands never list, attach,
// resume or prune records with a non-empty Surface, and the web service
// only opens its own, so neither takes over the other's conversations.
Surface string `json:"surface,omitempty"`
// Web is the web service's durable state for a SurfaceWeb record.
Web *WebState `json:"web,omitempty"`
// contains filtered or unexported fields
}
func (SessionRecord) MarshalJSON ¶
func (r SessionRecord) MarshalJSON() ([]byte, error)
func (*SessionRecord) UnmarshalJSON ¶
func (r *SessionRecord) UnmarshalJSON(data []byte) error
type Status ¶
type Status string
Status distinguishes records that should keep behaving as live sessions (StatusActive — recoverable on attach) from records the user deliberately retired (StatusClosedByUser).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) MarkSessionClosed ¶
MarkSessionClosed flags the record whose backend session name matches as user-closed and records the agent's exit code. It is what a session host calls when its agent exits — the native replacement for the tmux session-closed hook driving `uam notify-closed`. Idempotent and a no-op when no record matches (e.g. uam already deleted it via `uam rm`).
func (*Store) SetSessionProbe ¶
SetSessionProbe injects a callback that reports whether a backend session name is still live. Migration uses it to tell a reboot-survivor (live -> stays Active) apart from a user-stopped session (dead -> closed-by-user). When unset, migration conservatively keeps the legacy Active behavior (F07).
func (*Store) TryMarkSessionClosed ¶
TryMarkSessionClosed is the compatibility entry point for older callers. It records an explicit UAM stop and returns whether a durable record matched.
func (*Store) TryRecordSessionExit ¶
func (s *Store) TryRecordSessionExit(exit SessionExit) (bool, error)
TryRecordSessionExit records the provider's latest exit while preserving resumability for natural exits. Only an explicit UAM stop/restart retires the record into the closed-by-user group.
type UISettings ¶
type WebProject ¶ added in v0.8.0
type WebProject struct {
ID string `json:"id"`
Name string `json:"name"`
Dir string `json:"dir"`
CreatedAt time.Time `json:"created_at"`
// contains filtered or unexported fields
}
WebProject is a directory the web interface groups Tasks under. There is at most one per Dir.
func (WebProject) MarshalJSON ¶ added in v0.8.0
func (p WebProject) MarshalJSON() ([]byte, error)
func (*WebProject) UnmarshalJSON ¶ added in v0.8.0
func (p *WebProject) UnmarshalJSON(data []byte) error
type WebState ¶ added in v0.8.0
type WebState struct {
// Turn is the last known session state (for example "working" or
// "completed").
Turn string `json:"turn,omitempty"`
// RequestID is the client-generated ID of the last prompt submission.
RequestID string `json:"request_id,omitempty"`
// RequestStatus is that submission's outcome: accepted, rejected or
// uncertain.
RequestStatus string `json:"request_status,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
// Detail is a sanitized, short explanation of the state (usually an error).
Detail string `json:"detail,omitempty"`
// ProjectID is the WebProject the session (a Task) belongs to.
ProjectID string `json:"project_id,omitempty"`
// Model is the selected model ID; empty means the provider default.
Model string `json:"model,omitempty"`
Effort string `json:"effort,omitempty"`
ContextSize string `json:"context_size,omitempty"`
// Title is the provider-generated conversation title, sanitized and
// bounded.
Title string `json:"title,omitempty"`
// Stage is the Task's lifecycle stage: "" (active), "settled" or
// "archived". Records written before stages existed are active.
Stage string `json:"stage,omitempty"`
// SettledAt is when the Task was settled; zero unless it is settled, or
// was settled before it was archived.
SettledAt time.Time `json:"settled_at,omitzero"`
// ArchivedAt is when the Task was archived.
ArchivedAt time.Time `json:"archived_at,omitzero"`
// contains filtered or unexported fields
}
WebState is the small durable part of a web session. Transcripts stay with the provider; only the last known turn state and the last prompt request outcome are kept so a restarted service can report them.