Skip to content

Commit 8c4f762

Browse files
authored
feat(ai): add agent skill rendering core (#287)
1 parent 51adab5 commit 8c4f762

9 files changed

Lines changed: 916 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Project structure: `cmd/` (entry points), `internal/` (business logic), `magefil
2929

3030
Documentation structure: `docs/user/reference/cli/` (auto-generated CLI docs, regenerated by `mage docs`), `docs/user/reference/config/` (hand-written TOML config reference), `docs/user/how-to/` (workflow guides), `docs/user/explanation/` (conceptual docs).
3131

32+
**Agent skills track tool behavior.** `internal/app/azldev/agentskill/` emits the AI-agent skills and instruction files that describe azldev's CLI, config, and workflows. After a behavioral change (command syntax, flags, config schema, overlay types, workflows), check whether these need updating — see [instructions/agent-skills.instructions.md](instructions/agent-skills.instructions.md).
33+
3234
The TOML config files in `defaultconfigs/` are loaded via `internal/projectconfig/`.
3335

3436
**IMPORTANT**: Code generation runs automatically with build/test commands. `mage generate` (runs `go generate` for each package in parallel) is a prerequisite for building and runs automatically with `mage build` and `mage unit`. `mage docs` rebuilds the binary and updates the JSON schema (`schemas/azldev.schema.json`) and CLI docs (`docs/user/reference/cli/`). Run `mage docs` explicitly after changing config structs or Cobra command descriptions so that checked-in generated files stay current (checked by PR gates).
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
applyTo: "internal/app/azldev/agentskill/**"
3+
description: "How to maintain azldev's emitted AI-agent skills and instruction files. Read before adding or editing a skill, an instruction wrapper, or the emit mechanism in the agentskill package."
4+
---
5+
6+
# Maintaining the emitted agent skills and instruction files
7+
8+
The `agentskill` package is the **single source of truth** for the AI-agent skill and
9+
instruction files that `azldev docs agent install` writes into distro repositories, and
10+
that `azldev docs agent show` (a read-only MCP tool) serves. Everything is embedded in
11+
the binary so the on-disk files, the CLI output, and the MCP response stay version-matched.
12+
13+
For the full architecture — the registries, the redirect-wrapper-vs-full-body rendering,
14+
and how dynamic values are substituted — read the package doc in
15+
[doc.go](../../internal/app/azldev/agentskill/doc.go).
16+
17+
## Model
18+
19+
- **Skills hold the content.** A `Skill` in the `skills` registry
20+
([agentskill.go](../../internal/app/azldev/agentskill/agentskill.go)) pairs a name with a
21+
body template under [content/](../../internal/app/azldev/agentskill/content/). Skills are the
22+
cross-agent medium — served via `docs agent show` / the `docs-agent-show` MCP tool, or inlined
23+
on disk with `--full`.
24+
- **Instruction files are lightweight wrappers.** An `Instruction` in the `instructions` registry
25+
is selected by its `applyTo` glob and only *points at* skills — `SkillPointer{Skill, Purpose}`
26+
renders as "You MUST read the `<skill>` skill `<purpose>`". Put substantive guidance in a
27+
**skill**, never in a wrapper. Do not make a wrapper reference the CLI or MCP tool — those are
28+
unavailable in `--full` installs; naming the skill works in every mode.
29+
30+
## Adding or editing a skill
31+
32+
1. Add a `Skill{Name, Description, bodyTemplate}` to the `skills` registry.
33+
2. Add a `content/<topic>.md.tmpl` body, named for the topic (e.g. `mock.md.tmpl`,
34+
`azldev.md.tmpl`). The front-matter `name` must equal the skill's base name (and its on-disk
35+
directory), lowercase-hyphen, ≤ 64 chars. The `description` drives discovery, ≤ 1024 chars.
36+
3. Write the description inline in the registry entry. The description is the **load gate**
37+
(an agent decides whether to open the skill from it), so **lead with a directive**
38+
"Read this before <action>; do not <do it> from memory." — then what the skill covers,
39+
then a `Triggers include ...` keyword list.
40+
4. Add a content test in
41+
[agentskill_test.go](../../internal/app/azldev/agentskill/agentskill_test.go) (assert the
42+
front-matter `name` and a distinctive, validated phrase). `TestSkillFrontmatterInvariants`
43+
auto-covers the spec limits.
44+
45+
## Adding or editing an instruction wrapper
46+
47+
1. Add an `Instruction{Name, ApplyTo, Description, Title, Intro, Skills}` to the `instructions`
48+
registry. `ApplyTo` may reference bindings (e.g. `{{ .RenderedSpecsDir }}/**/*`) — it is
49+
rendered against `Params` at emit time.
50+
2. `Skills` is a list of `SkillPointer` — name each skill with a short purpose ("to add or change
51+
overlays").
52+
3. A little hand-written prose here is fine, if it helps direct agents to the right skill. Keep it short, and avoid
53+
repeating the skill content.
54+
4. Keep the count-based tests happy: `Files()` emits one file per skill plus one per instruction.
55+
56+
## Content accuracy is the hard part
57+
58+
Distilled content **drifts**. The azurelinux copies these are distilled from are frequently stale.
59+
Before shipping any skill/instruction:
60+
61+
- **Validate every CLI, flag, and config claim against the current code** (command trees under
62+
`internal/app/azldev/cmds/`, config under `internal/projectconfig/`). Do not trust the source you
63+
distilled from. Confirm with `./out/bin/azldev <cmd> --help` and `azldev config generate-schema`.
64+
- Prefer a **drift-guard test** whenever a code enum can back the content. Example:
65+
`TestOverlaysSkillCoversAllOverlayTypes` extracts the overlay-type enum from the jsonschema tag
66+
on `projectconfig.ComponentOverlay.Type` and fails if the skill omits a type.
67+
68+
## Config-resolved bindings
69+
70+
Repo-specific values (lock dir, rendered-specs dir, work dir) are resolved from the target `azldev.toml` in
71+
[cmds/docs/agent.go](../../internal/app/azldev/cmds/docs/agent.go) and degrade to azldev's defaults
72+
when no config is present. To add a binding, extend `Bindings`, resolve it in `resolveBindings`, and
73+
reference it in a template as `{{ .FieldName }}`.
74+
75+
## Before you commit
76+
77+
- `mage unit` and `mage check all` pass.
78+
- `mage docs` produces **no drift** (adding a registry skill/instruction should not change CLI docs,
79+
the JSON schema, or the MCP snapshot).
80+
- Sanity-check emitted output: `./out/bin/azldev docs agent install -o "$(mktemp -d)"` and
81+
`./out/bin/azldev docs agent show --skill <name>`.

0 commit comments

Comments
 (0)