From 8e7c100864c0e2283bbf75f5d4c654bf36cdda21 Mon Sep 17 00:00:00 2001 From: Christopher Burns Date: Thu, 19 Feb 2026 23:17:02 +0000 Subject: [PATCH 1/5] Add TSDoc and JSDoc Authoring Skills and Reference Documentation - Introduced comprehensive authoring guides for TSDoc and JSDoc, including best practices for writing documentation comments. - Created detailed reference documents outlining TSDoc comment structure, tag kinds, and high-quality patterns. - Established focused indexes for TSDoc and JSDoc rules to streamline documentation processes. - Added specific rules for documenting async behavior, constructors, and object shapes to enhance clarity and consistency in API documentation. - Implemented checks for required tags and descriptions to ensure thorough documentation standards across JavaScript and TypeScript projects. --- .../skills/tsdoc-jsdoc-authoring/AGENTS.md | 228 ++++++++++++++++++ .agents/skills/tsdoc-jsdoc-authoring/SKILL.md | 123 ++++++++++ .../indexes/jsdoc-authoring-index.md | 30 +++ .../indexes/jsdoc-consistency-index.md | 37 +++ .../indexes/tsdoc-index.md | 39 +++ .../skills/tsdoc-jsdoc-authoring/reference.md | 194 +++++++++++++++ .../rules/jsdoc/advanced/jsdoc-async.md | 34 +++ .../jsdoc/advanced/jsdoc-class-constructor.md | 34 +++ .../advanced/jsdoc-implements-on-classes.md | 43 ++++ .../rules/jsdoc/advanced/jsdoc-module.md | 32 +++ .../jsdoc/advanced/jsdoc-typedef-property.md | 37 +++ .../rules/jsdoc/advanced/jsdoc-yields.md | 32 +++ .../rules/jsdoc/core/jsdoc-check-access.md | 53 ++++ .../rules/jsdoc/core/jsdoc-example.md | 34 +++ .../rules/jsdoc/core/jsdoc-no-defaults.md | 46 ++++ .../jsdoc/core/jsdoc-optional-default.md | 34 +++ .../rules/jsdoc/core/jsdoc-param.md | 33 +++ .../jsdoc/core/jsdoc-property-namepaths.md | 34 +++ .../jsdoc/core/jsdoc-require-param-type.md | 29 +++ .../rules/jsdoc/core/jsdoc-require-param.md | 40 +++ .../jsdoc-require-property-description.md | 33 +++ .../jsdoc/core/jsdoc-require-property-name.md | 33 +++ .../jsdoc/core/jsdoc-require-property-type.md | 33 +++ .../jsdoc/core/jsdoc-require-property.md | 45 ++++ .../core/jsdoc-require-returns-description.md | 36 +++ .../jsdoc/core/jsdoc-require-returns-type.md | 29 +++ .../rules/jsdoc/core/jsdoc-require-returns.md | 53 ++++ .../rules/jsdoc/core/jsdoc-require-yields.md | 50 ++++ .../rules/jsdoc/core/jsdoc-returns.md | 31 +++ .../rules/jsdoc/core/jsdoc-summary.md | 31 +++ .../rules/jsdoc/core/jsdoc-throws.md | 32 +++ .../rules/tsdoc/core/tsdoc-deprecated.md | 31 +++ .../rules/tsdoc/core/tsdoc-example.md | 35 +++ .../rules/tsdoc/core/tsdoc-param.md | 71 ++++++ .../rules/tsdoc/core/tsdoc-remarks.md | 36 +++ .../rules/tsdoc/core/tsdoc-returns.md | 31 +++ .../rules/tsdoc/core/tsdoc-summary.md | 31 +++ .../rules/tsdoc/core/tsdoc-throws.md | 32 +++ .../rules/tsdoc/core/tsdoc-typeparam.md | 32 +++ .../rules/tsdoc/crossref/tsdoc-inheritdoc.md | 39 +++ .../rules/tsdoc/crossref/tsdoc-label.md | 33 +++ .../rules/tsdoc/crossref/tsdoc-link.md | 31 +++ .../rules/tsdoc/crossref/tsdoc-see.md | 33 +++ .../rules/tsdoc/policy/tsdoc-default-value.md | 32 +++ .../rules/tsdoc/policy/tsdoc-modifier-tags.md | 35 +++ .../tsdoc/policy/tsdoc-no-jsdoc-braces.md | 33 +++ .../policy/tsdoc-package-documentation.md | 32 +++ .../tsdoc/policy/tsdoc-private-remarks.md | 34 +++ .../rules/tsdoc/policy/tsdoc-release-tags.md | 36 +++ .claude/skills/tsdoc-jsdoc-authoring | 1 + .cursor/skills/tsdoc-jsdoc-authoring | 1 + src/cli/commands/generate-workspace.ts | 15 ++ src/cli/commands/generate.ts | 13 + src/cli/commands/init.ts | 8 + src/cli/help.ts | 3 + src/cli/resolve-invocation.ts | 21 ++ src/config/load-config.ts | 66 +++++ src/config/starter-config.ts | 9 + src/config/types.ts | 93 ++++++- src/index.ts | 9 + src/readme-generator/generator.ts | 45 ++++ src/readme-generator/template.ts | 43 ++++ 62 files changed, 2535 insertions(+), 1 deletion(-) create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/AGENTS.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/SKILL.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-authoring-index.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-consistency-index.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/indexes/tsdoc-index.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/reference.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-async.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-class-constructor.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-check-access.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-example.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-optional-default.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-name.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-type.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-description.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-type.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-returns.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-summary.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-deprecated.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-remarks.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-returns.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-summary.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-typeparam.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-label.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-link.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-see.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-default-value.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-modifier-tags.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-no-jsdoc-braces.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-package-documentation.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-private-remarks.md create mode 100644 .agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-release-tags.md create mode 120000 .claude/skills/tsdoc-jsdoc-authoring create mode 120000 .cursor/skills/tsdoc-jsdoc-authoring diff --git a/.agents/skills/tsdoc-jsdoc-authoring/AGENTS.md b/.agents/skills/tsdoc-jsdoc-authoring/AGENTS.md new file mode 100644 index 0000000..117d153 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/AGENTS.md @@ -0,0 +1,228 @@ +# TSDoc and JSDoc Best Practices + +**Version 1.0.0** +Custom Authoring Guide +February 2026 + +> **Note:** +> This document is designed for agents and LLMs writing or reviewing TypeScript +> and JavaScript documentation comments using TSDoc and JSDoc. It mirrors a +> rule-driven format where each rule has clear "use" and "avoid" guidance with +> incorrect and correct examples. + +--- + +## Abstract + +Comprehensive TSDoc and JSDoc authoring guide for automated documentation generation and review. Contains focused rules across core contract tags, linking/reuse tags, package/internal docs, policy tags, and JavaScript-focused docstring patterns. Each rule explains when to use the tag, when not to use it, and includes concrete incorrect/correct examples. + +## Read Order (Context-Safe) + +Before using this catalog, route through one focused index: + +- `indexes/tsdoc-index.md` +- `indexes/jsdoc-authoring-index.md` +- `indexes/jsdoc-consistency-index.md` + +This file is a reference catalog. Load only the relevant subsection after choosing an index. + +--- + +## Rule Index + +### 1. Core API Contract Rules + +1.1 [Write Clear Summary Sentences](#11-write-clear-summary-sentences) +1.2 [Use `@remarks` for Long-Form Context](#12-use-remarks-for-long-form-context) +1.3 [Document Parameters with `@param`](#13-document-parameters-with-param) +1.4 [Document Generics with `@typeParam`](#14-document-generics-with-typeparam) +1.5 [Document Return Semantics with `@returns`](#15-document-return-semantics-with-returns) +1.6 [Document Expected Failures with `@throws`](#16-document-expected-failures-with-throws) +1.7 [Use `@example` for Non-Obvious Usage](#17-use-example-for-non-obvious-usage) +1.8 [Use `@deprecated` with Migration Guidance](#18-use-deprecated-with-migration-guidance) + +### 2. Cross-Reference and Reuse Rules + +2.1 [Prefer `{@link ...}` for Symbol References](#21-prefer-link--for-symbol-references) +2.2 [Use `@see` for Related APIs](#22-use-see-for-related-apis) +2.3 [Use `@inheritDoc` Only for Equivalent Contracts](#23-use-inheritdoc-only-for-equivalent-contracts) +2.4 [Use `{@label ...}` Only for Structured References](#24-use-label--only-for-structured-references) + +### 3. Package and Internal Notes + +3.1 [Use `@packageDocumentation` for Entrypoint Docs](#31-use-packagedocumentation-for-entrypoint-docs) +3.2 [Use `@privateRemarks` for Maintainer-Only Notes](#32-use-privateremarks-for-maintainer-only-notes) +3.3 [Document Defaults with `@defaultValue`](#33-document-defaults-with-defaultvalue) + +### 4. Stability and Modifier Policy + +4.1 [Apply Release Tags Consistently](#41-apply-release-tags-consistently) +4.2 [Use Modifier Tags Only When Semantically True](#42-use-modifier-tags-only-when-semantically-true) +4.3 [Do Not Mix JSDoc Type Syntax into TSDoc](#43-do-not-mix-jsdoc-type-syntax-into-tsdoc) + +### 5. JSDoc Rules (JavaScript) + +5.1 [Write JSDoc Summaries with Intent](#51-write-jsdoc-summaries-with-intent) +5.2 [Document Parameters with JSDoc Type Expressions](#52-document-parameters-with-jsdoc-type-expressions) +5.3 [Use Optional and Default Parameter Strings Correctly](#53-use-optional-and-default-parameter-strings-correctly) +5.4 [Use Nested Property Namepaths for Object Inputs](#54-use-nested-property-namepaths-for-object-inputs) +5.5 [Document Return Value Semantics with `@returns`](#55-document-return-value-semantics-with-returns) +5.6 [Document Error Contracts with `@throws`](#56-document-error-contracts-with-throws) +5.7 [Add Practical `@example` Snippets](#57-add-practical-example-snippets) +5.8 [Define Reusable Shapes with `@typedef` and `@property`](#58-define-reusable-shapes-with-typedef-and-property) +5.9 [Document Async Behavior with `@async`](#59-document-async-behavior-with-async) +5.10 [Document Generator Output with `@yields`](#510-document-generator-output-with-yields) +5.11 [Document Constructors and Classes Clearly](#511-document-constructors-and-classes-clearly) +5.12 [Use `@module` for Module-Level Docs](#512-use-module-for-module-level-docs) +5.13 [Validate Access Tags with `check-access`](#513-validate-access-tags-with-check-access) +5.14 [Restrict `@implements` to Classes or Constructors](#514-restrict-implements-to-classes-or-constructors) + +--- + +## 1. Core API Contract Rules + +### 1.1 Write Clear Summary Sentences + +See: `rules/tsdoc/core/tsdoc-summary.md` + +### 1.2 Use `@remarks` for Long-Form Context + +See: `rules/tsdoc/core/tsdoc-remarks.md` + +### 1.3 Document Parameters with `@param` + +See: `rules/tsdoc/core/tsdoc-param.md` + +### 1.4 Document Generics with `@typeParam` + +See: `rules/tsdoc/core/tsdoc-typeparam.md` + +### 1.5 Document Return Semantics with `@returns` + +See: `rules/tsdoc/core/tsdoc-returns.md` + +### 1.6 Document Expected Failures with `@throws` + +See: `rules/tsdoc/core/tsdoc-throws.md` + +### 1.7 Use `@example` for Non-Obvious Usage + +See: `rules/tsdoc/core/tsdoc-example.md` + +### 1.8 Use `@deprecated` with Migration Guidance + +See: `rules/tsdoc/core/tsdoc-deprecated.md` + +## 2. Cross-Reference and Reuse Rules + +### 2.1 Prefer `{@link ...}` for Symbol References + +See: `rules/tsdoc/crossref/tsdoc-link.md` + +### 2.2 Use `@see` for Related APIs + +See: `rules/tsdoc/crossref/tsdoc-see.md` + +### 2.3 Use `@inheritDoc` Only for Equivalent Contracts + +See: `rules/tsdoc/crossref/tsdoc-inheritdoc.md` + +### 2.4 Use `{@label ...}` Only for Structured References + +See: `rules/tsdoc/crossref/tsdoc-label.md` + +## 3. Package and Internal Notes + +### 3.1 Use `@packageDocumentation` for Entrypoint Docs + +See: `rules/tsdoc/policy/tsdoc-package-documentation.md` + +### 3.2 Use `@privateRemarks` for Maintainer-Only Notes + +See: `rules/tsdoc/policy/tsdoc-private-remarks.md` + +### 3.3 Document Defaults with `@defaultValue` + +See: `rules/tsdoc/policy/tsdoc-default-value.md` + +## 4. Stability and Modifier Policy + +### 4.1 Apply Release Tags Consistently + +See: `rules/tsdoc/policy/tsdoc-release-tags.md` + +### 4.2 Use Modifier Tags Only When Semantically True + +See: `rules/tsdoc/policy/tsdoc-modifier-tags.md` + +### 4.3 Do Not Mix JSDoc Type Syntax into TSDoc + +See: `rules/tsdoc/policy/tsdoc-no-jsdoc-braces.md` + +## 5. JSDoc Rules (JavaScript) + +These rules are part of the default documentation standard and should be followed even without an active linter. + +### 5.1 Write JSDoc Summaries with Intent + +See: `rules/jsdoc/core/jsdoc-summary.md` + +### 5.2 Document Parameters with JSDoc Type Expressions + +See: `rules/jsdoc/core/jsdoc-param.md` + +### 5.3 Use Optional and Default Parameter Strings Correctly + +See: `rules/jsdoc/core/jsdoc-optional-default.md` + +### 5.4 Use Nested Property Namepaths for Object Inputs + +See: `rules/jsdoc/core/jsdoc-property-namepaths.md` + +### 5.5 Document Return Value Semantics with `@returns` + +See: `rules/jsdoc/core/jsdoc-returns.md` + +### 5.6 Document Error Contracts with `@throws` + +See: `rules/jsdoc/core/jsdoc-throws.md` + +### 5.7 Add Practical `@example` Snippets + +See: `rules/jsdoc/core/jsdoc-example.md` + +### 5.8 Define Reusable Shapes with `@typedef` and `@property` + +See: `rules/jsdoc/advanced/jsdoc-typedef-property.md` + +### 5.9 Document Async Behavior with `@async` + +See: `rules/jsdoc/advanced/jsdoc-async.md` + +### 5.10 Document Generator Output with `@yields` + +See: `rules/jsdoc/advanced/jsdoc-yields.md` + +### 5.11 Document Constructors and Classes Clearly + +See: `rules/jsdoc/advanced/jsdoc-class-constructor.md` + +### 5.12 Use `@module` for Module-Level Docs + +See: `rules/jsdoc/advanced/jsdoc-module.md` + +### 5.13 Validate Access Tags with `check-access` + +See: `rules/jsdoc/core/jsdoc-check-access.md` + +### 5.14 Restrict `@implements` to Classes or Constructors + +See: `rules/jsdoc/advanced/jsdoc-implements-on-classes.md` + +--- + +## References + +1. [https://tsdoc.org](https://tsdoc.org) +2. [https://github.com/microsoft/tsdoc](https://github.com/microsoft/tsdoc) +3. [https://jsdoc.app](https://jsdoc.app) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/SKILL.md b/.agents/skills/tsdoc-jsdoc-authoring/SKILL.md new file mode 100644 index 0000000..c4e6ec1 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/SKILL.md @@ -0,0 +1,123 @@ +--- +name: tsdoc-jsdoc-authoring +description: Write and review API documentation comments using TSDoc and JSDoc best practices. Use when the user asks for docs, doc comments, TSDoc, JSDoc, @param/@returns help, or documentation quality improvements in JavaScript or TypeScript code. +metadata: + author: custom + version: "1.0.0" + argument-hint: +--- + +# TSDoc and JSDoc Authoring + +Create high-quality documentation comments for functions, classes, interfaces, types, modules, and exported APIs. + +## When to Apply + +Use this skill when the user asks to: + +- add or improve code comments/docs +- write TSDoc or JSDoc +- document params, return values, thrown errors, or examples +- standardize documentation style across files + +## Routing (Read This First) + +Choose one focused index before loading rule files: + +- TypeScript APIs and typed exports: `indexes/tsdoc-index.md` +- JavaScript authoring and shape docs: `indexes/jsdoc-authoring-index.md` +- Strict consistency/lint-safe output standards: `indexes/jsdoc-consistency-index.md` + +## Rule 1: Choose the Correct Standard + +- Use **TSDoc** for TypeScript code and typed public APIs. +- Use **JSDoc** for JavaScript code or projects using JSDoc tooling. +- Do not mix tag syntaxes from both standards in one comment block. + +## Workflow + +1. Read the target file and identify the symbol's purpose and side effects. +2. Prefer documenting exported/public APIs first. +3. Write a one-line summary in plain language. +4. Add only meaningful tags (no empty or redundant tags). +5. Validate tag names and formatting against the relevant standard. +6. Ensure comments match actual behavior (inputs, outputs, errors, async behavior). + +## Authoring Rules (Both Standards) + +- Describe intent and behavior, not obvious implementation details. +- Keep summaries concise and action-oriented ("Returns...", "Creates...", "Parses..."). +- Document every parameter and explain what each parameter does. +- If a parameter is an object, document each object property and what it does. +- Use imperative, consistent phrasing for `@param` descriptions. +- Document thrown errors with `@throws` when behavior depends on error handling. +- Add `@example` only when it clarifies non-obvious usage. +- Do not restate TypeScript types in prose unless it adds semantic meaning. + +## TSDoc Rules + +Use these tags by default when relevant: + +- `@param` for each function argument +- `@typeParam` for generic parameters +- `@returns` for return semantics +- `@remarks` for longer contextual details +- `@throws` for exceptional behavior +- `@example` for practical usage +- `@deprecated` for migration guidance + +TSDoc formatting reminders: + +- Use `@param name - Description` with a hyphen separator. +- Prefer inline links with `{@link SymbolName}`. +- Keep release tags (`@alpha`, `@beta`, `@public`, `@internal`) aligned with project policy. +- For object parameters in TypeScript, prefer a named `type` or `interface` and add `/** ... */` comments on each property so VS Code hovers/autocomplete show per-property docs. + +## JSDoc Rules + +Use these tags by default when relevant: + +- `@param {Type} name` (with optional/default forms when needed) +- `@returns {Type}` (or `@return`) +- `@throws {Type}` when known +- `@typedef` and `@property` for reusable object shapes +- `@example` for usage snippets +- `@async` and `@yields` for async/generator behavior when needed + +JSDoc formatting reminders: + +- Optional params: `@param {string} [name]` +- Optional with default: `@param {string} [name=John Doe]` +- Nested object props: `@param {Object} options` and `@param {string} options.mode` + +## JSDoc Consistency Standard + +Apply these rules by default in all JavaScript documentation, regardless of lint setup. + +- Keep `@access` usage consistent per block (`@access ` or one shorthand access tag). +- Use `@implements` only on classes/constructors. +- Prefer rule-specific guidance from the `rules/jsdoc/**` files when there is a conflict. + +## Output Expectations + +When updating comments: + +- keep existing project conventions unless user requests a migration +- preserve behavior accuracy over verbosity +- avoid adding comments to private/internal symbols unless requested + +## Additional Reference + +For templates and tag cheat sheets, see [reference.md](reference.md). + +## Rule Files + +Use focused indexes to avoid loading unrelated rules: + +- TSDoc index: `indexes/tsdoc-index.md` +- JSDoc authoring index: `indexes/jsdoc-authoring-index.md` +- JSDoc consistency index: `indexes/jsdoc-consistency-index.md` + +## Full Compiled Document + +For the full rule index and category guide: `AGENTS.md` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-authoring-index.md b/.agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-authoring-index.md new file mode 100644 index 0000000..10cba59 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-authoring-index.md @@ -0,0 +1,30 @@ +--- +title: JSDoc Authoring Index +scope: JavaScript documentation patterns +--- + +# JSDoc Authoring Index + +Use this index for normal JavaScript doc authoring tasks. For strict consistency rules, use `indexes/jsdoc-consistency-index.md`. + +## Core Authoring + +- `rules/jsdoc/core/jsdoc-summary.md` +- `rules/jsdoc/core/jsdoc-param.md` +- `rules/jsdoc/core/jsdoc-optional-default.md` +- `rules/jsdoc/core/jsdoc-property-namepaths.md` +- `rules/jsdoc/core/jsdoc-returns.md` +- `rules/jsdoc/core/jsdoc-throws.md` +- `rules/jsdoc/core/jsdoc-example.md` + +## Advanced Authoring + +- `rules/jsdoc/advanced/jsdoc-typedef-property.md` +- `rules/jsdoc/advanced/jsdoc-async.md` +- `rules/jsdoc/advanced/jsdoc-yields.md` +- `rules/jsdoc/advanced/jsdoc-class-constructor.md` +- `rules/jsdoc/advanced/jsdoc-module.md` + +## Deep Reference + +- `reference.md` (templates and syntax cheatsheets) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-consistency-index.md b/.agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-consistency-index.md new file mode 100644 index 0000000..0064048 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/indexes/jsdoc-consistency-index.md @@ -0,0 +1,37 @@ +--- +title: JSDoc Consistency Index +scope: Lint-safe and standard-safe JSDoc output +--- + +# JSDoc Consistency Index + +Use this index when requests need strict, consistent, lint-safe JSDoc output. These rules are part of the default standard. + +## Access and Class Semantics + +- `rules/jsdoc/core/jsdoc-check-access.md` +- `rules/jsdoc/advanced/jsdoc-implements-on-classes.md` + +## Parameter Requirements + +- `rules/jsdoc/core/jsdoc-no-defaults.md` +- `rules/jsdoc/core/jsdoc-require-param.md` +- `rules/jsdoc/core/jsdoc-require-param-type.md` + +## Property Requirements + +- `rules/jsdoc/core/jsdoc-require-property.md` +- `rules/jsdoc/core/jsdoc-require-property-name.md` +- `rules/jsdoc/core/jsdoc-require-property-type.md` +- `rules/jsdoc/core/jsdoc-require-property-description.md` + +## Return and Yield Requirements + +- `rules/jsdoc/core/jsdoc-require-returns.md` +- `rules/jsdoc/core/jsdoc-require-returns-type.md` +- `rules/jsdoc/core/jsdoc-require-returns-description.md` +- `rules/jsdoc/core/jsdoc-require-yields.md` + +## Deep Reference + +- `reference.md` (consistency checklist and templates) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/indexes/tsdoc-index.md b/.agents/skills/tsdoc-jsdoc-authoring/indexes/tsdoc-index.md new file mode 100644 index 0000000..044e6cc --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/indexes/tsdoc-index.md @@ -0,0 +1,39 @@ +--- +title: TSDoc Index +scope: TypeScript API docs +--- + +# TSDoc Index + +Use this index for TypeScript symbols and typed public APIs. Load only the sections you need. + +## Core Contract + +- `rules/tsdoc/core/tsdoc-summary.md` +- `rules/tsdoc/core/tsdoc-remarks.md` +- `rules/tsdoc/core/tsdoc-param.md` +- `rules/tsdoc/core/tsdoc-typeparam.md` +- `rules/tsdoc/core/tsdoc-returns.md` +- `rules/tsdoc/core/tsdoc-throws.md` +- `rules/tsdoc/core/tsdoc-example.md` +- `rules/tsdoc/core/tsdoc-deprecated.md` + +## Cross-Reference and Reuse + +- `rules/tsdoc/crossref/tsdoc-link.md` +- `rules/tsdoc/crossref/tsdoc-see.md` +- `rules/tsdoc/crossref/tsdoc-inheritdoc.md` +- `rules/tsdoc/crossref/tsdoc-label.md` + +## Package and Policy + +- `rules/tsdoc/policy/tsdoc-package-documentation.md` +- `rules/tsdoc/policy/tsdoc-private-remarks.md` +- `rules/tsdoc/policy/tsdoc-default-value.md` +- `rules/tsdoc/policy/tsdoc-release-tags.md` +- `rules/tsdoc/policy/tsdoc-modifier-tags.md` +- `rules/tsdoc/policy/tsdoc-no-jsdoc-braces.md` + +## Deep Reference + +- `reference.md` (templates and review checklist) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/reference.md b/.agents/skills/tsdoc-jsdoc-authoring/reference.md new file mode 100644 index 0000000..a27f54d --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/reference.md @@ -0,0 +1,194 @@ +# TSDoc Deep Reference + +This file is the detailed TSDoc authoring spec for this skill. Use it when generating or reviewing TypeScript API documentation comments. + +## 1) TSDoc Comment Structure + +Standard order for a high-quality TSDoc block: + +1. Summary sentence(s) +2. Optional `@remarks` (long-form details) +3. Parameter docs (`@typeParam`, then `@param`) +4. Return docs (`@returns`) when applicable +5. Error docs (`@throws`) when behavior depends on error handling +6. Optional `@example` +7. Optional policy tags (`@deprecated`, release tags, modifiers) +8. Optional `@see` + +Template: + +````ts +/** + * One-sentence summary in plain language. + * + * @remarks + * Long-form context, constraints, caveats, and behavior notes. + * + * @typeParam T - Meaning of generic type. + * @param input - What this value represents and constraints. + * @returns What is returned and key semantics. + * @throws ErrorType when and why this fails. + * @example + * ```ts + * const value = fn(input) + * ``` + * @deprecated Use `newFn()` instead. + */ +```` + +## 2) TSDoc Tag Kinds (Syntax Types) + +TSDoc tags are grouped into three syntax kinds: + +- `InlineTag`: used inside prose (example: `{@link Foo}`) +- `BlockTag`: starts a new section block (example: `@remarks`) +- `ModifierTag`: marker-style tags with no body (example: `@public`) + +Use the right syntax kind for the right purpose. Do not write modifier tags as prose blocks. + +## 3) Routing to Focused Rule Sets + +Use focused indexes instead of loading full rule catalogs into context: + +- TSDoc work: `indexes/tsdoc-index.md` +- JSDoc authoring work: `indexes/jsdoc-authoring-index.md` +- JSDoc consistency and lint-safe output: `indexes/jsdoc-consistency-index.md` + +Load only the minimum rule files needed for the current edit/review task. + +## 4) High-Quality TSDoc Patterns + +### Document async behavior precisely + +```ts +/** + * Fetches the current profile. + * @returns The active user profile. + * @throws Error when the auth token is invalid. + */ +export async function getProfile(): Promise {} +``` + +### Document generics meaningfully + +```ts +/** + * Creates a dictionary from items. + * @typeParam T - Source item type. + * @param items - Source collection. + * @param getKey - Derives a stable key from each item. + * @returns A map from key to item. + */ +export function toMap( + items: T[], + getKey: (item: T) => string +): Map {} +``` + +### Document thrown contract only + +```ts +/** + * Parses a signed payload. + * @param token - Signed token string. + * @returns Decoded payload. + * @throws Error when signature validation fails. + */ +export function parseSignedToken(token: string): Payload {} +``` + +## 5) TSDoc Mistakes To Avoid + +- Using JSDoc type braces in TSDoc `@param` lines. +- Missing `@typeParam` for public generic APIs. +- Writing verbose summaries that hide key behavior. +- Adding `@example` blocks that are stale or too long. +- Documenting implementation trivia instead of API contract. +- Tagging release level (`@alpha`, `@beta`, etc.) inconsistently across related APIs. + +## 6) TSDoc Review Checklist + +Use this checklist when reviewing generated comments: + +- Summary accurately states what the API does. +- Every parameter has a meaningful `@param`. +- All generics have `@typeParam` when public. +- `@returns` describes semantics, not just type. +- `@throws` documents expected caller-relevant failures. +- `@remarks` is used only when needed. +- Links use `{@link ...}` where appropriate. +- Release/visibility/modifier tags match project policy. +- Comment behavior matches implementation exactly. + +## 7) JSDoc Quick Appendix (Cross-Standard Projects) + +Use this only for JavaScript files or JSDoc-based tooling. + +### JSDoc function template + +```js +/** + * Normalizes a user profile for rendering. + * @param {Object} input - Raw user profile. + * @param {string} input.id - Stable identifier. + * @param {string} [input.displayName] - Optional display name. + * @returns {Object} Normalized profile object. + * @throws {Error} If required fields are missing. + */ +``` + +### JSDoc typedef template + +```js +/** + * @typedef {Object} UserProfile + * @property {string} id - Stable user identifier. + * @property {string} [displayName] - Optional display name. + * @property {boolean} active - Whether the user is active. + */ +``` + +### JSDoc String Syntax Cheatsheet + +Use these exact JSDoc "strings" for common cases: + +- Required param: `@param {string} name - Description` +- Optional param: `@param {string} [name] - Description` +- Optional with default: `@param {string} [name=John Doe] - Description` +- Object param: `@param {Object} options - Description` +- Nested object field: `@param {string} options.mode - Description` +- Array object field: `@param {string} items[].id - Description` +- Return type: `@returns {Promise} Description` +- Throws type: `@throws {Error} Description` +- Access style (pick one): `@access private` or `@private` (do not mix on one doc block) +- `@implements` placement: use only on classes/constructors (not regular functions) + +### TypeScript Object Param Hover Pattern (Recommended) + +For best VS Code hover and autocomplete docs on object properties, use a named type/interface and `/** ... */` on each property: + +```ts +type SearchOptions = { + /** Query string used to match results. */ + query: string; + /** Maximum number of results to return. */ + limit?: number; +}; + +/** + * @param options - Search configuration. + */ +export function search(options: SearchOptions) {} +``` + +## 8) JSDoc Consistency Checklist + +Use this quick pass before finalizing JSDoc blocks in any project: + +- Access tags: use one access style per block; valid `@access` values are `package|private|protected|public`. +- `@implements` placement: use it only on class constructors or constructor-style functions. + +## 9) Sources Used For This Skill + +- TSDoc: `/microsoft/tsdoc` (Context7) +- JSDoc: `/jsdoc/jsdoc.github.io` (Context7) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-async.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-async.md new file mode 100644 index 0000000..f4679c7 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-async.md @@ -0,0 +1,34 @@ +--- +title: Document Async Behavior with @async +impact: MEDIUM +impactDescription: clarifies asynchronous control flow in generated docs +tags: jsdoc, async, promises, functions +--- + +## Document Async Behavior with `@async` + +Use `@async` where tooling or virtual comments need explicit async annotation. + +**Use this when:** async behavior is not obvious from implementation context. +**Avoid this when:** async is already clear and the project style avoids redundant tags. + +**Incorrect (no async contract in virtual docs):** + +```js +/** + * Downloads data from a URL. + * @param {string} url - Source URL. + * @returns {Promise} Downloaded content. + */ +``` + +**Correct (explicit async behavior):** + +```js +/** + * Downloads data from a URL. + * @async + * @param {string} url - Source URL. + * @returns {Promise} Downloaded content. + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-class-constructor.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-class-constructor.md new file mode 100644 index 0000000..4f3a1c4 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-class-constructor.md @@ -0,0 +1,34 @@ +--- +title: Document Constructors and Classes Clearly +impact: HIGH +impactDescription: improves class API onboarding and usage clarity +tags: jsdoc, class, constructor, oop +--- + +## Document Constructors and Classes Clearly + +Document constructor arguments and class purpose clearly. + +**Use this when:** documenting class-based JavaScript APIs. +**Avoid this when:** constructor parameters are undocumented. + +**Incorrect (class intent unclear):** + +```js +/** + * @constructor + */ +function Book(title, author) {} +``` + +**Correct (constructor contract documented):** + +```js +/** + * Represents a book in the catalog. + * @constructor + * @param {string} title - Book title. + * @param {string} author - Book author. + */ +function Book(title, author) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md new file mode 100644 index 0000000..59b91a3 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md @@ -0,0 +1,43 @@ +--- +title: Restrict @implements to Classes or Constructors +impact: HIGH +impactDescription: prevents invalid interface implementation annotations on non-constructors +tags: jsdoc, implements, classes, constructors, lint +--- + +## Restrict `@implements` to Classes or Constructors + +Use `@implements` only on class constructors or constructor-style functions. + +**Use this when:** documenting classes, constructors, or constructor functions. +**Avoid this when:** annotating regular functions, callbacks, or `@function` docs. + +**Incorrect (non-constructor function):** + +```js +/** + * @implements {SomeClass} + */ +function quux() {} +``` + +**Correct (class constructor):** + +```js +class Foo { + /** + * @implements {SomeClass} + */ + constructor() {} +} +``` + +**Correct (constructor-style function):** + +```js +/** + * @implements {SomeClass} + * @class + */ +function quux() {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md new file mode 100644 index 0000000..504275f --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md @@ -0,0 +1,32 @@ +--- +title: Use @module for Module-Level Docs +impact: MEDIUM +impactDescription: clarifies module boundaries and exported responsibilities +tags: jsdoc, module, entrypoint, organization +--- + +## Use `@module` for Module-Level Docs + +Use `@module` at file/module scope for package organization and generated docs. + +**Use this when:** documenting JavaScript module entrypoints or grouped exports. +**Avoid this when:** annotating individual functions with module-level semantics. + +**Incorrect (module tag on member doc):** + +```js +/** + * @module auth + * Issues access tokens. + */ +function issueToken(userId) {} +``` + +**Correct (module-level declaration):** + +```js +/** + * Authentication helpers. + * @module auth + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md new file mode 100644 index 0000000..22699e1 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md @@ -0,0 +1,37 @@ +--- +title: Define Reusable Shapes with @typedef and @property +impact: HIGH +impactDescription: centralizes object contracts and improves consistency +tags: jsdoc, typedef, property, object-shapes +--- + +## Define Reusable Shapes with `@typedef` and `@property` + +Use `@typedef` and `@property` for repeated object shapes. + +**Use this when:** multiple APIs share the same object structure. +**Avoid this when:** duplicating long inline object type expressions everywhere. + +**Incorrect (duplicated inline shape):** + +```js +/** + * @param {{ id: string, active: boolean }} user - User object. + */ +function saveUser(user) {} +``` + +**Correct (reusable typedef):** + +```js +/** + * @typedef {Object} UserRecord + * @property {string} id - Stable user identifier. + * @property {boolean} active - Whether the user is active. + */ + +/** + * @param {UserRecord} user - User object. + */ +function saveUser(user) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md new file mode 100644 index 0000000..fd3ab87 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md @@ -0,0 +1,32 @@ +--- +title: Document Generator Output with @yields +impact: MEDIUM +impactDescription: clarifies yielded value contracts for iterators +tags: jsdoc, yields, generators, iterators +--- + +## Document Generator Output with `@yields` + +Use `@yields {Type}` to describe generator output values. + +**Use this when:** documenting generator functions. +**Avoid this when:** function is not a generator. + +**Incorrect (missing yielded type):** + +```js +/** + * Generates Fibonacci numbers. + */ +function* fibonacci() {} +``` + +**Correct (explicit yielded contract):** + +```js +/** + * Generates Fibonacci numbers. + * @yields {number} The next number in the sequence. + */ +function* fibonacci() {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-check-access.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-check-access.md new file mode 100644 index 0000000..5f2d6fe --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-check-access.md @@ -0,0 +1,53 @@ +--- +title: Validate Access Tags with check-access +impact: HIGH +impactDescription: prevents ambiguous visibility semantics in JSDoc comments +tags: jsdoc, access, lint, visibility +--- + +## Validate Access Tags with `check-access` + +When documenting visibility in JSDoc, use exactly one access style per doc block: + +- `@access package|private|protected|public`, or +- one shorthand tag: `@package`, `@private`, `@protected`, or `@public` + +**Use this when:** documenting API/member visibility in JavaScript files. +**Avoid this when:** mixing access styles or using unsupported access values. + +**Incorrect (mixed access styles):** + +```js +/** + * @access private + * @public + */ +function normalizeUser(input) {} +``` + +**Incorrect (invalid access value):** + +```js +/** + * @access internal-only + */ +function normalizeUser(input) {} +``` + +**Correct (single valid access tag):** + +```js +/** + * @access private + */ +function normalizeUser(input) {} +``` + +**Correct (single shorthand access tag):** + +```js +/** + * @private + */ +function normalizeUser(input) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-example.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-example.md new file mode 100644 index 0000000..10297b9 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-example.md @@ -0,0 +1,34 @@ +--- +title: Add Practical @example Snippets +impact: MEDIUM +impactDescription: reduces misuse by showing expected call patterns +tags: jsdoc, example, usage, snippets +--- + +## Add Practical `@example` Snippets + +Use `@example` for behavior that is not obvious from signature alone. + +**Use this when:** API behavior or output format may be misunderstood. +**Avoid this when:** examples are trivial, stale, or verbose. + +**Incorrect (no concrete usage):** + +```js +/** + * Formats a currency value. + */ +function formatCurrency(amount, currency) {} +``` + +**Correct (practical usage):** + +```js +/** + * Formats a currency value. + * @example + * // "$12.50" + * formatCurrency(12.5, "USD") + */ +function formatCurrency(amount, currency) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md new file mode 100644 index 0000000..8821a23 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md @@ -0,0 +1,46 @@ +--- +title: Avoid Defaults in JSDoc Param Tags +impact: MEDIUM +impactDescription: keeps parameter documentation aligned with modern JavaScript defaults +tags: jsdoc, param, defaults, lint +--- + +## Avoid Defaults in JSDoc Param Tags + +Do not include default values inside `@param` or `@default` tag syntax when documenting function parameters. + +**Use this when:** documenting JavaScript function parameters where defaults/optionality are represented in code. +**Avoid this when:** writing bracketed defaults like `[name="value"]` in JSDoc. + +This prevents redundant default notation in docs where ES2015+ default parameters already express runtime behavior. + +**Incorrect (default value in `@param`):** + +```js +/** + * @param {number} [foo="7"] + */ +function quux(foo) {} +``` + +**Correct (required param notation):** + +```js +/** + * @param {number} foo + */ +function quux(foo) {} +``` + +**Correct (untyped required param notation):** + +```js +/** + * @param foo + */ +function quux(foo) {} +``` + +Configuration option: + +- `noOptionalParamNames` (`boolean`, default `false`): when `true`, also report square-bracket optional names on `@param` tags. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-optional-default.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-optional-default.md new file mode 100644 index 0000000..9c8eaea --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-optional-default.md @@ -0,0 +1,34 @@ +--- +title: Use Optional and Default Parameter Strings Correctly +impact: CRITICAL +impactDescription: prevents caller confusion around optional inputs +tags: jsdoc, param, optional, defaults, syntax +--- + +## Use Optional and Default Parameter Strings Correctly + +Use JSDoc optional/default syntax strings consistently: + +- Optional: `@param {string} [name]` +- Optional with default: `@param {string} [name=John Doe]` + +**Use this when:** documenting optional JavaScript parameters. +**Avoid this when:** optionality is described only in prose and not in tag syntax. + +**Incorrect (optionality hidden):** + +```js +/** + * @param {string} name - Optional display name. + */ +function greet(name) {} +``` + +**Correct (explicit optional/default string syntax):** + +```js +/** + * @param {string} [name=John Doe] - Optional display name. + */ +function greet(name) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md new file mode 100644 index 0000000..d1cf937 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md @@ -0,0 +1,33 @@ +--- +title: Document Parameters with JSDoc Type Expressions +impact: CRITICAL +impactDescription: defines input contract for JavaScript APIs +tags: jsdoc, param, types, contracts +--- + +## Document Parameters with JSDoc Type Expressions + +Use `@param {Type} name - Description` for each parameter. + +**Use this when:** documenting JavaScript API parameters. +**Avoid this when:** type expressions are missing or inconsistent. + +Each parameter comment must explain what that specific parameter does. + +**Incorrect (missing type expression):** + +```js +/** + * @param timeoutMs - Wait time. + */ +function waitForReady(timeoutMs) {} +``` + +**Correct (typed parameter contract):** + +```js +/** + * @param {number} timeoutMs - Maximum wait time in milliseconds. + */ +function waitForReady(timeoutMs) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md new file mode 100644 index 0000000..d880947 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md @@ -0,0 +1,34 @@ +--- +title: Use Nested Property Namepaths for Object Inputs +impact: HIGH +impactDescription: makes object parameter contracts explicit +tags: jsdoc, param, property, namepath, objects +--- + +## Use Nested Property Namepaths for Object Inputs + +When a parameter is an object, document its fields using namepaths. +Each object property needs its own comment that explains what it does. + +**Use this when:** function expects structured objects or arrays of objects. +**Avoid this when:** only top-level object parameter is documented. + +**Incorrect (missing nested fields):** + +```js +/** + * @param {Object} options - Query options. + */ +function search(options) {} +``` + +**Correct (nested property paths):** + +```js +/** + * @param {Object} options - Query options. + * @param {string} options.query - Search query string. + * @param {number} [options.limit=20] - Maximum number of results. + */ +function search(options) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md new file mode 100644 index 0000000..d1c3db2 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md @@ -0,0 +1,29 @@ +--- +title: Require Types in @param Tags +impact: HIGH +impactDescription: ensures parameter contracts include explicit JSDoc type information +tags: jsdoc, param, types, lint +--- + +## Require Types in `@param` Tags + +Ensure each JSDoc `@param` tag includes a type expression in curly braces. + +**Use this when:** documenting JavaScript function parameters with JSDoc. +**Avoid this when:** writing untyped `@param` tags like `@param foo`. + +The parameter type should be documented so callers and tooling can understand expected input shapes. + +**Incorrect (missing type in `@param`):** + +```js +/** @param foo */ +function quux(foo) {} +``` + +**Correct (typed `@param`):** + +```js +/** @param {SomeType} foo */ +function quux(foo) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md new file mode 100644 index 0000000..9c77524 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md @@ -0,0 +1,40 @@ +--- +title: Require @param for Function Parameters +impact: HIGH +impactDescription: ensures complete input contracts for documented functions +tags: jsdoc, param, completeness, lint +--- + +## Require `@param` for Function Parameters + +Document all function parameters with JSDoc `@param` tags. + +**Use this when:** writing JSDoc for functions, methods, and callable APIs. +**Avoid this when:** some parameters are undocumented in the JSDoc block. + +This improves code quality and maintainability by making function inputs explicit. + +**Incorrect (missing a parameter tag):** + +```js +/** @param foo */ +function quux(foo, bar) {} +``` + +**Correct (all parameters documented):** + +```js +/** @param foo */ +function quux(foo) {} +``` + +Configuration options: + +- `checkConstructors` (`boolean`, default `false`): whether to check constructor methods. +- `checkDestructured` (`boolean`, default `true`): whether to check destructured parameters. +- `checkDestructuredRoots` (`boolean`, default `true`): whether to require a root `@param` tag for root destructured parameters like `function f({a, b}) {}`. +- `checkGetters` (`boolean`, default `true`): whether to check getter methods. +- `checkRestProperty` (`boolean`, default `false`): whether to check rest properties. +- `checkSetters` (`boolean`, default `true`): whether to check setter methods. +- `checkTypesPattern` (`string`, default `"^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$"`): regex pattern for types exempted from checking. +- `exemptedBy` (`string[]`, default `["inheritdoc"]`): JSDoc tags that exempt functions from `@param` checking. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md new file mode 100644 index 0000000..aa6d664 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md @@ -0,0 +1,33 @@ +--- +title: Require Descriptions for @property Tags +impact: HIGH +impactDescription: improves object-shape clarity by documenting property intent +tags: jsdoc, property, descriptions, lint +--- + +## Require Descriptions for `@property` Tags + +Ensure all `@property` tags include a description. + +**Use this when:** documenting typedef or namespace properties. +**Avoid this when:** leaving property tags without explanatory text. + +Property descriptions should be documented so consumers understand each field's purpose. + +**Incorrect (missing property description):** + +```js +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo + */ +``` + +**Correct (property description present):** + +```js +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo Foo. + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-name.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-name.md new file mode 100644 index 0000000..22be0bd --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-name.md @@ -0,0 +1,33 @@ +--- +title: Require Names in @property Tags +impact: HIGH +impactDescription: ensures each documented property is identifiable by name +tags: jsdoc, property, names, lint +--- + +## Require Names in `@property` Tags + +Ensure all `@property` tags include a property name. + +**Use this when:** documenting typedef or namespace object properties. +**Avoid this when:** writing `@property` tags without an identifier. + +Property names should be documented so object fields can be referenced unambiguously. + +**Incorrect (missing property name):** + +```js +/** + * @typedef {SomeType} SomeTypedef + * @property {number} + */ +``` + +**Correct (property name present):** + +```js +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-type.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-type.md new file mode 100644 index 0000000..1a70bd0 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-type.md @@ -0,0 +1,33 @@ +--- +title: Require Types in @property Tags +impact: HIGH +impactDescription: ensures property contracts include explicit type information +tags: jsdoc, property, types, lint +--- + +## Require Types in `@property` Tags + +Ensure each `@property` tag includes a type expression in curly braces. + +**Use this when:** documenting typedef, namespace, or class properties with JSDoc. +**Avoid this when:** writing untyped `@property` tags like `@property foo`. + +Property types should be documented so consumers and tooling can infer expected data shapes. + +**Incorrect (missing property type):** + +```js +/** + * @typedef {SomeType} SomeTypedef + * @property foo + */ +``` + +**Correct (typed property):** + +```js +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property.md new file mode 100644 index 0000000..40e5d72 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property.md @@ -0,0 +1,45 @@ +--- +title: Require @property for Object Typedefs and Namespaces +impact: HIGH +impactDescription: prevents incomplete object-shape documentation for typedefs and namespaces +tags: jsdoc, typedef, namespace, property, lint +--- + +## Require `@property` for Object Typedefs and Namespaces + +When using `@typedef` or `@namespace` with plain object types, include one or more `@property` tags. + +**Use this when:** documenting object-based typedefs or namespaces. +**Avoid this when:** leaving object typedefs/namespaces without property definitions. + +Object shapes should have properties defined so consumers can understand the contract. + +**Incorrect (missing `@property`):** + +```js +/** + * @typedef {Object} SomeTypedef + */ + +/** + * @namespace {Object} SomeNamespace + */ +``` + +**Correct (object typedef with properties):** + +```js +/** + * @typedef {Object} SomeTypedef + * @property {SomeType} propName Prop description + */ +``` + +**Correct (object typedef with shorthand property):** + +```js +/** + * @typedef {object} Foo + * @property someProp + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-description.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-description.md new file mode 100644 index 0000000..02b23cb --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-description.md @@ -0,0 +1,36 @@ +--- +title: Require Descriptions in @returns Tags +impact: HIGH +impactDescription: clarifies return-value semantics beyond raw type information +tags: jsdoc, returns, descriptions, lint +--- + +## Require Descriptions in `@returns` Tags + +Ensure `@returns` tags include a description value. + +**Use this when:** documenting return behavior for functions and methods. +**Avoid this when:** leaving `@returns` empty or type-only without meaning. + +A `@returns` tag should explain what is returned, not just indicate that a return exists. + +The error is not reported when the return type is: + +- `void` +- `undefined` +- `Promise` +- `Promise` + +**Incorrect (missing return description):** + +```js +/** @returns */ +function quux(foo) {} +``` + +**Correct (return description present):** + +```js +/** @returns Foo. */ +function quux(foo) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-type.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-type.md new file mode 100644 index 0000000..5e9bcd2 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns-type.md @@ -0,0 +1,29 @@ +--- +title: Require Types in @returns Tags +impact: HIGH +impactDescription: ensures return contracts include explicit type information +tags: jsdoc, returns, types, lint +--- + +## Require Types in `@returns` Tags + +Ensure each `@returns` tag includes a type expression in curly braces. + +**Use this when:** documenting return values in JavaScript JSDoc blocks. +**Avoid this when:** writing untyped `@returns` tags like `@returns`. + +A `@returns` tag should include a type value to clearly define return shape expectations. + +**Incorrect (missing return type):** + +```js +/** @returns */ +function quux(foo) {} +``` + +**Correct (typed return):** + +```js +/** @returns {string} */ +function quux(foo) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md new file mode 100644 index 0000000..142b397 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md @@ -0,0 +1,53 @@ +--- +title: Require @returns for Return Statements +impact: HIGH +impactDescription: prevents missing or ambiguous return-value documentation +tags: jsdoc, returns, completeness, lint +--- + +## Require `@returns` for Return Statements + +Document return statements with `@returns` and avoid multiple `@returns` tags in a single doc block. + +**Use this when:** documenting functions or methods that return values. +**Avoid this when:** omitting `@returns` for returning functions or adding duplicate `@returns` tags. + +This prevents missing return contracts and inconsistent return documentation. + +**Incorrect (missing `@returns`):** + +```js +/** Foo. */ +function quux() { + return foo; +} +``` + +**Incorrect (duplicate `@returns` tags):** + +```js +/** + * @returns Foo! + * @returns Foo? + */ +function quux() { + return foo; +} +``` + +**Correct (single `@returns`):** + +```js +/** @returns Foo. */ +function quux() { + return foo; +} +``` + +Configuration options: + +- `checkConstructors` (`boolean`, default `false`): whether to check constructor methods. +- `checkGetters` (`boolean`, default `true`): whether to check getter methods. +- `exemptedBy` (`string[]`, default `["inheritdoc"]`): tags that exempt functions from requiring `@returns`. +- `forceRequireReturn` (`boolean`, default `false`): whether to require `@returns` even if no value is returned. +- `forceReturnsWithAsync` (`boolean`, default `false`): whether to require `@returns` on async functions. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md new file mode 100644 index 0000000..effc597 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md @@ -0,0 +1,50 @@ +--- +title: Require @yields for Generator Output +impact: HIGH +impactDescription: ensures generator output contracts are documented and unambiguous +tags: jsdoc, yields, generators, lint +--- + +## Require `@yields` for Generator Output + +Document generator yields with `@yields` and avoid multiple `@yields` tags in a single doc block. + +**Use this when:** documenting generator functions that yield values. +**Avoid this when:** omitting `@yields` on yielding generators or adding duplicate `@yields` tags. + +This prevents missing yield contracts and inconsistent generator documentation. + +**Incorrect (missing `@yields`):** + +```js +function* quux(foo) { + yield foo; +} +``` + +**Incorrect (duplicate `@yields` tags):** + +```js +/** + * @yields {undefined} + * @yields {void} + */ +function* quux(foo) {} +``` + +**Correct (single `@yields`):** + +```js +/** + * @yields Foo + */ +function* quux(foo) { + yield foo; +} +``` + +Configuration options: + +- `exemptedBy` (`string[]`, default `["inheritdoc"]`): functions with these tags are exempt. +- `forceRequireYields` (`boolean`, default `false`): require `@yields` on all generators, even empty/non-yielding ones. +- `withGeneratorTag` (`boolean`, default `false`): require `@yields` when a `@generator` tag is present. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-returns.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-returns.md new file mode 100644 index 0000000..44f55aa --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-returns.md @@ -0,0 +1,31 @@ +--- +title: Document Return Value Semantics with @returns +impact: HIGH +impactDescription: clarifies output behavior and expected shape +tags: jsdoc, returns, output, contracts +--- + +## Document Return Value Semantics with @returns + +Use `@returns {Type}` with semantic description. + +**Use this when:** functions return a value or Promise payload. +**Avoid this when:** only stating raw type without meaning. + +**Incorrect (type-only):** + +```js +/** + * @returns {Object} + */ +function parseConfig() {} +``` + +**Correct (semantics included):** + +```js +/** + * @returns {{ retries: number, timeoutMs: number }} Normalized runtime configuration. + */ +function parseConfig() {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-summary.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-summary.md new file mode 100644 index 0000000..740866d --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-summary.md @@ -0,0 +1,31 @@ +--- +title: Write JSDoc Summaries with Intent +impact: HIGH +impactDescription: improves API readability for JavaScript consumers +tags: jsdoc, summary, readability +--- + +## Write JSDoc Summaries with Intent + +Write concise summaries that explain behavior and purpose. + +**Use this when:** documenting JavaScript functions, classes, and modules. +**Avoid this when:** repeating symbol names without useful meaning. + +**Incorrect (name restatement):** + +```js +/** + * Gets data. + */ +function getData() {} +``` + +**Correct (behavior-focused):** + +```js +/** + * Fetches and parses JSON data from the configured endpoint. + */ +function getData() {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md new file mode 100644 index 0000000..fa932dd --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md @@ -0,0 +1,32 @@ +--- +title: Document Error Contracts with @throws +impact: HIGH +impactDescription: enables predictable caller error handling +tags: jsdoc, throws, errors, reliability +--- + +## Document Error Contracts with @throws + +Use `@throws {Type} ...` for expected, caller-relevant failures. + +**Use this when:** function may throw known errors callers should handle. +**Avoid this when:** listing incidental internal errors with no contract value. + +**Incorrect (no throws contract):** + +```js +/** + * Parses a signed token. + */ +function parseSignedToken(token) {} +``` + +**Correct (typed throws contract):** + +```js +/** + * Parses a signed token. + * @throws {Error} If the token signature is invalid. + */ +function parseSignedToken(token) {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-deprecated.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-deprecated.md new file mode 100644 index 0000000..9bd7587 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-deprecated.md @@ -0,0 +1,31 @@ +--- +title: Use @deprecated with Migration Guidance +impact: HIGH +impactDescription: prevents dead-end API usage and migration confusion +tags: tsdoc, deprecated, migration, lifecycle +--- + +## Use @deprecated with Migration Guidance + +Use `@deprecated` only with explicit replacement guidance. + +**Use this when:** a symbol should no longer be used. +**Avoid this when:** deprecation is unclear or no replacement exists. + +**Incorrect (no migration path):** + +```ts +/** + * @deprecated + */ +export function oldHash(input: string): string {} +``` + +**Correct (clear migration path):** + +```ts +/** + * @deprecated Use `hashSha256()` for stable cross-platform output. + */ +export function oldHash(input: string): string {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md new file mode 100644 index 0000000..2639e8a --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md @@ -0,0 +1,35 @@ +--- +title: Use @example for Non-Obvious Usage +impact: MEDIUM +impactDescription: reduces misuse and clarifies edge cases +tags: tsdoc, example, usage, snippets +--- + +## Use @example for Non-Obvious Usage + +Use `@example` for tricky, non-obvious, or high-value usage patterns. + +**Use this when:** behavior is subtle or edge-case driven. +**Avoid this when:** examples are trivial, stale, or excessively long. + +**Incorrect (no usage guidance for tricky API):** + +```ts +/** + * Retries an operation with backoff. + */ +export async function retry(fn: () => Promise): Promise {} +``` + +**Correct (clear example):** + +````ts +/** + * Retries an operation with backoff. + * @example + * ```ts + * const result = await retry(() => fetchJson("/api/data")) + * ``` + */ +export async function retry(fn: () => Promise): Promise {} +```` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md new file mode 100644 index 0000000..ffc754c --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md @@ -0,0 +1,71 @@ +--- +title: Document Parameters with @param +impact: CRITICAL +impactDescription: clarifies caller obligations and input semantics +tags: tsdoc, param, function-contract, api-docs +--- + +## Document Parameters with @param + +Use one `@param` line per parameter: `@param name - Description`. + +**Use this when:** documenting any function or method parameters. +**Avoid this when:** repeating type annotations already in the signature. + +Each parameter comment must explain what that specific parameter does. +If a parameter is an object, document each relevant property and what each property does. +For TypeScript object params, prefer a named object type/interface with `/** ... */` comments on each property. + +**Incorrect (missing semantics):** + +```ts +/** + * @param timeoutMs - number + */ +export function waitForReady(timeoutMs: number): Promise {} +``` + +**Correct (caller-relevant semantics):** + +```ts +/** + * @param timeoutMs - Maximum wait time in milliseconds before timing out. + */ +export function waitForReady(timeoutMs: number): Promise {} +``` + +**Incorrect (object parameter properties undocumented):** + +```ts +/** + * @param options - Search configuration. + */ +export function search(options: { query: string; limit?: number }): Result[] {} +``` + +**Correct (object parameter properties documented):** + +```ts +/** + * @param options - Search configuration. + * @param options.query - Query string used to match results. + * @param options.limit - Maximum number of results to return. + */ +export function search(options: { query: string; limit?: number }): Result[] {} +``` + +**Preferred (VS Code hover/autocomplete friendly pattern):** + +```ts +type SearchOptions = { + /** Query string used to match results. */ + query: string; + /** Maximum number of results to return. */ + limit?: number; +}; + +/** + * @param options - Search configuration. + */ +export function search(options: SearchOptions): Result[] {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-remarks.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-remarks.md new file mode 100644 index 0000000..7be061f --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-remarks.md @@ -0,0 +1,36 @@ +--- +title: Use @remarks for Long-Form Context +impact: HIGH +impactDescription: prevents overloaded summaries and preserves detail +tags: tsdoc, remarks, context, contracts +--- + +## Use @remarks for Long-Form Context + +Use `@remarks` for deeper context, caveats, and non-trivial behavior. + +**Use this when:** summary alone cannot express constraints or trade-offs. +**Avoid this when:** a one-line summary is sufficient. + +**Incorrect (long narrative in summary):** + +```ts +/** + * Generates cache keys and also normalizes locale and strips unsupported + * fields and retries once if key generation collides. + */ +export function buildCacheKey(input: Input): string {} +``` + +**Correct (summary + remarks):** + +```ts +/** + * Builds a deterministic cache key for request inputs. + * + * @remarks + * Normalizes locale casing, removes unsupported fields, and retries once on + * hash collisions to preserve key uniqueness guarantees. + */ +export function buildCacheKey(input: Input): string {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-returns.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-returns.md new file mode 100644 index 0000000..a9d2660 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-returns.md @@ -0,0 +1,31 @@ +--- +title: Document Return Semantics with @returns +impact: HIGH +impactDescription: clarifies output guarantees and expectations +tags: tsdoc, returns, output, contracts +--- + +## Document Return Semantics with @returns + +Use `@returns` to describe return meaning, guarantees, and ordering. + +**Use this when:** function returns non-void values (including Promise payloads). +**Avoid this when:** output is `void` and no return contract exists. + +**Incorrect (type-only restatement):** + +```ts +/** + * @returns A string. + */ +export function getCacheKey(): string {} +``` + +**Correct (semantic output contract):** + +```ts +/** + * @returns A deterministic cache key that is stable for equivalent inputs. + */ +export function getCacheKey(): string {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-summary.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-summary.md new file mode 100644 index 0000000..2f3b66b --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-summary.md @@ -0,0 +1,31 @@ +--- +title: Write Clear Summary Sentences +impact: HIGH +impactDescription: improves API discoverability and comprehension +tags: tsdoc, summary, readability, api-docs +--- + +## Write Clear Summary Sentences + +Write a short summary that explains behavior and intent in plain language. + +**Use this when:** every documented symbol. +**Avoid this when:** copying symbol names or implementation trivia. + +**Incorrect (name restatement, no meaning):** + +```ts +/** + * Gets user. + */ +export function getUser(id: string): Promise {} +``` + +**Correct (behavior and outcome):** + +```ts +/** + * Fetches a user by ID from the primary data source. + */ +export function getUser(id: string): Promise {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md new file mode 100644 index 0000000..4b1f360 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md @@ -0,0 +1,32 @@ +--- +title: Document Expected Failures with @throws +impact: HIGH +impactDescription: defines caller-facing error-handling contracts +tags: tsdoc, throws, errors, reliability +--- + +## Document Expected Failures with @throws + +Use `@throws` for expected, contract-relevant failures. + +**Use this when:** callers should handle known failure modes. +**Avoid this when:** documenting incidental low-level errors with no API contract value. + +**Incorrect (no throw contract):** + +```ts +/** + * Parses a signed token. + */ +export function parseToken(token: string): Payload {} +``` + +**Correct (caller-relevant error path):** + +```ts +/** + * Parses a signed token. + * @throws Error if token signature verification fails. + */ +export function parseToken(token: string): Payload {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-typeparam.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-typeparam.md new file mode 100644 index 0000000..88fdb3b --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-typeparam.md @@ -0,0 +1,32 @@ +--- +title: Document Generics with @typeParam +impact: CRITICAL +impactDescription: preserves generic API intent for consumers +tags: tsdoc, typeparam, generics, api-contract +--- + +## Document Generics with @typeParam + +Use `@typeParam` for each public generic parameter. + +**Use this when:** function/class/interface/type alias has generic type params. +**Avoid this when:** symbol has no generic parameters. + +**Incorrect (undocumented generic intent):** + +```ts +/** + * Builds an index from items. + */ +export function toIndex(items: T[]): Map {} +``` + +**Correct (clear generic role):** + +```ts +/** + * Builds an index from items. + * @typeParam T - Source item type stored in the resulting map. + */ +export function toIndex(items: T[]): Map {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md new file mode 100644 index 0000000..f3c4d59 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md @@ -0,0 +1,39 @@ +--- +title: Use @inheritDoc Only for Equivalent Contracts +impact: HIGH +impactDescription: prevents inherited docs from drifting from real behavior +tags: tsdoc, inheritdoc, inheritance, contracts +--- + +## Use @inheritDoc Only for Equivalent Contracts + +Use `@inheritDoc` only when behavior is truly equivalent to the referenced declaration. + +**Use this when:** override/wrapper keeps the same contract. +**Avoid this when:** behavior, defaults, errors, or side effects differ. + +**Incorrect (inherits despite changed behavior):** + +```ts +/** + * @inheritDoc BaseClient.fetch + */ +export class CachedClient extends BaseClient { + public override fetch(id: string): Promise {} +} +``` + +**Correct (document differences explicitly):** + +```ts +/** + * Fetches an item by ID, serving stale-while-revalidate responses from cache. + * + * @remarks + * Unlike `BaseClient.fetch`, this method may return cached data immediately + * and refresh the cache asynchronously. + */ +export class CachedClient extends BaseClient { + public override fetch(id: string): Promise {} +} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-label.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-label.md new file mode 100644 index 0000000..dd6c85d --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-label.md @@ -0,0 +1,33 @@ +--- +title: Use {@label ...} Only for Structured References +impact: LOW +impactDescription: avoids unnecessary complexity in standard docs +tags: tsdoc, label, inline-tags, references +--- + +## Use `{@label ...}` Only for Structured References + +Use `{@label ...}` sparingly for advanced reference labeling scenarios. + +**Use this when:** your doc tooling relies on explicit labels for cross-reference flows. +**Avoid this when:** ordinary symbol linking via `{@link ...}` is sufficient. + +**Incorrect (using labels as normal links):** + +```ts +/** + * {@label parseToken} + * Parses a signed token. + */ +export function parseToken(token: string): Payload {} +``` + +**Correct (use link for normal references):** + +```ts +/** + * Parses a signed token. + * See {@link verifyToken} for signature checks. + */ +export function parseToken(token: string): Payload {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-link.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-link.md new file mode 100644 index 0000000..96a10b6 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-link.md @@ -0,0 +1,31 @@ +--- +title: Prefer {@link ...} for Symbol References +impact: MEDIUM +impactDescription: improves navigation and reference accuracy +tags: tsdoc, link, cross-reference, discoverability +--- + +## Prefer `{@link ...}` for Symbol References + +Use inline `{@link ...}` when referring to symbols or canonical URLs. + +**Use this when:** references should be navigable and unambiguous. +**Avoid this when:** plain text names could be confused or drift over time. + +**Incorrect (non-linking text reference):** + +```ts +/** + * Works with TokenVerifier.verify for signature validation. + */ +export function parseSignedToken(token: string): Payload {} +``` + +**Correct (navigable reference):** + +```ts +/** + * Works with {@link TokenVerifier.verify} for signature validation. + */ +export function parseSignedToken(token: string): Payload {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-see.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-see.md new file mode 100644 index 0000000..739971b --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-see.md @@ -0,0 +1,33 @@ +--- +title: Use @see for Related APIs +impact: MEDIUM +impactDescription: connects related APIs and reduces duplicated docs +tags: tsdoc, see, references, api-navigation +--- + +## Use @see for Related APIs + +Use `@see` to point readers to related entry points, alternatives, or companion APIs. + +**Use this when:** relationship is important for correct API selection. +**Avoid this when:** references are irrelevant or redundant. + +**Incorrect (no relationship guidance):** + +```ts +/** + * Verifies token signatures. + */ +export function verifyToken(token: string): boolean {} +``` + +**Correct (points to related APIs):** + +```ts +/** + * Verifies token signatures. + * @see {@link decodeToken} + * @see {@link parseSignedToken} + */ +export function verifyToken(token: string): boolean {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-default-value.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-default-value.md new file mode 100644 index 0000000..0a4cd32 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-default-value.md @@ -0,0 +1,32 @@ +--- +title: Document Defaults with @defaultValue +impact: MEDIUM +impactDescription: prevents ambiguity in option and property behavior +tags: tsdoc, defaultValue, options, configuration +--- + +## Document Defaults with `@defaultValue` + +Use `@defaultValue` to document meaningful default behavior. + +**Use this when:** options/properties have user-visible defaults. +**Avoid this when:** defaults are unstable, implicit, or undocumented in implementation. + +**Incorrect (default hidden from docs):** + +```ts +/** + * Maximum retry attempts. + */ +export const DEFAULT_RETRY_ATTEMPTS = 3; +``` + +**Correct (explicit default):** + +```ts +/** + * Maximum retry attempts. + * @defaultValue 3 + */ +export const DEFAULT_RETRY_ATTEMPTS = 3; +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-modifier-tags.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-modifier-tags.md new file mode 100644 index 0000000..b628b71 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-modifier-tags.md @@ -0,0 +1,35 @@ +--- +title: Use Modifier Tags Only When Semantically True +impact: HIGH +impactDescription: prevents misleading API semantics in generated docs +tags: tsdoc, modifier-tags, readonly, override, virtual, sealed, decorator, eventProperty +--- + +## Use Modifier Tags Only When Semantically True + +Use modifier tags only when they match real API semantics. + +Common modifier tags: `@readonly`, `@override`, `@virtual`, `@sealed`, `@decorator`, `@eventProperty`. + +**Use this when:** code behavior and design contract actually match the tag. +**Avoid this when:** tags are decorative or used for emphasis. + +**Incorrect (tag conflicts with implementation):** + +```ts +/** + * Tracks current request count. + * @readonly + */ +export let requestCount = 0; +``` + +**Correct (tag matches behavior):** + +```ts +/** + * Current build version. + * @readonly + */ +export const BUILD_VERSION = "1.0.0"; +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-no-jsdoc-braces.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-no-jsdoc-braces.md new file mode 100644 index 0000000..82cc164 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-no-jsdoc-braces.md @@ -0,0 +1,33 @@ +--- +title: Do Not Mix JSDoc Type Syntax into TSDoc +impact: CRITICAL +impactDescription: avoids parser/tooling incompatibilities and inconsistent style +tags: tsdoc, jsdoc, syntax, consistency +--- + +## Do Not Mix JSDoc Type Syntax into TSDoc + +In TSDoc, avoid JSDoc-style type braces in tag lines. + +**Use this when:** writing TSDoc in TypeScript codebases. +**Avoid this when:** authoring JavaScript files that intentionally use JSDoc tooling. + +**Incorrect (JSDoc-style braces in TSDoc):** + +```ts +/** + * @param {string} id - User identifier. + * @returns {Promise} User record. + */ +export async function getUser(id: string): Promise {} +``` + +**Correct (TSDoc syntax):** + +```ts +/** + * @param id - User identifier. + * @returns User record. + */ +export async function getUser(id: string): Promise {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-package-documentation.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-package-documentation.md new file mode 100644 index 0000000..d56c2f6 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-package-documentation.md @@ -0,0 +1,32 @@ +--- +title: Use @packageDocumentation for Entrypoint Docs +impact: MEDIUM +impactDescription: improves package-level discoverability and onboarding +tags: tsdoc, packageDocumentation, modules, entrypoints +--- + +## Use `@packageDocumentation` for Entrypoint Docs + +Use `@packageDocumentation` on module/entrypoint docs, not regular members. + +**Use this when:** documenting package/module purpose and usage at top level. +**Avoid this when:** documenting individual functions, classes, or fields. + +**Incorrect (tag on a normal function):** + +```ts +/** + * @packageDocumentation + * Creates a token. + */ +export function createToken(userId: string): string {} +``` + +**Correct (tag on entrypoint-level docs):** + +```ts +/** + * @packageDocumentation + * Authentication helpers for issuing, parsing, and validating signed tokens. + */ +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-private-remarks.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-private-remarks.md new file mode 100644 index 0000000..ab914a4 --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-private-remarks.md @@ -0,0 +1,34 @@ +--- +title: Use @privateRemarks for Maintainer-Only Notes +impact: MEDIUM +impactDescription: separates internal guidance from public API docs +tags: tsdoc, privateRemarks, maintainers, internals +--- + +## Use `@privateRemarks` for Maintainer-Only Notes + +Use `@privateRemarks` for internal notes that should not appear in public docs. + +**Use this when:** maintainers need migration or implementation caveats. +**Avoid this when:** information is essential for API consumers. + +**Incorrect (internal rollout note in public remarks):** + +```ts +/** + * @remarks + * Keep legacy payload shape until mobile v4 rollout finishes. + */ +export function serializeUser(user: User): Payload {} +``` + +**Correct (internal detail isolated):** + +```ts +/** + * Serializes user data for API responses. + * @privateRemarks + * Keep legacy payload shape until mobile v4 rollout finishes. + */ +export function serializeUser(user: User): Payload {} +``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-release-tags.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-release-tags.md new file mode 100644 index 0000000..6b3bfaf --- /dev/null +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/policy/tsdoc-release-tags.md @@ -0,0 +1,36 @@ +--- +title: Apply Release Tags Consistently +impact: CRITICAL +impactDescription: ensures stable public API lifecycle communication +tags: tsdoc, release-tags, public, internal, alpha, beta, experimental +--- + +## Apply Release Tags Consistently + +Apply one clear release/visibility policy and keep it consistent across related APIs. + +Supported policy tags include `@public`, `@internal`, `@alpha`, `@beta`, and `@experimental`. + +**Use this when:** API lifecycle and visibility matter to consumers. +**Avoid this when:** tags are mixed arbitrarily or conflict with actual support policy. + +**Incorrect (conflicting policy):** + +```ts +/** + * Creates session tokens. + * @public + * @internal + */ +export function createSessionToken(userId: string): string {} +``` + +**Correct (single clear policy):** + +```ts +/** + * Creates session tokens. + * @beta + */ +export function createSessionToken(userId: string): string {} +``` diff --git a/.claude/skills/tsdoc-jsdoc-authoring b/.claude/skills/tsdoc-jsdoc-authoring new file mode 120000 index 0000000..74d9f11 --- /dev/null +++ b/.claude/skills/tsdoc-jsdoc-authoring @@ -0,0 +1 @@ +../../.agents/skills/tsdoc-jsdoc-authoring \ No newline at end of file diff --git a/.cursor/skills/tsdoc-jsdoc-authoring b/.cursor/skills/tsdoc-jsdoc-authoring new file mode 120000 index 0000000..74d9f11 --- /dev/null +++ b/.cursor/skills/tsdoc-jsdoc-authoring @@ -0,0 +1 @@ +../../.agents/skills/tsdoc-jsdoc-authoring \ No newline at end of file diff --git a/src/cli/commands/generate-workspace.ts b/src/cli/commands/generate-workspace.ts index 833bddc..5acf353 100644 --- a/src/cli/commands/generate-workspace.ts +++ b/src/cli/commands/generate-workspace.ts @@ -7,15 +7,30 @@ import { parsePackageList, } from "#src/readme-generator/generator"; +/** + * Parsed arguments for the `generate:workspace` command. + */ interface GenerateWorkspaceCommandArgs { + /** Workspace root containing project subdirectories. */ root: string; + /** Config filename to find within each project directory. */ configName: string; + /** Raw repeatable/comma-delimited package filter values from CLI. */ packageValues: string[]; + /** Enables dry-run mode without writing files. */ dryRun: boolean; + /** Forces non-zero exit code when any project fails. */ strict: boolean; + /** Disables discovery of `readie.global.json` when true. */ noGlobal: boolean; } +/** + * CLI command that generates README files for projects under a workspace root. + * + * In `--strict` mode, the command sets `process.exitCode = 1` when any project + * fails, while still printing summary information for the entire run. + */ export const generateWorkspaceCommand = Command.make( "generate:workspace", { diff --git a/src/cli/commands/generate.ts b/src/cli/commands/generate.ts index 8a61db2..2b44993 100644 --- a/src/cli/commands/generate.ts +++ b/src/cli/commands/generate.ts @@ -3,13 +3,23 @@ import { Effect } from "effect"; import { generateReadmeFromConfig } from "#src/readme-generator/generator"; +/** + * Parsed arguments for the `generate` command. + */ interface GenerateCommandArgs { + /** Path to the input readie config file. */ config: string; + /** Optional output path override. */ output: string; + /** Enables dry-run mode without writing files. */ dryRun: boolean; + /** Disables discovery of `readie.global.json` when true. */ noGlobal: boolean; } +/** + * Returns user-facing status text based on write and dry-run outcomes. + */ const resultStatus = (updated: boolean, dryRun: boolean) => { if (!updated) { return "No changes"; @@ -17,6 +27,9 @@ const resultStatus = (updated: boolean, dryRun: boolean) => { return dryRun ? "Would update" : "Generated"; }; +/** + * CLI command that generates a README from a single `readie.json` file. + */ export const generateCommand = Command.make( "generate", { diff --git a/src/cli/commands/init.ts b/src/cli/commands/init.ts index a851be7..36728e3 100644 --- a/src/cli/commands/init.ts +++ b/src/cli/commands/init.ts @@ -5,11 +5,19 @@ import { resolve } from "pathe"; import { starterConfigText } from "#src/config/starter-config"; +/** + * Parsed arguments for the `init` command. + */ interface InitCommandArgs { + /** Destination path for the generated starter config file. */ config: string; + /** Overwrites an existing config file when true. */ force: boolean; } +/** + * CLI command that writes a starter `readie.json` file. + */ export const initCommand = Command.make( "init", { diff --git a/src/cli/help.ts b/src/cli/help.ts index 6460134..196a6b5 100644 --- a/src/cli/help.ts +++ b/src/cli/help.ts @@ -1,3 +1,6 @@ +/** + * Prints top-level CLI usage text for the `readie` binary. + */ export const printRootHelp = () => { console.log(`readie diff --git a/src/cli/resolve-invocation.ts b/src/cli/resolve-invocation.ts index 19dfdcf..a4909cd 100644 --- a/src/cli/resolve-invocation.ts +++ b/src/cli/resolve-invocation.ts @@ -1,3 +1,6 @@ +/** + * Supported high-level invocation modes accepted by the root CLI entrypoint. + */ export type InvocationMode = | "generate" | "generate:workspace" @@ -5,15 +8,27 @@ export type InvocationMode = | "help" | "unknown"; +/** + * Normalized invocation data used to route CLI execution. + */ export interface ResolvedInvocation { + /** Resolved top-level mode used for command routing. */ mode: InvocationMode; + /** Arguments passed to the selected subcommand handler. */ commandArgs: string[]; + /** Original raw argument list before normalization. */ originalArgs: string[]; } +/** + * Checks whether a token is a standard help flag. + */ const isHelpFlag = (value: string | undefined) => value === "--help" || value === "-h"; +/** + * Maps the first CLI token to a known invocation mode. + */ const modeFromToken = (token: string | undefined): InvocationMode => { if (!token) { return "generate"; @@ -31,6 +46,12 @@ const modeFromToken = (token: string | undefined): InvocationMode => { return commandModes[token] ?? "unknown"; }; +/** + * Resolves CLI arguments into a mode and command argument payload. + * + * @param {string[]} args - Raw user arguments after the binary name. + * @returns {ResolvedInvocation} Invocation details used by the root command dispatcher. + */ export const resolveInvocation = (args: string[]): ResolvedInvocation => { const [first, ...rest] = args; const mode = modeFromToken(first); diff --git a/src/config/load-config.ts b/src/config/load-config.ts index 62a148a..11cac27 100644 --- a/src/config/load-config.ts +++ b/src/config/load-config.ts @@ -4,6 +4,9 @@ import { dirname, join, resolve } from "pathe"; import type { ReadieConfig, ReadieGlobalConfig } from "./types"; +/** + * Runtime schema for command entries declared in config files. + */ const commandSchema = Schema.Struct({ description: Schema.NonEmptyString, name: Schema.NonEmptyString, @@ -97,8 +100,18 @@ const decodeReadieGlobalConfig = Schema.decodeUnknownSync( readieGlobalConfigSchema ); +/** + * File name searched while walking up directories for global defaults. + */ const GLOBAL_CONFIG_NAME = "readie.global.json"; +/** + * Reads and parses a JSON file. + * + * @param {string} absolutePath - Absolute path to a JSON file. + * @returns {Promise} Parsed JSON value. + * @throws Error if the file cannot be parsed as valid JSON. + */ const parseJsonFile = async (absolutePath: string): Promise => { const raw = await readFile(absolutePath, "utf8"); try { @@ -111,6 +124,13 @@ const parseJsonFile = async (absolutePath: string): Promise => { } }; +/** + * Loads and validates a project-level `readie.json` config. + * + * @param {string} configPath - Path to a project config file. + * @returns {Promise} Parsed and validated readie config. + * @throws Error if JSON parsing or schema validation fails. + */ export const loadReadieConfig = async ( configPath: string ): Promise => { @@ -128,6 +148,13 @@ export const loadReadieConfig = async ( } }; +/** + * Loads and validates a global readie config file. + * + * @param {string} configPath - Path to a global config file. + * @returns {Promise} Parsed and validated global config values. + * @throws Error if JSON parsing or schema validation fails. + */ const loadGlobalReadieConfig = async ( configPath: string ): Promise => { @@ -145,6 +172,12 @@ const loadGlobalReadieConfig = async ( } }; +/** + * Searches upward from a starting directory for `readie.global.json`. + * + * @param {string} startDir - Directory where upward discovery begins. + * @returns {Promise} The first discovered global config, or `null` when none exists. + */ export const loadGlobalConfig = async ( startDir: string ): Promise => { @@ -167,9 +200,13 @@ export const loadGlobalConfig = async ( const hasOwn = (obj: object, key: string): boolean => Object.hasOwn(obj, key); interface InterpolationContext { + /** Package name resolved from adjacent `package.json` when available. */ packageName?: string; } +/** + * Replaces `{{placeholder}}` tokens using known interpolation values. + */ const interpolatePlaceholders = ( value: string, placeholders: Record @@ -179,6 +216,9 @@ const interpolatePlaceholders = ( (match, key: string) => placeholders[key] ?? match ); +/** + * Creates all placeholder values available to config interpolation. + */ const createInterpolationPlaceholders = ( config: ReadieConfig, interpolationContext: InterpolationContext @@ -193,6 +233,9 @@ const createInterpolationPlaceholders = ( }; }; +/** + * Applies placeholder interpolation to custom section values. + */ const interpolateCustomSections = ( customSections: Record | undefined, placeholders: Record @@ -208,6 +251,9 @@ const interpolateCustomSections = ( return interpolatedSections; }; +/** + * Interpolates top-level string fields and custom section values. + */ const interpolateTopLevelStrings = ( config: ReadieConfig, interpolationContext: InterpolationContext @@ -232,6 +278,11 @@ const interpolateTopLevelStrings = ( return interpolated as unknown as ReadieConfig; }; +/** + * Resolves a field with project-over-global precedence. + * + * Explicit `null` values in either config are treated as "unset". + */ const resolveMergedValue = ( key: keyof ReadieConfig, projectConfig: ReadieConfig, @@ -256,6 +307,9 @@ const readGlobalCustomSections = (global: Record) => { return global.customSections as Record; }; +/** + * Reads custom sections from project config while preserving explicit nulls. + */ const readProjectCustomSections = (project: Record) => { const projectCustomSections = project.customSections; if (projectCustomSections === null) { @@ -267,6 +321,9 @@ const readProjectCustomSections = (project: Record) => { return projectCustomSections as Record; }; +/** + * Merges custom sections with project values overriding global duplicates. + */ const resolveMergedCustomSections = ( globalConfig: ReadieGlobalConfig | null, projectConfig: ReadieConfig @@ -294,6 +351,15 @@ const resolveMergedCustomSections = ( }; }; +/** + * Merges project config with optional global defaults and interpolates + * supported placeholders in resulting string fields. + * + * @param {ReadieGlobalConfig | null} globalConfig - Optional global defaults discovered from parent dirs. + * @param {ReadieConfig} projectConfig - Required project-level config. + * @param {InterpolationContext} interpolationContext - Optional runtime interpolation context. + * @returns {ReadieConfig} A merged config where project values win over global values. + */ export const mergeConfigs = ( globalConfig: ReadieGlobalConfig | null, projectConfig: ReadieConfig, diff --git a/src/config/starter-config.ts b/src/config/starter-config.ts index 01d2b91..a7509c5 100644 --- a/src/config/starter-config.ts +++ b/src/config/starter-config.ts @@ -1,8 +1,14 @@ import type { ReadieConfig } from "./types"; +/** + * Default schema URL written to starter configs. + */ export const DEFAULT_SCHEMA_URL = "https://unpkg.com/readie/schemas/readie.schema.json"; +/** + * Baseline `readie.json` content used by the `init` command. + */ export const starterConfig: ReadieConfig = { $schema: DEFAULT_SCHEMA_URL, description: "A short description of what this project does.", @@ -15,4 +21,7 @@ export const starterConfig: ReadieConfig = { version: "1", }; +/** + * Stringified starter config with a trailing newline for file output. + */ export const starterConfigText = `${JSON.stringify(starterConfig, null, 2)}\n`; diff --git a/src/config/types.ts b/src/config/types.ts index 59741cd..fc3fb0c 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -1,78 +1,169 @@ +/** + * Describes a CLI command that should be rendered in generated README content. + */ export interface ReadieCommand { + /** Command name shown in the README command list. */ name: string; + /** Short description of what the command does. */ description: string; } +/** + * Describes a global flag that should be rendered in generated README content. + */ export interface ReadieFlag { + /** Flag token such as `--dry-run`. */ flag: string; + /** Short description of the flag behavior. */ description: string; } +/** + * Represents a README badge image with an optional click-through link. + */ export interface ReadieBadge { + /** Accessible label used as badge alt text. */ label: string; + /** Badge image URL. */ image: string; + /** Optional link URL wrapped around the badge image. */ link?: string; } +/** + * Represents a license entry rendered as a linked label. + */ export interface ReadieLicenseObject { + /** Display name of the license. */ name: string; + /** URL to the full license text or page. */ url: string; } +/** + * License configuration accepted by readie. + */ export type ReadieLicense = string | ReadieLicenseObject; +/** + * Defines all supported fields for a project-level `readie.json` file. + */ export interface ReadieConfig { + /** Optional JSON schema URL for editor tooling. */ $schema?: string; + /** Config format version. */ version?: "1"; + /** Project title rendered as the README H1 when no banner H1 exists. */ title: string; + /** Primary project description paragraph. */ description: string; + /** Optional output path for generated README content. */ output?: string; + /** Controls whether a table of contents section is rendered. */ includeTableOfContents?: boolean; + /** Feature bullets rendered in the Key Features section. */ features?: string[]; + /** Prerequisite bullets required before usage or installation. */ prerequisites?: string[]; + /** Installation steps, typically command snippets. */ installation?: string[]; + /** Optional manual installation steps separate from standard install. */ manualInstallation?: string[]; + /** Usage steps rendered as numbered entries with code blocks support. */ usage?: string[]; + /** Command metadata rendered in the Available Commands section. */ commands?: ReadieCommand[]; + /** Global CLI flag metadata rendered in the Global Flags section. */ globalFlags?: ReadieFlag[]; + /** Badge metadata rendered near the top of the README. */ badges?: ReadieBadge[]; + /** Optional markdown/HTML block rendered before the title. */ banner?: string; + /** Quick start markdown block. */ quickStart?: string; + /** Support bullets for where users can get help. */ support?: string[]; + /** Contributing bullets for contribution workflow notes. */ contributing?: string[]; + /** Security section content such as disclosure guidance. */ security?: string; + /** License section content as text or linked object form. */ license?: ReadieLicense; + /** Optional footer content appended at the end of the README. */ footer?: string; + /** Link used to render the Documentation section. */ docsLink?: string; + /** Link used to render the Additional Quick Start section. */ quickStartLink?: string; + /** Additional custom sections keyed by heading title. */ customSections?: Record; } +/** + * Defines optional defaults loaded from `readie.global.json`. + */ export type ReadieGlobalConfig = Partial; +/** + * Options for generating a single README from one config file. + */ export interface GenerateSingleOptions { + /** Path to the input `readie.json` file. */ configPath: string; + /** Optional explicit output path that overrides config output. */ outputPath?: string; + /** If true, computes changes without writing files. */ dryRun: boolean; + /** If false, disables `readie.global.json` discovery and merge. */ useGlobalConfig?: boolean; } +/** + * Result of generating a single README file. + */ export interface GenerateSingleResult { + /** Resolved path where README content was written or would be written. */ outputPath: string; + /** Whether generated content differs from existing file content. */ updated: boolean; } +/** + * Options for generating README files across workspace projects. + */ export interface GenerateWorkspaceOptions { + /** Workspace root directory containing project subdirectories. */ rootDir: string; + /** Config file name to search for in each project directory. */ configName: string; + /** Optional package-name filter for selecting projects. */ packageFilter: Set; + /** If true, computes changes without writing files. */ dryRun: boolean; + /** If false, disables `readie.global.json` discovery and merge. */ useGlobalConfig?: boolean; } +/** + * Represents a failed workspace project generation attempt. + */ +export interface GenerateWorkspaceFailure { + /** Absolute project directory path that failed generation. */ + projectDir: string; + /** Original error value captured during project processing. */ + error: unknown; +} + +/** + * Aggregated outcome from a workspace generation run. + */ export interface GenerateWorkspaceResult { + /** Project names whose README files were created or changed. */ updated: string[]; + /** Project names whose README content was already up to date. */ unchanged: string[]; - failed: { projectDir: string; error: unknown }[]; + /** Projects that failed with the associated error payload. */ + failed: GenerateWorkspaceFailure[]; + /** Project names skipped because they were filtered out by package flags. */ skippedByFilter: string[]; } diff --git a/src/index.ts b/src/index.ts index c9b2e24..687094b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,6 +30,9 @@ const runInit = (args: string[]) => version, })(args).pipe(Effect.provide(NodeContext.layer)); +/** + * Selects and builds the Effect program for the resolved invocation mode. + */ const selectCommandEffect = ( resolved: ReturnType ) => { @@ -45,6 +48,9 @@ const selectCommandEffect = ( throw new Error(`Unsupported invocation mode: ${resolved.mode}`); }; +/** + * Normalizes CLI error output and sets non-zero exit code. + */ const handleError = (error: unknown) => { if (ValidationError.isValidationError(error)) { console.error(String(error)); @@ -56,6 +62,9 @@ const handleError = (error: unknown) => { process.exitCode = 1; }; +/** + * Resolves invocation mode and executes the selected command flow. + */ const main = async () => { const resolved = resolveInvocation(process.argv.slice(2)); diff --git a/src/readme-generator/generator.ts b/src/readme-generator/generator.ts index 1634d00..e3e7b50 100644 --- a/src/readme-generator/generator.ts +++ b/src/readme-generator/generator.ts @@ -15,6 +15,12 @@ import type { import { baseReadmeTemplate } from "./template"; +/** + * Normalizes repeated and comma-separated `--package` option values. + * + * @param {string[]} values - Raw CLI values that may contain comma-delimited package names. + * @returns {Set} A de-duplicated set of trimmed package names. + */ export const parsePackageList = (values: string[]): Set => { const packages = new Set(); for (const value of values) { @@ -28,6 +34,10 @@ export const parsePackageList = (values: string[]): Set => { return packages; }; +/** + * Resolves the final README output path using CLI override first, then config, + * then a default `README.md` next to the config file. + */ const resolveOutputPath = ( configPath: string, configOutputPath: string | undefined, @@ -42,6 +52,11 @@ const resolveOutputPath = ( return resolve(dirname(configPath), "README.md"); }; +/** + * Attempts to read a package name from `package.json` beside the config file. + * + * @returns {Promise} The package name when present, otherwise `undefined`. + */ const resolvePackageName = async ( configPath: string ): Promise => { @@ -69,6 +84,11 @@ const loadMergedConfig = async ( return mergeConfigs(globalConfig, projectConfig, { packageName }); }; +/** + * Reads existing file content if the target exists. + * + * @returns {Promise} The current file content, or `null` if the file does not exist. + */ const readExistingContent = async (filePath: string) => { if (!(await pathExists(filePath))) { return null; @@ -76,6 +96,12 @@ const readExistingContent = async (filePath: string) => { return readFile(filePath, "utf8"); }; +/** + * Generates a README for a single project config. + * + * @param {GenerateSingleOptions} options - Generation options for one config file. + * @returns {Promise} Generation metadata including output path and whether content changed. + */ export const generateReadmeFromConfig = async ({ configPath, outputPath, @@ -110,6 +136,9 @@ export const generateReadmeFromConfig = async ({ }; }; +/** + * Returns immediate child directories under `rootDir` that include `configName`. + */ const listProjectDirsWithConfig = async ( rootDir: string, configName: string @@ -137,6 +166,9 @@ const selectProjectDirs = ( ? allProjectDirs.filter((dir) => packageFilter.has(basename(dir))) : allProjectDirs; +/** + * Lists project directory names excluded by the package filter. + */ const collectSkippedByFilter = ( allProjectDirs: string[], packageFilter: Set @@ -149,6 +181,9 @@ const collectSkippedByFilter = ( .filter((dirName) => !packageFilter.has(dirName)); }; +/** + * Records a project result and emits the corresponding status message. + */ const pushProjectResult = ( result: GenerateWorkspaceResult, projectName: string, @@ -166,6 +201,9 @@ const pushProjectResult = ( console.log(`No changes for ${projectName}`); }; +/** + * Generates a README for one workspace project and appends success/failure info. + */ const processWorkspaceProject = async ( projectDir: string, configName: string, @@ -188,6 +226,13 @@ const processWorkspaceProject = async ( } }; +/** + * Generates README files for projects inside a workspace root. + * + * @param {GenerateWorkspaceOptions} options - Workspace generation options. + * @returns {Promise} Aggregated status across updated, unchanged, skipped, and failed projects. + * @throws Error if the workspace root does not exist. + */ export const generateWorkspaceReadmes = async ({ rootDir, configName, diff --git a/src/readme-generator/template.ts b/src/readme-generator/template.ts index 1e0ebaf..1fa647b 100644 --- a/src/readme-generator/template.ts +++ b/src/readme-generator/template.ts @@ -7,6 +7,9 @@ import type { const isNonEmpty = (value?: string | null): value is string => typeof value === "string" && value.trim().length > 0; +/** + * Collapses excessive blank lines between rendered markdown fragments. + */ const normalizeSections = (sections: string[]) => sections .join("\n") @@ -43,6 +46,9 @@ const renderNumberedWithCodeBlocks = (items: string[]) => { return normalizeSections(lines); }; +/** + * Renders a markdown section when content is present. + */ const addSection = ( header: string, content: string[] | undefined, @@ -55,6 +61,9 @@ const addSection = ( return `${header}\n\n${body}`.trim(); }; +/** + * Renders free-form section content and preserves already-headed markdown. + */ const renderHeadingBlock = ( heading: string, content: string | undefined @@ -115,27 +124,49 @@ const renderLicenseBlock = (license: ReadieConfig["license"]) => { }; interface ReadmeSections { + /** Optional top-of-file banner block. */ bannerBlock: string; + /** Main H1 title block. */ titleBlock: string; + /** Rendered badges block. */ badgesBlock: string; + /** Key Features section block. */ featuresBlock: string; + /** Prerequisites section block. */ prerequisitesBlock: string; + /** Quick Start section block. */ quickStartBlock: string; + /** Installation section block. */ installationBlock: string; + /** Manual Installation section block. */ manualInstallationBlock: string; + /** Usage section block. */ usageBlock: string; + /** Available Commands section block. */ commandsBlock: string; + /** Global Flags section block. */ globalFlagsBlock: string; + /** Documentation link section block. */ docsBlock: string; + /** Additional Quick Start link section block. */ quickStartLinkBlock: string; + /** Support section block. */ supportBlock: string; + /** Contributing section block. */ contributingBlock: string; + /** Security section block. */ securityBlock: string; + /** License section block. */ licenseBlock: string; + /** Concatenated custom section blocks. */ customSectionsBlock: string; + /** Optional trailing footer block. */ footerBlock: string; } +/** + * Builds all top-level section blocks from a readie config. + */ const createReadmeSections = (config: ReadieConfig): ReadmeSections => { const bannerBlock = isNonEmpty(config.banner) ? config.banner : ""; const titleBlock = @@ -197,6 +228,9 @@ const slugifyHeading = (title: string) => .trim() .replaceAll(/\s+/g, "-"); +/** + * Creates unique heading anchors by suffixing duplicate slugs. + */ const createUniqueSlug = (title: string, seenSlugs: Map) => { const baseSlug = slugifyHeading(title); const count = seenSlugs.get(baseSlug) ?? 0; @@ -237,6 +271,9 @@ const createTocTitles = (config: ReadieConfig, sections: ReadmeSections) => { return visibleTocSectionTitles; }; +/** + * Renders a table of contents block from visible section titles. + */ const createTocBlock = ( includeTableOfContents: boolean | undefined, titles: TocTitleEntry[] @@ -251,6 +288,12 @@ const createTocBlock = ( return `## Table of Contents\n\n${links}`; }; +/** + * Generates README markdown content for a project config. + * + * @param {ReadieConfig} rawConfig - Fully merged config used to render the README. + * @returns {string} Rendered README markdown with a trailing newline. + */ export const baseReadmeTemplate = (rawConfig: ReadieConfig) => { const sections = createReadmeSections(rawConfig); const tocTitles = createTocTitles(rawConfig, sections); From a49cc670812d9ff70b1d63b1df58724033923c65 Mon Sep 17 00:00:00 2001 From: Christopher Burns Date: Thu, 19 Feb 2026 23:17:26 +0000 Subject: [PATCH 2/5] Refactor documentation formatting for TSDoc and JSDoc - Adjusted indentation in various documentation files to ensure consistent formatting. - Updated examples in the TSDoc and JSDoc rules to enhance readability and maintainability. --- .agents/skills/tsdoc-jsdoc-authoring/reference.md | 12 ++++++------ .../jsdoc/advanced/jsdoc-implements-on-classes.md | 8 ++++---- .../rules/jsdoc/core/jsdoc-require-returns.md | 6 +++--- .../rules/jsdoc/core/jsdoc-require-yields.md | 4 ++-- .../rules/tsdoc/core/tsdoc-param.md | 8 ++++---- .../rules/tsdoc/crossref/tsdoc-inheritdoc.md | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/reference.md b/.agents/skills/tsdoc-jsdoc-authoring/reference.md index a27f54d..640212a 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/reference.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/reference.md @@ -80,8 +80,8 @@ export async function getProfile(): Promise {} * @returns A map from key to item. */ export function toMap( - items: T[], - getKey: (item: T) => string + items: T[], + getKey: (item: T) => string ): Map {} ``` @@ -169,10 +169,10 @@ For best VS Code hover and autocomplete docs on object properties, use a named t ```ts type SearchOptions = { - /** Query string used to match results. */ - query: string; - /** Maximum number of results to return. */ - limit?: number; + /** Query string used to match results. */ + query: string; + /** Maximum number of results to return. */ + limit?: number; }; /** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md index 59b91a3..36c7ef0 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-implements-on-classes.md @@ -25,10 +25,10 @@ function quux() {} ```js class Foo { - /** - * @implements {SomeClass} - */ - constructor() {} + /** + * @implements {SomeClass} + */ + constructor() {} } ``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md index 142b397..5d22c46 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md @@ -19,7 +19,7 @@ This prevents missing return contracts and inconsistent return documentation. ```js /** Foo. */ function quux() { - return foo; + return foo; } ``` @@ -31,7 +31,7 @@ function quux() { * @returns Foo? */ function quux() { - return foo; + return foo; } ``` @@ -40,7 +40,7 @@ function quux() { ```js /** @returns Foo. */ function quux() { - return foo; + return foo; } ``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md index effc597..35e3e38 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md @@ -18,7 +18,7 @@ This prevents missing yield contracts and inconsistent generator documentation. ```js function* quux(foo) { - yield foo; + yield foo; } ``` @@ -39,7 +39,7 @@ function* quux(foo) {} * @yields Foo */ function* quux(foo) { - yield foo; + yield foo; } ``` diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md index ffc754c..be0002e 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md @@ -58,10 +58,10 @@ export function search(options: { query: string; limit?: number }): Result[] {} ```ts type SearchOptions = { - /** Query string used to match results. */ - query: string; - /** Maximum number of results to return. */ - limit?: number; + /** Query string used to match results. */ + query: string; + /** Maximum number of results to return. */ + limit?: number; }; /** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md index f3c4d59..e740ce4 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/crossref/tsdoc-inheritdoc.md @@ -19,7 +19,7 @@ Use `@inheritDoc` only when behavior is truly equivalent to the referenced decla * @inheritDoc BaseClient.fetch */ export class CachedClient extends BaseClient { - public override fetch(id: string): Promise {} + public override fetch(id: string): Promise {} } ``` @@ -34,6 +34,6 @@ export class CachedClient extends BaseClient { * and refresh the cache asynchronously. */ export class CachedClient extends BaseClient { - public override fetch(id: string): Promise {} + public override fetch(id: string): Promise {} } ``` From e5fa24379fb0a0ccdb116767cbf333af200c1846 Mon Sep 17 00:00:00 2001 From: Christopher Burns Date: Thu, 19 Feb 2026 23:21:59 +0000 Subject: [PATCH 3/5] Add comprehensive documentation for Readie CLI and configuration - Introduced new documentation files: CLI Reference, Configuration, Quickstart, and Workspace Guide. - Detailed command usage, options, and configuration fields for `readie.json` and `readie.global.json`. - Enhanced the main documentation index to improve navigation and accessibility for users. --- docs/cli-reference.mdx | 58 ++++++++++++++++++++++++++++++++++++++ docs/configuration.mdx | 64 ++++++++++++++++++++++++++++++++++++++++++ docs/index.mdx | 26 +++++++++++++++++ docs/introduction.mdx | 33 ++++++++++++++++++++++ docs/meta.json | 10 +++++++ docs/quickstart.mdx | 56 ++++++++++++++++++++++++++++++++++++ docs/workspace.mdx | 49 ++++++++++++++++++++++++++++++++ 7 files changed, 296 insertions(+) create mode 100644 docs/cli-reference.mdx create mode 100644 docs/configuration.mdx create mode 100644 docs/index.mdx create mode 100644 docs/introduction.mdx create mode 100644 docs/meta.json create mode 100644 docs/quickstart.mdx create mode 100644 docs/workspace.mdx diff --git a/docs/cli-reference.mdx b/docs/cli-reference.mdx new file mode 100644 index 0000000..9ae49a7 --- /dev/null +++ b/docs/cli-reference.mdx @@ -0,0 +1,58 @@ +--- +title: CLI Reference +description: Commands and flags available in the Readie CLI. +lastModified: 2026-02-19 +--- + +## Top-Level Usage + +```bash +readie [options] +readie generate [options] +readie generate:workspace [options] +readie init [options] +``` + +## Commands + +### `readie` / `readie generate` + +Generate one README from a config file. + +Options: + +- `--config, -c`: Path to config file (default `./readie.json`) +- `--output, -o`: Optional output path override +- `--dry-run`: Show changes without writing files +- `--no-global`: Disable `readie.global.json` discovery + +### `readie generate:workspace` + +Generate READMEs for multiple projects under a workspace root. + +Options: + +- `--root, -r`: Workspace root directory (default `./packages`) +- `--config-name`: Config filename to search for (default `readie.json`) +- `--package, -p`: Package filters (repeatable and comma-separated) +- `--dry-run`: Show changes without writing files +- `--strict`: Exit with code 1 if any project fails +- `--no-global`: Disable `readie.global.json` discovery + +### `readie init` + +Create a starter `readie.json`. + +Options: + +- `--config, -c`: Path for generated file (default `./readie.json`) +- `--force, -f`: Overwrite existing config + +## Help + +```bash +readie --help +readie generate --help +readie generate:workspace --help +readie init --help +``` diff --git a/docs/configuration.mdx b/docs/configuration.mdx new file mode 100644 index 0000000..4644983 --- /dev/null +++ b/docs/configuration.mdx @@ -0,0 +1,64 @@ +--- +title: Configuration +description: Reference for readie.json and readie.global.json fields. +lastModified: 2026-02-19 +--- + +## Project Config (`readie.json`) + +Use `readie.json` to define README content for one project. + +### Common Fields + +| Field | Type | Purpose | +| ---------------- | ------------------------- | ------------------------------- | +| `title` | `string` | Main project title | +| `description` | `string` | Introductory summary paragraph | +| `features` | `string[]` | Key feature bullets | +| `installation` | `string[]` | Installation steps and snippets | +| `usage` | `string[]` | Usage steps and code blocks | +| `commands` | `{ name, description }[]` | Command list in README | +| `globalFlags` | `{ flag, description }[]` | Shared flags section | +| `license` | `string \| { name, url }` | License section | +| `customSections` | `Record` | Additional custom headings | + +### Optional Rendering Controls + +- `includeTableOfContents`: enable or disable TOC rendering +- `output`: write README to a custom path instead of `README.md` +- `banner`, `footer`: inject custom top/bottom markdown + +## Global Config (`readie.global.json`) + +Use `readie.global.json` to define defaults shared across nearby projects. +Readie searches upward from each project directory until it finds one. + +### Merge Behavior + +- Project config values override global values +- If project config omits a field, global value can fill it +- Global config is optional and can be disabled with `--no-global` + +## Placeholders + +Readie supports placeholder interpolation in top-level string fields: + +- `{{title}}` +- `{{packageName}}` +- `{{packageNameEncoded}}` + +Example: + +```json +{ + "banner": "

{{title}}

", + "footer": "https://example.com/pkg/{{packageNameEncoded}}" +} +``` + +## Schemas + +- Project schema: `/schemas/readie.schema.json` +- Global schema: `/schemas/readie.global.schema.json` + +For editor autocomplete and validation, set `$schema` in your config file. diff --git a/docs/index.mdx b/docs/index.mdx new file mode 100644 index 0000000..78ad0b3 --- /dev/null +++ b/docs/index.mdx @@ -0,0 +1,26 @@ +--- +title: Readie Documentation +description: Learn how to generate consistent, polished README files with Readie. +lastModified: 2026-02-19 +full: true +--- + +# Readie Documentation + +Readie is a developer-first CLI that generates high-quality README files from a simple JSON config. + +## What You Can Do + +- Generate one README from a local `readie.json` +- Generate many READMEs across a workspace +- Reuse shared defaults via `readie.global.json` +- Keep docs consistent with schema-validated config files +- Preview changes safely with `--dry-run` + +## Start Here + +- New to Readie: [Introduction](/docs/introduction) +- Want to run it quickly: [Quickstart](/docs/quickstart) +- Need config details: [Configuration](/docs/configuration) +- Working in a monorepo: [Workspace Guide](/docs/workspace) +- Need command and flag details: [CLI Reference](/docs/cli-reference) diff --git a/docs/introduction.mdx b/docs/introduction.mdx new file mode 100644 index 0000000..95dd11d --- /dev/null +++ b/docs/introduction.mdx @@ -0,0 +1,33 @@ +--- +title: Introduction +description: Understand what Readie is, how it works, and where it fits in your docs workflow. +lastModified: 2026-02-19 +--- + +## What Is Readie? + +Readie is a CLI for generating README content from structured config files. +It helps teams standardize documentation while still allowing per-project customization. + +## Why Use It? + +- **Consistency:** keep section order and formatting predictable across repositories +- **Speed:** update docs through config changes instead of manual copy/paste edits +- **Safety:** compare generated output with existing files before writing +- **Scale:** apply generation to many projects inside a workspace + +## How It Works + +1. You create a `readie.json` config in a project. +2. Readie validates and loads the config. +3. Readie renders markdown from your configured sections. +4. Readie writes `README.md` (or a custom output path) when content changed. + +## Config Sources + +Readie supports two config layers: + +- **Project config (`readie.json`)** for package-specific content +- **Global config (`readie.global.json`)** for shared defaults across multiple projects + +When both are present, project values take precedence. diff --git a/docs/meta.json b/docs/meta.json new file mode 100644 index 0000000..eafef59 --- /dev/null +++ b/docs/meta.json @@ -0,0 +1,10 @@ +{ + "pages": [ + "index", + "introduction", + "quickstart", + "configuration", + "workspace", + "cli-reference" + ] +} diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx new file mode 100644 index 0000000..a1b85e7 --- /dev/null +++ b/docs/quickstart.mdx @@ -0,0 +1,56 @@ +--- +title: Quickstart +description: Install Readie, initialize config, and generate your first README. +lastModified: 2026-02-19 +--- + +## Prerequisites + +- Node.js 18+ +- npm, pnpm, or yarn + +## 1) Initialize a Config + +```bash +npx readie init +``` + +This creates a starter `readie.json`. + +## 2) Generate a README + +```bash +npx readie +``` + +By default, this runs the single-project generate flow using `./readie.json`. + +## 3) Preview Without Writing + +```bash +npx readie --dry-run +``` + +Use this mode in CI or before committing large docs updates. + +## Example `readie.json` + +````json +{ + "$schema": "https://unpkg.com/readie/schemas/readie.schema.json", + "version": "1", + "title": "Acme Toolkit", + "description": "A TypeScript toolkit for building internal tools.", + "includeTableOfContents": true, + "installation": ["```bash\nnpm install acme-toolkit\n```"], + "usage": [ + "Import the toolkit and initialize your client.", + "```ts\nimport { createClient } from \"acme-toolkit\";\n\nconst client = createClient();\n```" + ] +} +```` + +## Next Steps + +- Learn all available fields in [Configuration](/docs/configuration) +- Generate docs for many packages with [Workspace Guide](/docs/workspace) diff --git a/docs/workspace.mdx b/docs/workspace.mdx new file mode 100644 index 0000000..8cb7133 --- /dev/null +++ b/docs/workspace.mdx @@ -0,0 +1,49 @@ +--- +title: Workspace Guide +description: Generate README files across multiple packages in a monorepo or workspace. +lastModified: 2026-02-19 +--- + +## Generate Across Packages + +Use `generate:workspace` to scan child directories and process projects that contain a config file. + +```bash +npx readie generate:workspace --root ./packages --config-name readie.json +``` + +## Filter Specific Packages + +Use `--package` to target specific directories by name. + +```bash +npx readie generate:workspace \ + --root ./packages \ + --package api \ + --package ui +``` + +`--package` supports repeated flags and comma-separated values. + +## Safe Rollouts + +Preview updates first: + +```bash +npx readie generate:workspace --root ./packages --dry-run +``` + +Fail CI when any package fails: + +```bash +npx readie generate:workspace --root ./packages --strict +``` + +## Result Summary + +The command reports: + +- Updated projects +- Unchanged projects +- Failed projects +- Projects skipped by package filter From 632da11974208e2ca596b8dd931ea0ad0d958d6c Mon Sep 17 00:00:00 2001 From: Christopher Burns Date: Thu, 19 Feb 2026 23:35:51 +0000 Subject: [PATCH 4/5] Enhance documentation clarity and consistency across TSDoc and JSDoc rules - Updated various documentation files to improve phrasing and clarity, including changes to usage guidance and avoidance recommendations. - Added explicit examples and corrected formatting for better readability. - Ensured consistency in parameter and return type documentation across multiple files. - Revised schema references in configuration documentation for accuracy. --- .agents/skills/tsdoc-jsdoc-authoring/reference.md | 4 ++-- .../rules/jsdoc/advanced/jsdoc-module.md | 2 +- .../rules/jsdoc/advanced/jsdoc-typedef-property.md | 2 +- .../rules/jsdoc/advanced/jsdoc-yields.md | 4 +++- .../rules/jsdoc/core/jsdoc-no-defaults.md | 9 +++++++++ .../rules/jsdoc/core/jsdoc-param.md | 2 +- .../rules/jsdoc/core/jsdoc-property-namepaths.md | 2 +- .../rules/jsdoc/core/jsdoc-require-param-type.md | 2 +- .../rules/jsdoc/core/jsdoc-require-param.md | 2 +- .../jsdoc/core/jsdoc-require-property-description.md | 2 +- .../rules/jsdoc/core/jsdoc-require-returns.md | 2 +- .../rules/jsdoc/core/jsdoc-require-yields.md | 2 +- .../rules/jsdoc/core/jsdoc-throws.md | 2 +- .../rules/tsdoc/core/tsdoc-example.md | 4 ++-- .../rules/tsdoc/core/tsdoc-param.md | 2 +- .../rules/tsdoc/core/tsdoc-throws.md | 2 +- docs/configuration.mdx | 4 ++-- docs/introduction.mdx | 8 ++++---- docs/workspace.mdx | 6 ++++++ 19 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/reference.md b/.agents/skills/tsdoc-jsdoc-authoring/reference.md index 640212a..a6bc7f4 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/reference.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/reference.md @@ -190,5 +190,5 @@ Use this quick pass before finalizing JSDoc blocks in any project: ## 9) Sources Used For This Skill -- TSDoc: `/microsoft/tsdoc` (Context7) -- JSDoc: `/jsdoc/jsdoc.github.io` (Context7) +- TSDoc: `/microsoft/tsdoc` (Context7 internal context identifier for source mapping) +- JSDoc: `/jsdoc/jsdoc.github.io` (Context7 internal context identifier for source mapping) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md index 504275f..f90534e 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-module.md @@ -9,7 +9,7 @@ tags: jsdoc, module, entrypoint, organization Use `@module` at file/module scope for package organization and generated docs. -**Use this when:** documenting JavaScript module entrypoints or grouped exports. +**Apply it when:** documenting JavaScript module entrypoints or grouped exports. **Avoid this when:** annotating individual functions with module-level semantics. **Incorrect (module tag on member doc):** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md index 22699e1..3aabd7d 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-typedef-property.md @@ -10,7 +10,7 @@ tags: jsdoc, typedef, property, object-shapes Use `@typedef` and `@property` for repeated object shapes. **Use this when:** multiple APIs share the same object structure. -**Avoid this when:** duplicating long inline object type expressions everywhere. +**Avoid inline shapes when:** the same structure appears in multiple places. **Incorrect (duplicated inline shape):** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md index fd3ab87..a2c6581 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md @@ -18,7 +18,9 @@ Use `@yields {Type}` to describe generator output values. /** * Generates Fibonacci numbers. */ -function* fibonacci() {} +function* fibonacci() { + yield 0; +} ``` **Correct (explicit yielded contract):** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md index 8821a23..9d82d01 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-no-defaults.md @@ -32,6 +32,15 @@ function quux(foo) {} function quux(foo) {} ``` +**Correct (optional param without default value):** + +```js +/** + * @param {number} [foo] + */ +function quux(foo) {} +``` + **Correct (untyped required param notation):** ```js diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md index d1cf937..cb4ff6c 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-param.md @@ -10,7 +10,7 @@ tags: jsdoc, param, types, contracts Use `@param {Type} name - Description` for each parameter. **Use this when:** documenting JavaScript API parameters. -**Avoid this when:** type expressions are missing or inconsistent. +**Avoid this when:** using TypeScript with explicit parameter types or when types are reliably inferred from existing annotations/tooling. Each parameter comment must explain what that specific parameter does. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md index d880947..3ee8f95 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-property-namepaths.md @@ -11,7 +11,7 @@ When a parameter is an object, document its fields using namepaths. Each object property needs its own comment that explains what it does. **Use this when:** function expects structured objects or arrays of objects. -**Avoid this when:** only top-level object parameter is documented. +**Avoid this when:** you are only documenting a single top-level object parameter and none of its nested properties need separate documentation. **Incorrect (missing nested fields):** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md index d1c3db2..fa961e1 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param-type.md @@ -10,7 +10,7 @@ tags: jsdoc, param, types, lint Ensure each JSDoc `@param` tag includes a type expression in curly braces. **Use this when:** documenting JavaScript function parameters with JSDoc. -**Avoid this when:** writing untyped `@param` tags like `@param foo`. +**Avoid this when:** your project already uses TypeScript or external type definitions that make extra `{type}` expressions redundant. The parameter type should be documented so callers and tooling can understand expected input shapes. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md index 9c77524..478b695 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-param.md @@ -10,7 +10,7 @@ tags: jsdoc, param, completeness, lint Document all function parameters with JSDoc `@param` tags. **Use this when:** writing JSDoc for functions, methods, and callable APIs. -**Avoid this when:** some parameters are undocumented in the JSDoc block. +**Avoid this when:** TypeScript types already provide complete parameter documentation. This improves code quality and maintainability by making function inputs explicit. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md index aa6d664..7b4fc01 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-property-description.md @@ -10,7 +10,7 @@ tags: jsdoc, property, descriptions, lint Ensure all `@property` tags include a description. **Use this when:** documenting typedef or namespace properties. -**Avoid this when:** leaving property tags without explanatory text. +**Avoid this when:** the property tag already includes an explanatory description. Property descriptions should be documented so consumers understand each field's purpose. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md index 5d22c46..e79e90a 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-returns.md @@ -10,7 +10,7 @@ tags: jsdoc, returns, completeness, lint Document return statements with `@returns` and avoid multiple `@returns` tags in a single doc block. **Use this when:** documenting functions or methods that return values. -**Avoid this when:** omitting `@returns` for returning functions or adding duplicate `@returns` tags. +**Avoid this when:** the function truly has no return value or return information is inherited from external type declarations. This prevents missing return contracts and inconsistent return documentation. diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md index 35e3e38..f99ec50 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-require-yields.md @@ -36,7 +36,7 @@ function* quux(foo) {} ```js /** - * @yields Foo + * @yields {Foo} */ function* quux(foo) { yield foo; diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md index fa932dd..91f1332 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/core/jsdoc-throws.md @@ -12,7 +12,7 @@ Use `@throws {Type} ...` for expected, caller-relevant failures. **Use this when:** function may throw known errors callers should handle. **Avoid this when:** listing incidental internal errors with no contract value. -**Incorrect (no throws contract):** +**Incorrect (no-throws-contract):** ```js /** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md index 2639e8a..b54538c 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-example.md @@ -9,8 +9,8 @@ tags: tsdoc, example, usage, snippets Use `@example` for tricky, non-obvious, or high-value usage patterns. -**Use this when:** behavior is subtle or edge-case driven. -**Avoid this when:** examples are trivial, stale, or excessively long. +**When to use:** behavior is subtle or edge-case driven. +**When to avoid:** examples are trivial, stale, or excessively long. **Incorrect (no usage guidance for tricky API):** diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md index be0002e..6d5570f 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-param.md @@ -54,7 +54,7 @@ export function search(options: { query: string; limit?: number }): Result[] {} export function search(options: { query: string; limit?: number }): Result[] {} ``` -**Preferred (VS Code hover/autocomplete friendly pattern):** +**Preferred (VS Code hover/autocomplete-friendly pattern):** ```ts type SearchOptions = { diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md index 4b1f360..f106c1e 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/tsdoc/core/tsdoc-throws.md @@ -12,7 +12,7 @@ Use `@throws` for expected, contract-relevant failures. **Use this when:** callers should handle known failure modes. **Avoid this when:** documenting incidental low-level errors with no API contract value. -**Incorrect (no throw contract):** +**Incorrect (no-throw-contract):** ```ts /** diff --git a/docs/configuration.mdx b/docs/configuration.mdx index 4644983..c0aa5e2 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -58,7 +58,7 @@ Example: ## Schemas -- Project schema: `/schemas/readie.schema.json` -- Global schema: `/schemas/readie.global.schema.json` +- Project schema: `https://unpkg.com/readie/schemas/readie.schema.json` +- Global schema: `https://unpkg.com/readie/schemas/readie.global.schema.json` For editor autocomplete and validation, set `$schema` in your config file. diff --git a/docs/introduction.mdx b/docs/introduction.mdx index 95dd11d..8e882f8 100644 --- a/docs/introduction.mdx +++ b/docs/introduction.mdx @@ -18,10 +18,10 @@ It helps teams standardize documentation while still allowing per-project custom ## How It Works -1. You create a `readie.json` config in a project. -2. Readie validates and loads the config. -3. Readie renders markdown from your configured sections. -4. Readie writes `README.md` (or a custom output path) when content changed. +1. Create a `readie.json` config in your project. +2. Validate and load the config. +3. Render markdown from the configured sections. +4. Write `README.md` (or a custom output path) when content changes. ## Config Sources diff --git a/docs/workspace.mdx b/docs/workspace.mdx index 8cb7133..a09a1be 100644 --- a/docs/workspace.mdx +++ b/docs/workspace.mdx @@ -12,6 +12,12 @@ Use `generate:workspace` to scan child directories and process projects that con npx readie generate:workspace --root ./packages --config-name readie.json ``` +Disable global config discovery and merge when needed: + +```bash +npx readie generate:workspace --root ./packages --config-name readie.json --no-global +``` + ## Filter Specific Packages Use `--package` to target specific directories by name. From 6103745df27e55b994c57c286489b1d77992881b Mon Sep 17 00:00:00 2001 From: Christopher Burns Date: Thu, 19 Feb 2026 23:40:24 +0000 Subject: [PATCH 5/5] Implement yield functionality in Fibonacci generator example for JSDoc documentation --- .../rules/jsdoc/advanced/jsdoc-yields.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md index a2c6581..c3c7c44 100644 --- a/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md +++ b/.agents/skills/tsdoc-jsdoc-authoring/rules/jsdoc/advanced/jsdoc-yields.md @@ -30,5 +30,7 @@ function* fibonacci() { * Generates Fibonacci numbers. * @yields {number} The next number in the sequence. */ -function* fibonacci() {} +function* fibonacci() { + yield 0; +} ```