diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8d469cf..07f0932 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,4 +13,4 @@ - [ ] **No unsourced claim added**: no invented statistics, testimonials, customer names, awards, urgency, or superlatives, in the components or in this repo's own docs (`references/claims-and-evidence.md`) - [ ] Inventories and counts in README/AGENTS.md verified against the tree - [ ] New or renamed component wired into the router **and** `hooks/session-start.sh` (the validator enforces this) -- [ ] Version bumped and [CHANGELOG.md](../CHANGELOG.md) updated (if component content changed); see [docs/versioning.md](../docs/versioning.md) +- [ ] Version bumped, README version badge updated, and [CHANGELOG.md](../CHANGELOG.md) updated (if component content changed); see [docs/versioning.md](../docs/versioning.md) diff --git a/AGENTS.md b/AGENTS.md index 1b94918..18a9d7a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,9 @@ The **Docs Editing Plugin** (`docs-editing`) is an AI plugin by Cadasto B.V. tha It is **general-purpose and stack-agnostic** by design: the components operate on prose (`*.md`, page copy, site metadata, `llms.txt`) and on the target repository's own conventions, so the same skills serve an MkDocs site, a Docusaurus site, and a plain `docs/` tree unchanged. -> **Do not assume a component exists because it is documented here; check the tree first.** The shipped surface is the auto-invoked `docs-editing` **router**; the worker skills `technical-writing`, `copy-editing`, `humanize`, `marketing-copy`, `seo-audit`, `ai-seo`; the user-invoked `/docs-lint-setup`; the report-only `prose-reviewer` and `seo-auditor` agents; five canonical references plus the reference `vale.ini`, its `vocab-accept.txt` seed and the `ai-tells` Vale style; the `rules/docs-editing-context.mdc` Cursor rule; and host-agnostic `session-start` + `prose-lint-on-save` hooks. The current version and what changed in it live in `CHANGELOG.md` and the git tags, not here, where they only go stale. +> **Do not assume a component exists because it is documented here; check the tree first.** The shipped surface is the auto-invoked `docs-editing` **router**; seven worker skills: `technical-writing`, `copy-editing`, `humanize`, `marketing-copy`, `seo-audit`, `ai-seo`, and `docs-lint-setup` (the Vale scaffolder, usually run as `/docs-lint-setup`); the report-only `prose-reviewer` and `seo-auditor` agents; five canonical references plus the reference `vale.ini`, its `vocab-accept.txt` seed and the `ai-tells` Vale style; the `rules/docs-editing-context.mdc` Cursor rule; and host-agnostic `session-start` + `prose-lint-on-save` hooks. The current version and what changed in it live in `CHANGELOG.md` and the git tags, not here, where they only go stale. + +Scope is the **human-facing prose and content layer**. Deliberately **not** in scope: **agent-instruction files** (read for conventions, never authored; see the [audience boundary](#audience-boundary-human-facing-prose-only)); source-code review; specification, requirement, and traceability authoring (the `sdd` plugin's layer); and domain facts, which come from the target repo's named ground-truth source. This keeps the surface small and non-colliding. The human-facing pitch is [README.md](README.md); do not restate it here. ## Domain Context @@ -54,7 +56,7 @@ This repo supports **both Claude Code and Cursor**; shared assets (skills, agent - **Claude manifest**: `.claude-plugin/plugin.json`: `name` (`docs-editing`), `version`, `description`, `author` (an **object** `{name, url}`; `claude plugin validate` rejects a bare string), `license`, `repository`, `keywords`. Claude Code discovers components from the **default folders** (`skills/`, `agents/`, `hooks/`) automatically. - **Cursor manifest**: `.cursor-plugin/plugin.json`: same metadata **plus** explicit top-level path keys (`skills`, `agents`, `rules`, `hooks`). No `mcpServers`: this plugin has no MCP backend. Keep `name`/`version`/`description`/`author` identical to the Claude manifest. -- **Skills**: `skills//SKILL.md`, shared by both hosts. The seven worker skills carry `argument-hint` + `allowed-tools` so they are both auto-invoked on intent and user-invocable as `/`; `docs-editing` is the always-on router. **Skills use `allowed-tools:` (the Claude Code skill/command key; Cursor reads it too); only agents use `tools:`.** +- **Skills**: `skills//SKILL.md`, shared by both hosts. The seven worker skills carry `argument-hint` + `allowed-tools` so they are both auto-invoked on intent and user-invocable as `/`; `docs-editing` is the always-on router (`allowed-tools`, no `argument-hint`). **Skills use `allowed-tools:` (the Claude Code skill/command key; Cursor reads it too); only agents use `tools:`.** - **Agents**: `agents/.md`: report-only, context-isolated specialists (`tools:` not `allowed-tools:`). Neither declares `Write`/`Edit`; both declare `Bash` to run the linters, so the no-edit property is a contract in the body, not a sandbox. - **References**: `references/`: the five canonical rule documents plus the reference linter config (`vale.ini`), the `vocab-accept.txt` vocabulary seed it points at, and the plugin's own Vale style in `vale-styles/ai-tells/`, which `/docs-lint-setup` copies into a repo's `styles/`. Components cite these instead of duplicating rules. - **Cursor rules**: `rules/*.mdc`: Cursor-only rule guidance (`description` / `globs` / `alwaysApply`), referenced by the Cursor manifest's `rules` path. Shipped: `rules/docs-editing-context.mdc`. @@ -62,13 +64,11 @@ This repo supports **both Claude Code and Cursor**; shared assets (skills, agent - **Cursor hooks**: `hooks/cursor-hooks.json`: object `{ "version": 1, "hooks": { "sessionStart": [...], "afterFileEdit": [...] } }`; the command runs from the plugin root (**workspace-relative**, **not** `${CLAUDE_PLUGIN_ROOT}`). - **Shared hook scripts**: `hooks/session-start.sh` (detects a docs/content workspace and prints context + the skill surface) and `hooks/prose-lint-on-save.sh` (reports `vale` alerts for the just-edited Markdown file). Both host-agnostic; both exit 0 always. - **Claude settings**: `.claude/settings.json` enables the maintainer plugins used while developing this repo (skill-creator, superpowers, plugin-dev, claude-md-management) and pre-approves the validate commands; `.claude/CLAUDE.md` imports this file via `@../AGENTS.md`. `.claude/settings.local.json` is gitignored. -- **Validation**: `scripts/validate.sh` (graceful local wrapper: warns and skips if Python is absent) runs `scripts/validate.py`, which checks both manifests, dual-host parity, declared component paths, kebab-case names, hook-config JSON *and script executability*, skill/agent/rule frontmatter, plus the four plugin-specific invariants below. Stdlib-only. CI pins Python, runs the validator strictly, and `bash -n`s both hook scripts ([`.github/workflows/validate.yml`](.github/workflows/validate.yml)). -- **Contributor docs**: `docs/` holds committed human-facing references: [install](docs/install.md), [testing](docs/testing.md), [versioning](docs/versioning.md), [authoring](docs/authoring.md). `.github/` holds issue + PR templates, `copilot-instructions.md`, and the validate workflow. (Planning/research working notes under `docs/plans/` and `docs/research/` are gitignored, not part of the published plugin.) +- **Validation**: `scripts/validate.sh` (graceful local wrapper: warns and skips if Python is absent) runs `scripts/validate.py`, stdlib-only; the full list of checks, including the four plugin-specific invariants (reference resolution, links and anchors, tool grants, doc sync), is owned by [docs/testing.md](docs/testing.md#validation). CI pins Python, runs the validator strictly, and `bash -n`s both hook scripts ([`.github/workflows/validate.yml`](.github/workflows/validate.yml)). +- **Contributor docs**: `docs/`, where each page **owns** its topic and this file keeps only the one-line rule plus a pointer: [install](docs/install.md) (marketplace, `--plugin-dir`, Cursor, host toolchain), [authoring](docs/authoring.md) (naming, layout, `description`, body, adding a component), [testing](docs/testing.md) (validator checks, triggering tests), [versioning](docs/versioning.md) (SemVer, release steps, marketplace repin). When a convention changes, update the owning page and do not restate it in two places. `.github/` holds issue + PR templates, `copilot-instructions.md`, and the validate workflow. (Planning/research working notes under `docs/plans/` and `docs/research/` are gitignored, not part of the published plugin.) ## Components -Scope is the **human-facing prose and content layer**. Deliberately **not** in scope: **agent-instruction files** (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `rules/*.mdc`, `.github/copilot-instructions.md`, skill and agent definitions; read for conventions, never authored; see the audience boundary above); source-code review; specification, requirement, and traceability authoring (the `sdd` plugin's layer); and domain facts, which come from the target repo's named ground-truth source. This keeps the surface small and non-colliding. - ### Skills (8) | Skill | Purpose | @@ -106,18 +106,16 @@ claude plugin validate . # manifest + component structure claude --plugin-dir /path/to/docs-editing-plugin # load a working copy (session-scoped) ``` -Then exercise the components on a real docs repository and verify skill auto-triggering and both agents on both hosts. Fuller guidance: [`docs/`](docs/). +Then exercise the components on a real docs repository and verify skill auto-triggering and both agents on both hosts; the per-component checks are in [docs/testing.md](docs/testing.md#local-triggering-tests). **The regression test that matters most:** ask any skill to make a technical page "more compelling" with no source material available. Correct behaviour is to **name what it cannot claim** and offer specificity instead. A plausible statistic, a testimonial, or "trusted by teams worldwide" is a **defect in the component**, not a prompt problem. Fix it in `references/claims-and-evidence.md`, not only in the skill that slipped. ### File Conventions -- Skills go in `skills//SKILL.md` (this includes user-invoked slash commands, carrying `argument-hint`/`allowed-tools`); agents in `agents/.md`; Cursor rules in `rules/.mdc`. The legacy `commands/.md` layout is **not** used; host validators treat every `commands/**/*.md` as a command and warn on missing frontmatter. -- Shared reference material lives in top-level **`references/`**, never under `commands/`. +- Skills go in `skills//SKILL.md` (this includes user-invoked slash commands, carrying `argument-hint`/`allowed-tools`); agents in `agents/.md`; Cursor rules in `rules/.mdc`. The legacy `commands/.md` layout is **not** used; host validators treat every `commands/**/*.md` as a command and warn on missing frontmatter. Rationale, naming (task-named, unprefixed worker skills), and the `description` and body conventions: [docs/authoring.md](docs/authoring.md). - All Markdown components use YAML frontmatter; frontmatter `name` MUST equal the directory (skills) or filename stem (agents). - Use **kebab-case** for all directory and file names. -- `allowed-tools:` (skills) pre-approves tools; **agents use `tools:`**; `allowed-tools:` in an agent file is ignored and the agent silently inherits all tools. -- Worker skills are named for the **task**, unprefixed (`copy-editing`, not `docs-copy-editing`); they read better as `/copy-editing`, and the plugin namespace already disambiguates. +- `allowed-tools:` (skills) pre-approves tools; **agents use `tools:`** (see Gotchas). - Skill bodies are imperative and **cite `references/`** rather than restating rules. Every component carries the one-line note that `references/` resolves from the **plugin root**. - Use `${CLAUDE_PLUGIN_ROOT}` for intra-plugin paths in Claude hook fields; never hardcode absolute paths or `~`. - **This repo's own human-facing prose follows its own rules.** README, `docs/`, and CHANGELOG are held to `references/style-guide.md` and `references/claims-and-evidence.md`. Dogfooding is the cheapest test the plugin has. This file and the component bodies are agent-instruction prose: the claims rule still binds them, the style guide does not. @@ -126,10 +124,6 @@ Then exercise the components on a real docs repository and verify skill auto-tri When adding or renaming a component, update in lockstep: the **router's routing table** (`skills/docs-editing/SKILL.md`), the announced surface in **`hooks/session-start.sh`**, **AGENTS.md** (component tables), **README.md**, and **CHANGELOG.md**. The first two are **enforced by `scripts/validate.py`** and fail CI if skipped; the rest are on you. The full ordered procedure is in [docs/authoring.md](docs/authoring.md#adding-a-component). -### Versioning - -Plugin version (and, for consistency, description and author) must be kept in sync in **both** `.claude-plugin/plugin.json` and `.cursor-plugin/plugin.json`. Follow Semantic Versioning; update both manifests and **CHANGELOG.md** when releasing. See [docs/versioning.md](docs/versioning.md). - ### CHANGELOG style - Entries go under `## [Unreleased]` while work is in flight and fold into the next `## [X.Y.Z] - YYYY-MM-DD` section at release. @@ -140,9 +134,13 @@ Plugin version (and, for consistency, description and author) must be kept in sy Follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), e.g. `feat(skills): add copy-editing skill`, `fix(agents): correct tools list in prose-reviewer`. Scopes: `skills`, `agents`, `hooks`, `references`, `rules`, `docs`. +### Versioning + +Plugin version (and, for consistency, description and author) must be kept in sync in **both** `.claude-plugin/plugin.json` and `.cursor-plugin/plugin.json`. Follow Semantic Versioning; update both manifests and **CHANGELOG.md** when releasing. Tags are annotated `vX.Y.Z` (`git tag -a`). The bump rules and release steps are owned by [docs/versioning.md](docs/versioning.md); a tag ships nothing until the marketplace entry is repinned (see Gotchas). + ### Branching -Use feature branches and pull requests. Validation runs on every push/PR. +Use feature branches and pull requests. CI ([`.github/workflows/validate.yml`](.github/workflows/validate.yml)) runs on every pull request and on pushes to `main`. ## Gotchas diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b92e0d..eea57ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,22 @@ # Changelog -All notable changes to this project will be documented in this file. +All notable changes to this project are recorded in this file. -The format is based on Keep a Changelog, and this project adheres to Semantic Versioning. - -- Keep a Changelog: https://keepachangelog.com/en/1.1.0/ -- Semantic Versioning: https://semver.org/spec/v2.0.0.html +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Docs: `README.md` gains a badge row, a requirements paragraph, a table of contents and a `Features` list; `Install` and `Component surface` become `Installation` and `Components`, and the scope section folds into the intro and `How it decides`. +- Docs: `README.md` links the validator's four plugin-specific invariants in `docs/testing.md` instead of restating them. +- Docs: each `docs/` page opens with a paragraph naming its reader and purpose. +- Docs: `docs/testing.md` adds a `/humanize` smoke test and checks that `/docs-lint-setup` copies the `ai-tells` style. +- Docs: `docs/versioning.md` adds a release step to update the README version badge. + +### Fixed +- Docs: `docs/install.md` no longer lists `go install` as a Vale install route, and names one prose linter instead of two. +- Docs: `docs/testing.md` says to load a working copy with `--plugin-dir`, not install it. + ## [0.4.0] - 2026-09-24 Adds `/humanize` and the `ai-tells` catalogue and Vale style, and makes the house style em-dash free: the assistant writes none, a human author's deliberate dash is kept, and the plugin's own prose now follows the rule. diff --git a/README.md b/README.md index 9c3962c..13dea62 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,53 @@ # Docs Editing Plugin -An AI plugin by **Cadasto B.V.** that teaches AI coding assistants **documentation, editing, and content standards** (technical writing, copy editing, marketing copy, SEO, and AI citability) through skills, two report-only review agents, session-start and prose-lint hooks, and a Cursor rule. It targets **both Claude Code and Cursor** from a single shared component set. +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) +[![Version](https://img.shields.io/badge/version-0.4.0-blue)](CHANGELOG.md) +[![Claude Code](https://img.shields.io/badge/Claude_Code-plugin-D97757?logo=anthropic&logoColor=white)](https://claude.ai/code) +[![Cursor](https://img.shields.io/badge/Cursor-plugin-000?logo=cursor&logoColor=white)](https://cursor.com) +[![Keep a Changelog](https://img.shields.io/badge/Keep%20a%20Changelog-1.1.0-E05735)](CHANGELOG.md) -Pure Markdown + JSON. No build step and **no MCP server** to wire up. +An AI plugin by **Cadasto B.V.** that teaches AI coding assistants documentation, editing, and content standards: technical writing, copy editing, AI-tell cleanup, marketing copy, SEO, and AI citability. It is for anyone who has an assistant write or edit human-facing docs. It adds eight skills, two report-only review agents, a session-start hook, a prose-lint hook, and a Cursor rule, shared by **Claude Code** and **Cursor** from one component set. -## The rule that defines it +The plugin owns the prose and content layer, and one rule defines it: a claim that cannot be traced to a source does not ship ([why](#the-rule-that-defines-it)). It reads agent-instruction files (`AGENTS.md`, `CLAUDE.md`, rule files, skill and agent definitions) for a repository's conventions but never writes them. It does not review source code, and it leaves specification, requirement, and traceability authoring to the `sdd` plugin. Domain facts come from the target repository's named ground-truth source, never from the plugin. -> **A claim that cannot be traced to a source does not ship.** +**Requirements.** A Claude Code or Cursor host; nothing else. The skills apply the standards by judgment with no tooling installed. To make the prose rules machine-enforced, install [Vale](https://vale.sh) and run `/docs-lint-setup` in your repository; see [Host toolchain](docs/install.md#host-toolchain-optional-but-recommended). Without Vale the prose-lint hook stays silent. The plugin is pure Markdown + JSON, with no build step and no MCP server. -Generative copy tooling fails in one predictable way: asked to make a page more persuasive, it invents the persuasion: statistics, customer counts, testimonials, awards, urgency. Those are the conventional ingredients of landing-page copy, which is exactly why they get fabricated. +## Table of contents -For a technical audience they also backfire. Developers, engineers, and clinicians read an unsourced number as evidence of unseriousness, so the growth-copy move that lifts conversion on a consumer page lowers trust here. Every skill in this plugin substitutes the same thing instead, the **observable mechanism**: +- [Features](#features) +- [Installation](#installation) +- [Components](#components) +- [The rule that defines it](#the-rule-that-defines-it) +- [How it decides](#how-it-decides) +- [Development](#development) +- [Documentation](#documentation) +- [License](#license) -> ❌ "Cuts documentation review time by 40%." -> ✅ "Flags unsourced statistics, doc-kind bleed, and inventories that no longer match the tree." +## Features -Specific, checkable, and more convincing to this reader than a number they assume was invented. Hedging is not an escape hatch: "up to", "designed to", and "teams report" preserve the violation. The full rule, including the never-invent list and the repair pattern, is [`references/claims-and-evidence.md`](references/claims-and-evidence.md). +- **Evidence before persuasion**: every skill replaces an invented statistic, testimonial, or superlative with the observable mechanism, per [`references/claims-and-evidence.md`](references/claims-and-evidence.md). +- **Writing and editing**: `/technical-writing` drafts new docs in one document kind, `/copy-editing` tightens existing prose under a stated contract, and `/humanize` removes AI tells. +- **Marketing copy**: `/marketing-copy` writes landing, feature, and announcement copy for technical readers, with the anti-fabrication guardrails applied before drafting. +- **Discoverability**: `/seo-audit` audits the published output for search engines; `/ai-seo` covers `llms.txt`, Markdown twins, and JSON-LD. +- **Prose linting**: `/docs-lint-setup` scaffolds Vale with the `ai-tells` style, and the prose-lint hook reports Vale alerts after each Markdown edit without rewriting the file. +- **Independent review**: the report-only `prose-reviewer` and `seo-auditor` agents return ranked findings in an isolated context. -## Install +## Installation **Claude Code**, from the Cadasto marketplace: -``` +```text /plugin marketplace add Cadasto/plugin-marketplace /plugin install docs-editing@cadasto ``` -Or load a local working copy for one session: `claude --plugin-dir /path/to/docs-editing-plugin`. +Or load a local working copy for a single session: `claude --plugin-dir /path/to/docs-editing-plugin`. -**Cursor**: add this repository as a plugin (Settings → Plugins). See [`docs/install.md`](docs/install.md) for both hosts. +**Cursor**: add this repository through Cursor's plugin flow (Settings → Plugins), from a Git URL or a local path. The repository includes a Cursor manifest at [`.cursor-plugin/plugin.json`](.cursor-plugin/plugin.json); skills, agents, and references are shared with the Claude plugin. -**Prerequisites**: none. The skills apply the standards by judgment with no tooling installed. To make the prose rules machine-enforced, install [Vale](https://vale.sh) and run `/docs-lint-setup` in your repo; see [Host toolchain](docs/install.md#host-toolchain-optional-but-recommended). +See [docs/install.md](docs/install.md) for marketplace, local-development, update, and Cursor install details. -## Component surface +## Components | Component | Status | Purpose | |-----------|--------|---------| @@ -51,21 +66,30 @@ Or load a local working copy for one session: `claude --plugin-dir /path/to/docs | References | shipped | The canonical rules, cited by every component: [claims and evidence](references/claims-and-evidence.md), [house style](references/style-guide.md), [document kinds](references/doc-types.md), [AI tells](references/ai-tells.md), [SEO checklist](references/seo-checklist.md), plus the reference `vale.ini`, its `vocab-accept.txt` seed and the `ai-tells` Vale style. | | Cursor rule `docs-editing-context.mdc` | shipped | Markdown- and docs-scoped guidance mirroring the router for Cursor. | -## What it covers +## The rule that defines it + +> **A claim that cannot be traced to a source does not ship.** -**Prose written for people**: documentation, guides, references, page and marketing copy, changelogs, release notes, site metadata, `llms.txt`. +Generative copy tooling fails in one predictable way: asked to make a page more persuasive, it invents the persuasion (statistics, customer counts, testimonials, awards, urgency). Those are the conventional ingredients of landing-page copy, which is why they get fabricated. -**Not agent-instruction files.** `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, rule files, and skill or agent definitions are **read** for a repo's conventions and never authored or rewritten by these components. They address a model rather than a reader, which inverts three of the rules here: repetition becomes deliberate, hard constraints must stay hard, rigid parallel structure becomes a feature. A prose editor tuned for human readers quietly degrades them, so that genre belongs to tooling built for it. Also out of scope: source-code review, and specification/traceability authoring. +For a technical audience they also backfire. Developers, engineers, and clinicians read an unsourced number as evidence of unseriousness, so the growth-copy move that lifts conversion on a consumer page lowers trust here. Every skill in this plugin substitutes the **observable mechanism** instead: + +> ❌ "Cuts documentation review time by 40%." +> ✅ "Flags unsourced statistics, doc-kind bleed, and inventories that no longer match the tree." + +The mechanism is specific and checkable, and it convinces this reader more than a number they assume was invented. Hedging is no escape: "up to", "designed to", and "teams report" preserve the violation. The full rule, including the never-invent list and the repair pattern, is [`references/claims-and-evidence.md`](references/claims-and-evidence.md). ## How it decides -Three principles, in priority order: +One constraint comes first: **the repository being worked on outranks this plugin.** Every skill reads the target repo's `AGENTS.md`, style guide, and linter config first, and reports a conflict rather than silently overriding it, including any named ground-truth source for domain facts. -1. **Evidence before persuasion**: the rule above. It outranks every stylistic preference. +Within that constraint, three principles apply in priority order: + +1. **Evidence before persuasion**: [the rule that defines it](#the-rule-that-defines-it). It outranks every stylistic preference. 2. **One document kind per file**: most bad documentation is a tutorial and a reference merged into one page. Decide the kind first ([Diátaxis](https://diataxis.fr)-based; see [`references/doc-types.md`](references/doc-types.md)), then write only that kind. 3. **Deterministic beats prose**: whatever `vale` enforces, run the tool rather than reasoning it out by hand. Markdown *structure* has no shipped enforcer; those conventions are applied by judgment. -And one constraint above all three: **the repository being worked on outranks this plugin.** Every skill reads the target repo's `AGENTS.md`, style guide, and linter config first, and reports a conflict rather than silently overriding it, including any named ground-truth source for domain facts. +The components write **prose for people**: documentation, guides, references, page and marketing copy, changelogs, release notes, site metadata, `llms.txt`. Agent-instruction files address a model rather than a reader, which inverts three of the rules here: repetition becomes deliberate, hard constraints must stay hard, and rigid parallel structure becomes a feature. A prose editor tuned for human readers quietly degrades them, so that genre belongs to tooling built for it. ## Development @@ -76,22 +100,15 @@ No build step: the plugin is pure Markdown + JSON. Validate locally: claude plugin validate . # manifest + component structure ``` -Beyond the shared checks, the validator enforces four invariants specific to this plugin: - -- **Reference resolution**: every `references/` a component cites exists. The bundled references sit at the plugin root, so a stale path fails silently at load time instead of erroring. -- **Markdown links**: every relative link resolves, and every `#anchor` matches a heading in the file it points at. -- **Tool grants**: a component whose body prescribes a shell command declares `Bash`, and no agent declares `Write` or `Edit`. Advice a component cannot act on is a defect, not a nuance. -- **Doc sync**: every skill and agent is named in both the router body and the session-start surface. - -See [`docs/testing.md`](docs/testing.md) for the full validation story and [`AGENTS.md`](AGENTS.md) for contributor conventions. +Beyond the checks shared with the sibling Cadasto plugins, the validator enforces four invariants specific to this plugin: reference resolution, Markdown links and anchors, tool grants, and doc sync. The [Validation section of docs/testing.md](docs/testing.md#validation) defines each one and the drift it guards against. See [`AGENTS.md`](AGENTS.md) for contributor conventions. ## Documentation - [docs/install.md](docs/install.md): install on both hosts, and the optional linter toolchain - [docs/testing.md](docs/testing.md): validate and dogfood -- [docs/versioning.md](docs/versioning.md): SemVer + release steps -- [docs/authoring.md](docs/authoring.md): skill / agent / rule authoring conventions +- [docs/versioning.md](docs/versioning.md): SemVer and release steps +- [docs/authoring.md](docs/authoring.md): skill, agent, and rule authoring conventions ## License -[MIT](LICENSE) © 2026 Cadasto B.V. +[MIT](LICENSE) diff --git a/docs/authoring.md b/docs/authoring.md index 79a06c7..829c684 100644 --- a/docs/authoring.md +++ b/docs/authoring.md @@ -1,8 +1,8 @@ # Skill, agent, and rule authoring conventions -The detailed companion to [AGENTS.md](../AGENTS.md) (which is authoritative); this expands on the *how*. The shipped components are the reference examples. +This page is for contributors adding or changing a skill, agent, or Cursor rule in this repository: naming and layout, the trigger `description`, body conventions, and the order of work that keeps the validator passing. [AGENTS.md](../AGENTS.md) is authoritative; this page expands on the *how*, and the shipped components are the reference examples. -## Naming & layout +## Naming and layout - **Components are kebab-case** and namespaced `:` (for example `docs-editing:copy-editing`). A component's frontmatter `name` MUST equal its directory (skills) or filename stem (agents); `scripts/validate.py` enforces this. - `skills//SKILL.md` (includes user-invoked slash commands) · `agents/.md` · `rules/.mdc`. Shared reference material lives in top-level **`references/`**. The legacy `commands/.md` layout is not used; host validators treat every `commands/**/*.md` as a command and warn on missing frontmatter. diff --git a/docs/install.md b/docs/install.md index 7a2e4a1..3f825fe 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,14 +1,12 @@ # Installing the Docs Editing Plugin -> Pure Markdown + JSON; there is no build step and **no MCP server** to wire up. - -Distributed for both [Claude Code](https://docs.claude.com/en/docs/claude-code/plugins) (`.claude-plugin/`) and [Cursor](https://cursor.com/docs/plugins) (`.cursor-plugin/`). Skill, agent, and reference content is shared; only the manifest and hook layer differ. +This page is for anyone installing, updating, or loading a working copy of the plugin on [Claude Code](https://docs.claude.com/en/docs/claude-code/plugins) (`.claude-plugin/`) or [Cursor](https://cursor.com/docs/plugins) (`.cursor-plugin/`), and for setting up the optional Vale toolchain. Skill, agent, and reference content is shared; only the manifest and hook layer differ. The plugin is pure Markdown + JSON, with no build step and **no MCP server** to wire up. ## Claude Code ### Install (from the Cadasto marketplace) -``` +```text /plugin marketplace add Cadasto/plugin-marketplace /plugin install docs-editing@cadasto ``` @@ -38,7 +36,7 @@ claude plugin validate . # manifest + component structure claude plugin details docs-editing # component inventory + projected token cost ``` -``` +```text /plugin marketplace update cadasto /plugin update docs-editing ``` @@ -53,15 +51,15 @@ Add this repository as a plugin (Cursor **Settings → Plugins**, via Git URL or ## Host toolchain (optional but recommended) -The plugin installs and its skills work with no tooling at all. Two prose linters make the mechanical half of the house style machine-enforced rather than a reviewer's problem: +The plugin installs and its skills work with no tooling at all. One prose linter, Vale, makes the mechanical half of the house style machine-enforced rather than a reviewer's problem: | Tool | Owns | Install | |---|---|---| -| **[Vale](https://vale.sh)** | Prose style: voice, hedges, weasel words, condescension, terminology | `brew install vale`, `go install github.com/errata-ai/vale/v3/cmd/vale@latest`, or a release binary | +| **[Vale](https://vale.sh)** | Prose style: voice, hedges, weasel words, condescension, terminology | A [release binary](https://github.com/vale-cli/vale/releases) or `brew install vale` | Vale checks **prose**, not Markdown structure. Heading nesting, fence language tags, and trailing whitespace are conventions applied by judgment (`references/style-guide.md` §6); this plugin ships no structural linter. Where a repo already runs one, the skills respect its config. -Run `/docs-lint-setup` in a repository to scaffold `.vale.ini` from the plugin's reference config, seed the Vale vocabulary, and gitignore the downloaded style packages. Then: +Run `/docs-lint-setup` in a repository to scaffold `.vale.ini` from the plugin's reference config, seed the Vale vocabulary, copy the `ai-tells` style, and gitignore the downloaded style packages. Then: ```bash vale sync # download the style packages named in .vale.ini @@ -69,7 +67,7 @@ vale . vale --minAlertLevel=error . # errors only -- the triage baseline ``` -Vale exits `0` clean, `1` on findings, `2` on a config error. Install it from the [release binaries](https://github.com/vale-cli/vale/releases); `go install` currently fails to build. +Vale exits `0` clean, `1` on findings, `2` on a config error. Prefer the [release binaries](https://github.com/vale-cli/vale/releases); `go install` currently fails to build. Without Vale the skills still apply the standards by judgment, and the save hook stays silent. diff --git a/docs/testing.md b/docs/testing.md index 4a30a10..fffc366 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -1,6 +1,6 @@ # Testing and validation -This is a pure-content repository: JSON manifests + Markdown components, with no build step and no package manager. Testing means validating structure, then installing locally and exercising the components. +This page is for contributors checking a change before a pull request or a release. The repository is pure content (JSON manifests and Markdown components, with no build step and no package manager), so testing means validating structure, then loading a working copy and exercising each component. ## Validation @@ -32,17 +32,18 @@ All four are negative-tested: adding a component without wiring it in, citing a ## Local triggering tests -Install from your working copy (see [install.md](install.md)), then exercise each component. The most thorough test is to **dogfood the plugin on a real docs repository**. +Load your working copy with `--plugin-dir` (see [install.md](install.md)), then exercise each component. The most thorough test is to **dogfood the plugin on a real docs repository**. - **Session-start hook**: open a repo with a `docs/` tree containing Markdown, or an `mkdocs.yml`; one docs-standards line should print. Open a repo with only a `README.md` and confirm it stays **silent**. - **`prose-lint-on-save` hook**: in a repo with a `.vale.ini`, edit a `.md` file and confirm alerts print and **the file is not rewritten**. Remove the config and confirm the hook goes silent. - **`docs-editing` router**: ask "should this be a tutorial or a how-to?" or "improve these docs"; it should route and cite, not perform the work itself. - **`technical-writing`**: ask it to document a real feature. Confirm it reads the code before drafting, picks exactly one document kind, and runs the commands it puts in the doc. - **`copy-editing`**: hand it a page with a planted unsourced statistic and a planted "simply". Confirm it flags the statistic as a **blocker** and does not merely soften it, and that it establishes the proofread / line-edit / structural contract before editing. +- **`humanize`**: hand it a page with planted AI tells (a chatbot pleasantry, a staged contrast, stock vocabulary) and a sentence that carries a fact. Confirm it runs the `ai-tells` Vale style, removes the tells without adding or dropping a fact, and keeps a human author's em dash where the passage carries no other tell. With `--report-only`, confirm it edits nothing and names patterns without judging authorship. Point it at an `AGENTS.md` and confirm it declines. - **`marketing-copy`**: ask for a landing page for something with no published metrics. **Confirm it refuses to invent statistics or testimonials** and offers the mechanism instead. This is the plugin's headline behaviour; test it deliberately. - **`seo-audit`**: point it at a built site directory and a live URL. Confirm it states which source it audited and what it could not check, and that `--fix` edits the **source**, never the build output. - **`ai-seo`**: point it at a site with a stale `llms.txt`. Confirm it notices the drift against the nav, and validates any JSON-LD rather than eyeballing it. -- **`/docs-lint-setup`**: run in a repo that already has a `.vale.ini` and confirm it does **not** overwrite it without `--force`. Run in a clean repo and confirm the configs, the vocabulary directory, and the `styles/` gitignore entry all appear. +- **`/docs-lint-setup`**: run in a repo that already has a `.vale.ini` and confirm it does **not** overwrite it without `--force`. Run in a clean repo and confirm the configs, the vocabulary directory, the `ai-tells` style in `styles/ai-tells/`, and the `styles/` gitignore entry all appear, with the vocabulary and `styles/ai-tells/` still tracked. - **Agents**: dispatch `prose-reviewer` at a page with planted claim violations and `seo-auditor` at a docs tree. Confirm each returns ranked findings with an explicit coverage statement, edits nothing, and dispatches no sub-agents. - **Cursor rule**: in Cursor, open a file under `docs/` and confirm `docs-editing-context.mdc` attaches. diff --git a/docs/versioning.md b/docs/versioning.md index 527e430..03e0161 100644 --- a/docs/versioning.md +++ b/docs/versioning.md @@ -1,6 +1,6 @@ # Versioning and releases -This plugin uses [Semantic Versioning](https://semver.org), adapted to skill / agent / rule / reference content: +This page is for maintainers cutting a release: how the plugin applies [Semantic Versioning](https://semver.org) to skill, agent, rule, and reference content, the release steps, and the marketplace update that makes a release live. | Bump | When | |------|------| @@ -13,13 +13,14 @@ While on the `0.x` line, treat the plugin as pre-stable: a breaking change may s ## Release steps 1. Bump `version` in **both** manifests (they must agree): `.claude-plugin/plugin.json` and `.cursor-plugin/plugin.json`. Keep `description` and `author` identical across both; `scripts/validate.py` enforces this parity. -2. Run `./scripts/validate.sh` and `claude plugin validate .`. -3. **Dogfood:** load a working copy (`claude --plugin-dir /path/to/docs-editing-plugin`) and exercise the components on a real docs repository on **both** hosts; see [testing.md](testing.md). Include the claims-refusal test. -4. Fold the accumulated `## [Unreleased]` notes into a dated `## [X.Y.Z] - YYYY-MM-DD` section in [CHANGELOG.md](../CHANGELOG.md) (Keep a Changelog: groups in order Added, Changed, Deprecated, Removed, Fixed, Security; see [AGENTS.md](../AGENTS.md#changelog-style)). -5. Sync the docs surface (AGENTS.md, README.md) with what shipped. The router body and `hooks/session-start.sh` are checked mechanically by the validator, so a missed component fails CI rather than shipping quietly. -6. Commit (`chore(release): vX.Y.Z`) and tag: `git tag -a vX.Y.Z -m "docs-editing-plugin vX.Y.Z"`. -7. Push commits and the tag: `git push origin main --follow-tags`. -8. **Update the marketplace entry**: the release is not live until this lands. See below. +2. Update the version badge in [README.md](../README.md) to the new version. +3. Run `./scripts/validate.sh` and `claude plugin validate .`. +4. **Dogfood:** load a working copy (`claude --plugin-dir /path/to/docs-editing-plugin`) and exercise the components on a real docs repository on **both** hosts; see [testing.md](testing.md). Include the claims-refusal test. +5. Fold the accumulated `## [Unreleased]` notes into a dated `## [X.Y.Z] - YYYY-MM-DD` section in [CHANGELOG.md](../CHANGELOG.md) (Keep a Changelog: groups in order Added, Changed, Deprecated, Removed, Fixed, Security; see [AGENTS.md](../AGENTS.md#changelog-style)). +6. Sync the docs surface (AGENTS.md, README.md) with what shipped. The router body and `hooks/session-start.sh` are checked mechanically by the validator, so a missed component fails CI rather than shipping quietly. +7. Commit (`chore(release): vX.Y.Z`) and tag: `git tag -a vX.Y.Z -m "docs-editing-plugin vX.Y.Z"`. +8. Push commits and the tag: `git push origin main --follow-tags`. +9. **Update the marketplace entry**: the release is not live until this lands. See below. ## Coupling to external tooling @@ -33,7 +34,7 @@ This plugin has **no companion MCP server**, so there is no server-compatibility Public install is via the [Cadasto marketplace](https://github.com/Cadasto/plugin-marketplace) as `docs-editing@cadasto`. The catalog **pins every entry to a release tag**, so tagging and pushing a release here does not ship it; users see nothing until the marketplace entry moves. -After step 7, update the entry in `Cadasto/plugin-marketplace`: +After step 8, update the entry in `Cadasto/plugin-marketplace`: 1. Bump that entry's `version` to `X.Y.Z` and `source.ref` to `vX.Y.Z` together (validation there rejects a mismatch). 2. Bump the catalog's own `metadata.version`: a plugin minor/major is a catalog **minor**, a plugin patch is a catalog **patch**.