From 62c6486e7a8fd833d68e6c498a8aa5188d7e2dfc Mon Sep 17 00:00:00 2001 From: Sam Markowitz Date: Wed, 18 Mar 2026 14:34:40 +0200 Subject: [PATCH] Restructure sdk-docs-writing skill for progressive disclosure Extract detailed reference material (JSDoc tag table, example-writing patterns, pipeline configuration) into separate reference files that load on demand, reducing the main SKILL.md from 212 to 96 lines. Made-with: Cursor --- .claude/skills/sdk-docs-writing/SKILL.md | 133 ++---------------- .../references/example-patterns.md | 46 ++++++ .../sdk-docs-writing/references/jsdoc-tags.md | 35 +++++ .../references/pipeline-config.md | 24 ++++ 4 files changed, 114 insertions(+), 124 deletions(-) create mode 100644 .claude/skills/sdk-docs-writing/references/example-patterns.md create mode 100644 .claude/skills/sdk-docs-writing/references/jsdoc-tags.md create mode 100644 .claude/skills/sdk-docs-writing/references/pipeline-config.md diff --git a/.claude/skills/sdk-docs-writing/SKILL.md b/.claude/skills/sdk-docs-writing/SKILL.md index 6f067e0..ef1bfd9 100644 --- a/.claude/skills/sdk-docs-writing/SKILL.md +++ b/.claude/skills/sdk-docs-writing/SKILL.md @@ -11,7 +11,7 @@ Docs in this repo are **auto-generated** from JSDoc comments in TypeScript sourc .types.ts JSDoc → TypeDoc → custom Mintlify plugin → post-processing → Mintlify MDX ``` -You write JSDoc. The tooling produces the final pages. This skill covers how to write JSDoc that generates clear, useful reference docs. +You write JSDoc. The tooling produces the final pages. ## Where docs come from @@ -24,11 +24,11 @@ You write JSDoc. The tooling produces the final pages. This skill covers how to Only types and functions **not** marked `@internal` appear in the generated docs. Implementation files should mark their exports `@internal`. -## JSDoc structure for interfaces and types +## JSDoc structure ### Module interface (top-level) -Module interfaces like `EntitiesModule`, `AuthModule`, and `IntegrationsModule` are the entry points. Their JSDoc becomes the module's intro page. Write a thorough description: +Module interfaces like `EntitiesModule`, `AuthModule`, and `IntegrationsModule` are the entry points. Their JSDoc becomes the module's intro page: ```typescript /** @@ -58,11 +58,6 @@ Every public method needs: description, `@param` tags, `@returns`, and at least /** * Lists records with optional pagination and sorting. * - * Retrieves all records of this type with support for sorting, - * pagination, and field selection. - * - * **Note:** The maximum limit is 5,000 items per request. - * * @param sort - Sort parameter, such as `'-created_date'` for descending. Defaults to `'-created_date'`. * @param limit - Maximum number of results to return. Defaults to `50`. * @param skip - Number of results to skip for pagination. Defaults to `0`. @@ -74,132 +69,23 @@ Every public method needs: description, `@param` tags, `@returns`, and at least * // Get all records * const records = await base44.entities.MyEntity.list(); * ``` - * - * @example - * ```typescript - * // Get first 10 records sorted by date - * const recentRecords = await base44.entities.MyEntity.list('-created_date', 10); - * ``` - */ -``` - -### Interface properties - -Use inline JSDoc comments. One line per property: - -```typescript -export interface DeleteManyResult { - /** Whether the deletion was successful */ - success: boolean; - /** Number of entities that were deleted */ - deleted: number; -} -``` - -For properties with defaults or special behavior, use `@default`: - -```typescript -/** If set to `true`, the LLM will use Google Search to gather context. - * @default false */ -add_context_from_internet?: boolean; -``` - -## Tag reference - -| Tag | When to use | Notes | -|---|---|---| -| `@param name - Description.` | Every function/method parameter | Include default value in prose: "Defaults to `50`." | -| `@returns` | Every function/method | Start with "Promise resolving to..." for async methods | -| `@example` | Every public method (at least one) | Each `@example` block becomes a tab in `` | -| `@typeParam T` | Generic type parameters | Explain what the type represents and its default | -| `@throws {Error}` | Methods that throw on known conditions | Describe the condition | -| `@internal` | Implementation details hidden from docs | Use on factory functions, config interfaces, helpers | -| `@default value` | Properties with default values | The plugin renders this in the output | -| `{@link Type \| display}` | Cross-reference another type or module | Use for "see also" references | -| `{@linkcode method \| display()}` | Link to a method with code formatting | Use when saying "use X() first" | - -## Writing examples - -Examples are the most impactful part of the docs. The TypeDoc plugin converts each `@example` block into a `` tab. - -### Format - -Always use TypeScript fenced code blocks. The first comment line becomes the tab title: - -```typescript -@example -```typescript -// Basic usage -const records = await base44.entities.MyEntity.list(); -``` ``` -### Guidelines - -- **Start simple.** First example should be the most basic call with minimal parameters. -- **Show real patterns.** Use realistic entity names (`Task`, `User`), not abstract ones. -- **Build complexity.** Progress from basic → with options → with error handling. -- **Use `base44.` prefix.** All examples should show the call path from the SDK client: `base44.entities.X`, `base44.auth.X`, `base44.integrations.Core.X`. -- **Include error handling** for methods that can fail (auth, network calls): - ```typescript - @example - ```typescript - // With error handling - try { - const result = await base44.auth.loginViaEmailPassword(email, password); - } catch (error) { - console.error('Login failed:', error); - } - ``` - ``` -- **Show cleanup** for subscriptions and resources: - ```typescript - @example - ```typescript - // Subscribe and clean up - const unsubscribe = base44.entities.Task.subscribe((event) => { - console.log(event); - }); - // Later: - unsubscribe(); - ``` - ``` - ## Writing style - **Developer audience.** These are SDK reference docs for JavaScript/TypeScript developers. - **Concise descriptions.** First sentence is a verb phrase: "Lists records...", "Creates a new...", "Sends an invitation...". -- **Sentence case** for free-text headings in JSDoc (e.g., `## Built-in User Entity`). -- **Avoid gerunds** in section headings within JSDoc. Prefer imperatives or noun phrases. +- **Sentence case** for free-text headings in JSDoc. - **State environment constraints** when a method is browser-only: "Requires a browser environment and can't be used in the backend." - **Document side effects** explicitly (e.g., "automatically sets the token for subsequent requests"). -- **Link method references.** When mentioning another SDK method or module by name in JSDoc prose, always use `{@link}` or `{@linkcode}` to create a cross-reference. Never leave a method name as plain text when a link target exists. - -## Doc generation pipeline - -After editing JSDoc, regenerate and review: - -```bash -npm run create-docs -cd docs -mint dev -``` - -### Pipeline configuration files - -| File | Purpose | -|---|---| -| `scripts/mintlify-post-processing/category-map.json` | Maps TypeDoc output folders to nav group names | -| `scripts/mintlify-post-processing/types-to-expose.json` | Whitelist of types included in generated docs | -| `scripts/mintlify-post-processing/appended-articles.json` | Stitches helper types into host pages | -| `scripts/mintlify-post-processing/file-processing/docs-json-template.json` | Template for generated `docs.json` | - -When adding a new public type, add it to `types-to-expose.json`. When a helper type should live inside another page, add it to `appended-articles.json`. +- **Link method references.** When mentioning another SDK method or module by name in JSDoc prose, always use `{@link}` or `{@linkcode}` to create a cross-reference. -## Review checklist for multi-page changes +## References -When a docs task touches three or more pages in `mintlify-docs` (including pages regenerated by `create-docs-local`), create a `REVIEW-CHECKLIST.md` file in the mintlify-docs repo root listing every affected page with its URL path and what to verify. Split the list into intentional changes and side-effect changes from regeneration. Add a reminder to delete the file before committing. Tell the user the checklist exists so they can work through it at their own pace. +- For the full JSDoc tag reference table, see [references/jsdoc-tags.md](references/jsdoc-tags.md) +- For detailed example-writing patterns, see [references/example-patterns.md](references/example-patterns.md) +- For pipeline configuration and generation workflow, see [references/pipeline-config.md](references/pipeline-config.md) ## Checklist before submitting a PR @@ -208,4 +94,3 @@ When a docs task touches three or more pages in `mintlify-docs` (including pages 3. **Examples work:** Code examples are syntactically valid TypeScript and use the `base44.` call path. 4. **Pipeline config:** New public types are in `types-to-expose.json`. Helper types that belong on another page are in `appended-articles.json`. 5. **Generate and review:** Run `npm run create-docs` and check the output renders correctly. -6. **README:** If adding a new module or major feature, update `README.md`. diff --git a/.claude/skills/sdk-docs-writing/references/example-patterns.md b/.claude/skills/sdk-docs-writing/references/example-patterns.md new file mode 100644 index 0000000..cd02842 --- /dev/null +++ b/.claude/skills/sdk-docs-writing/references/example-patterns.md @@ -0,0 +1,46 @@ +# Writing JSDoc Examples + +Examples are the most impactful part of the docs. The TypeDoc plugin converts each `@example` block into a `` tab. + +## Format + +Always use TypeScript fenced code blocks. The first comment line becomes the tab title: + +```typescript +@example +```typescript +// Basic usage +const records = await base44.entities.MyEntity.list(); +``` +``` + +## Guidelines + +- **Start simple.** First example should be the most basic call with minimal parameters. +- **Show real patterns.** Use realistic entity names (`Task`, `User`), not abstract ones. +- **Build complexity.** Progress from basic → with options → with error handling. +- **Use `base44.` prefix.** All examples should show the call path from the SDK client: `base44.entities.X`, `base44.auth.X`, `base44.integrations.Core.X`. +- **Include error handling** for methods that can fail (auth, network calls): + ```typescript + @example + ```typescript + // With error handling + try { + const result = await base44.auth.loginViaEmailPassword(email, password); + } catch (error) { + console.error('Login failed:', error); + } + ``` + ``` +- **Show cleanup** for subscriptions and resources: + ```typescript + @example + ```typescript + // Subscribe and clean up + const unsubscribe = base44.entities.Task.subscribe((event) => { + console.log(event); + }); + // Later: + unsubscribe(); + ``` + ``` diff --git a/.claude/skills/sdk-docs-writing/references/jsdoc-tags.md b/.claude/skills/sdk-docs-writing/references/jsdoc-tags.md new file mode 100644 index 0000000..be864c4 --- /dev/null +++ b/.claude/skills/sdk-docs-writing/references/jsdoc-tags.md @@ -0,0 +1,35 @@ +# JSDoc Tag Reference + +| Tag | When to use | Notes | +|---|---|---| +| `@param name - Description.` | Every function/method parameter | Include default value in prose: "Defaults to `50`." | +| `@returns` | Every function/method | Start with "Promise resolving to..." for async methods | +| `@example` | Every public method (at least one) | Each `@example` block becomes a tab in `` | +| `@typeParam T` | Generic type parameters | Explain what the type represents and its default | +| `@throws {Error}` | Methods that throw on known conditions | Describe the condition | +| `@internal` | Implementation details hidden from docs | Use on factory functions, config interfaces, helpers | +| `@default value` | Properties with default values | The plugin renders this in the output | +| `{@link Type \| display}` | Cross-reference another type or module | Use for "see also" references | +| `{@linkcode method \| display()}` | Link to a method with code formatting | Use when saying "use X() first" | + +## Interface properties + +Use inline JSDoc comments. One line per property: + +```typescript +export interface DeleteManyResult { + /** Whether the deletion was successful */ + success: boolean; + /** Number of entities that were deleted */ + deleted: number; +} +``` + +For properties with defaults or special behavior, use `@default`: + +```typescript +/** If set to `true`, the LLM will use Google Search to gather context. + * @default false + */ +add_context_from_internet?: boolean; +``` diff --git a/.claude/skills/sdk-docs-writing/references/pipeline-config.md b/.claude/skills/sdk-docs-writing/references/pipeline-config.md new file mode 100644 index 0000000..1eef266 --- /dev/null +++ b/.claude/skills/sdk-docs-writing/references/pipeline-config.md @@ -0,0 +1,24 @@ +# Doc Generation Pipeline + +After editing JSDoc, regenerate and review: + +```bash +npm run create-docs +cd docs +mint dev +``` + +## Pipeline configuration files + +| File | Purpose | +|---|---| +| `scripts/mintlify-post-processing/category-map.json` | Maps TypeDoc output folders to nav group names | +| `scripts/mintlify-post-processing/types-to-expose.json` | Whitelist of types included in generated docs | +| `scripts/mintlify-post-processing/appended-articles.json` | Stitches helper types into host pages | +| `scripts/mintlify-post-processing/file-processing/docs-json-template.json` | Template for generated `docs.json` | + +When adding a new public type, add it to `types-to-expose.json`. When a helper type should live inside another page, add it to `appended-articles.json`. + +## Review checklist for multi-page changes + +When a docs task touches three or more pages in `mintlify-docs` (including pages regenerated by `create-docs-local`), create a `REVIEW-CHECKLIST.md` file in the mintlify-docs repo root listing every affected page with its URL path and what to verify. Split the list into intentional changes and side-effect changes from regeneration. Add a reminder to delete the file before committing. Tell the user the checklist exists so they can work through it at their own pace.