Documentation
¶
Overview ¶
Package skills defines the shared model for personal and workspace skills used by chatd.
Glossary:
- Personal skill: A user-owned skill that follows the user across Coder chats and workspaces, stored by Coder rather than discovered from a workspace filesystem.
- Workspace skill: A skill discovered from the workspace filesystem, currently under .agents/skills by default.
- Skill source: The origin of a skill available to chatd, such as personal storage or workspace filesystem discovery.
- Skill alias: A chat or tool lookup name for a skill. Bare aliases use the skill name. Qualified aliases use personal/<name> or workspace/<name>.
Decision:
Personal skills are stored by Coder. For each chat turn, chatd fetches personal skill metadata fresh, combines it with workspace skill metadata, and injects the available skills into the existing skill prompt. When chatd needs skill content, it resolves personal skills through the read_skill flow instead of syncing files into workspace filesystems.
If a personal skill and workspace skill share the same kebab-case name, both are exposed with qualified aliases: personal/<name> for the personal skill and workspace/<name> for the workspace skill. One source must not silently override the other.
Site admins can read and delete personal skill content. Personal skills are user-authored instructions, not secret material. Audit records can include raw Markdown content diffs alongside the actor, target user, and relevant metadata.
Personal skill edits affect the next chat turn. Old chat turns are not exact snapshots of the personal skill state that existed when they ran.
The v1 design does not include CLI support, web UI support, supporting files, organization-scoped personal skills, syncing personal skills into workspace filesystems, or stable public API documentation.
Consequences:
Chatd can use personal and workspace skills through one prompt and one read path, while storage remains owned by Coder instead of individual workspace filesystems. Fresh metadata keeps skill changes responsive, but chat history is less reproducible because old turns do not capture an exact copy of personal skill content.
Explicit qualified aliases make ambiguous names visible to users and tools. Admin access improves operability and abuse handling, but it creates a privacy trade-off that must remain clear in product and support expectations.
Index ¶
Constants ¶
const MaxPersonalSkillDescriptionBytes = 4096
MaxPersonalSkillDescriptionBytes is the maximum frontmatter description size accepted for a personal skill upload.
const MaxPersonalSkillNameBytes = 256
MaxPersonalSkillNameBytes is the maximum skill name length accepted for a personal skill upload. Skill names are also used in URL paths.
const MaxPersonalSkillSizeBytes = workspacesdk.MaxSkillMetaBytes
MaxPersonalSkillSizeBytes is the maximum raw Markdown size accepted for a personal skill upload.
const MaxPersonalSkillsPerUser = 100
MaxPersonalSkillsPerUser is the maximum number of personal skills a user may create.
Variables ¶
var ( // ErrInvalidSkillName indicates that a skill name is missing, not valid // kebab-case, or exceeds the maximum length. ErrInvalidSkillName = xerrors.New("invalid skill name") // ErrSkillBodyRequired indicates that the skill has no body after frontmatter. ErrSkillBodyRequired = xerrors.New("skill body is required") // ErrSkillTooLarge indicates that the raw skill Markdown is too large. ErrSkillTooLarge = xerrors.New("skill is too large") // ErrSkillDescriptionTooLarge indicates that the description is too large. ErrSkillDescriptionTooLarge = xerrors.New("skill description is too large") // ErrSkillNotFound indicates that a skill lookup did not match any alias. ErrSkillNotFound = xerrors.New("skill not found") // ErrSkillAmbiguous indicates that a skill lookup matched multiple sources. ErrSkillAmbiguous = xerrors.New("skill lookup is ambiguous") )
Functions ¶
func QualifiedAlias ¶
QualifiedAlias returns the stable source-qualified alias for a skill name.
Types ¶
type ParsedSkill ¶
ParsedSkill is a parsed skill with the Markdown body after frontmatter. Body has HTML comments stripped and surrounding whitespace trimmed.
func ParsePersonalSkillMarkdown ¶
func ParsePersonalSkillMarkdown(raw []byte) (ParsedSkill, error)
ParsePersonalSkillMarkdown parses raw personal skill Markdown and enforces the personal skill contract. The raw size must not exceed MaxPersonalSkillSizeBytes, frontmatter must contain a valid kebab-case name, the skill name must not exceed MaxPersonalSkillNameBytes, the description must not exceed MaxPersonalSkillDescriptionBytes, and the body after frontmatter must be non-empty.
type ResolvedSkill ¶
ResolvedSkill is a skill with the alias exposed to chat tools.
func Lookup ¶
func Lookup(resolved []ResolvedSkill, lookup string) (ResolvedSkill, error)
Lookup finds a resolved skill by bare alias or qualified source alias. It returns ErrSkillNotFound if no alias matches, or ErrSkillAmbiguous if a bare name matches skills from multiple sources.
func MergeSkills ¶
func MergeSkills(personalSkills, workspaceSkills []Skill) []ResolvedSkill
MergeSkills combines personal and workspace skills into a deterministic list with aliases for chat tool display and lookup. Skill names must already be valid kebab-case names because qualified aliases use / as a separator. If a source contains duplicate names, the first skill for that source wins.