state

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: May 13, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OldEmbeddedSkillName = "scribe-agent"
	EmbeddedSkillName    = "scribe"
)
View Source
const (
	SourceSync      = "sync"
	SourceMigration = "migration"
)
View Source
const CurrentSchemaVersion = 6

State is the contents of ~/.scribe/state.json.

View Source
const LegacyGlobalProjectionCompatBanner = "" /* 166-byte string literal not displayed */
View Source
const LocalNamespace = "local"

LocalNamespace is the namespace prefix for skills without a registry.

Variables

This section is empty.

Functions

func FileExists

func FileExists() (bool, error)

func LegacyGlobalProjectionCompatBannerPath

func LegacyGlobalProjectionCompatBannerPath() (string, error)

func MigrationSnapshotsDir

func MigrationSnapshotsDir() (string, error)

func NormalizeToolSelection

func NormalizeToolSelection(in []string) []string

NormalizeToolSelection dedupes a user-provided tool list while preserving order. Used by `scribe skill edit --tools` and --add.

func ShouldEmitLegacyGlobalProjectionCompatBanner

func ShouldEmitLegacyGlobalProjectionCompatBanner(now time.Time) (bool, error)

ShouldEmitLegacyGlobalProjectionCompatBanner applies the per-user daily throttle for the legacy global-projection deprecation banner.

func ShouldEmitLegacyGlobalProjectionCompatBannerAt

func ShouldEmitLegacyGlobalProjectionCompatBannerAt(timestampPath string, now time.Time) (bool, error)

ShouldEmitLegacyGlobalProjectionCompatBannerAt returns true at most once per local calendar day, updating timestampPath when the banner should be shown.

Types

type BinaryUpdateCheck

type BinaryUpdateCheck struct {
	LastSucceededAt time.Time `json:"last_succeeded_at,omitempty"`
}

type EmbeddedSkillRenameMigrationResult

type EmbeddedSkillRenameMigrationResult struct {
	Changed  bool
	Conflict bool
	Warnings []string
}

func MigrateEmbeddedSkillRename

func MigrateEmbeddedSkillRename(s *State) (EmbeddedSkillRenameMigrationResult, error)

MigrateEmbeddedSkillRename renames the v1.0 embedded bootstrap skill state from "scribe-agent" to "scribe". It is intentionally idempotent.

type InstalledKit

type InstalledKit struct {
	Name           string    `json:"name,omitempty"`
	SourceRegistry string    `json:"source_registry,omitempty"`
	Rev            string    `json:"rev,omitempty"`
	ContentHash    string    `json:"content_hash,omitempty"`
	InstalledAt    time.Time `json:"installed_at,omitempty"`
	Source         string    `json:"source,omitempty"`
	Version        string    `json:"version,omitempty"`
	Skills         []string  `json:"skills,omitempty"`
}

InstalledKit indexes an installed kit definition in the local state file.

type InstalledSkill

type InstalledSkill struct {
	Revision      int           `json:"revision"`
	InstalledHash string        `json:"installed_hash"`
	Sources       []SkillSource `json:"sources,omitempty"`
	InstalledAt   time.Time     `json:"installed_at"`
	// Deprecated in schema v5: projections replace the single global tools set.
	// Kept through v5 for parsing and compatibility with existing commands.
	Tools     []string  `json:"tools"`
	ToolsMode ToolsMode `json:"tools_mode,omitempty"`
	// Deprecated in schema v5: managed paths are superseded by projections.
	// Kept through v5 for parsing and compatibility with existing commands.
	Paths        []string             `json:"paths"`
	Projections  []ProjectionEntry    `json:"projections,omitempty"`
	ManagedPaths []string             `json:"managed_paths,omitempty"`
	Conflicts    []ProjectionConflict `json:"projection_conflicts,omitempty"`
	Origin       Origin               `json:"origin,omitempty"`

	// Kind distinguishes auto-detected tree packages (files under
	// ~/.scribe/packages/<name>/) from regular skills. Missing value on
	// legacy entries defaults to KindSkill; the first sync after upgrade
	// may flip an entry to KindPackage via the reclassification pass.
	Kind Kind `json:"kind,omitempty"`
	// AliasFor records the upstream skill name when this local entry was
	// installed under a kit-defined alias.
	AliasFor string `json:"alias_for,omitempty"`

	// Package-specific fields (omitted for regular skills).
	Type       string            `json:"type,omitempty"`
	InstallCmd string            `json:"install_cmd,omitempty"`
	UpdateCmd  string            `json:"update_cmd,omitempty"`
	Installs   map[string]string `json:"installs,omitempty"`
	Updates    map[string]string `json:"updates,omitempty"`
	CmdHash    string            `json:"cmd_hash,omitempty"`
	Approval   string            `json:"approval,omitempty"`
	ApprovedAt time.Time         `json:"approved_at,omitempty"`
}

InstalledSkill records everything needed to detect updates and uninstall.

func (InstalledSkill) DisplayVersion

func (s InstalledSkill) DisplayVersion() string

DisplayVersion returns the version string shown in `scribe list`. Returns "rev N" based on the revision counter.

func (InstalledSkill) EffectiveTools

func (s InstalledSkill) EffectiveTools(available []string) []string

EffectiveTools returns the tool names a skill should be installed into, given the currently available (globally enabled) tool names.

Inherit mode (default): union of available tools — the skill tracks global settings. Pinned mode: intersection of the skill's Tools with availability, preserving the user's chosen order.

Packages (Type == "package") bypass per-skill routing and always receive the full available list. This mirrors the existing behavior where packages install independently of tool-facing symlinks.

func (InstalledSkill) EffectiveToolsForProject

func (s InstalledSkill) EffectiveToolsForProject(available []string, projectRoot string) []string

EffectiveToolsForProject returns the tool names a skill should be installed into for a specific project scope.

Project projections are more specific than the legacy/global Tools pin. This lets one project's projected tool set survive unrelated per-skill trimming in another scope.

func (InstalledSkill) IsPackage

func (i InstalledSkill) IsPackage() bool

IsPackage reports whether this state entry is a tree-package (new kind field) or a legacy manifest-declared command-only package (Type field). Both flavours skip projection into tool skill dirs.

type InstalledSnippet

type InstalledSnippet struct {
	Source  string   `json:"source,omitempty"`
	Version string   `json:"version,omitempty"`
	Targets []string `json:"targets,omitempty"`
}

InstalledSnippet indexes an installed snippet definition in the local state file.

type Kind

type Kind string

Kind classifies how a tracked entry is stored and projected.

KindSkill (zero-value, also legacy default) is the canonical skill case: files in ~/.scribe/skills/<name>/ and dir-symlinked into tool skill dirs.

KindPackage is a self-installing multi-skill bundle. Files live in ~/.scribe/packages/<name>/ and are NEVER projected into agent skill dirs. Reconcile, discovery, and the list TUI all treat packages as opaque.

const (
	KindSkill   Kind = ""
	KindPackage Kind = "package"
)

type LegacyGlobalProjectionCompat

type LegacyGlobalProjectionCompat struct {
	Enabled              bool
	CWD                  string
	HasGlobalProjections bool
	ProjectFile          string
}

LegacyGlobalProjectionCompat describes whether Scribe should preserve the pre-project global projection behavior for this invocation.

func DetectLegacyGlobalProjectionCompat

func DetectLegacyGlobalProjectionCompat(st *State, cwd string) (LegacyGlobalProjectionCompat, error)

DetectLegacyGlobalProjectionCompat enables compatibility mode only when state still records global projections and the current directory is not inside a project with .scribe.yaml.

TODO(v1.0): remove this legacy global-projection compatibility path and direct users to clean up orphaned global symlinks via migration.

type Origin

type Origin string

Origin describes how a skill was acquired.

const (
	// OriginRegistry is the zero value: skill came from a registry.
	// Existing state files without an "origin" field deserialize as OriginRegistry.
	OriginRegistry Origin = ""
	// OriginLocal means the skill was adopted or hand-written locally.
	OriginLocal Origin = "local"
	// OriginBootstrap means the skill was installed from the embedded scribe bootstrap.
	OriginBootstrap Origin = "bootstrap"
	// OriginProject means the skill is authored for project vendoring.
	OriginProject Origin = "project"
)

type ProjectionConflict

type ProjectionConflict struct {
	Tool      string    `json:"tool"`
	Path      string    `json:"path"`
	FoundHash string    `json:"found_hash"`
	SeenAt    time.Time `json:"seen_at"`
}

ProjectionConflict records a divergent tool-facing projection that Scribe intentionally preserved during reconcile.

type ProjectionEntry

type ProjectionEntry struct {
	Project       string   `json:"project"`
	Tools         []string `json:"tools"`
	Source        string   `json:"source,omitempty"`
	ExcludedTools []string `json:"excluded_tools,omitempty"`
}

ProjectionEntry records the set of tool projections currently linked for a project. An empty Project is the legacy global projection.

type RegistryFailure

type RegistryFailure struct {
	Consecutive int       `json:"consecutive"`
	Muted       bool      `json:"muted,omitempty"`
	LastError   string    `json:"last_error,omitempty"`
	LastFailure time.Time `json:"last_failure,omitempty"`
}

type RemovedSkill

type RemovedSkill struct {
	Name      string    `json:"name"`
	Registry  string    `json:"registry"`
	SourceKey string    `json:"source_key,omitempty"`
	RemovedAt time.Time `json:"removed_at"`
}

RemovedSkill records a user's intent not to reinstall a registry skill.

type SkillSource

type SkillSource struct {
	Registry   string            `json:"registry"`
	SourceRepo string            `json:"source_repo,omitempty"`
	Path       string            `json:"path,omitempty"`
	Author     string            `json:"author,omitempty"`
	Ref        string            `json:"ref"`
	LastSHA    string            `json:"last_sha"`
	BlobSHAs   map[string]string `json:"blob_shas,omitempty"`
	LastSynced time.Time         `json:"last_synced"`

	SourceKey   string             `json:"source_key,omitempty"`
	Source      *source.SourceSpec `json:"source,omitempty"`
	ResolvedRev string             `json:"resolved_rev,omitempty"`
}

SkillSource records a registry that provides this skill.

func (SkillSource) IdentityKey

func (s SkillSource) IdentityKey() string

IdentityKey returns the structured source identity when present, falling back to the legacy registry key used by old state files.

func (SkillSource) PushRegistry

func (s SkillSource) PushRegistry() string

PushRegistry returns the repository that should receive local edits.

type State

type State struct {
	SchemaVersion int                         `json:"schema_version"`
	LastSync      time.Time                   `json:"last_sync,omitempty"`
	Installed     map[string]InstalledSkill   `json:"installed"`
	Kits          map[string]InstalledKit     `json:"kits"`
	Snippets      map[string]InstalledSnippet `json:"snippets"`
	// Schema v5 is shared with the kits/snippets pivot; its projection, kit,
	// and snippet indexes are additive siblings of this deny-list.
	RemovedByUser      []RemovedSkill               `json:"removed_by_user"`
	Migrations         map[string]bool              `json:"migrations,omitempty"`
	RegistryFailures   map[string]RegistryFailure   `json:"registry_failures,omitempty"`
	BinaryUpdateChecks map[string]BinaryUpdateCheck `json:"binary_update_checks,omitempty"`
	VendorState        map[string]VendorState       `json:"vendor_state,omitempty"`
}

func Load

func Load() (*State, error)

Load reads state from disk. Returns an empty state if the file doesn't exist yet. A shared advisory lock is held while reading to prevent torn reads.

func (*State) ClearRegistryFailure

func (s *State) ClearRegistryFailure(repo string) bool

func (*State) ClearRemovedByRegistry

func (s *State) ClearRemovedByRegistry(registry string) bool

ClearRemovedByRegistry removes all deny-list entries scoped to registry.

func (*State) ClearRemovedByUser

func (s *State) ClearRemovedByUser(name, registry string) bool

ClearRemovedByUser removes deny-list entries for name. If registry is empty, all registries for that name are cleared.

func (*State) HasLegacyGlobalProjections

func (s *State) HasLegacyGlobalProjections() bool

HasLegacyGlobalProjections reports whether any installed skill still has an empty-project projection entry, the state shape used before project-local projection was introduced.

func (*State) HasMigration

func (s *State) HasMigration(name string) bool

func (*State) IsRemovedByUser

func (s *State) IsRemovedByUser(registry, name string) bool

IsRemovedByUser reports whether the registry/name pair is deny-listed.

func (*State) MarkMigration

func (s *State) MarkMigration(name string)

func (*State) RecordInstall

func (s *State) RecordInstall(name string, skill InstalledSkill)

RecordInstall records a successful skill install. Safe to call mid-sync — the state file is only written when Save() is called.

func (*State) RecordRegistryFailure

func (s *State) RecordRegistryFailure(repo string, err error, muteAfter int) (RegistryFailure, bool)

func (*State) RecordRemovedByUser

func (s *State) RecordRemovedByUser(name string, sources []SkillSource)

RecordRemovedByUser records user removal intent for each registry source.

func (*State) RecordScribeBinaryUpdateSuccess

func (s *State) RecordScribeBinaryUpdateSuccess()

RecordScribeBinaryUpdateSuccess records a successful scribe binary check using UTC now.

func (*State) RecordScribeBinaryUpdateSuccessAt

func (s *State) RecordScribeBinaryUpdateSuccessAt(at time.Time)

RecordScribeBinaryUpdateSuccessAt records a successful scribe binary check at a specific time.

func (*State) RecordSync

func (s *State) RecordSync()

RecordSync updates the last sync timestamp.

func (*State) RegistryFailure

func (s *State) RegistryFailure(repo string) RegistryFailure

func (*State) Remove

func (s *State) Remove(name string)

Remove deletes a skill from state (does not touch disk files).

func (*State) Save

func (s *State) Save() error

Save writes state to disk atomically (write temp file, rename). An exclusive advisory lock is held during the write to prevent concurrent corruption.

func (*State) ScribeBinaryUpdateCheck

func (s *State) ScribeBinaryUpdateCheck() BinaryUpdateCheck

ScribeBinaryUpdateCheck returns the cached upgrade-check entry for scribe.

func (*State) ScribeBinaryUpdateCooldownFresh

func (s *State) ScribeBinaryUpdateCooldownFresh(now time.Time) bool

ScribeBinaryUpdateCooldownFresh reports whether the last successful scribe binary check is still within the 24-hour cooldown window.

type ToolsMode

type ToolsMode string

ToolsMode controls how the Tools field is interpreted at sync time.

const (
	// ToolsModeInherit is the zero value: the skill installs to whichever
	// tools are globally enabled. Tools is a cache of the most recent
	// effective list and may be rewritten by sync.
	ToolsModeInherit ToolsMode = ""
	// ToolsModePinned means the user explicitly chose this skill's tools.
	// Sync must respect Tools verbatim (intersected with availability) and
	// must not overwrite it based on global toggles.
	ToolsModePinned ToolsMode = "pinned"
)

type VendorState

type VendorState struct {
	FirstSeenAt time.Time `json:"first_seen_at,omitempty"`
}

Jump to

Keyboard shortcuts

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