From ca4a97b8bf5b91e0055fa3a05abdf02d591fb461 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 09:44:15 +0000 Subject: [PATCH] chore(skills): reduce token cost of skill descriptions and bodies Split the jsdoc skill's example gallery into references/examples.md so the default load only carries the tag tables and guidelines, shortened its frontmatter description (always in context in every skill listing), and tightened repetitive prose in the pr skill's steps without dropping any instruction. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01T8T7uGR5JcXVN3S5zi3nHN --- .agents/skills/jsdoc/SKILL.md | 178 ++++---------------- .agents/skills/jsdoc/references/examples.md | 127 ++++++++++++++ .agents/skills/pr/SKILL.md | 63 +++---- .changeset/reduce-skill-token-cost.md | 13 ++ .codex-plugin/plugin.json | 2 +- AGENTS.md | 2 +- GEMINI.md | 2 +- gemini-extension.json | 2 +- 8 files changed, 198 insertions(+), 191 deletions(-) create mode 100644 .agents/skills/jsdoc/references/examples.md create mode 100644 .changeset/reduce-skill-token-cost.md diff --git a/.agents/skills/jsdoc/SKILL.md b/.agents/skills/jsdoc/SKILL.md index 58f7b16..b4f8101 100644 --- a/.agents/skills/jsdoc/SKILL.md +++ b/.agents/skills/jsdoc/SKILL.md @@ -1,71 +1,34 @@ --- name: jsdoc -description: Full JSDoc format guide for TypeScript, covering @example formats (short, multi-line, multi-variant), tag usage (@default, @deprecated, what to avoid), documentation patterns for properties/enums/functions, and tag order. +description: Full JSDoc format guide for TypeScript, covering @example formats, tag usage (@default, @deprecated, what to avoid), documentation patterns, and tag order. --- # JSDoc -The detailed JSDoc format guide with examples for every case. The essentials live in the -`jsdoc` rule. Reach here when you need the full reference. - -## `@example` format - -### Short one-liner: label on the `@example` line, code as inline backtick on the next line - -```typescript -/** - * @example Required parameter - * `name: Type` - * - * @example Optional parameter - * `name?: Type` - */ -``` - -### Multi-line: fenced code block immediately after `@example` - -````typescript -/** - * @example - * ```ts - * const result = buildParams(node, { - * paramsType: 'inline', - * }) - * ``` - */ -```` - -### Multiple variants: use multiple `@example` blocks - -```typescript -/** - * @example Object mode - * `{ id, data, params }: { id: string; data: Data; params?: QueryParams }` - * - * @example Inline mode - * `id: string, data: Data, params?: QueryParams` - */ -``` - -### Rules - -| Rule | Correct | Incorrect | -| ----------------------- | ----------------------------------- | -------------------------------------------- | -| Label + inline code | `@example Required\n\`name: Type\`` | `@example \`name: Type\`` (code on tag line) | -| Multi-line code | Fenced ` ```ts ``` ` block | Bare code lines without a fence | -| Short examples | Inline backtick | Triple-backtick fence (too heavy) | -| One concern per example | Separate `@example` blocks | One example covering all cases | +The detailed JSDoc format guide. The essentials live in the `jsdoc` rule; reach here for the +full reference, including every `@example` format and documentation pattern in +[references/examples.md](references/examples.md). + +## `@example` format, in brief + +- Short value: label on the `@example` line, code as inline backtick on the next line. +- Multi-line code: a fenced ` ```ts ``` ` block immediately after `@example`, never bare lines. +- Multiple variants: separate `@example` blocks, one concern each, never one example for every + case. + +See [references/examples.md](references/examples.md) for a worked example of each, plus the +property, enum, nested-property, and function documentation patterns. ## Tags ### Use frequently -| Tag | Purpose | Notes | -| ------------- | ------------------ | ------------------------------------------------------ | +| Tag | Purpose | Notes | +| ------------- | ------------------ | ----------------------------------------------------------- | | `@default` | Default value | Only when the default is non-obvious (omit for `undefined`) | -| `@example` | Usage example | Prefer for complex or multi-variant APIs | -| `@note` | Important caveat | Version info, breaking changes | -| `@deprecated` | Mark as deprecated | Include a migration path | +| `@example` | Usage example | Prefer for complex or multi-variant APIs | +| `@note` | Important caveat | Version info, breaking changes | +| `@deprecated` | Mark as deprecated | Include a migration path | ### Use sparingly @@ -77,106 +40,25 @@ The detailed JSDoc format guide with examples for every case. The essentials liv ### Avoid (TypeScript already provides these) -- `@param`: use TypeScript parameter types -- `@returns`: use the TypeScript return type -- `@type`: use a TypeScript type annotation -- `@typedef`: use `type` or `interface` -- `@default undefined`: optional (`?`) already implies this - -## Documentation patterns - -### Simple property: always multi-line - -```typescript -/** - * Output directory for generated files. - */ -outDir?: string -``` - -Never use single-line `/** description */`. Always expand to multi-line. - -### Property with a non-obvious default - -```typescript -/** - * Maximum number of concurrent callbacks during traversal. - * Higher values overlap I/O-bound work, lower values save memory. - * - * @default 30 - */ -concurrency?: number -``` - -Do not add `@default false` or `@default undefined` when the TypeScript type already makes the -default obvious. - -### Enum or union with options - -```typescript -/** - * How path parameters are emitted in the function signature. - * - `'object'` groups them as a single destructured parameter - * - `'inline'` spreads them as individual parameters - * - `'inlineSpread'` emits a single rest parameter - */ -pathParamsType: 'object' | 'inline' | 'inlineSpread' -``` - -### Nested properties: every field gets its own multi-line JSDoc - -```typescript -names?: { - /** - * Name for the request body parameter. - * @default 'data' - */ - data?: string - /** - * Name for the query parameters group parameter. - * @default 'params' - */ - params?: string -} -``` - -### Function documentation - -Only add JSDoc when it adds value beyond the signature: - -```typescript -// No JSDoc needed: the signature is self-explanatory -function camelCase(str: string): string { ... } - -// JSDoc adds value: it explains behavior and non-obvious edge cases -/** - * Returns `true` when the schema resolves to a plain string output. - * - * - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings. - * - `date` and `time` are plain strings when their `representation` is `'string'`. - */ -function isStringType(node: SchemaNode): boolean { ... } -``` +`@param`, `@returns`, `@type`, and `@typedef` duplicate the TypeScript signature; use the type, +return type, or a `type`/`interface` instead. Skip `@default undefined` too, since an optional +(`?`) property already implies it. ## Guidelines Do: -- Document what the property does, not its TypeScript type -- Give every exported type, property, and function a JSDoc comment -- Always use multi-line JSDoc blocks -- Use concrete, full-sentence descriptions -- Include `@default` only when the default is non-obvious -- Use multiple `@example` blocks for different variants -- Keep `@example` labels short and descriptive +- Document what the property does, not its TypeScript type. +- Give every exported type, property, and function a JSDoc comment, always multi-line, with + concrete, full-sentence descriptions. +- Include `@default` only when the default is non-obvious. +- Use multiple `@example` blocks for different variants, with short, descriptive labels. Do not: -- Write single-line `/** description */` -- Write `@default undefined` -- Put code directly on the `@example` line -- Use `@param` or `@returns` tags -- Over-document trivial, self-explanatory properties +- Write single-line `/** description */` or `@default undefined`. +- Put code directly on the `@example` line, or use `@param`/`@returns`. +- Over-document trivial, self-explanatory properties. ## Tag order diff --git a/.agents/skills/jsdoc/references/examples.md b/.agents/skills/jsdoc/references/examples.md new file mode 100644 index 0000000..1510379 --- /dev/null +++ b/.agents/skills/jsdoc/references/examples.md @@ -0,0 +1,127 @@ +# JSDoc examples and patterns + +Full examples for the `@example` formats and the documentation patterns the `jsdoc` skill +summarizes. + +## `@example` format + +### Short one-liner: label on the `@example` line, code as inline backtick on the next line + +```typescript +/** + * @example Required parameter + * `name: Type` + * + * @example Optional parameter + * `name?: Type` + */ +``` + +### Multi-line: fenced code block immediately after `@example` + +````typescript +/** + * @example + * ```ts + * const result = buildParams(node, { + * paramsType: 'inline', + * }) + * ``` + */ +```` + +### Multiple variants: use multiple `@example` blocks + +```typescript +/** + * @example Object mode + * `{ id, data, params }: { id: string; data: Data; params?: QueryParams }` + * + * @example Inline mode + * `id: string, data: Data, params?: QueryParams` + */ +``` + +### Rules + +| Rule | Correct | Incorrect | +| ----------------------- | ----------------------------------- | -------------------------------------------- | +| Label + inline code | `@example Required\n\`name: Type\`` | `@example \`name: Type\`` (code on tag line) | +| Multi-line code | Fenced ` ```ts ``` ` block | Bare code lines without a fence | +| Short examples | Inline backtick | Triple-backtick fence (too heavy) | +| One concern per example | Separate `@example` blocks | One example covering all cases | + +## Documentation patterns + +### Simple property: always multi-line + +```typescript +/** + * Output directory for generated files. + */ +outDir?: string +``` + +Never use single-line `/** description */`. Always expand to multi-line. + +### Property with a non-obvious default + +```typescript +/** + * Maximum number of concurrent callbacks during traversal. + * Higher values overlap I/O-bound work, lower values save memory. + * + * @default 30 + */ +concurrency?: number +``` + +Do not add `@default false` or `@default undefined` when the TypeScript type already makes the +default obvious. + +### Enum or union with options + +```typescript +/** + * How path parameters are emitted in the function signature. + * - `'object'` groups them as a single destructured parameter + * - `'inline'` spreads them as individual parameters + * - `'inlineSpread'` emits a single rest parameter + */ +pathParamsType: 'object' | 'inline' | 'inlineSpread' +``` + +### Nested properties: every field gets its own multi-line JSDoc + +```typescript +names?: { + /** + * Name for the request body parameter. + * @default 'data' + */ + data?: string + /** + * Name for the query parameters group parameter. + * @default 'params' + */ + params?: string +} +``` + +### Function documentation + +Only add JSDoc when it adds value beyond the signature: + +```typescript +// No JSDoc needed: the signature is self-explanatory +function camelCase(str: string): string { ... } + +// JSDoc adds value: it explains behavior and non-obvious edge cases +/** + * Returns `true` when the schema resolves to a plain string output. + * + * - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings. + * - `date` and `time` are plain strings when their `representation` is `'string'`. + */ +function isStringType(node: SchemaNode): boolean { ... } +``` diff --git a/.agents/skills/pr/SKILL.md b/.agents/skills/pr/SKILL.md index 885525a..4675b8d 100644 --- a/.agents/skills/pr/SKILL.md +++ b/.agents/skills/pr/SKILL.md @@ -22,8 +22,8 @@ for a PR body under 150 words. Run the `humanizer` skill over anything you write ## 1. Confirm the branch -Never commit to `main`. Check where you are, and branch from an up-to-date `main` if you are -still on it: +Never commit to `main`. Check where you are, and branch from an up-to-date `main` when still on +it: ```bash git status @@ -61,10 +61,10 @@ The `changeset` skill decides whether this branch needs one, which bump it takes entry is laid out. `/create-changeset` does the step for you. Both plugin manifests version through Changesets, so a change under `tools/claude` or -`tools/cursor` needs its own changeset. Never hand-edit `version` in -`tools/claude/.claude-plugin/plugin.json` or `tools/cursor/.cursor-plugin/plugin.json`. A -change under `.agents/skills/` also ships in Codex and Gemini, so bump `version` by hand in -`.codex-plugin/plugin.json` and `gemini-extension.json` in the same PR. +`tools/cursor` needs its own changeset; never hand-edit `version` in either +`.claude-plugin/plugin.json` or `.cursor-plugin/plugin.json`. A change under `.agents/skills/` +also ships in Codex and Gemini, so bump `version` by hand in `.codex-plugin/plugin.json` and +`gemini-extension.json` in the same PR. ## 4. Commit @@ -85,8 +85,8 @@ One Conventional Commit line, imperative, under 72 characters, no trailing perio the squash-merge commit, so write it for whoever reads the changelog later. The branch category (`feature`, `hotfix`, `release`) is too coarse for a Conventional Commit -type, so read the type the same way the `branch` skill's step 2 does, off the issue's labels or -the change itself, rather than off the branch prefix: +type. Read the type the way the `branch` skill's step 2 does, off the issue's labels or the +change itself, not the branch prefix: 1. Pick the type: `feat`, `fix`, `docs`, `chore`, `refactor`, `test`, or `perf`. 2. Drop the issue reference from the branch name, then turn the kebab-case rest into a sentence, @@ -121,22 +121,15 @@ result. ### How to test -Three lines, replacing the placeholders: - -- Step 1: [Clear reproduction step] -- Step 2: [Next step] -- Step 3: [Expected result] - -Use a real command or path, starting from a clean checkout. Fix steps someone hands you rather -than pasting them as-is: add the missing prerequisite, order them, name the expected result. Ask -for steps you can't derive from the diff. Add a screenshot for a visible change, before and -after when you changed something that already existed. +Replace the placeholders with three real steps, from a clean checkout: a reproduction step, the +next step, and the expected result. Fix steps someone hands you rather than pasting them as-is: +add the missing prerequisite, order them, name the result. Ask for steps you can't derive from +the diff. Add a before/after screenshot for a visible change. ### Impact -One line. Say who this reaches: someone using the published package, someone consuming the -generated output, or nobody outside this repo. Name the migration step when the change breaks -someone. +One line naming who this reaches: someone using the published package, someone consuming the +generated output, or nobody outside this repo. Name the migration step when it breaks someone. ## 6. Push and open the PR @@ -152,28 +145,20 @@ gh pr create \ --assignee @me ``` -Use the `gh` CLI rather than a GitHub MCP server or any other bot token, so the PR is authored -by whoever ran it and lands in their own list. - -Open it ready for review, not draft. Mark a draft ready with `gh pr ready` once the branch is -finished and the checks pass. +Use the `gh` CLI, never a GitHub MCP server or another bot token, so the PR is authored by +whoever ran it and lands in their own list. -Add a label the repo already uses; `gh label list` shows them. Inventing one is worse than -leaving the PR unlabeled. - -`gh pr merge --squash --delete-branch` squashes and deletes the branch in one step. No merge -rights: say in the body that the PR is meant to be squashed. - -One PR does one thing. Unrelated work noticed along the way stays out, mentioned in the body -instead. +Open it ready for review, not draft; mark a draft ready with `gh pr ready` once checks pass. Add +a label the repo already uses (`gh label list`) rather than inventing one. `gh pr merge --squash +--delete-branch` squashes and deletes the branch in one step; with no merge rights, say in the +body that the PR is meant to be squashed. One PR does one thing: mention unrelated work noticed +along the way in the body and leave it out of the diff. ## 7. After CI runs -A red PR is work now, whatever its review state. - -Read the failing job, reproduce it locally, fix the cause, push again. Re-run a job only when -the failure never reached a test body (a checkout or install error) or the same commit passed -before. +A red PR is work now, whatever its review state. Read the failing job, reproduce it locally, fix +the cause, push again. Re-run a job only when the failure never reached a test body (a checkout +or install error) or the same commit passed before. Answer every review comment in a sentence or two: what you changed, how the reviewer can check it. Push the fix for a small, local ask; for a larger one, reply with what you propose and let diff --git a/.changeset/reduce-skill-token-cost.md b/.changeset/reduce-skill-token-cost.md new file mode 100644 index 0000000..0d9e16b --- /dev/null +++ b/.changeset/reduce-skill-token-cost.md @@ -0,0 +1,13 @@ +--- +'@stijnvanhulle/template-claude-plugin': patch +'@stijnvanhulle/template-cursor-plugin': patch +--- + +Cut the token cost of the `jsdoc` and `pr` skills without dropping any guidance. + +- Moved the `jsdoc` skill's full `@example` gallery and documentation patterns into + `references/examples.md`, so the default load only carries the tag tables, guidelines, and tag + order. +- Shortened the `jsdoc` skill's frontmatter description, since it stays in context in every + `` listing whether or not the skill loads. +- Tightened repetitive prose across the `pr` skill's steps, keeping every check and guardrail. diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index b20f1fd..1cd900d 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "toolkit", "displayName": "stijnvanhulle template", - "version": "0.12.1", + "version": "0.12.2", "description": "Writing-voice skills and shared TypeScript-monorepo conventions.", "author": { "name": "stijnvanhulle", diff --git a/AGENTS.md b/AGENTS.md index 2b05e07..fa3c4e0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -126,6 +126,6 @@ You have new skills. If any skill might be relevant then you MUST read it. - [documentation](.agents/skills/documentation/SKILL.md) - Use when writing blog posts or documentation markdown files. Provides a writing style guide (active voice, present tense), content structure patterns, and SEO optimization. Overrides brevity rules for proper grammar. - [humanizer](.agents/skills/humanizer/SKILL.md) - Remove AI writing patterns to make documentation sound natural, specific, and human. Covers content patterns, language patterns, style patterns, and communication patterns. - [issue](.agents/skills/issue/SKILL.md) - Open a GitHub issue or a Jira ticket with its sidebar filled in, so the labels, the type, and the fields are set rather than left empty. Use when filing an issue, filing a Jira ticket, turning a report into one, or triaging an issue whose fields are empty. -- [jsdoc](.agents/skills/jsdoc/SKILL.md) - Full JSDoc format guide for TypeScript, covering @example formats (short, multi-line, multi-variant), tag usage (@default, @deprecated, what to avoid), documentation patterns for properties/enums/functions, and tag order. +- [jsdoc](.agents/skills/jsdoc/SKILL.md) - Full JSDoc format guide for TypeScript, covering @example formats, tag usage (@default, @deprecated, what to avoid), documentation patterns, and tag order. - [pr](.agents/skills/pr/SKILL.md) - Open or update a pull request in this monorepo. Covers the pre-push checks, the changeset decision, Conventional Commit titles, how to fill the PR template, and what to do once CI runs. Use when asked to open a PR, push a branch for review, fix a red PR, or judge whether a branch is ready to merge. diff --git a/GEMINI.md b/GEMINI.md index 214a8db..9918b69 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -128,7 +128,7 @@ You have new skills. If any skill might be relevant then you MUST read it. - [documentation](.agents/skills/documentation/SKILL.md) - Use when writing blog posts or documentation markdown files. Provides a writing style guide (active voice, present tense), content structure patterns, and SEO optimization. Overrides brevity rules for proper grammar. - [humanizer](.agents/skills/humanizer/SKILL.md) - Remove AI writing patterns to make documentation sound natural, specific, and human. Covers content patterns, language patterns, style patterns, and communication patterns. - [issue](.agents/skills/issue/SKILL.md) - Open a GitHub issue or a Jira ticket with its sidebar filled in, so the labels, the type, and the fields are set rather than left empty. Use when filing an issue, filing a Jira ticket, turning a report into one, or triaging an issue whose fields are empty. -- [jsdoc](.agents/skills/jsdoc/SKILL.md) - Full JSDoc format guide for TypeScript, covering @example formats (short, multi-line, multi-variant), tag usage (@default, @deprecated, what to avoid), documentation patterns for properties/enums/functions, and tag order. +- [jsdoc](.agents/skills/jsdoc/SKILL.md) - Full JSDoc format guide for TypeScript, covering @example formats, tag usage (@default, @deprecated, what to avoid), documentation patterns, and tag order. - [pr](.agents/skills/pr/SKILL.md) - Open or update a pull request in this monorepo. Covers the pre-push checks, the changeset decision, Conventional Commit titles, how to fill the PR template, and what to do once CI runs. Use when asked to open a PR, push a branch for review, fix a red PR, or judge whether a branch is ready to merge. diff --git a/gemini-extension.json b/gemini-extension.json index 583ff46..878b15f 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "toolkit", - "version": "0.12.1", + "version": "0.12.2", "description": "Writing-voice skills and shared TypeScript-monorepo conventions.", "contextFileName": "GEMINI.md" }