Documentation
¶
Index ¶
- Constants
- func ClearBundledSkills()
- func CoerceDescriptionToString(value any, skillName string) *string
- func DiscoverSkillDirsForPaths(filePaths []string, cwd string) []string
- func ExtractDescriptionFromMarkdown(content string, fallbackLabel string) string
- func FormatSkillsList(skills []Skill) string
- func FormatSkillsListWithin(skills []Skill, budgetChars int) string
- func GetBuiltinSkillsPath() string
- func GetBundledSkillsRoot() string
- func GetMCPHealth() map[string]string
- func GetMCPServers() []string
- func GetManagedSkillsPath() string
- func GetProjectCommandsPath(projectDir string) string
- func GetProjectSkillsPath(projectDir string) string
- func GetPrompt() string
- func GetPromptWithSkills(skillsList string) string
- func GetSkillReposPath() string
- func GetSkillsRootPath() string
- func GetUserSkillsPath() string
- func GetUserSkillsPathForUser(userID string) string
- func IsMCPEnabled() bool
- func ParseArgumentNames(value any) []string
- func ParseBooleanFrontmatter(value any) bool
- func ParseEffortValue(value string) string
- func ParsePreambleTier(value any) int
- func ParseStringList(value any) []string
- func ReadSkillEnabled(path string) bool
- func RegisterBundledSkill(def BundledSkillDefinition)
- func RegisterSkillAlias(alias string, target string)
- func ResolveSkillAlias(name string) string
- func SetExternalDirs(userID string, dirs []ExternalDir)
- func SetMCPManager(manager *mcp.MCPClientManager)
- func SplitPathInFrontmatter(paths any) []string
- func SubstituteArguments(content string, args string, argumentNames []string) string
- func SubstituteSeshatVariables(content string, skillDir string, sessionID string) string
- func ValidateSkillPath(skillPath string) error
- type BundledSkillDefinition
- type ContentBlock
- type ExecutionContext
- type ExternalDir
- type FileSkillLoader
- func NewCollectionSkillLoader(repoRoot string, source SettingSource) *FileSkillLoader
- func NewFileSkillLoader(directory string) *FileSkillLoader
- func NewFileSkillLoaderWithSource(directory string, source SettingSource) *FileSkillLoader
- func NewRepoSkillLoader(repoRoot string, source SettingSource) *FileSkillLoader
- type ForkRunner
- type FrontmatterData
- type FrontmatterShell
- type HooksSettings
- type LoadedFrom
- type RepoInstall
- type SettingSource
- type Skill
- func CreateSkillFromFrontmatter(frontmatter FrontmatterData, markdownContent string, skillName string, ...) (Skill, error)
- func DiscoverMCPSkills(ctx context.Context) ([]Skill, error)
- func GetAllSkills(cwd string) ([]Skill, error)
- func GetAllSkillsForUser(cwd string, userID string) ([]Skill, error)
- func GetBundledSkills() []Skill
- func GetSkillsForContext(cwd string, filePaths []string, userID string) ([]Skill, error)
- func LoadExternalDir(path string, source SettingSource) ([]Skill, error)
- func LoadMCPSkills(ctx context.Context, serverName string) ([]Skill, error)
- func MatchTrigger(userInput string, skills []Skill) *Skill
- type SkillAlias
- type SkillInput
- type SkillLoader
- type SkillOutput
- type SkillRequirement
- type SkillScope
- type SkillSource
- type SkillTool
- func (t *SkillTool) BackfillInput(ctx context.Context, input map[string]any) map[string]any
- func (t *SkillTool) Call(ctx context.Context, input contract.CallInput, ...) (contract.CallResult, error)
- func (t *SkillTool) CheckPermissions(ctx context.Context, input map[string]any, toolCtx contract.ToolUseContext) types.PermissionResult
- func (t *SkillTool) Definition() contract.Definition
- func (t *SkillTool) Description(ctx context.Context) (string, error)
- func (t *SkillTool) FormatResult(data any) string
- func (t *SkillTool) IsConcurrencySafe(input map[string]any) bool
- func (t *SkillTool) IsEnabled() bool
- func (t *SkillTool) IsReadOnly(input map[string]any) bool
- func (t *SkillTool) SetAllowedSkills(names []string)
- func (t *SkillTool) SetCwd(cwd string)
- func (t *SkillTool) SetForkRunner(runner ForkRunner)
- func (t *SkillTool) SetUserID(userID string)
- func (t *SkillTool) ValidateInput(ctx context.Context, input map[string]any) (map[string]any, error)
- type SkillWithPath
Constants ¶
const ( DefaultSkillDirectory = ".seshat/skills" DefaultCommandsDirectory = ".seshat/commands" BundledSkillExtractDir = ".seshat/bundled-skills" )
const ( // DefaultCatalogBudgetChars caps the skill index in the `skill` tool description. About 2,000 tokens, which is 2 % // of a 100k window: the index costs context on every request, so it must not grow with the number of skills. DefaultCatalogBudgetChars = 8_000 )
const DefaultMaxSkills = 50
const RepoInstallFile = ".seshat-install.json"
RepoInstallFile is the name, at the root of a cloned skill repository, of the file that says how the person installed it.
const SkillToolName = "skill"
Variables ¶
This section is empty.
Functions ¶
func ClearBundledSkills ¶
func ClearBundledSkills()
func FormatSkillsList ¶
FormatSkillsList renders the skill index within DefaultCatalogBudgetChars.
func FormatSkillsListWithin ¶ added in v1.10.1
FormatSkillsListWithin renders the skill index within budgetChars characters, degrading it level by level rather than letting it grow: full entries (description, when-to-use, triggers), then descriptions only, then descriptions shortened to an even share, then names only, then as many names as fit. A degraded index ends with a line saying so.
func GetBuiltinSkillsPath ¶
func GetBuiltinSkillsPath() string
func GetBundledSkillsRoot ¶
func GetBundledSkillsRoot() string
func GetMCPHealth ¶
func GetMCPServers ¶
func GetMCPServers() []string
func GetManagedSkillsPath ¶
func GetManagedSkillsPath() string
GetManagedSkillsPath returns the directory for admin-managed (policy) skills. Respects SESHAT_RUNTIME_ROOT so the path moves with the deployment.
func GetProjectCommandsPath ¶
func GetProjectSkillsPath ¶
func GetPromptWithSkills ¶
func GetSkillReposPath ¶
func GetSkillReposPath() string
func GetSkillsRootPath ¶
func GetSkillsRootPath() string
func GetUserSkillsPath ¶
func GetUserSkillsPath() string
GetUserSkillsPath returns the default single-user skill path (legacy CLI mode).
func IsMCPEnabled ¶
func IsMCPEnabled() bool
func ParseArgumentNames ¶
func ParseBooleanFrontmatter ¶
func ParseEffortValue ¶
func ParsePreambleTier ¶
ParsePreambleTier converts a frontmatter preamble-tier value to an int.
0 = unset (backward-compatible default: inject base dir) 1 = basic — skill content only, no extra context 2 = standard — + working directory header 3 = full — + working directory + full context hint
func ParseStringList ¶
func ReadSkillEnabled ¶
ReadSkillEnabled reads the user-invocable value from a skill.md file on disk. Returns true if the file cannot be read or the field is absent.
func RegisterBundledSkill ¶
func RegisterBundledSkill(def BundledSkillDefinition)
func RegisterSkillAlias ¶
func ResolveSkillAlias ¶
func SetExternalDirs ¶ added in v1.11.7
func SetExternalDirs(userID string, dirs []ExternalDir)
SetExternalDirs sets the external skill folders of a user, replacing the previous list. The folders set for the blank user are shared: every user gets them (a device-level setting), besides their own.
func SetMCPManager ¶
func SetMCPManager(manager *mcp.MCPClientManager)
func SplitPathInFrontmatter ¶
func SubstituteArguments ¶
SubstituteArguments fills ${argument:name} and ${name} placeholders in content from args. With a single declared name, the whole args string fills it - the common case, matching a single-placeholder ArgumentHint like "<file>". With more than one name, args is split on whitespace positionally (first word to the first name, and so on), with the LAST name absorbing everything remaining so a trailing multi-word value (a sentence, a path with spaces) isn't cut up. A name with nothing left to fill it gets substituted with "", not the whole string - unlike every other name getting the same full value, which is what every placeholder did before this function distinguished them.
func ValidateSkillPath ¶
Types ¶
type BundledSkillDefinition ¶
type BundledSkillDefinition struct {
Name string
Description string
Aliases []string
WhenToUse string
ArgumentHint string
AllowedTools []string
Model string
DisableModelInvocation bool
UserInvocable bool
IsEnabled func() bool
Hooks *HooksSettings
Context ExecutionContext
Agent string
Effort string
Files map[string]string
Triggers []string
GetPromptForCommand func(args string, ctx context.Context) ([]ContentBlock, error)
}
type ContentBlock ¶
func ExecuteSkillPrompt ¶
type ExecutionContext ¶
type ExecutionContext string
const ( ExecutionContextInline ExecutionContext = "inline" ExecutionContextFork ExecutionContext = "fork" )
type ExternalDir ¶ added in v1.11.7
type ExternalDir struct {
// Path is the folder; every sub-folder holding a SKILL.md is a skill.
Path string
// Source names where the skills come from. It is shown with each skill (Skill.LoadedFrom), for example "claudeCode".
Source SettingSource
// Skip, when set, leaves out the skills it returns true for: a host keeps out the ones that only make sense inside the other tool.
Skip func(Skill) bool
}
ExternalDir is a folder of skills that belongs to another tool or to the person (Claude Code's ~/.claude/skills, Codex's ~/.codex/skills, a folder of their own). It is read where it lies: nothing is copied, so a skill edited there is the skill the agent uses at the next turn.
func ExternalDirsFor ¶ added in v1.11.7
func ExternalDirsFor(userID string) []ExternalDir
ExternalDirsFor returns the external skill folders a user gets: the shared ones, then their own.
type FileSkillLoader ¶
type FileSkillLoader struct {
Directory string
Source SettingSource
// CollectionRoot, when non-empty, is the repo root that owns this skill
// collection. It is injected into skill prompts so the AI can resolve
// paths relative to the repo root (e.g. data/, scripts/).
CollectionRoot string
// SkipHidden leaves out every folder whose name starts with a dot (.trash, .git, .system...). A folder of another tool keeps
// its deleted skills and its own bundled ones there: they are not skills the person chose.
SkipHidden bool
// Skip, when set, leaves out the skills it returns true for.
Skip func(Skill) bool
// contains filtered or unexported fields
}
func NewCollectionSkillLoader ¶
func NewCollectionSkillLoader(repoRoot string, source SettingSource) *FileSkillLoader
NewCollectionSkillLoader creates a loader for a skill repo whose skills reference files relative to the repo root (e.g. data/, scripts/). directory must be the repo root — each subdirectory containing a SKILL.md becomes one skill, and the repo root is injected as the base path.
func NewFileSkillLoader ¶
func NewFileSkillLoader(directory string) *FileSkillLoader
func NewFileSkillLoaderWithSource ¶
func NewFileSkillLoaderWithSource(directory string, source SettingSource) *FileSkillLoader
func NewRepoSkillLoader ¶ added in v1.12.10
func NewRepoSkillLoader(repoRoot string, source SettingSource) *FileSkillLoader
NewRepoSkillLoader is the loader of a cloned repository: a collection that keeps to what the person chose when they installed it, and that gives the agent the environment made for it. A repository still being installed offers no skill.
func (*FileSkillLoader) GetSkillDirCommands ¶
func (l *FileSkillLoader) GetSkillDirCommands(cwd string) ([]Skill, error)
func (*FileSkillLoader) GetSkillDirCommandsForUser ¶
func (l *FileSkillLoader) GetSkillDirCommandsForUser(cwd string, userID string) ([]Skill, error)
func (*FileSkillLoader) LoadSkills ¶
func (l *FileSkillLoader) LoadSkills() ([]Skill, error)
type ForkRunner ¶
type ForkRunner interface {
// parentPermissionMode is the forking session's current permission
// mode, passed through unresolved so the implementation (which has
// access to the same sub-agent permission-inheritance policy every
// other sub-agent spawn path uses) decides what the forked skill
// actually runs under, instead of this package hardcoding a choice.
RunForkedSkill(ctx context.Context, skillName, task string, allowedTools []string, model string, parentPermissionMode types.PermissionMode) (string, error)
}
ForkRunner runs a skill declared with `context: fork` as an isolated sub-agent instead of inlining its prompt into the current conversation, and returns that sub-agent's final text output. allowedTools and model come straight from the skill's own frontmatter (Skill.AllowedTools, Skill.Model) - they only mean anything in this forked path, never in the default inline one.
internal/agent already imports this package (for RestrictSessionSkills), so this package cannot import internal/agent back without a cycle: a host that can reach the agent-running infrastructure implements this interface and wires it in via SkillTool.SetForkRunner. See internal/tools/agents.SkillForkRunner for the real implementation.
type FrontmatterData ¶
type FrontmatterData struct {
Name any `yaml:"name"`
Description any `yaml:"description"`
WhenToUse string `yaml:"when_to_use"`
ArgumentHint string `yaml:"argument-hint"`
Arguments any `yaml:"arguments"`
AllowedTools any `yaml:"allowed-tools"`
Model string `yaml:"model"`
DisableModelInvocation any `yaml:"disable-model-invocation"`
UserInvocable any `yaml:"user-invocable"`
Version string `yaml:"version"`
Context string `yaml:"context"`
Agent string `yaml:"agent"`
Effort string `yaml:"effort"`
Paths any `yaml:"paths"`
Hooks any `yaml:"hooks"`
Shell any `yaml:"shell"`
// Triggers is a list of natural-language phrases that should auto-activate
// this skill (e.g. ["browse this page", "take a screenshot"]). Inspired by
// gstack. When the user's prompt contains any trigger phrase, the skill is
// expanded automatically — no /slash-command needed.
Triggers any `yaml:"triggers,omitempty"`
// PreambleTier controls how much context is prepended to the expanded skill
// prompt. Accepts int (1/2/3) or string ("basic"/"standard"/"full").
// 1 / basic — skill content only (default)
// 2 / standard — + working directory info
// 3 / full — + working directory + user preferences block
PreambleTier any `yaml:"preamble-tier,omitempty"`
// Requires lists external dependencies the skill needs (Node.js, Python
// packages, system tools). The agent checks them at runtime and requests
// user permission before installing any missing dependency.
Requires any `yaml:"requires,omitempty"`
}
func ParseFrontmatter ¶
func ParseFrontmatter(content string, filePath string) (FrontmatterData, string)
type FrontmatterShell ¶
type FrontmatterShell struct {
Before []string `yaml:"before,omitempty"`
After []string `yaml:"after,omitempty"`
OnError []string `yaml:"on_error,omitempty"`
OnComplete []string `yaml:"on_complete,omitempty"`
}
func ParseShellFrontmatter ¶
func ParseShellFrontmatter(value any, skillName string) *FrontmatterShell
type HooksSettings ¶
type HooksSettings struct {
BeforeTool []string `yaml:"before_tool,omitempty"`
AfterTool []string `yaml:"after_tool,omitempty"`
Before []string `yaml:"before,omitempty"`
After []string `yaml:"after,omitempty"`
OnError []string `yaml:"on_error,omitempty"`
OnCancel []string `yaml:"on_cancel,omitempty"`
OnComplete []string `yaml:"on_complete,omitempty"`
ToolAllowed []string `yaml:"tool_allowed,omitempty"`
ToolDenied []string `yaml:"tool_denied,omitempty"`
}
func ParseHooksFromFrontmatter ¶
func ParseHooksFromFrontmatter(value any) *HooksSettings
type LoadedFrom ¶
type LoadedFrom string
const ( LoadedFromSkills LoadedFrom = "skills" LoadedFromPlugin LoadedFrom = "plugin" LoadedFromManaged LoadedFrom = "managed" LoadedFromBundled LoadedFrom = "bundled" LoadedFromMCP LoadedFrom = "mcp" )
type RepoInstall ¶ added in v1.12.10
type RepoInstall struct {
// Include lists the skills that were chosen, by the name of their folder. Empty means every skill of the repository.
Include []string `json:"include,omitempty"`
// Pending is true while the installation is not finished (the person has not confirmed, or the environment is being made):
// the repository's skills are not offered to the agent until then.
Pending bool `json:"pending,omitempty"`
// Python is the interpreter of the environment made for this repository.
Python string `json:"python,omitempty"`
// NodeModules is the folder of the Node packages installed for this repository.
NodeModules string `json:"node_modules,omitempty"`
}
RepoInstall is what the host wrote beside a cloned skill repository when the person installed it: which of its skills they chose, and the environment prepared for them. A repository with no such file is used as it is, every skill of it.
func LoadRepoInstall ¶ added in v1.12.10
func LoadRepoInstall(repoRoot string) (RepoInstall, bool)
LoadRepoInstall reads the install file of a repository; ok is false when there is none or it cannot be read.
type SettingSource ¶
type SettingSource string
const ( SettingSourcePolicySettings SettingSource = "policySettings" SettingSourceUserSettings SettingSource = "userSettings" SettingSourceProjectSettings SettingSource = "projectSettings" SettingSourcePlugin SettingSource = "plugin" )
type Skill ¶
type Skill struct {
Name string
DisplayName string
Description string
HasUserSpecifiedDescription bool
AllowedTools []string
ArgumentHint string
ArgNames []string
WhenToUse string
Version string
Model string
DisableModelInvocation bool
UserInvocable bool
Context ExecutionContext
Agent string
Effort string
Paths []string
Content string // raw markdown body, used by ExecuteSkillPrompt fallback
ContentLength int
IsHidden bool
ProgressMessage string
Source SkillSource
LoadedFrom LoadedFrom
SkillRoot string
Hooks *HooksSettings
Shell *FrontmatterShell
// Triggers holds natural-language phrases that auto-activate this skill
// without a slash command (e.g. "browse this page", "take a screenshot").
Triggers []string
// PreambleTier controls context injection depth: 0=default (base dir),
// 1=basic (none), 2=standard (base dir), 3=full (base dir + context hint).
PreambleTier int
// Scope indicates the ownership/access level of this skill.
Scope SkillScope
// Requires lists external dependencies that must be present before the
// skill runs. The agent verifies each and requests user permission to
// install any that are missing.
Requires []SkillRequirement
GetPromptForCommand func(args string, ctx context.Context) ([]ContentBlock, error)
}
func CreateSkillFromFrontmatter ¶
func CreateSkillFromFrontmatter(frontmatter FrontmatterData, markdownContent string, skillName string, baseDir string, loadedFrom string, source SettingSource) (Skill, error)
func GetAllSkills ¶
func GetBundledSkills ¶
func GetBundledSkills() []Skill
func GetSkillsForContext ¶
GetSkillsForContext returns skills that are active for the given file context. Skills with no Paths restriction are always included. Skills with Paths are included only when at least one of the provided filePaths matches a pattern. When filePaths is empty, all skills are returned (no filtering).
func LoadExternalDir ¶ added in v1.11.8
func LoadExternalDir(path string, source SettingSource) ([]Skill, error)
LoadExternalDir loads the skills of a folder the way the agent would, without the host's Skip filter, so a host can show what it leaves out and why.
func MatchTrigger ¶
MatchTrigger returns the first skill whose trigger phrases match userInput, or nil if no skill matches. Matching is case-insensitive substring search.
func (*Skill) MatchesTrigger ¶
MatchesTrigger reports whether userInput contains any of the skill's trigger phrases (case-insensitive substring match).
type SkillAlias ¶
func GetSkillAliases ¶
func GetSkillAliases() []SkillAlias
type SkillInput ¶
type SkillLoader ¶
type SkillOutput ¶
type SkillRequirement ¶
type SkillRequirement struct {
// Type is a human-readable label: "node", "python", "system", etc.
Type string `yaml:"type"`
// Check is a shell command that exits 0 when the dep is satisfied.
// Example: "node --version", "python3 -c 'import pptx'"
Check string `yaml:"check"`
// InstallCmd is run (with user permission) when Check fails.
// Supports ${SESHAT_SKILL_DIR} substitution.
InstallCmd string `yaml:"install-cmd"`
// Packages lists the packages for display purposes only.
Packages []string `yaml:"packages,omitempty"`
// Optional marks the requirement as non-blocking: the skill runs even if
// the dep is missing, but the agent is told some features may be degraded.
Optional bool `yaml:"optional,omitempty"`
}
SkillRequirement declares an external dependency (Node.js, Python package…) that must be present before the skill can run. If any requirement fails its check command, the skill prompt includes a pre-flight section instructing the agent to request user permission before installing.
func ParseRequires ¶
func ParseRequires(value any) []SkillRequirement
ParseRequires converts a frontmatter requires value into a slice of SkillRequirement. Accepts either a YAML list of maps or a single map.
type SkillScope ¶
type SkillScope string
SkillScope controls who can invoke a skill and what context it can access.
const ( ScopeUser SkillScope = "user" // created/owned by the end-user ScopeRepo SkillScope = "repo" // scoped to the current project ScopeSystem SkillScope = "system" // platform-level (plugins, MCP) ScopeAdmin SkillScope = "admin" // policy-managed (admin-controlled) )
type SkillSource ¶
type SkillSource string
const ( SourceBundled SkillSource = "bundled" SourceCommands SkillSource = "commands" SourcePlugin SkillSource = "plugin" SourceManaged SkillSource = "managed" SourceMCP SkillSource = "mcp" )
type SkillTool ¶
type SkillTool struct {
// contains filtered or unexported fields
}
func NewSkillTool ¶
func NewSkillTool(loader SkillLoader) *SkillTool
func (*SkillTool) BackfillInput ¶
func (*SkillTool) Call ¶
func (t *SkillTool) Call(ctx context.Context, input contract.CallInput, permissionCheck types.CanUseToolFn) (contract.CallResult, error)
func (*SkillTool) CheckPermissions ¶
func (t *SkillTool) CheckPermissions(ctx context.Context, input map[string]any, toolCtx contract.ToolUseContext) types.PermissionResult
func (*SkillTool) Definition ¶
func (t *SkillTool) Definition() contract.Definition
func (*SkillTool) Description ¶
func (*SkillTool) FormatResult ¶
func (*SkillTool) IsConcurrencySafe ¶
func (*SkillTool) SetAllowedSkills ¶
SetAllowedSkills restricts this tool to the given skill names (matched against Skill.Name or Skill.DisplayName): every other skill behaves as if it did not exist, in the tool's own description and in lookups alike. A nil or empty list means no restriction (every skill stays visible), which is also the default for a tool built by NewSkillTool.
func (*SkillTool) SetForkRunner ¶
func (t *SkillTool) SetForkRunner(runner ForkRunner)
SetForkRunner wires the sub-agent infrastructure a `context: fork` skill needs. A skill tool built by NewSkillTool has none set: calling such a skill returns an error naming the missing runner instead of silently running inline.