home / skills / open-circle / valibot / repo-source-code-document

repo-source-code-document skill

/skills/repo-source-code-document

This skill assists you generate precise JSDoc comments and inline documentation for Valibot source code, improving type-safety and maintainability.

npx playbooks add skill open-circle/valibot --skill repo-source-code-document

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
7.9 KB
---
name: repo-source-code-document
description: Write JSDoc comments and inline documentation for Valibot library source code in /library/src/. Use when documenting schemas, actions, methods, or utilities. Covers interface documentation, function overloads, purity annotations, inline comment patterns, and terminology consistency.
---

# Valibot Source Code Documentation

Documentation patterns for library source code in `/library/src/`.

## JSDoc Patterns

### Interface Documentation

```typescript
/**
 * String issue interface.
 */
export interface StringIssue extends BaseIssue<unknown> {
  /**
   * The issue kind.
   */
  readonly kind: 'schema';
  /**
   * The issue type.
   */
  readonly type: 'string';
}
```

**Rules:**

- First line: `[Name] [category] interface.` (e.g., "String issue interface.")
- Property comments: `The [description].` (always start with "The", end with period)
- All properties use `readonly`
- No blank lines between property and its comment

### Function Overloads

Each overload gets its own complete JSDoc:

```typescript
/**
 * Creates a string schema.
 *
 * @returns A string schema.
 */
export function string(): StringSchema<undefined>;

/**
 * Creates a string schema.
 *
 * @param message The error message.
 *
 * @returns A string schema.
 */
export function string<
  const TMessage extends ErrorMessage<StringIssue> | undefined,
>(message: TMessage): StringSchema<TMessage>;
```

**Rules:**

- First line: `Creates a [name] [category].` (use "a" vs "an" correctly)
- Blank line after description
- `@param name The [description].` (start with "The", end with period)
- Blank line after params
- `@returns A [name] [category].` or `@returns The [description].`

### Hints

Add hints after the main description, before `@param`:

```typescript
/**
 * Creates an object schema.
 *
 * Hint: This schema removes unknown entries. To include unknown entries, use
 * `looseObject`. To reject unknown entries, use `strictObject`.
 *
 * @param entries The entries schema.
 *
 * @returns An object schema.
 */
```

### Links

Link to external resources when relevant using markdown format:

```typescript
/**
 * Creates an [email](https://en.wikipedia.org/wiki/Email_address) validation action.
 */
```

### Implementation Function

The implementation has **NO JSDoc** but uses `// @__NO_SIDE_EFFECTS__`:

```typescript
// @__NO_SIDE_EFFECTS__
export function string(
  message?: ErrorMessage<StringIssue>
): StringSchema<ErrorMessage<StringIssue> | undefined> {
  return {
    /* ... */
  };
}
```

**`// @__NO_SIDE_EFFECTS__` rules:**

- Add for pure functions (no external state mutation, no I/O)
- Most schema/action/method factories are pure
- **Do NOT add** for functions that mutate arguments (like `_addIssue`)
- Used by bundlers for tree-shaking

### Utility Functions

```typescript
/**
 * Stringifies an unknown input to a literal or type string.
 *
 * @param input The unknown input.
 *
 * @returns A literal or type string.
 *
 * @internal
 */
// @__NO_SIDE_EFFECTS__
export function _stringify(input: unknown): string {
  // ...
}
```

**Rules:**

- Use `@internal` tag for internal utilities
- Prefix internal functions with `_`
- Only add `// @__NO_SIDE_EFFECTS__` if function is pure

## Inline Comment Patterns

### Section Headers

```typescript
'~run'(dataset, config) {
  // Get input value from dataset
  const input = dataset.value;

  // If root type is valid, check nested types
  if (Array.isArray(input)) {
    // Set typed to true and value to empty array
    dataset.typed = true;
    dataset.value = [];

    // Parse schema of each array item
    for (let key = 0; key < input.length; key++) {
      // ...
    }
  }
}
```

**Rules:**

- Describe WHAT the next code block does
- Present tense verbs: "Get", "Parse", "Check", "Set", "Add", "Create"
- **Omit articles** ("the", "a", "an"): "Get input value" not "Get the input value"
- No period at end
- Blank line before comment, no blank line after

### Conditional Logic

```typescript
// If root type is valid, check nested types
if (input && typeof input === 'object') {
  // ...
}

// Otherwise, add issue
else {
  _addIssue(this, 'type', dataset, config);
}
```

**Rules:**

- Use "If [condition], [action]"
- Use "Otherwise, [action]" for else branches
- Omit articles

### Hint Comments (Exception)

```typescript
// Hint: The issue is deliberately not constructed with the spread operator
// for performance reasons
const issue: BaseIssue<unknown> = {
  /* ... */
};
```

**Rules:**

- Start with "Hint:"
- Explain WHY, not just what
- **CAN use articles** (unlike other inline comments)
- Document performance decisions, non-obvious logic

### TODO Comments

```typescript
// TODO: Should we add "n" suffix to bigints?
if (type === 'bigint') {
  /* ... */
}
```

### @ts-expect-error

Used for internal dataset mutations TypeScript can't track:

```typescript
// @ts-expect-error
dataset.typed = true;
```

## File Type Patterns

### Schema Files (`string.ts`, `object.ts`, etc.)

1. Issue interface with JSDoc
2. Schema interface with JSDoc
3. Function overloads with full JSDoc each
4. Implementation with `// @__NO_SIDE_EFFECTS__`
5. Return object with `'~run'` method containing inline comments

### Action Files (`email.ts`, `minLength.ts`, etc.)

1. Issue interface (for validation actions)
2. Action interface with JSDoc
3. Function overloads with JSDoc
4. Implementation with `// @__NO_SIDE_EFFECTS__`

### Method Files (`parse.ts`, `pipe.ts`, etc.)

More complex logic, require more inline comments.

### Utility Files (`_addIssue.ts`, `_stringify.ts`)

1. Single function with JSDoc including `@internal`
2. `// @__NO_SIDE_EFFECTS__` only if pure

## Terminology Consistency

JSDoc descriptions must match the `kind` property if present:

| `kind` Property    | JSDoc Wording                          |
| ------------------ | -------------------------------------- |
| `'schema'`         | "Creates a ... schema."                |
| `'validation'`     | "Creates a ... validation action."     |
| `'transformation'` | "Creates a ... transformation action." |

## Quick Reference

### JSDoc First Lines

| Type      | Pattern                        |
| --------- | ------------------------------ |
| Interface | `[Name] [category] interface.` |
| Type      | `[Name] [category] type.`      |
| Function  | `Creates a [name] [category].` |
| Utility   | `[Verb]s [description].`       |

### Inline Comment Starters

| Pattern                        | Example                                        |
| ------------------------------ | ---------------------------------------------- |
| `// Get [what]`                | `// Get input value from dataset`              |
| `// If [condition], [action]`  | `// If root type is valid, check nested types` |
| `// Otherwise, [action]`       | `// Otherwise, add issue`                      |
| `// Create [what]`             | `// Create object path item`                   |
| `// Add [what] to [where]`     | `// Add issues to dataset`                     |
| `// Parse [what]`              | `// Parse schema of each array item`           |
| `// Set [property] to [value]` | `// Set typed to true`                         |
| `// Hint: [explanation]`       | `// Hint: This is for performance`             |
| `// TODO: [task]`              | `// TODO: Add bigint suffix`                   |

## Terminology

Use consistently:

- **Schema** (not "validator")
- **Action** (not "validation" for the object)
- **Issue** (not "error" in type names)
- **Dataset** (internal data structure)
- **Config/Configuration** (not "options")

## Checklist

- [ ] Interfaces: `[Name] [category] interface.`
- [ ] Properties: `The [description].`
- [ ] Overloads: Complete JSDoc each
- [ ] Implementation: NO JSDoc
- [ ] Pure functions: `// @__NO_SIDE_EFFECTS__`
- [ ] Impure functions (mutate args): NO `@__NO_SIDE_EFFECTS__`
- [ ] Internal utilities: `@internal` tag
- [ ] Inline comments: No articles (except Hint), no periods
- [ ] JSDoc comments: End with periods

Overview

This skill documents Valibot TypeScript source code in /library/src/ by generating JSDoc comments and inline comments that follow the library's conventions. It focuses on schemas, actions, methods, and utilities to produce consistent, parseable, and tree-shake friendly documentation. Use it to enforce terminology, purity annotations, overload patterns, and inline comment styles across the codebase.

How this skill works

The skill inspects TypeScript AST and source text to locate interfaces, function overloads, implementation blocks, and internal utilities under /library/src/. It emits JSDoc comments following strict first-line patterns, param/returns formats, @internal usage for utilities, and inserts // @__NO_SIDE_EFFECTS__ for pure factory functions. It also rewrites or adds inline comments using present-tense verbs, omitting articles except in Hint comments.

When to use it

  • When adding or updating schema factories (string, object, array, etc.)
  • When documenting validation or transformation actions (email, minLength, parse)
  • When writing or refactoring methods with complex logic (pipe, parse)
  • When creating or updating internal utilities (_addIssue, _stringify)
  • When enforcing terminology and JSDoc consistency across the library

Best practices

  • Follow first-line patterns exactly: interfaces use "[Name] [category] interface." and functions use "Creates a [name] [category]."
  • Give each function overload a complete JSDoc block with blank lines between description, params, and returns
  • Only add // @__NO_SIDE_EFFECTS__ to pure functions; omit for mutating functions like _addIssue
  • Prefix internal utilities with _ and mark them @internal in JSDoc
  • Write inline comments that describe WHAT the next block does using present-tense verbs and omit articles, except in Hint comments

Example use cases

  • Document new schema file: add issue interface JSDoc, schema interface JSDoc, overload JSDoc blocks, implementation without JSDoc and with // @__NO_SIDE_EFFECTS__ if pure
  • Annotate action files: create issue and action interfaces with JSDoc and implement pure factories with the purity marker
  • Refactor method file: add descriptive inline comments for each section header and conditional branch using present-tense, article-free phrasing
  • Add an internal utility: prefix with _, add @internal JSDoc, and add // @__NO_SIDE_EFFECTS__ only if function is pure

FAQ

How do I decide when to add // @__NO_SIDE_EFFECTS__?

Add it only for functions that do not mutate external state, do not perform I/O, and are deterministic; most schema/action/method factories qualify. Do not add it to functions that mutate arguments.

What wording should I use for property comments in interfaces?

Start with "The", describe the property, and end with a period. Keep no blank line between the comment and the property and mark properties readonly.

When should I use @internal?

Use @internal for utilities intended only for internal use (usually prefixed with _). Include it in the JSDoc of those functions so they are excluded from public docs and treated as internal by tooling.