Documentation
¶
Index ¶
- Constants
- Variables
- func AreSessionsEnabled() bool
- func CleanupOrphanedBackpointers(teamContextPath string) (int, error)
- func CreateLedgerMarker(checkoutPath, endpoint, repoID string) error
- func CreateOrUpdateProjectSymlink(projectRoot, rel, targetPath string) error
- func CreateProjectLedgerSymlink(projectRoot, repoID, ep string) error
- func CreateProjectTeamSymlinks(projectRoot, teamID, ep string) error
- func CreateTeamContextMarker(checkoutPath, endpoint, teamID string) error
- func CreateTeamSymlink(repoName, projectRoot, teamID, ep string) error
- func DefaultLedgerPath(repoID, endpointURL string) string
- func DefaultPlanFooterAttribution() string
- func DefaultSageoxSiblingDir(repoName, projectRoot string) string
- func DefaultTeamContextPath(teamID, ep string) string
- func DefaultTeamSymlinkPath(repoName, projectRoot, endpointURL, teamID string) string
- func DiscoverLegacyTeamContexts(projectRoot string) ([]string, error)
- func DiscoverTeamContexts() ([]string, error)
- func FindProjectConfigPath() (string, error)
- func FindProjectRoot() string
- func GetConfiguredEndpoints(projectRoot string) []string
- func GetContextGitAutoCommit() bool
- func GetContextGitAutoPush() bool
- func GetDisplayName() string
- func GetRepoID(projectRoot string) string
- func GetSessionPublishing(projectRoot string) string
- func GetSessionRecording(projectRoot string) string
- func GetUserConfigDir() string
- func IsInitialized(gitRoot string) bool
- func IsInitializedInCwd() bool
- func IsRepoTeamContext(projectRoot, teamID string) bool
- func IsValidSessionPublishingMode(mode string) bool
- func IsValidSessionRecordingMode(mode string) bool
- func LegacyLedgerPath(repoName, projectRoot string) string
- func LegacyTeamContextPath(teamID, projectRoot string) string
- func NormalizeSessionPublishing(mode string) string
- func NormalizeSessionRecording(mode string) string
- func RegisterWorkspace(teamContextPath, workspaceID, projectPath string) error
- func RemoveTeamSymlink(repoName, projectRoot, teamID, ep string) error
- func ResolveProjectRootOverride() string
- func SanitizeDisplayName(name string) string
- func SaveBackpointers(teamContextPath string, backpointers []WorkspaceBackpointer) error
- func SaveCheckoutMarker(checkoutPath string, marker *CheckoutMarker) error
- func SaveHealth(projectRoot string, h *Health) error
- func SaveLocalConfig(projectRoot string, cfg *LocalConfig) error
- func SaveProjectConfig(gitRoot string, cfg *ProjectConfig) error
- func SaveTeamConfig(teamContextPath string, cfg *TeamConfig) error
- func SaveUserConfig(cfg *UserConfig) error
- func SetContextGitAutoCommit(value bool) error
- func SetContextGitAutoPush(value bool) error
- func SetDisplayName(name string) error
- func SetSessionsEnabled(value bool) error
- func SiblingLedgerPath(repoName, projectRoot, endpointURL string) string
- func StringPtr(s string) *string
- func UpdateTeamSymlink(repoName, projectRoot, teamID, oldEndpoint, newEndpoint string) error
- func UpdateWorkspaceActivity(teamContextPath, workspaceID string) error
- func ValidateDisplayName(name string) error
- func ValidateLedgerMarker(checkoutPath, currentEndpoint, currentRepoID string) error
- func ValidateProjectConfig(cfg *ProjectConfig) []string
- func ValidateTeamContextMarker(checkoutPath, currentEndpoint string) error
- type Attribution
- func (a *Attribution) GetCommit() string
- func (a *Attribution) GetPR() string
- func (a *Attribution) GetPlan() string
- func (a *Attribution) GetSession() string
- func (a *Attribution) IsCommitSet() bool
- func (a *Attribution) IsPRSet() bool
- func (a *Attribution) IsPlanSet() bool
- func (a *Attribution) IsSessionSet() bool
- type BadgeConfig
- type CheckoutMarker
- type CheckoutMarkerMismatch
- type Config
- type ContextGitConfig
- type Health
- func (h *Health) DoctorFixHintMessage() string
- func (h *Health) DoctorFixStaleness() time.Duration
- func (h *Health) DoctorHintMessage() string
- func (h *Health) DoctorStaleness() time.Duration
- func (h *Health) RecordDoctorFixRun()
- func (h *Health) RecordDoctorRun()
- func (h *Health) ShouldHintDoctor() bool
- func (h *Health) ShouldHintDoctorFix() bool
- type LedgerConfig
- type LocalConfig
- func (c *LocalConfig) GetLedgerPath(repoID, endpointURL string) string
- func (c *LocalConfig) GetTeamContext(teamID string) *TeamContext
- func (c *LocalConfig) GetTeamContextPath(teamID, ep string) string
- func (c *LocalConfig) RemoveTeamContext(teamID string)
- func (c *LocalConfig) SetLedgerPath(path string)
- func (c *LocalConfig) SetTeamContext(teamID, teamName, path string)
- func (c *LocalConfig) UpdateLedgerLastSync()
- func (c *LocalConfig) UpdateTeamContextLastSync(teamID string)
- type ProjectConfig
- type ProjectContext
- func (p *ProjectContext) Config() *ProjectConfig
- func (p *ProjectContext) DefaultLedgerPath() string
- func (p *ProjectContext) Endpoint() string
- func (p *ProjectContext) LedgerDir(repoID string) string
- func (p *ProjectContext) LocalConfig() *LocalConfig
- func (p *ProjectContext) RepoID() string
- func (p *ProjectContext) RepoName() string
- func (p *ProjectContext) Root() string
- func (p *ProjectContext) SiblingDir() string
- func (p *ProjectContext) SiblingLedgerPath() string
- func (p *ProjectContext) TeamContextDir(teamID string) string
- func (p *ProjectContext) TeamsDataDir() string
- type ResolvedAttribution
- type ResolvedSessionPublishing
- type ResolvedSessionRecording
- type SessionRecordingSource
- type SessionsConfig
- type TeamConfig
- type TeamContext
- type TeamContextHealth
- type UserConfig
- func (c *UserConfig) AreSessionsEnabled() bool
- func (c *UserConfig) AreTipsEnabled() bool
- func (c *UserConfig) GetContextGitAutoCommit() bool
- func (c *UserConfig) GetContextGitAutoPush() bool
- func (c *UserConfig) GetDisplayName() string
- func (c *UserConfig) GetViewFormat() string
- func (c *UserConfig) HasSeenSessionTerms() bool
- func (c *UserConfig) IsTelemetryEnabled() bool
- func (c *UserConfig) SetContextGitAutoCommit(enabled bool)
- func (c *UserConfig) SetContextGitAutoPush(enabled bool)
- func (c *UserConfig) SetDisplayName(name string)
- func (c *UserConfig) SetSessionTermsShown(shown bool)
- func (c *UserConfig) SetSessionsEnabled(enabled bool)
- func (c *UserConfig) SetTelemetryEnabled(enabled bool)
- type Validator
- func (v *Validator) ValidateAPIEndpoint(endpoint string) error
- func (v *Validator) ValidateAttribution(attr *Attribution) []error
- func (v *Validator) ValidateConfigVersion(version string) error
- func (v *Validator) ValidateID(id, prefix string) error
- func (v *Validator) ValidateOrgSlug(slug string) error
- func (v *Validator) ValidateProjectConfig(cfg *ProjectConfig) []error
- func (v *Validator) ValidateProjectID(id string) error
- func (v *Validator) ValidateProjectSlug(slug string) error
- func (v *Validator) ValidateRemoteHash(hash string) error
- func (v *Validator) ValidateRepoID(id string) error
- func (v *Validator) ValidateTeamID(id string) error
- func (v *Validator) ValidateTeamSlug(slug string) error
- func (v *Validator) ValidateTimestamp(ts string) error
- func (v *Validator) ValidateUpdateFrequency(hours int) error
- func (v *Validator) ValidateUserConfig(cfg *UserConfig) []error
- func (v *Validator) ValidateWorkspaceID(id string) error
- type WorkspaceBackpointer
Constants ¶
const ( // EnvProjectRoot overrides project root discovery (walk-up from cwd). // Consumed by: ResolveProjectRootOverride() EnvProjectRoot = "OX_PROJECT_ROOT" // EnvSessionRecording overrides the session recording mode. // Consumed by: ResolveSessionRecording() EnvSessionRecording = "OX_SESSION_RECORDING" // EnvUserConfig overrides the user config file path. // Consumed by: LoadUserConfig() EnvUserConfig = "OX_USER_CONFIG" )
Environment variable names for configuration overrides. Each variable is consumed in exactly one resolver function.
const ( StalenessWeek = 7 * 24 * time.Hour StalenessWeek2 = 14 * 24 * time.Hour StalenessWeek3 = 21 * 24 * time.Hour StalenessMonth = 30 * 24 * time.Hour // hint probabilities per staleness tier ProbabilityNone = 0.0 // < 1 week: no hints ProbabilityWeek1 = 0.10 // 1 week: 10% ProbabilityWeek2 = 0.30 // 2 weeks: 30% ProbabilityWeek3 = 0.50 // 3 weeks: 50% ProbabilityMonth = 0.80 // 1 month+: 80% )
Staleness thresholds and corresponding hint probabilities. Progressive nudging increases as time since last doctor run grows.
const ( SessionRecordingDisabled = "disabled" // no recording SessionRecordingManual = "manual" // explicit start required SessionRecordingAuto = "auto" // automatic recording )
SessionRecording constants: disabled -> manual -> auto
const ( SessionPublishingAuto = "auto" // upload to ledger on session stop (default) SessionPublishingManual = "manual" // save locally, user uploads explicitly )
SessionPublishing constants
const CurrentConfigVersion = "2"
CurrentConfigVersion is the latest config version supported by this ox binary Increment this when making breaking changes to .sageox config structure
const MaxDisplayNameLength = 40
MaxDisplayNameLength is the maximum allowed length (in runes) for a display name. Generous for real names/handles, constraining enough to prevent CLI layout breakage.
Variables ¶
var ValidSessionPublishingModes = []string{SessionPublishingAuto, SessionPublishingManual}
ValidSessionPublishingModes lists all valid session publishing mode values.
var ValidSessionRecordingModes = []string{SessionRecordingDisabled, SessionRecordingManual, SessionRecordingAuto}
ValidSessionRecordingModes lists all valid session recording mode values.
Functions ¶
func AreSessionsEnabled ¶
func AreSessionsEnabled() bool
AreSessionsEnabled loads user config and returns the sessions.enabled setting. This is a convenience function for use without loading the full config. Default: false
func CleanupOrphanedBackpointers ¶
CleanupOrphanedBackpointers removes backpointers for workspaces that no longer exist.
func CreateLedgerMarker ¶
CreateLedgerMarker creates a checkout marker for a ledger repository.
func CreateOrUpdateProjectSymlink ¶ added in v0.2.0
CreateOrUpdateProjectSymlink creates or updates a symlink inside the project root. The rel path is relative to projectRoot (e.g. ".sageox/ledger"). If the symlink already points to targetPath, this is a no-op.
func CreateProjectLedgerSymlink ¶ added in v0.2.0
CreateProjectLedgerSymlink creates .sageox/ledger -> user-dir ledger path.
func CreateProjectTeamSymlinks ¶ added in v0.2.0
CreateProjectTeamSymlinks creates .sageox/teams/<team_id> and .sageox/teams/primary.
Today we only support a single team per repo, but that is not a hard requirement. The "primary" symlink always points to the repo's team for convenient access.
func CreateTeamContextMarker ¶
CreateTeamContextMarker creates a checkout marker for a team context repository.
func CreateTeamSymlink ¶
CreateTeamSymlink creates a symlink from repo_sageox/<endpoint>/teams/<team_id> to the XDG team context directory (~/.sageox/data/<endpoint>/teams/<team_id>).
The symlink allows agents and tools working within the repository to access team context data through a path relative to the project, while the actual data lives in the centralized XDG location.
Returns nil on Windows (symlinks require Developer Mode). Returns error if symlink creation fails.
func DefaultLedgerPath ¶
DefaultLedgerPath returns the CANONICAL path for the ledger git checkout. Ledgers are stored in the user directory, shared across all worktrees of a repo.
Format: ~/.local/share/sageox/<endpoint_slug>/ledgers/<repo_id>/
IMPORTANT: This is the ONLY function that should determine the ledger checkout location. NEVER construct ledger paths manually. Changes to path locations require Ryan's review.
func DefaultPlanFooterAttribution ¶
func DefaultPlanFooterAttribution() string
DefaultPlanFooterAttribution returns the canonical plan footer text. This is always-on (not config-gated) as a transparency requirement.
func DefaultSageoxSiblingDir ¶
DefaultSageoxSiblingDir returns the CANONICAL base sageox sibling directory for a project. This is a sibling directory to the project root that contains endpoint-namespaced ledger repos and team symlinks.
Format: <project_parent>/<repo_name>_sageox
Example: /path/to/myrepo -> /path/to/myrepo_sageox
IMPORTANT: This is the ONLY function that should determine the sibling directory location. NEVER construct sibling paths manually. Changes to path locations require Ryan's review.
func DefaultTeamContextPath ¶
DefaultTeamContextPath returns the default path for a team context repo.
For production endpoints (api.sageox.ai, app.sageox.ai, www.sageox.ai, sageox.ai):
~/.sageox/data/teams/<team_id>/
For non-production endpoints:
~/.sageox/data/<endpoint>/teams/<team_id>/
This centralized location allows all projects to share team contexts and enables daemons to discover team contexts at a known location.
Legacy format (for migration): <project_parent>/sageox_team_<team_id>_context Use LegacyTeamContextPath() to check for existing sibling-directory team contexts.
The projectRoot parameter is ignored in the new format but kept for API compatibility. The endpoint parameter determines the namespace; empty uses the current endpoint.
func DefaultTeamSymlinkPath ¶
DefaultTeamSymlinkPath returns the path where team context symlinks should be created. This is inside the sageox sibling directory, namespaced by endpoint.
Format: <project_parent>/<repo_name>_sageox/<endpoint_slug>/teams/<team_id>
Example: /path/to/myrepo with endpoint sageox.ai and team abc123 -> /path/to/myrepo_sageox/sageox.ai/teams/abc123
func DiscoverLegacyTeamContexts ¶
DiscoverLegacyTeamContexts finds team contexts in the old sibling directory format. Searches parent directories for sageox_team_*_context directories.
func DiscoverTeamContexts ¶
DiscoverTeamContexts finds all team context directories across all endpoints. Scans ~/.sageox/data/<endpoint>/teams/ for each endpoint directory.
func FindProjectConfigPath ¶
FindProjectConfigPath walks up from the current working directory looking for .sageox/config.json Returns the path to the config file if found, empty string if not found Stops at filesystem root
func FindProjectRoot ¶
func FindProjectRoot() string
FindProjectRoot walks up from the current working directory looking for .sageox directory. Returns the project root if found, empty string if not found. This is useful for finding the project root without requiring a config file to exist.
OX_PROJECT_ROOT env var overrides discovery when set to a valid initialized project.
func GetConfiguredEndpoints ¶
GetConfiguredEndpoints returns all unique endpoints configured for a project. Collects from: project config only (local config no longer has endpoint fields). Returns empty slice if no endpoints are configured.
func GetContextGitAutoCommit ¶
func GetContextGitAutoCommit() bool
GetContextGitAutoCommit loads user config and returns the auto-commit setting. This is a convenience function for use without loading the full config. Default: true
func GetContextGitAutoPush ¶
func GetContextGitAutoPush() bool
GetContextGitAutoPush loads user config and returns the auto-push setting. This is a convenience function for use without loading the full config. Default: false
func GetDisplayName ¶
func GetDisplayName() string
GetDisplayName loads user config and returns the display_name setting. Returns "" if not set.
func GetRepoID ¶
GetRepoID returns the repo ID for the given project root. Returns empty string if the config doesn't exist or has no repo ID. The repo ID is a prefixed UUIDv7 (repo_01jfk3mab...) used for identifying the repo in context storage and API calls.
func GetSessionPublishing ¶ added in v0.3.0
GetSessionPublishing is a convenience function that returns just the publishing mode string.
func GetSessionRecording ¶
GetSessionRecording is a convenience function that returns just the mode string.
func GetUserConfigDir ¶
func GetUserConfigDir() string
GetUserConfigDir returns the user config directory path.
Path Resolution (via internal/paths package):
Default: ~/.sageox/config/ With OX_XDG_ENABLE: $XDG_CONFIG_HOME/sageox/ (default: ~/.config/sageox/)
The consolidated ~/.sageox/ structure provides a single discoverable location for all SageOx data. Users who prefer XDG standard locations can set OX_XDG_ENABLE=1 to use traditional XDG paths.
See internal/paths/doc.go for architecture rationale.
func IsInitialized ¶
IsInitialized checks if SageOx is initialized in the given git root directory. Returns true if .sageox/config.json exists (the canonical file created by ox init).
func IsInitializedInCwd ¶
func IsInitializedInCwd() bool
IsInitializedInCwd checks if SageOx is initialized by walking up from current directory. Returns true if .sageox/config.json is found in current dir or any parent.
func IsRepoTeamContext ¶ added in v0.2.0
IsRepoTeamContext returns true if the given team ID matches the repo's owning team.
func IsValidSessionPublishingMode ¶ added in v0.3.0
IsValidSessionPublishingMode returns true if the mode is a recognized value.
func IsValidSessionRecordingMode ¶
IsValidSessionRecordingMode returns true if the mode is a recognized value.
func LegacyLedgerPath ¶
LegacyLedgerPath returns the old sibling-directory path for the ledger repo. This is used for migration detection and backward compatibility.
Format: <project_parent>/<repo_name>_sageox_ledger
func LegacyTeamContextPath ¶
LegacyTeamContextPath returns the old sibling-directory path for a team context. This is used for migration detection and backward compatibility. Format: <project_parent>/sageox_team_<team_id>_context
func NormalizeSessionPublishing ¶ added in v0.3.0
NormalizeSessionPublishing normalizes session_publishing values. Returns "auto" for unrecognized or empty values (backward compatible default).
func NormalizeSessionRecording ¶
NormalizeSessionRecording normalizes session_recording values. Returns default (manual) for unrecognized values. Maps legacy "none" to "disabled" for backwards compatibility.
func RegisterWorkspace ¶
RegisterWorkspace adds or updates a workspace backpointer in a team context. This should be called when a daemon starts watching a project that uses this team context.
func RemoveTeamSymlink ¶
RemoveTeamSymlink removes the team symlink from the sibling directory. This only removes the symlink, not the actual team context data.
Returns nil on Windows. Returns nil if the symlink doesn't exist. Returns error if removal fails.
func ResolveProjectRootOverride ¶ added in v0.3.0
func ResolveProjectRootOverride() string
ResolveProjectRootOverride checks OX_PROJECT_ROOT env var for an explicit project root override. Returns the resolved path if valid, empty string otherwise. This is the single source of truth for the env var — all callers should use this.
func SanitizeDisplayName ¶
SanitizeDisplayName cleans a display name for safe storage and rendering. Replaces control characters with spaces (preserving word boundaries), trims whitespace, and collapses internal whitespace runs. Returns "" for whitespace-only input.
func SaveBackpointers ¶
func SaveBackpointers(teamContextPath string, backpointers []WorkspaceBackpointer) error
SaveBackpointers writes workspace backpointers to a team context.
func SaveCheckoutMarker ¶
func SaveCheckoutMarker(checkoutPath string, marker *CheckoutMarker) error
SaveCheckoutMarker writes the checkout marker to a ledger/team context directory. Creates the .sageox directory if it doesn't exist.
func SaveHealth ¶
SaveHealth saves health data to .sageox/cache/health.json.
func SaveLocalConfig ¶
func SaveLocalConfig(projectRoot string, cfg *LocalConfig) error
SaveLocalConfig saves the local configuration to .sageox/config.local.toml relative to projectRoot. Creates the .sageox directory if it does not exist.
func SaveProjectConfig ¶
func SaveProjectConfig(gitRoot string, cfg *ProjectConfig) error
SaveProjectConfig saves the project configuration to .sageox/config.json relative to gitRoot
func SaveTeamConfig ¶
func SaveTeamConfig(teamContextPath string, cfg *TeamConfig) error
SaveTeamConfig saves team configuration to <teamContextPath>/config.toml.
func SaveUserConfig ¶
func SaveUserConfig(cfg *UserConfig) error
SaveUserConfig saves user configuration to the config directory. Uses atomic write (temp file + rename) to prevent corruption from concurrent writes or crashes mid-write.
func SetContextGitAutoCommit ¶
SetContextGitAutoCommit loads user config, sets auto-commit, and saves. This is a convenience function for setting a single value.
func SetContextGitAutoPush ¶
SetContextGitAutoPush loads user config, sets auto-push, and saves. This is a convenience function for setting a single value.
func SetDisplayName ¶
SetDisplayName loads user config, validates, sets display_name, and saves. Returns an error if the name exceeds MaxDisplayNameLength after sanitization.
func SetSessionsEnabled ¶
SetSessionsEnabled loads user config, sets sessions.enabled, and saves. This is a convenience function for setting a single value.
func SiblingLedgerPath ¶ added in v0.2.0
SiblingLedgerPath returns the DEPRECATED sibling-directory path for the ledger repo. This is used for migration detection when upgrading from the sibling to user-directory layout.
Format: <project_parent>/<repo_name>_sageox/<endpoint_slug>/ledger
func UpdateTeamSymlink ¶
UpdateTeamSymlink updates an existing team symlink to point to a new target. This is useful when the endpoint changes and the symlink target needs updating.
Returns nil on Windows. Returns error if the symlink doesn't exist or update fails.
func UpdateWorkspaceActivity ¶
UpdateWorkspaceActivity updates the last active time for a workspace. Call this periodically while a daemon is active.
func ValidateDisplayName ¶
ValidateDisplayName checks a display name after sanitization. Returns an error if the sanitized name exceeds MaxDisplayNameLength. Empty string is valid (means "use auto-derivation").
func ValidateLedgerMarker ¶
ValidateLedgerMarker checks if the ledger checkout matches the current endpoint and repo. Returns nil if OK, CheckoutMarkerMismatch if mismatched.
func ValidateProjectConfig ¶
func ValidateProjectConfig(cfg *ProjectConfig) []string
ValidateProjectConfig validates the project configuration and returns a list of validation errors
func ValidateTeamContextMarker ¶
ValidateTeamContextMarker checks if the team context checkout matches the current endpoint. Returns nil if OK, CheckoutMarkerMismatch if mismatched.
Types ¶
type Attribution ¶
type Attribution struct {
Plan *string `yaml:"plan,omitempty" json:"plan,omitempty"`
Commit *string `yaml:"commit,omitempty" json:"commit,omitempty"`
PR *string `yaml:"pr,omitempty" json:"pr,omitempty"`
Session *string `yaml:"session,omitempty" json:"session,omitempty"` // session URL trailer; nil=auto, ""=disabled
}
Attribution configures how ox-guided work is credited in plans, git commits, and PRs. Use pointer fields to distinguish between "not set" (nil) and "explicitly disabled" ("").
func DefaultAttribution ¶
func DefaultAttribution() Attribution
DefaultAttribution returns the default attribution settings. These are used when no user or project config overrides are set.
func (*Attribution) GetCommit ¶
func (a *Attribution) GetCommit() string
GetCommit returns the commit attribution value, or empty string if nil
func (*Attribution) GetPR ¶
func (a *Attribution) GetPR() string
GetPR returns the PR attribution value, or empty string if nil
func (*Attribution) GetPlan ¶
func (a *Attribution) GetPlan() string
GetPlan returns the plan attribution value, or empty string if nil
func (*Attribution) GetSession ¶ added in v0.3.0
func (a *Attribution) GetSession() string
GetSession returns the session attribution value, or empty string if nil
func (*Attribution) IsCommitSet ¶
func (a *Attribution) IsCommitSet() bool
IsCommitSet returns true if commit attribution is explicitly set (including to empty string)
func (*Attribution) IsPRSet ¶
func (a *Attribution) IsPRSet() bool
IsPRSet returns true if PR attribution is explicitly set (including to empty string)
func (*Attribution) IsPlanSet ¶
func (a *Attribution) IsPlanSet() bool
IsPlanSet returns true if plan attribution is explicitly set (including to empty string)
func (*Attribution) IsSessionSet ¶ added in v0.3.0
func (a *Attribution) IsSessionSet() bool
IsSessionSet returns true if session attribution is explicitly set (including to empty string)
type BadgeConfig ¶
type BadgeConfig struct {
// SuggestionStatus tracks user response: "not_asked", "added", "declined"
SuggestionStatus string `yaml:"suggestion_status,omitempty"`
// LastDeclined timestamp if user chose "never" - we respect this permanently
LastDeclined *string `yaml:"last_declined,omitempty"`
}
BadgeConfig tracks badge suggestion state across all projects.
type CheckoutMarker ¶
type CheckoutMarker struct {
// Type is "ledger" or "team-context"
Type string `json:"type"`
// Endpoint is the SageOx API endpoint this checkout is associated with
Endpoint string `json:"endpoint"`
// RepoID is the main repo's ID (from .repo_<id>) that this ledger belongs to.
// Only set for ledger type, empty for team-context.
RepoID string `json:"repo_id,omitempty"`
// TeamID is the team ID for team-context checkouts.
// Only set for team-context type, empty for ledger.
TeamID string `json:"team_id,omitempty"`
// CheckedOutAt is when the checkout was created
CheckedOutAt time.Time `json:"checked_out_at"`
// CheckedOutBy is the user who created the checkout (optional)
CheckedOutBy string `json:"checked_out_by,omitempty"`
}
CheckoutMarker tracks metadata about a ledger or team context checkout. This file lives in <checkout-path>/.sageox/checkout.json and is gitignored.
func LoadCheckoutMarker ¶
func LoadCheckoutMarker(checkoutPath string) (*CheckoutMarker, error)
LoadCheckoutMarker reads the checkout marker from a ledger/team context directory. Returns nil, nil if the marker doesn't exist.
type CheckoutMarkerMismatch ¶
type CheckoutMarkerMismatch struct {
CheckoutPath string
MarkerType string
MarkerEndpoint string
MarkerRepoID string // for ledger
CurrentEndpoint string
CurrentRepoID string // for ledger
}
CheckoutMarkerMismatch indicates a checkout is for a different endpoint or repo.
func (CheckoutMarkerMismatch) Error ¶
func (e CheckoutMarkerMismatch) Error() string
type Config ¶
type ContextGitConfig ¶
type ContextGitConfig struct {
// AutoCommit controls whether to commit on session stop / session end.
// Default: true
AutoCommit *bool `yaml:"auto_commit,omitempty"`
// AutoPush controls whether to push after commit.
// Default: false
AutoPush *bool `yaml:"auto_push,omitempty"`
}
ContextGitConfig holds settings for context git repo operations. These control automatic commit/push behavior during session operations.
func (*ContextGitConfig) IsAutoCommitEnabled ¶
func (c *ContextGitConfig) IsAutoCommitEnabled() bool
IsAutoCommitEnabled returns true if auto-commit is enabled (default: true)
func (*ContextGitConfig) IsAutoPushEnabled ¶
func (c *ContextGitConfig) IsAutoPushEnabled() bool
IsAutoPushEnabled returns true if auto-push is enabled (default: false)
type Health ¶
type Health struct {
LastDoctorAt time.Time `json:"last_doctor_at"`
LastDoctorFixAt time.Time `json:"last_doctor_fix_at"`
}
Health tracks diagnostic command execution times. Stored in .sageox/cache/health.json (machine-specific, not committed). Note: omitempty is not used on time.Time fields because encoding/json does not treat zero time as empty for nested structs.
func LoadHealth ¶
LoadHealth loads health data from .sageox/cache/health.json. Returns empty Health if file doesn't exist.
func (*Health) DoctorFixHintMessage ¶
DoctorFixHintMessage returns appropriate hint message based on staleness.
func (*Health) DoctorFixStaleness ¶
DoctorFixStaleness returns duration since last doctor --fix run. Returns max duration if never run.
func (*Health) DoctorHintMessage ¶
DoctorHintMessage returns appropriate hint message based on staleness.
func (*Health) DoctorStaleness ¶
DoctorStaleness returns duration since last doctor run. Returns max duration if never run.
func (*Health) RecordDoctorFixRun ¶
func (h *Health) RecordDoctorFixRun()
RecordDoctorFixRun updates LastDoctorFixAt timestamp.
func (*Health) RecordDoctorRun ¶
func (h *Health) RecordDoctorRun()
RecordDoctorRun updates LastDoctorAt timestamp.
func (*Health) ShouldHintDoctor ¶
ShouldHintDoctor returns true if a doctor hint should be shown. Uses probabilistic display based on staleness.
func (*Health) ShouldHintDoctorFix ¶
ShouldHintDoctorFix returns true if a doctor --fix hint should be shown. Uses probabilistic display based on staleness.
type LedgerConfig ¶
LedgerConfig holds configuration for the local ledger git repo. Note: omitempty is intentionally not used on LastSync because go-toml v2 does not serialize time.Time fields with omitempty correctly.
func (*LedgerConfig) HasLastSync ¶
func (c *LedgerConfig) HasLastSync() bool
HasLastSync returns true if LastSync has been set (is non-zero).
type LocalConfig ¶
type LocalConfig struct {
Ledger *LedgerConfig `toml:"ledger,omitempty"`
TeamContexts []TeamContext `toml:"team_contexts,omitempty"`
}
LocalConfig represents machine-specific config stored in .sageox/config.local.toml. This file tracks local paths for git repos (ledger and team-context) and is NOT committed to version control.
ARCHITECTURE DECISION: Why config.local.toml stores [[team_contexts]]
Team membership is inherently user-level data, but we store it per-repo because:
- Each workspace runs its own daemon. Per-repo config means each daemon writes to its own file with no locking or coordination needed.
- Different repos can point to different endpoints (e.g., sageox.ai vs self-hosted). Per-repo config naturally scopes team contexts to the correct endpoint.
- A user-level file (~/) would require file locking across concurrent daemons, or namespace partitioning by endpoint — complexity that per-repo config avoids.
The daemon discovers all team contexts the user can access (via GET /api/v1/cli/repos) and records them here. This includes cross-team contexts (teams the user belongs to beyond the repo's own team). For the repo's own team, FindRepoTeamContext() has a fallback that computes the path from config.json's team_id without requiring this file.
FUTURE: Consider replacing this with a user-level file if we move to a single global daemon, which would eliminate the multi-writer locking problem.
func LoadLocalConfig ¶
func LoadLocalConfig(projectRoot string) (*LocalConfig, error)
LoadLocalConfig loads the local configuration from .sageox/config.local.toml relative to projectRoot. Returns an empty config if the file does not exist.
func (*LocalConfig) GetLedgerPath ¶
func (c *LocalConfig) GetLedgerPath(repoID, endpointURL string) string
GetLedgerPath returns the configured ledger path, or the default if not configured.
func (*LocalConfig) GetTeamContext ¶
func (c *LocalConfig) GetTeamContext(teamID string) *TeamContext
GetTeamContext returns the team context config for the given team ID, or nil if not found.
func (*LocalConfig) GetTeamContextPath ¶
func (c *LocalConfig) GetTeamContextPath(teamID, ep string) string
GetTeamContextPath returns the configured team context path, or the default if not configured. The endpoint parameter is used for the default path when no explicit path is configured.
func (*LocalConfig) RemoveTeamContext ¶
func (c *LocalConfig) RemoveTeamContext(teamID string)
RemoveTeamContext removes a team context configuration by team ID.
func (*LocalConfig) SetLedgerPath ¶
func (c *LocalConfig) SetLedgerPath(path string)
SetLedgerPath sets the ledger path in the config.
func (*LocalConfig) SetTeamContext ¶
func (c *LocalConfig) SetTeamContext(teamID, teamName, path string)
SetTeamContext adds or updates a team context configuration.
func (*LocalConfig) UpdateLedgerLastSync ¶
func (c *LocalConfig) UpdateLedgerLastSync()
UpdateLedgerLastSync updates the last sync time for the ledger. No-ops if Ledger is nil (consistent with UpdateTeamContextLastSync behavior).
func (*LocalConfig) UpdateTeamContextLastSync ¶
func (c *LocalConfig) UpdateTeamContextLastSync(teamID string)
UpdateTeamContextLastSync updates the last sync time for a team context.
type ProjectConfig ¶
type ProjectConfig struct {
ConfigVersion string `json:"config_version,omitempty"` // tracks .sageox config version
Org string `json:"org,omitempty"`
Team string `json:"team,omitempty"`
Project string `json:"project,omitempty"`
ProjectID string `json:"project_id,omitempty"` // API project ID (prj_xxx)
WorkspaceID string `json:"workspace_id,omitempty"` // API workspace ID (ws_xxx)
RepoID string `json:"repo_id,omitempty"` // prefixed UUIDv7 (repo_01jfk3mab...)
RepoRemoteHashes []string `json:"repo_remote_hashes,omitempty"` // salted SHA256 hashes of remote URLs
TeamID string `json:"team_id,omitempty"` // team ID from server response
TeamName string `json:"team_name,omitempty"` // team display name from server response
Endpoint string `json:"endpoint,omitempty"` // SageOx endpoint URL (matches SAGEOX_ENDPOINT env var)
// Legacy fields - kept for backward compatibility with old config files
// TODO: Remove after 2026-01-31 - legacy field support
APIBaseURL string `json:"api_base_url,omitempty"` // deprecated: use Endpoint
WebBaseURL string `json:"web_base_url,omitempty"` // deprecated: use Endpoint
UpdateFrequencyHours int `json:"update_frequency_hours"`
LastUpdateCheckUTC *string `json:"last_update_check_utc,omitempty"`
Attribution *Attribution `json:"attribution,omitempty"`
OfflineSnapshotStaleDays int `json:"offline_snapshot_stale_days,omitempty"` // days until offline snapshot is considered stale (default: 7)
// BadgeStatus tracks badge state for this specific project.
// Values: "" (not asked), "added", "declined"
// This enables per-project tracking of user's badge preference.
BadgeStatus string `json:"badge_status,omitempty"`
// SessionRecording controls automatic session recording behavior.
// Values: "disabled" (no recording), "auto" (automatic recording), "manual" (explicit start required)
// Empty string defaults to "auto".
SessionRecording string `json:"session_recording,omitempty"`
// SessionPublishing controls what happens when a session stops.
// Values: "auto" (upload to ledger on stop), "manual" (save locally, user uploads explicitly)
// Empty string defaults to "auto" for backward compatibility.
SessionPublishing string `json:"session_publishing,omitempty"`
}
ProjectConfig represents the per-repository configuration stored in .sageox/config.json
func GetDefaultProjectConfig ¶
func GetDefaultProjectConfig() *ProjectConfig
GetDefaultProjectConfig returns a ProjectConfig with default values
func GetProjectContext ¶
func GetProjectContext() (*ProjectConfig, string, error)
GetProjectContext is a convenience function that finds and loads the project config Returns (config, configPath, error) If config is not found, returns (nil, "", nil) - not an error
func LoadProjectConfig ¶
func LoadProjectConfig(gitRoot string) (*ProjectConfig, error)
LoadProjectConfig loads the project configuration from .sageox/config.json relative to gitRoot
func (*ProjectConfig) GetEndpoint ¶
func (c *ProjectConfig) GetEndpoint() string
GetEndpoint returns the SageOx endpoint URL. Priority: config.Endpoint > endpoint.Get() (from SAGEOX_ENDPOINT env or default)
func (*ProjectConfig) GetOfflineSnapshotStaleThreshold ¶
func (c *ProjectConfig) GetOfflineSnapshotStaleThreshold() time.Duration
GetOfflineSnapshotStaleThreshold returns the offline snapshot staleness threshold as a duration
func (*ProjectConfig) GitCredentials ¶
func (c *ProjectConfig) GitCredentials() (*gitserver.GitCredentials, error)
GitCredentials returns the git credentials scoped to this project's endpoint.
func (*ProjectConfig) NeedsUpgrade ¶
func (c *ProjectConfig) NeedsUpgrade() bool
NeedsUpgrade returns true if the config version is older than CurrentConfigVersion
func (*ProjectConfig) SetCurrentVersion ¶
func (c *ProjectConfig) SetCurrentVersion()
SetCurrentVersion sets the config version to the current version
type ProjectContext ¶
type ProjectContext struct {
// contains filtered or unexported fields
}
ProjectContext provides project configuration with guaranteed endpoint consistency. The endpoint is ALWAYS derived from ProjectConfig - never stored elsewhere.
Use LoadProjectContext() to create a ProjectContext for a project root, then access configuration and paths through the accessor methods.
func LoadProjectContext ¶
func LoadProjectContext(projectRoot string) (*ProjectContext, error)
LoadProjectContext creates a ProjectContext for the given project root. Validates the root path and loads both project and local configurations.
Returns error if projectRoot is empty or configuration loading fails.
func (*ProjectContext) Config ¶
func (p *ProjectContext) Config() *ProjectConfig
Config returns the project config.
func (*ProjectContext) DefaultLedgerPath ¶
func (p *ProjectContext) DefaultLedgerPath() string
DefaultLedgerPath returns the default ledger path for this project. Uses the project's endpoint and repo ID for path resolution. Format: ~/.local/share/sageox/<endpoint_slug>/ledgers/<repo_id>/
func (*ProjectContext) Endpoint ¶
func (p *ProjectContext) Endpoint() string
Endpoint returns the project's endpoint (single source of truth). Calls config.GetEndpoint() if config exists, otherwise returns empty string.
func (*ProjectContext) LedgerDir ¶
func (p *ProjectContext) LedgerDir(repoID string) string
LedgerDir returns the path to the ledger directory for a repository. Uses the project's endpoint for path resolution.
func (*ProjectContext) LocalConfig ¶
func (p *ProjectContext) LocalConfig() *LocalConfig
LocalConfig returns the local config (machine-specific).
func (*ProjectContext) RepoID ¶
func (p *ProjectContext) RepoID() string
RepoID returns the repo ID from project config. Returns empty string if config doesn't exist or has no repo ID.
func (*ProjectContext) RepoName ¶
func (p *ProjectContext) RepoName() string
RepoName returns the base name of the project root directory.
func (*ProjectContext) Root ¶
func (p *ProjectContext) Root() string
Root returns the project root path.
func (*ProjectContext) SiblingDir ¶
func (p *ProjectContext) SiblingDir() string
SiblingDir returns the sageox sibling directory for this project. Format: <project_parent>/<repo_name>_sageox
func (*ProjectContext) SiblingLedgerPath ¶ added in v0.2.0
func (p *ProjectContext) SiblingLedgerPath() string
SiblingLedgerPath returns the deprecated sibling-directory ledger path. Used for migration detection only.
func (*ProjectContext) TeamContextDir ¶
func (p *ProjectContext) TeamContextDir(teamID string) string
TeamContextDir returns the path to a team context directory. Uses the project's endpoint for path resolution.
func (*ProjectContext) TeamsDataDir ¶
func (p *ProjectContext) TeamsDataDir() string
TeamsDataDir returns the base directory for all team contexts. Uses the project's endpoint for path resolution.
type ResolvedAttribution ¶
type ResolvedAttribution struct {
Plan string `json:"plan"`
Commit string `json:"commit"`
PR string `json:"pr"`
Session string `json:"session"` // "auto" = append when recording, "" = disabled
}
ResolvedAttribution holds the final resolved attribution values (non-pointer). Use this after merging configs for easier consumption.
func MergeAttribution ¶
func MergeAttribution(project, user *Attribution) ResolvedAttribution
MergeAttribution merges project and user attribution with project taking precedence. Returns resolved values with defaults applied where not overridden.
Precedence (highest to lowest):
- Project config (repo-specific)
- User config (user preferences)
- Default values
Setting a field to empty string ("") explicitly disables that attribution type. Leaving a field unset (nil) means "use lower priority config or default".
type ResolvedSessionPublishing ¶ added in v0.3.0
type ResolvedSessionPublishing struct {
Mode string // effective mode: "auto" or "manual"
Source SessionRecordingSource // where the setting came from (reuses same source type)
}
ResolvedSessionPublishing contains the effective publishing mode and its source.
func ResolveSessionPublishing ¶ added in v0.3.0
func ResolveSessionPublishing(projectRoot string) *ResolvedSessionPublishing
ResolveSessionPublishing determines the effective session publishing mode. Priority: project config > "auto" (default)
"auto" uploads to ledger on session stop (backward compatible default). "manual" saves locally without uploading.
type ResolvedSessionRecording ¶
type ResolvedSessionRecording struct {
Mode string // effective mode: "disabled", "manual", or "auto"
Source SessionRecordingSource // where the setting came from
}
ResolvedSessionRecording contains the effective mode and its source.
func ResolveSessionRecording ¶
func ResolveSessionRecording(projectRoot string) *ResolvedSessionRecording
ResolveSessionRecording determines the effective session recording mode. Priority: OX_SESSION_RECORDING env > user config > project config > team config > "manual"
This priority ensures env vars (for pipelines) override everything, users can override team/repo settings, and teams can set defaults.
func (*ResolvedSessionRecording) IsAuto ¶
func (r *ResolvedSessionRecording) IsAuto() bool
IsAuto returns true if recording is automatic.
func (*ResolvedSessionRecording) IsManual ¶
func (r *ResolvedSessionRecording) IsManual() bool
IsManual returns true if recording requires explicit start.
func (*ResolvedSessionRecording) ShouldRecord ¶
func (r *ResolvedSessionRecording) ShouldRecord() bool
ShouldRecord returns true if the mode enables any recording.
type SessionRecordingSource ¶
type SessionRecordingSource string
SessionRecordingSource indicates where the session recording setting came from.
const ( SessionRecordingSourceDefault SessionRecordingSource = "default" // no config, using default SessionRecordingSourceEnv SessionRecordingSource = "env" // from OX_SESSION_RECORDING env var SessionRecordingSourceUser SessionRecordingSource = "user" // from user config SessionRecordingSourceTeam SessionRecordingSource = "team" // from team defaults (future) SessionRecordingSourceRepo SessionRecordingSource = "repo" // from .sageox/config.json )
type SessionsConfig ¶
type SessionsConfig struct {
// Enabled controls whether sessions are automatically recorded during agent sessions.
// Deprecated: Use Mode instead. Kept for backward compatibility.
// Default: false
Enabled *bool `yaml:"enabled,omitempty"`
// Mode controls the session recording level.
// Values: "none", "infra", "all"
// Default: "none" (or "all" if Enabled=true for backward compatibility)
Mode string `yaml:"mode,omitempty"`
}
SessionsConfig holds settings for session recording.
func (*SessionsConfig) GetMode ¶
func (c *SessionsConfig) GetMode() string
GetMode returns the effective session mode. Supports backward compatibility: if Mode is not set but Enabled=true, returns "all". Returns "none" if nothing is configured.
func (*SessionsConfig) IsEnabled ¶
func (c *SessionsConfig) IsEnabled() bool
IsEnabled returns true if session recording is enabled (default: false) Deprecated: Use GetMode() instead
type TeamConfig ¶
type TeamConfig struct {
// SessionRecording controls the default session recording mode for the team.
// Values: "disabled", "manual", "auto"
// Empty string means no team default (fall back to system default).
SessionRecording string `toml:"session_recording,omitempty"`
// SessionNotification is the message shown to users when recording starts.
// If empty, uses the default notification message.
SessionNotification string `toml:"session_notification,omitempty"`
}
TeamConfig represents team-level configuration stored in the team context directory. Located at: <team_context_path>/config.toml
This allows teams to set default policies that apply to all team members, while still allowing individual users to override via their user config.
func LoadTeamConfig ¶
func LoadTeamConfig(teamContextPath string) (*TeamConfig, error)
LoadTeamConfig loads team configuration from <teamContextPath>/config.toml. Returns nil, nil if the config file does not exist. Returns an error if the file exists but cannot be parsed.
type TeamContext ¶
type TeamContext struct {
TeamID string `toml:"team_id"`
TeamName string `toml:"team_name"`
Slug string `toml:"slug,omitempty"`
Path string `toml:"path"`
LastSync time.Time `toml:"last_sync"`
}
TeamContext holds configuration for a team context git repo. Note: omitempty is intentionally not used on LastSync because go-toml v2 does not serialize time.Time fields with omitempty correctly.
func FindAllTeamContexts ¶ added in v0.3.0
func FindAllTeamContexts(projectRoot string) []TeamContext
FindAllTeamContexts returns all team contexts available to the user. Primary source is LocalConfig.TeamContexts (populated by daemon). Falls back to scanning paths.TeamsDataDir(endpoint) subdirectories. Returns empty slice (not nil) if none found.
func FindRepoTeamContext ¶ added in v0.2.0
func FindRepoTeamContext(projectRoot string) *TeamContext
FindRepoTeamContext returns the team context that belongs to this repo's team. Loads ProjectConfig.TeamID and matches it against LocalConfig.TeamContexts. Falls back to the first configured team context if no match is found.
If no team contexts are configured in config.local.toml (daemon hasn't synced yet), falls back to computing the expected path from config.json's team_id + endpoint. This ensures the repo's own team context is discoverable immediately after ox init, without waiting for the daemon to populate [[team_contexts]].
func (*TeamContext) HasLastSync ¶
func (c *TeamContext) HasLastSync() bool
HasLastSync returns true if LastSync has been set (is non-zero).
type TeamContextHealth ¶
type TeamContextHealth struct {
TeamID string
Path string
Exists bool
IsGitRepo bool
LastSyncAge time.Duration
Workspaces []WorkspaceBackpointer
ActiveCount int // workspaces active in last 7 days
StaleCount int // workspaces not active in 30+ days
OrphanedCount int // workspaces whose project paths no longer exist
IsOrphaned bool // no valid workspace references
IsStale bool // no activity in 30+ days
}
TeamContextHealth represents the health status of a team context directory.
func AnalyzeTeamContextHealth ¶
func AnalyzeTeamContextHealth(teamID, teamPath string, lastSync time.Time) TeamContextHealth
AnalyzeTeamContextHealth checks the health of a team context directory.
type UserConfig ¶
type UserConfig struct {
DisplayName string `yaml:"display_name,omitempty"`
TipsEnabled *bool `yaml:"tips_enabled,omitempty"`
TelemetryEnabled *bool `yaml:"telemetry_enabled,omitempty"`
SessionTermsShown *bool `yaml:"session_terms_shown,omitempty"`
Attribution *Attribution `yaml:"attribution,omitempty"`
Badge *BadgeConfig `yaml:"badge,omitempty"`
ContextGit *ContextGitConfig `yaml:"context_git,omitempty"`
Sessions *SessionsConfig `yaml:"sessions,omitempty"`
ViewFormat string `yaml:"view_format,omitempty"` // "html", "text", "json" (default: "html")
}
UserConfig holds user-level configuration from config.yaml
func LoadUserConfig ¶
func LoadUserConfig() (*UserConfig, error)
LoadUserConfig loads user configuration using standard path discovery. Checks OX_USER_CONFIG env var first, then XDG/default paths.
For tests that need to load from an explicit directory, use LoadUserConfigFrom.
func LoadUserConfigFrom ¶ added in v0.3.0
func LoadUserConfigFrom(configDir string) (*UserConfig, error)
LoadUserConfigFrom loads user configuration from the specified config directory. If configDir is empty, uses GetUserConfigDir() which respects XDG_CONFIG_HOME. This is primarily for tests that need to point at a temp directory.
func (*UserConfig) AreSessionsEnabled ¶
func (c *UserConfig) AreSessionsEnabled() bool
AreSessionsEnabled returns whether session recording is enabled. Default: false
func (*UserConfig) AreTipsEnabled ¶
func (c *UserConfig) AreTipsEnabled() bool
AreTipsEnabled returns true if tips are enabled (default: true)
func (*UserConfig) GetContextGitAutoCommit ¶
func (c *UserConfig) GetContextGitAutoCommit() bool
GetContextGitAutoCommit returns whether auto-commit is enabled for context git. Default: true
func (*UserConfig) GetContextGitAutoPush ¶
func (c *UserConfig) GetContextGitAutoPush() bool
GetContextGitAutoPush returns whether auto-push is enabled for context git. Default: false
func (*UserConfig) GetDisplayName ¶
func (c *UserConfig) GetDisplayName() string
GetDisplayName returns the user's configured display name, or "" if not set.
func (*UserConfig) GetViewFormat ¶
func (c *UserConfig) GetViewFormat() string
GetViewFormat returns the preferred session view format. Default: "web"
func (*UserConfig) HasSeenSessionTerms ¶
func (c *UserConfig) HasSeenSessionTerms() bool
HasSeenSessionTerms returns true if the user has seen the session recording notice.
func (*UserConfig) IsTelemetryEnabled ¶
func (c *UserConfig) IsTelemetryEnabled() bool
IsTelemetryEnabled returns true if telemetry is enabled (default: true)
func (*UserConfig) SetContextGitAutoCommit ¶
func (c *UserConfig) SetContextGitAutoCommit(enabled bool)
SetContextGitAutoCommit sets the auto-commit preference for context git.
func (*UserConfig) SetContextGitAutoPush ¶
func (c *UserConfig) SetContextGitAutoPush(enabled bool)
SetContextGitAutoPush sets the auto-push preference for context git.
func (*UserConfig) SetDisplayName ¶
func (c *UserConfig) SetDisplayName(name string)
SetDisplayName sets the user's display name for privacy-aware rendering. Silently sanitizes the input (strips control chars, trims whitespace).
func (*UserConfig) SetSessionTermsShown ¶
func (c *UserConfig) SetSessionTermsShown(shown bool)
SetSessionTermsShown records whether the user has seen the session recording notice.
func (*UserConfig) SetSessionsEnabled ¶
func (c *UserConfig) SetSessionsEnabled(enabled bool)
SetSessionsEnabled sets the session recording preference.
func (*UserConfig) SetTelemetryEnabled ¶
func (c *UserConfig) SetTelemetryEnabled(enabled bool)
SetTelemetryEnabled sets the telemetry preference
type Validator ¶
type Validator struct{}
Validator provides reusable config validation functions
func (*Validator) ValidateAPIEndpoint ¶
ValidateAPIEndpoint validates an API endpoint URL
func (*Validator) ValidateAttribution ¶
func (v *Validator) ValidateAttribution(attr *Attribution) []error
ValidateAttribution validates attribution configuration
func (*Validator) ValidateConfigVersion ¶
ValidateConfigVersion validates a config version string
func (*Validator) ValidateID ¶
ValidateID validates a prefixed ID (e.g., prj_xxx, ws_xxx, repo_xxx)
func (*Validator) ValidateOrgSlug ¶
ValidateOrgSlug validates an organization slug slugs should be lowercase alphanumeric with hyphens (kebab-case)
func (*Validator) ValidateProjectConfig ¶
func (v *Validator) ValidateProjectConfig(cfg *ProjectConfig) []error
ValidateProjectConfig validates a complete ProjectConfig object
func (*Validator) ValidateProjectID ¶
ValidateProjectID validates a project ID (prj_xxx format)
func (*Validator) ValidateProjectSlug ¶
ValidateProjectSlug validates a project slug (same rules as org slug)
func (*Validator) ValidateRemoteHash ¶
ValidateRemoteHash validates a remote hash (SHA256 hex string)
func (*Validator) ValidateRepoID ¶
ValidateRepoID validates a repo ID (repo_xxx format with UUIDv7)
func (*Validator) ValidateTeamID ¶
ValidateTeamID validates a team ID
func (*Validator) ValidateTeamSlug ¶
ValidateTeamSlug validates a team slug (same rules as org slug)
func (*Validator) ValidateTimestamp ¶
ValidateTimestamp validates an ISO 8601 timestamp string
func (*Validator) ValidateUpdateFrequency ¶
ValidateUpdateFrequency validates update frequency in hours
func (*Validator) ValidateUserConfig ¶
func (v *Validator) ValidateUserConfig(cfg *UserConfig) []error
ValidateUserConfig validates a UserConfig object
func (*Validator) ValidateWorkspaceID ¶
ValidateWorkspaceID validates a workspace ID (ws_xxx format)
type WorkspaceBackpointer ¶
type WorkspaceBackpointer struct {
WorkspaceID string `json:"workspace_id"`
ProjectPath string `json:"project_path"`
LastActive time.Time `json:"last_active"`
}
WorkspaceBackpointer tracks a workspace that references a team context. Stored as JSONL in <team_context>/.sageox/workspaces.jsonl
func LoadBackpointers ¶
func LoadBackpointers(teamContextPath string) ([]WorkspaceBackpointer, error)
LoadBackpointers reads workspace backpointers from a team context.