Documentation
¶
Overview ¶
Package docent loads, validates, and serves embedded Markdown runbooks (guides) for AI agents, and models a CLI's command tree as a framework-neutral schema. It is a library — it never writes to stdout and never terminates the host process; all results are returned values, and hosts own all output.
Guides are YAML-frontmatter Markdown files embedded via go:embed. Each file must conform to the Agent Guide Standard (https://github.com/matcra587/docent/blob/main/docs/agent-guide-standard.md). LoadGuides is the primary entry point; all other types are its output.
The module is organized as five public packages:
- docent (this package): the guide and schema model, loading, and validation — Guide, Section, GuideSet, Command, Flag, FlagGroup, SchemaRegistry, and Config, the host integration surface.
- docent/export: renderers that turn guides into exportable artifacts, such as Agent Skills SKILL.md files.
- docent/cobra: the cobra adapter — a Tree walker producing the neutral Command schema from a live cobra tree, and NewCommand, the mountable "agent" command group.
- docent/harness: agent-runtime detection from environment markers — which agent is driving the process, and which harness's skill conventions apply.
- docent/docenttest: contract-test helpers so hosts can validate their own guides in CI.
Every emitted artifact — guide index, concatenated guides, schema JSON, exported skills — is deterministic and byte-stable by contract.
Index ¶
Examples ¶
Constants ¶
const MaxSkillCompatibility = 500
MaxSkillCompatibility is the character budget for an exported skill's optional compatibility frontmatter, taken from the Agent Skills spec, which caps it at 500 characters.
const MaxSkillDescription = 1024
MaxSkillDescription is the character budget for an exported skill's description frontmatter, taken from the Agent Skills spec (agentskills.io), which caps skill descriptions at 1024 characters. Validation enforces it at load time against SkillDescription — the exact composed value the agent-skill export emits.
const StandardVersion = 1
StandardVersion is the Agent Guide Standard revision that validation enforces. Version 1 requires exactly six sections in the prescribed order.
Variables ¶
var ( // ErrMissingFrontmatter is returned when a guide file has no YAML frontmatter block. ErrMissingFrontmatter = errors.New("docent: missing frontmatter") // ErrInvalidFrontmatter is returned when a guide file has a frontmatter // block that is not valid YAML. ErrInvalidFrontmatter = errors.New("docent: invalid frontmatter") // ErrMissingField is returned when a required frontmatter field is absent or empty. ErrMissingField = errors.New("docent: missing required field") // ErrSlugMismatch is returned when the frontmatter slug value does not match the filename (without extension). ErrSlugMismatch = errors.New("docent: slug does not match filename") // ErrInvalidSlug is returned when a slug does not satisfy the Agent Skills // name rules: 1-64 lowercase alphanumeric characters and hyphens, with no // leading, trailing, or consecutive hyphens. Slugs become exported skill // names and directory names, so the constraint is enforced at load time. ErrInvalidSlug = errors.New("docent: invalid slug") // ErrDescriptionTooLong is returned when a guide's description and // when_to_use together exceed the exported skill description budget // (MaxSkillDescription), which the Agent Skills spec caps at 1024 // characters. ErrDescriptionTooLong = errors.New("docent: description budget exceeded") // ErrInvalidSections is returned when the guide body does not have the // six section headings required by StandardVersion, in the expected order. ErrInvalidSections = errors.New("docent: invalid sections") // ErrDuplicateOrder is returned when two or more guides share the same // sparse-integer order value; the canonical guide order is a contract, // so a collision fails the load like any other validation class. ErrDuplicateOrder = errors.New("docent: duplicate order value") // ErrAliasCollision is returned when a guide alias is empty, declared by // two guides, or shadows a guide slug — an ambiguous name cannot // resolve, so lookup behavior would depend on iteration order. ErrAliasCollision = errors.New("docent: alias collision") // ErrCompatibilityTooLong is returned when a guide's compatibility field // exceeds the exported skill budget (MaxSkillCompatibility), which the // Agent Skills spec caps at 500 characters. ErrCompatibilityTooLong = errors.New("docent: compatibility budget exceeded") // ErrMultilineField is returned when a frontmatter field the guide index // emits line-oriented — title, description, when_to_use, or a commands or // aliases element — contains a newline. A multiline value would corrupt // the index's key: value shape (or forge extra entries), so it fails the // load. ErrMultilineField = errors.New("docent: multiline frontmatter field") // ErrFormFeed is returned when a guide file contains a form-feed // character. The form feed is reserved as the guide-concatenation // separator (export.GuideSeparator, the adapter's "agent guide --all"), // so content containing one would make the concatenation split // ambiguously. ErrFormFeed = errors.New("docent: form feed in guide content") // ErrCommandNotFound is the sentinel adapters and docenttest wrap when a // path or reference names no command in the tree. FindByPath itself // signals absence with its comma-ok result and never returns this error. ErrCommandNotFound = errors.New("docent: command not found") )
Sentinel errors for use with errors.Is and errors.As. Validation errors are reported by wrapping one of these sentinels in a *ValidationError so callers can branch on the class without matching strings.
Functions ¶
func MarshalSchema ¶ added in v0.2.0
MarshalSchema renders cmd as the canonical schema JSON emission: compact (no insignificant whitespace), single line, no trailing newline. The schema is a machine-facing artifact read by agents whose context windows bill per token, so indentation is pure cost; a host that wants a readable view pipes through a JSON formatter or registers a schema transform. MarshalSchema is the single source for the byte shape of the "agent schema" surface — the cobra adapter's schema command and docenttest.SchemaGolden both emit through it (each appending the artifact's trailing newline at its write site), so a golden pinned with one cannot drift from the bytes the other writes. The adapter may further stamp a contract version, strip embedded shapes from the full tree, pool repeated shape bodies into $defs, and apply host schema transforms on top of this shape; goldens that must pin those effects golden the command output itself.
func SectionHeadings ¶ added in v0.2.0
func SectionHeadings() []string
SectionHeadings returns the section headings StandardVersion requires, in their required order. Surfaces that enumerate the section vocabulary — shell completion, documentation, tooling — derive from this accessor so they cannot drift from validation when the standard revises. The returned slice is a copy; mutating it affects nothing.
Example ¶
ExampleSectionHeadings pins the standard's required section order — the vocabulary shell completion and tooling derive from.
package main
import (
"fmt"
"strings"
"github.com/matcra587/docent"
)
func main() {
fmt.Println(strings.Join(docent.SectionHeadings(), ", "))
}
Output: Decide, Run, Save, Preconditions, Recover, Next
Types ¶
type Command ¶
type Command struct {
// Name is the command's short name (the last path segment).
Name string `json:"name"`
// Path is the space-separated sequence of names from the root to this
// command, e.g. "issue create".
Path string `json:"path"`
// Description is the short, one-line description of the command.
Description string `json:"description,omitempty"`
// Aliases lists alternative names the command answers to, sorted for
// determinism. An agent that reads documentation mentioning an alias can
// recognize it as this command.
Aliases []string `json:"aliases,omitempty"`
// Deprecated carries the framework's deprecation message when the
// command is deprecated, empty otherwise. Agents should prefer the
// replacement the message names instead of invoking this command.
Deprecated string `json:"deprecated,omitempty"`
// ReadOnly indicates the command performs no writes. Adapters set this
// from framework-specific metadata; when unavailable it defaults to false.
ReadOnly bool `json:"read_only,omitempty"`
// Hidden indicates the command is not shown in help output.
Hidden bool `json:"hidden,omitempty"`
// Flags contains all flags available on this command, sorted by Name.
Flags []Flag `json:"flags,omitempty"`
// FlagGroups contains mutual-exclusion and required-together relations
// among the command's flags, sorted for determinism.
FlagGroups []FlagGroup `json:"flag_groups,omitempty"`
// Extensions carries host-owned structured metadata — the slot for
// everything the neutral IR deliberately does not model: auth
// requirements, environment variables, exit codes, output contracts,
// per-command examples. On the root command it describes the tool; on
// any other node, that command. One documented exception to host
// ownership: when Config.ContractVersion is set, the cobra adapter's
// schema command stamps a "contract_version" entry onto the emitted
// root at emission time, overwriting a host entry of that name — the
// stored tree is never touched. Values must be JSON-marshalable;
// emission sorts keys, and every API boundary deep-copies the map like
// the schema fields.
Extensions map[string]any `json:"extensions,omitempty"`
// InputSchema is an optional JSON Schema object describing the command's
// structured input. Nil when the framework does not supply schema metadata.
InputSchema map[string]any `json:"input_schema,omitempty"`
// HasInputSchema marks that an input schema exists for this command
// when the embedded body has been omitted from the emission. Set by
// StripShapes, never by adapters or hosts directly: a full-tree reader
// is routing and needs only the fact that a shape exists; the body is
// one --path call away.
HasInputSchema bool `json:"has_input_schema,omitempty"`
// OutputSchema is an optional JSON Schema object describing the command's
// structured output. Nil when the framework does not supply schema metadata.
OutputSchema map[string]any `json:"output_schema,omitempty"`
// HasOutputSchema is the output-side counterpart of HasInputSchema.
HasOutputSchema bool `json:"has_output_schema,omitempty"`
// Children contains this command's direct subcommands, sorted by Name.
Children []Command `json:"children,omitempty"`
// Defs holds shared JSON Schema bodies hoisted out of the tree's
// input/output schemas, keyed by definition name. Populated by
// PoolShapes on the emitted root — the bodies it replaces become
// {"$ref": "#/$defs/<name>"} objects, and the pointer form resolves
// against the emission document, so the key is emitted as "$defs" per
// JSON Schema convention. Meaningful only on the root of an emission.
Defs map[string]any `json:"$defs,omitempty"`
}
Command is a framework-neutral schema IR node for one command in a CLI tree. Children are sorted by Name for deterministic, byte-stable output. The zero value is not meaningful; use adapters such as the cobra package to produce it.
func FindByPath ¶
FindByPath searches cmd and its descendants for the node whose Path equals path. The comparison is exact and case-sensitive; path uses the space-separated form defined by Command.Path (e.g. "issue create").
Returns the matching Command and true when found; the zero Command and false otherwise. The search is depth-first pre-order. The returned Command is a deep copy; mutating it — including its slice and map fields — cannot affect the tree that was searched.
func (Command) Clone ¶ added in v0.2.0
Clone returns a deep copy of c sharing no slice or map storage with it, recursing through Children. It is the boundary-copy primitive: lookups and emission-time rewrites (masking volatile defaults, stamping a contract version) clone first so the original tree is never mutated.
func (Command) PoolShapes ¶ added in v0.3.0
PoolShapes returns a deep copy of c in which input and output schema bodies repeated across the tree are hoisted into the root's Defs map and each occurrence replaced by a JSON Schema reference object, {"$ref": "#/$defs/<name>"} — real hosts register one result shell on many sibling commands, and emitting it once instead of N times is where the embedded-shape bytes go. Only net wins are pooled: a body too small to pay for its reference objects and $defs entry stays inline. Bodies carrying document-relative references of their own ("$ref" values starting with "#", or "$defs"/"definitions" keys) are never pooled — hoisting would silently change what those pointers resolve against. Names are deterministic: "d1", "d2", … in first-occurrence order of a pre-order walk (input before output per node), skipping any names an existing Defs map on c already uses. c itself is never modified.
func (Command) StripShapes ¶ added in v0.3.0
StripShapes returns a deep copy of c in which every embedded input and output schema body — on c and every descendant — is replaced by its marker: a node carrying an InputSchema comes back with HasInputSchema true and InputSchema nil, likewise for the output side. Nodes without a schema are untouched, so a marker always means "a shape exists and was omitted". This is the standard's full-tree emission policy: an agent reading the whole tree is routing, and the embedded shapes — the dominant share of a real host's schema bytes, heavily duplicated across sibling commands — are one --path call away when it is time to build a payload. c itself is never modified.
type CommandSchemas ¶
type CommandSchemas struct {
// Input is the JSON Schema object describing the command's structured input.
// Nil when no input schema is registered for this command path.
Input map[string]any
// Output is the JSON Schema object describing the command's structured output.
// Nil when no output schema is registered for this command path.
Output map[string]any
}
CommandSchemas holds the optional input and output JSON Schema objects for one command path.
type Config ¶
type Config struct {
// Guides is the guide set to serve. Nil means no guides are available.
Guides *GuideSet
// Command is the framework-neutral schema IR for the host's command tree.
// Hosts build this from an adapter (e.g. cobra.Tree(root)) before mounting
// the agent command group, so the schema represents the host CLI without
// the agent commands themselves.
Command Command
// Out is the host-supplied destination for all emitted output. When nil,
// adapter commands write to their framework's output channel (e.g.
// cobra's cmd.OutOrStdout()). docent itself never writes to stdout.
Out io.Writer
// ContractVersion is the host's own agent-contract version — the number
// a host bumps when its envelope, exit codes, or output shapes change,
// distinct from docent's guide StandardVersion. When set, adapters stamp
// it on discovery surfaces: the schema root gains a "contract_version"
// extensions entry and the guide index gains a contract_version line, so
// an agent can pin behavior to the contract it read. Empty omits the
// stamp everywhere. The value is emitted verbatim into a single
// "key: value" index line — keep it one line with no colons; a plain
// semver string always qualifies. A value containing a newline,
// carriage return, or colon fails index emission with an error
// (export.ErrInvalidContractVersion) rather than corrupting the
// line-oriented shape.
ContractVersion string
}
Config is the host integration surface for docent. The zero value is usable; fields are populated by the host as needed. Hosts mount the agent command group by passing a populated Config to the adapter's NewCommand function.
type Flag ¶
type Flag struct {
// Name is the long flag name without leading dashes.
Name string `json:"name"`
// Shorthand is the single-character flag alias, or empty if none.
Shorthand string `json:"shorthand,omitempty"`
// Description is the flag's usage string.
Description string `json:"description,omitempty"`
// Type is the value type as reported by the flag framework (e.g. "string",
// "bool", "int", "stringSlice").
Type string `json:"type"`
// Default is the default value as a string. Empty means no default or the
// zero value for the type.
Default string `json:"default,omitempty"`
// Enum lists the allowed values when the flag type restricts to a finite
// set. Nil when the flag accepts arbitrary values.
Enum []string `json:"enum,omitempty"`
// Required is true when the flag must be set on every invocation.
Required bool `json:"required,omitempty"`
// Persistent is true when the flag is defined on this command and
// available to every descendant. Each flag appears exactly once in the
// tree — on the command that defines it — so inherited flags are not
// repeated per command; a consumer resolves a command's full flag
// surface by walking its ancestors' persistent flags. When a command's
// local flag shares a name with an ancestor's persistent flag, the
// nearest definition wins for that command.
Persistent bool `json:"persistent,omitempty"`
// Extensions carries structured per-flag metadata the neutral IR does
// not model — placeholders, value hints, display grouping. Like
// Command.Extensions the slot is host-owned, but adapters may contribute
// documented, namespaced entries: the cobra adapter surfaces a gechr/clib
// extras annotation under the "clib" key (with its enum field omitted —
// that is hoisted to Enum). Values must be JSON-marshalable; emission
// sorts keys, and every API boundary deep-copies the map.
Extensions map[string]any `json:"extensions,omitempty"`
}
Flag is a framework-neutral flag definition. Default holds the value exactly as the framework reports it (no type coercion). Enum is non-nil only when the flag's value type exposes a finite set of allowed values.
type FlagGroup ¶
type FlagGroup struct {
// Kind is the relation type: mutually_exclusive, required_together, or
// one_required.
Kind FlagGroupKind `json:"kind"`
// Flags is the sorted list of flag names in the group.
Flags []string `json:"flags"`
}
FlagGroup is a named relation over a set of flag names, attached to the command whose invocation it constrains. A member name may resolve to an ancestor's persistent flag rather than one of the command's own — flags are emitted once, on their defining command.
type FlagGroupKind ¶
type FlagGroupKind string
FlagGroupKind distinguishes the supported flag group relations.
const ( // FlagGroupMutuallyExclusive marks a group where at most one flag may be // set in a single invocation. FlagGroupMutuallyExclusive FlagGroupKind = "mutually_exclusive" // FlagGroupRequiredTogether marks a group where either all flags must be // set or none may be set. FlagGroupRequiredTogether FlagGroupKind = "required_together" // FlagGroupOneRequired marks a group where at least one flag must be set // in every invocation. FlagGroupOneRequired FlagGroupKind = "one_required" )
type Guide ¶
type Guide struct {
// Slug is the unique identifier derived from the filename.
Slug string
// Title is the human-readable name of the guide.
Title string
// Description is a short summary for index views.
Description string
// WhenToUse describes the conditions under which an agent should consult this guide.
WhenToUse string
// Commands lists the CLI command paths relevant to this guide.
Commands []string
// License names the license applied to exported skills built from this
// guide, or references a bundled license file. Optional; emitted in
// skill frontmatter when present.
License string
// Compatibility states environment requirements for exported skills
// (intended product, system packages, network access). Optional; the
// Agent Skills spec caps it at MaxSkillCompatibility characters.
Compatibility string
// Metadata carries additional string key-value properties for exported
// skill frontmatter — the spec's slot for anything it does not define.
// Optional; emitted with sorted keys for determinism.
Metadata map[string]string
// AllowedTools lists tools pre-approved for exported skills (the spec's
// experimental allowed-tools field). Optional; emitted space-separated.
AllowedTools []string
// Aliases lists alternative names Get resolves to this guide — typically
// the names a guide carried before a rename, so agents and scripts that
// memorized them keep working. Aliases are not held to the slug charset
// (legacy names are the point) but must be unique across the set and
// must not shadow any slug.
Aliases []string
// Order is the optional sparse-integer for canonical ordering. Nil means
// the guide has no explicit order and sorts alphabetically after ordered guides.
Order *int
// Sections contains the guide body in its required six-section shape,
// in the order they appear in the file.
Sections []Section
// Raw holds the complete original file bytes, including frontmatter.
Raw []byte
}
Guide is a single loaded and validated runbook. All fields are populated by LoadGuides; the zero value is not meaningful. Guide is a plain, field-only struct: constructing one directly (rather than through LoadGuides) bypasses load-time validation — slug charset, single-line title, and the other invariants LoadGuides enforces — and nothing in the type itself will catch the omission. Downstream consumers, including this package's export functionality, assume those invariants already hold and may produce malformed output for a hand-built Guide that violates them.
func (Guide) Section ¶ added in v0.2.0
Section returns the guide section whose heading matches name case-insensitively — the lookup behind section-scoped serving surfaces like the cobra adapter's --section flag, owned here so adapters cannot drift in matching semantics. The second return value is false when no section matches, mirroring GuideSet.Get.
Example ¶
ExampleGuide_Section looks up one section case-insensitively with the comma-ok idiom.
package main
import (
"fmt"
"testing/fstest"
"github.com/matcra587/docent"
)
// exampleGuide is a minimal valid guide file used by the examples.
const exampleGuide = `---
slug: safe-mutation
title: Preview every write before sending it
description: Validate a mutation with --dry-run, then submit.
when_to_use: Before any create/edit/delete against a live instance.
commands: [item create]
---
## Decide
Which command to use.
## Run
` + "```sh\nitem create --dry-run\n```" + `
## Save
The returned ID.
## Preconditions
Valid auth.
## Recover
Re-authenticate on 401.
## Next
See core-contract.
`
func main() {
fsys := fstest.MapFS{
"safe-mutation.md": &fstest.MapFile{Data: []byte(exampleGuide)},
}
gs, _ := docent.LoadGuides(fsys)
g, _ := gs.Get("safe-mutation")
s, ok := g.Section("preconditions")
fmt.Println(ok, s.Heading)
_, ok = g.Section("missing")
fmt.Println(ok)
}
Output: true Preconditions false
func (Guide) SkillDescription ¶
SkillDescription returns the guide's description and when_to_use composed into the single description field the Agent Skills open standard defines for exported skills. It is the value the agent-skill export emits and the value load-time validation holds to MaxSkillDescription — a single source so the two can never drift apart.
type GuideSet ¶
type GuideSet struct {
// contains filtered or unexported fields
}
GuideSet is a validated, canonically ordered collection of guides. It is immutable: LoadGuides populates it once, and no method mutates it. A nil *GuideSet behaves as an empty set — Guides returns nil, Get reports false, Len returns 0 — so hosts holding an optional set (Config.Guides documents nil as "no guides") can call methods without a guard.
func LoadGuides ¶
LoadGuides reads every *.md file from fsys, parses its YAML frontmatter and Markdown sections, validates each guide against StandardVersion 1, and returns a canonically ordered GuideSet.
Canonical order: guides with an order value ascending (ties broken by slug), followed by unordered guides sorted alphabetically by slug.
Fatal errors (missing frontmatter, absent required fields, slug≠filename, wrong or misordered sections) cause LoadGuides to return nil and a joined error covering every failing guide.
Duplicate order values are validation failures like every other class: the canonical order is a contract, and two guides claiming the same slot is a guide-authoring bug caught in the author's own CI (docenttest.Validate). On any failure the returned GuideSet is nil — a non-nil error is never paired with a usable set.
Example ¶
ExampleLoadGuides loads a guide set from an in-memory filesystem. Real hosts pass a go:embed FS instead.
package main
import (
"fmt"
"testing/fstest"
"github.com/matcra587/docent"
)
// exampleGuide is a minimal valid guide file used by the examples.
const exampleGuide = `---
slug: safe-mutation
title: Preview every write before sending it
description: Validate a mutation with --dry-run, then submit.
when_to_use: Before any create/edit/delete against a live instance.
commands: [item create]
---
## Decide
Which command to use.
## Run
` + "```sh\nitem create --dry-run\n```" + `
## Save
The returned ID.
## Preconditions
Valid auth.
## Recover
Re-authenticate on 401.
## Next
See core-contract.
`
func main() {
fsys := fstest.MapFS{
"safe-mutation.md": &fstest.MapFile{Data: []byte(exampleGuide)},
}
gs, err := docent.LoadGuides(fsys)
if err != nil {
fmt.Println("load:", err)
return
}
for _, g := range gs.Guides() {
fmt.Printf("%s: %s\n", g.Slug, g.Title)
}
}
Output: safe-mutation: Preview every write before sending it
func (*GuideSet) All ¶ added in v0.2.0
All returns an iterator over the guides in canonical order, yielding a deep copy per guide exactly as Guides does — but lazily, so a consumer that stops early never pays for copying the rest of the corpus, and no second slice is retained. Prefer it over Guides when iterating; Guides remains the snapshot form. A nil *GuideSet yields nothing.
Example ¶
ExampleGuideSet_All iterates guides lazily in canonical order; breaking out early skips the cost of copying the remaining guides.
package main
import (
"fmt"
"testing/fstest"
"github.com/matcra587/docent"
)
// exampleGuide is a minimal valid guide file used by the examples.
const exampleGuide = `---
slug: safe-mutation
title: Preview every write before sending it
description: Validate a mutation with --dry-run, then submit.
when_to_use: Before any create/edit/delete against a live instance.
commands: [item create]
---
## Decide
Which command to use.
## Run
` + "```sh\nitem create --dry-run\n```" + `
## Save
The returned ID.
## Preconditions
Valid auth.
## Recover
Re-authenticate on 401.
## Next
See core-contract.
`
func main() {
fsys := fstest.MapFS{
"safe-mutation.md": &fstest.MapFile{Data: []byte(exampleGuide)},
}
gs, _ := docent.LoadGuides(fsys)
for g := range gs.All() {
fmt.Println(g.Slug)
break
}
}
Output: safe-mutation
func (*GuideSet) Get ¶
Get returns the guide with the given slug, or — when no slug matches — the guide declaring the name as an alias, so renamed guides keep answering to their old names. The second return value is false when the name resolves to nothing. The returned guide is a deep copy; mutating it cannot affect the GuideSet.
Example ¶
ExampleGuideSet_Get looks up one guide by slug with the comma-ok idiom.
package main
import (
"fmt"
"testing/fstest"
"github.com/matcra587/docent"
)
// exampleGuide is a minimal valid guide file used by the examples.
const exampleGuide = `---
slug: safe-mutation
title: Preview every write before sending it
description: Validate a mutation with --dry-run, then submit.
when_to_use: Before any create/edit/delete against a live instance.
commands: [item create]
---
## Decide
Which command to use.
## Run
` + "```sh\nitem create --dry-run\n```" + `
## Save
The returned ID.
## Preconditions
Valid auth.
## Recover
Re-authenticate on 401.
## Next
See core-contract.
`
func main() {
fsys := fstest.MapFS{
"safe-mutation.md": &fstest.MapFile{Data: []byte(exampleGuide)},
}
gs, _ := docent.LoadGuides(fsys)
g, ok := gs.Get("safe-mutation")
fmt.Println(ok, g.Sections[0].Heading)
_, ok = gs.Get("missing")
fmt.Println(ok)
}
Output: true Decide false
func (*GuideSet) Guides ¶
Guides returns the guides in canonical order. The returned guides are deep copies; callers cannot mutate the GuideSet through them, including through slice and pointer fields.
func (*GuideSet) Resolve ¶
Resolve returns the guide a typed name refers to, applying progressively looser matching so agents holding an imperfect name still land on the right guide: exact slug, declared alias (both as Get), then the normalized form — case-folded with underscores read as hyphens, so "Auth_Setup" resolves auth-setup — and finally a substring of a normalized slug or alias, accepted only when it matches exactly one guide. An ambiguous substring resolves to nothing rather than guessing. The second return value is false when nothing matches; the returned guide is a deep copy.
Use Get when only declared names should answer — Resolve is for lookup surfaces serving humans and agents, like the cobra adapter's guide command.
type SchemaRegistry ¶
type SchemaRegistry map[string]CommandSchemas
SchemaRegistry maps command paths to host-provided input and output JSON Schema objects. Keys are Command.Path values (space-separated command names, e.g. "app issue create"). An entry with a nil field omits that schema side; only the non-nil side is applied.
Hosts build a registry and call Apply to enrich a Command tree produced by an adapter (e.g. the cobra adapter's Tree function). The registry itself is never modified by Apply.
func (SchemaRegistry) Apply ¶
func (r SchemaRegistry) Apply(cmd Command) Command
Apply walks cmd and its descendants, returning a new Command tree with the registered schemas attached. cmd is not modified. Commands whose Path has no registry entry are copied without schema changes. Schemas from the registry overwrite any schemas already present on a matched command.
type Section ¶
type Section struct {
// Heading is the bare heading text without the leading "## ".
Heading string
// Body is the content that follows the heading, up to the next heading
// or end of file, with trailing newlines stripped. Leading blank lines
// and other trailing whitespace (spaces, tabs) are preserved verbatim.
// Empty bodies are valid per the standard.
Body string
}
Section is a single named heading and its prose body within a guide.
type ValidationError ¶
type ValidationError struct {
// File is the guide filename or identifier where the violation was found.
File string
// Message describes the specific violation in human-readable form.
Message string
// Err is the sentinel that classifies the failure class.
Err error
}
ValidationError carries per-file context about a single validation failure. Unwrap returns the sentinel that classifies the failure, enabling errors.Is and errors.As to reach the sentinel from a joined or wrapped error.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error returns a human-readable description of the validation failure.
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap allows errors.Is and errors.As to traverse the error chain to the sentinel that classifies this failure.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cobra is the docent cobra adapter.
|
Package cobra is the docent cobra adapter. |
|
Package docenttest provides contract-test helpers for docent consumers.
|
Package docenttest provides contract-test helpers for docent consumers. |
|
Package export renders docent guides to exportable text formats.
|
Package export renders docent guides to exportable text formats. |
|
Package harness detects which AI agent runtime is invoking the host CLI.
|
Package harness detects which AI agent runtime is invoking the host CLI. |