mirror of
https://github.com/coder/coder.git
synced 2026-11-03 05:55:24 +08:00
Normalizes non-standard code-fence language tags across `docs/**` so a strict highlighter (Shiki, used by Fumadocs) won't fail the build on an unrecognized language, and unifies redundant synonym tags onto one canonical form per language. The current renderer (Speed-Highlight) detects the language from the code content, not the fence label, so this drift wasn't visible until now. ## Changes - `hcl` -> `tf` (199 fences, including indented ones nested in numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**` is actually Terraform resource/data/provider syntax, so the more specific `terraform` grammar is correct for all of them. `tf` is Shiki's own alias for that grammar, and it's also what GitHub's own markdown renderer resolves to the same HCL/Terraform highlighting. - `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a registered file extension (`.ps` isn't), so `ps1` renders identically to `powershell` there today while bare `ps` would silently lose highlighting. - `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files) - `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text fallback either way, just shorter. - `Dockerfile` -> `dockerfile` (lowercase) - `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all three to a single shell grammar; this was already the style guide's stated preference, just not enforced across the existing corpus until now. - `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki and GitHub. - `jsonc` -> `json` (1 fence). The block has no comments or trailing commas, so it doesn't need the comments-capable grammar. - `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`). Verified the actual content tokenizes identically under both grammars, and a sibling block in the same file already needs `tsx` for real JSX, so unifying to one tag is safe for this file. Documented a caveat: `tsx` mis-tokenizes the legacy angle-bracket type-assertion syntax (`<Type>value`), which is invalid in real `.tsx` files anyway, so use `value as Type` instead. - `yml` -> `yaml` (1 fence) - Updated `docs/.style/style-guide/formatting.md` to document all canonical tags `promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki doesn't bundle a grammar for either, so they need a custom grammar registration when the site adopts Shiki, rather than degrading to `txt`. Tracked as follow-up work under DOCS-118 and [DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting) (promql). Does not touch `offlinedocs/`. Linear: [DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs) <details> <summary>How the fence tags were verified</summary> Each tag was tested against a real `shiki@latest` highlighter instance (`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's `@wooorm/starry-night` grammar sources (the renderer that actually displays these `.md` files today, in repo browsing and PR diffs), since that's what determines whether brevity is safe before Shiki adoption: ```text FAIL env -- Language `env` is not included in this bundle. FAIL Dockerfile -- Language `Dockerfile` is not included in this bundle. FAIL promql -- Language `promql` is not included in this bundle. FAIL caddyfile -- Language `caddyfile` is not included in this bundle. FAIL pwsh -- Language `pwsh` is not included in this bundle. FAIL output -- Language `output` is not included in this bundle. ``` `hcl` doesn't error in Shiki, since it's a real grammar, but that's exactly the trap: it was silently rendering every fence with the generic HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged fence in `docs/**` was manually checked against `origin/main` and is genuinely Terraform content. For `ts`/`tsx`, tokenizing the actual doc content confirmed identical output under both grammars; a synthetic test with the legacy angle-bracket cast syntax confirmed `tsx` degrades on that specific construct, which the style guide now calls out. The first normalization pass only matched fence tags at column 0 (`^```tag$`), missing tags indented inside numbered/bulleted lists. A follow-up pass caught the remaining occurrences at any indentation level. </details> --- *This PR description and the underlying changes were prepared with Coder Agents assistance.*
169 lines
5.7 KiB
Markdown
169 lines
5.7 KiB
Markdown
# Extending Agents
|
|
|
|
Workspace templates can extend the agent with custom skills and MCP tools.
|
|
These mechanisms let platform teams provide repository-specific instructions,
|
|
domain expertise, and external tool integrations without modifying the agent
|
|
itself.
|
|
|
|
## Skills
|
|
|
|
Skills are structured, reusable instruction sets that the agent loads on
|
|
demand. They live in the workspace filesystem and are discovered
|
|
automatically when a chat attaches to a workspace.
|
|
|
|
### How skills work
|
|
|
|
Place skill directories under `.agents/skills/` relative to the workspace
|
|
working directory. Each directory contains a required `SKILL.md` file and
|
|
any supporting files the skill needs.
|
|
|
|
On the first turn of a workspace-attached chat, the agent scans
|
|
`.agents/skills/` and builds an `<available-skills>` block in its system
|
|
prompt listing each skill's name and description. Only frontmatter is read
|
|
during discovery. The full skill content is loaded lazily when the agent
|
|
calls a tool.
|
|
|
|
Two tools are registered when skills are present:
|
|
|
|
| Tool | Parameters | Description |
|
|
|-------------------|----------------------------------|------------------------------------------------------------------------------------------------------------|
|
|
| `read_skill` | `name` (string) | Returns the SKILL.md body, the absolute skill directory (workspace skills), and a list of supporting files |
|
|
| `read_skill_file` | `name` (string), `path` (string) | Returns the content of a supporting file |
|
|
|
|
For workspace skills, `read_skill` also returns `dir`, the absolute path to
|
|
the skill directory in the workspace. The agent's `read_file` and `execute`
|
|
tools operate on that same workspace filesystem, so you can join `dir` with a
|
|
supporting file's relative path to read or run that file directly, for example
|
|
to execute a bundled `scripts/` helper. `read_skill_file` remains available as
|
|
a path-safe convenience for reading supporting files.
|
|
|
|
### Directory structure
|
|
|
|
```txt
|
|
.agents/skills/
|
|
├── deep-review/
|
|
│ ├── SKILL.md
|
|
│ └── roles/
|
|
│ ├── security-reviewer.md
|
|
│ └── concurrency-reviewer.md
|
|
├── pull-requests/
|
|
│ └── SKILL.md
|
|
└── refine-plan/
|
|
└── SKILL.md
|
|
```
|
|
|
|
### SKILL.md format
|
|
|
|
Each `SKILL.md` starts with YAML frontmatter containing a `name` and an
|
|
optional `description`, followed by the full instructions in markdown:
|
|
|
|
```md
|
|
---
|
|
name: deep-review
|
|
description: "Multi-reviewer code review with domain-specific reviewers"
|
|
---
|
|
|
|
# Deep Review
|
|
|
|
Instructions for the skill go here...
|
|
```
|
|
|
|
### Naming and size constraints
|
|
|
|
- Names must be kebab-case (`^[a-z0-9]+(-[a-z0-9]+)*$`) and match the
|
|
directory name exactly.
|
|
- `SKILL.md` has a maximum size of 64 KB.
|
|
- Supporting files have a maximum size of 512 KB. Files exceeding the limit
|
|
are silently truncated.
|
|
|
|
### Path safety
|
|
|
|
`read_skill_file` rejects absolute paths, paths containing `..`, and
|
|
references to hidden files. All paths are resolved relative to the skill
|
|
directory.
|
|
|
|
## Personal skills
|
|
|
|
Personal skills are user-owned skills that are available to all of your
|
|
chats. They are not tied to a specific workspace. Manage them from the
|
|
**Agents** page, under **Settings** > **Personal Skills**.
|
|
|
|
Personal skills use the same `SKILL.md` format as workspace skills: YAML
|
|
frontmatter with a kebab-case `name`, an optional `description`, and a
|
|
markdown body. This keeps content portable between personal skills and
|
|
workspace skills.
|
|
|
|
```md
|
|
---
|
|
name: personal-reviewer
|
|
description: "Personal review guidance"
|
|
---
|
|
|
|
# Personal Reviewer
|
|
|
|
Instructions for the skill go here...
|
|
```
|
|
|
|
Each personal skill is stored as a single `SKILL.md` file containing
|
|
frontmatter and body content. Supporting files are not supported. Each
|
|
`SKILL.md` file can be up to 64 KB, and each user can create up to 100
|
|
personal skills.
|
|
|
|
If you need richer skills with supporting files or multiple files, use
|
|
workspace skills instead. Store them in the repo under
|
|
`.agents/skills/<name>/`, or load them from a workspace.
|
|
|
|
## Workspace MCP tools
|
|
|
|
Workspace templates can expose custom
|
|
[MCP](https://modelcontextprotocol.io/introduction) tools by placing a
|
|
`.mcp.json` file in the workspace working directory. The agent discovers
|
|
these tools automatically when it connects to a workspace and registers
|
|
them alongside its built-in tools.
|
|
|
|
### Configuration
|
|
|
|
Define MCP servers in `.mcp.json` at the workspace root. Each entry under
|
|
`mcpServers` describes a server. The transport type is inferred from
|
|
whether `command` or `url` is present, or you can set it explicitly with
|
|
`type`:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"github": {
|
|
"command": "github-mcp-server",
|
|
"args": ["--token", "..."]
|
|
},
|
|
"my-api": {
|
|
"type": "http",
|
|
"url": "http://localhost:8080/mcp",
|
|
"headers": { "Authorization": "Bearer ..." }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Stdio transport**: set `command`, and optionally `args` and `env`. The
|
|
agent spawns the process in the workspace.
|
|
|
|
**HTTP transport**: set `url`, and optionally `headers`. The agent connects
|
|
to the HTTP endpoint from the workspace.
|
|
|
|
### How discovery works
|
|
|
|
The agent reads `.mcp.json` via the workspace agent connection on each chat
|
|
turn. Discovery uses a 5-second timeout. Servers that fail to
|
|
respond are skipped. Partial success is acceptable. Empty results are not
|
|
cached because the MCP servers may still be starting.
|
|
|
|
### Tool naming
|
|
|
|
Tool names are prefixed with the server name as `serverName__toolName` to
|
|
avoid collisions between servers and with built-in tools.
|
|
|
|
### Timeouts
|
|
|
|
- **Discovery**: 5-second timeout.
|
|
- **Tool calls**: 60 seconds per invocation.
|