Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
159 changes: 159 additions & 0 deletions .agent/dart-doc/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
---
name: dart-doc
description: Document Dart and Flutter code by writing or improving dartdoc inline comments (`///`) and package/library-level documentation (README, library directives). Use this skill whenever the user wants to document Dart or Flutter code, add doc comments, write API docs, generate dartdoc, document a class, function, method, file, package, or library, or improve existing Dart documentation. Also trigger for requests like "add docs", "write comments", "document this code", or "add dartdoc" when Dart or Flutter files are involved.
---

# Dart Documentation Skill

This skill guides you in writing high-quality documentation for Dart and Flutter projects. It covers three layers:

1. **Inline doc comments** — `///` comments on classes, functions, methods, fields, and typedefs
2. **Library-level docs** — `library` directive comments and the main package entry file
3. **Package-level prose** — `README.md`, usage guides, and other Markdown documentation

Follow Effective Dart conventions + Flutter's extended dartdoc tags throughout. Reference files:
- `references/effective-dart-doc.md` — Effective Dart documentation rules (read when writing any doc comments)
- `references/flutter-dartdoc-tags.md` — Flutter-specific dartdoc tags like `{@template}`, `{@macro}`, `{@tool}` (read when working on Flutter code or widget documentation)

---

## Workflow

### Step 1: Understand the Scope

Ask or infer from context:
- Is this a Dart-only package or a Flutter package/app?
- What is the entry point? (typically `lib/<package_name>.dart`)
- Are we documenting the whole project, a single file, or a specific symbol?

If the user says "document the project" or similar, treat it as full-project scope: cover the entry file → individual files → public symbols.

### Step 2: Audit Existing Docs

Before writing anything, scan the target files to understand what's already documented and what's missing. Look for:
- Public classes, enums, typedefs, extensions without `///` doc comments
- Methods/functions/getters/setters with missing or thin docs
- Missing `library` directive on the package entry file
- Absent or outdated `README.md`

Use this audit to decide what to write first (start with the most user-facing public API).

### Step 3: Write Documentation

Work top-down: package README → library comment → classes → members.

**Priority order:**
1. Public API (classes, top-level functions, enums)
2. Constructors and important methods
3. Fields and properties
4. Private members (if complex enough to benefit from a comment)

See `references/effective-dart-doc.md` for the exact rules at each level.

For Flutter projects, read `references/flutter-dartdoc-tags.md` before documenting widgets or shared Widget sub-trees.

**When writing inline docs:**
- Edit the source `.dart` files directly using the file editing tools
- Place `///` comments immediately before the declaration (and before any `@` metadata annotations)
- Never use `/** ... */` JavaDoc style

**When writing README or library docs:**
- Edit `README.md` at the package root directly
- Library-level docs go before the `library;` directive (or `library name;`) at the top of `lib/<package>.dart`

### Step 4: Add a `library` Directive (if missing)

If the package entry file (`lib/<package>.dart`) doesn't have a `library` directive, add one with a doc comment:

```dart
/// Brief description of what this library provides.
///
/// Longer explanation including terminology, main concepts,
/// and links to key classes. Example:
///
/// ```dart
/// import 'package:<package>/<package>.dart';
///
/// final result = MyClass().doSomething();
/// ```
///
/// See also:
///
/// * [MyClass], the main entry point for most use cases.
library;
```

### Step 5: Write or Update README.md

A good README includes:
1. **One-line tagline** — what the package does
2. **Features** — bullet list of capabilities
3. **Getting started** — how to install/import
4. **Usage** — at least one complete code example
5. **Additional information** — links to API docs, contributing, license

Keep it practical and focused on helping a new user get up and running in under 5 minutes.

### Step 6: Verify

After writing, scan for:
- Dangling `[references]` that don't correspond to real types/functions in scope
- Doc comments that just restate the function name (add value or omit)
- Missing periods at the end of the first sentence
- Any public symbol without a `///` comment

---

## Key Rules to Always Follow

These are the most important Effective Dart conventions. The full rules are in `references/effective-dart-doc.md`.

- **First sentence is a self-contained summary**, ending with a period. One blank `///` line separates it from the rest.
- **Use `[SymbolName]`** to cross-reference classes, methods, and identifiers. Private symbols like `[_helper]` can be referenced within the same file — useful for linking a public method to the private helpers it delegates to.
- **Describe what, not how.** Explain the result/behavior from the caller's perspective.
- **Third-person verbs for side-effect methods** ("Saves the file." not "Save the file.")
- **Noun phrases for properties** ("The number of items." not "Gets the number of items.")
- **"Whether" for booleans** ("Whether the stream is closed.")
- **Prose for parameters, return values, exceptions** — don't use `@param` or `@returns` tags; weave them into sentences using `[paramName]`.
- **Document only the getter, not both getter and setter**, when a property has both.
- **Put doc comments before metadata annotations.**
- **`@override` members** — omit the doc comment to inherit the superclass's documentation if the behavior is identical. Only add `///` if this override meaningfully diverges from the parent contract.

---

## Example: Well-Documented Class

```dart
/// A paginated list of results returned by a search query.
///
/// Use [SearchResults.empty] to create an empty result set, or
/// construct one from raw [items].
///
/// ```dart
/// final results = SearchResults(items: hits, totalCount: 42);
/// print(results.hasMore); // true
/// ```
///
/// See also:
///
/// * [SearchClient.search], which returns this type.
class SearchResults {
/// Creates a result set from [items] with a given [totalCount].
const SearchResults({
required this.items,
required this.totalCount,
});

/// An empty result set with zero items.
static const SearchResults empty = SearchResults(items: [], totalCount: 0);

/// The items in this page of results.
final List<SearchHit> items;

/// The total number of results across all pages.
final int totalCount;

/// Whether there are more pages of results beyond this one.
bool get hasMore => items.length < totalCount;
}
```
224 changes: 224 additions & 0 deletions .agent/dart-doc/references/effective-dart-doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# Effective Dart: Documentation Reference

A condensed reference of the official Effective Dart documentation rules. Source: https://dart.dev/effective-dart/documentation

---

## Doc Comment Basics

### DO use `///` for all documentation
Always use triple-slash `///` style — never `/** ... */` JavaDoc style.

```dart
// GOOD
/// The number of items in the list.
int get length => ...

// BAD
/** The number of items in the list. */
int get length => ...
```

### PREFER writing doc comments for public APIs
Every public class, function, method, field, enum, typedef, and extension should have a doc comment. Private members can have doc comments too, especially if they're complex.

### DO start with a single-sentence summary
The first line should be a self-contained summary sentence, ending with a period. A sentence fragment is fine.

```dart
/// Deletes the file at [path] from the file system.
void delete(String path) { ... }
```

### DO separate the first sentence with a blank `///` line
If there's more to say, add a blank doc comment line after the summary to create a separate paragraph. dart doc uses the first paragraph as a short summary in indexes.

```dart
/// Deletes the file at [path].
///
/// Throws an [IOError] if the file could not be found. Throws a
/// [PermissionError] if the file is present but could not be deleted.
void delete(String path) { ... }
```

---

## Documentation by Member Type

### Functions and Methods (side-effect focus)
Start with a **third-person verb** when the main purpose is a side effect.

```dart
/// Saves the current state to disk.
void save() { ... }

/// Starts the stopwatch if not already running.
void start() { ... }
```

### Functions and Methods (return-value focus)
Start with a **noun phrase or non-imperative verb phrase** when returning a value is the main purpose.

```dart
/// The number of seconds since the epoch.
int get timestamp => ...

/// A [List] of the items currently selected.
List<Item> get selectedItems => ...
```

### Properties and Fields (non-boolean)
Start with a **noun phrase** describing what the property *is*.

```dart
/// The currently active theme color.
Color get primaryColor => ...

/// The number of pending requests.
int pendingCount = 0;
```

### Properties and Fields (boolean)
Start with **"Whether"** followed by a noun or gerund phrase.

```dart
/// Whether the connection is currently open.
bool get isConnected => ...

/// Whether this widget should be excluded from the semantics tree.
bool excludeFromSemantics = false;
```

### Classes, Enums, Typedefs, Extensions
Start with a **noun phrase** describing what the type *is*.

```dart
/// A paginated result set returned by a query.
class QueryResults { ... }

/// The available brightness modes for the display.
enum Brightness { light, dark }
```

### Constructors
Describe what the constructor creates or configures. Skip documenting parameters unless they need non-obvious explanation — the parameter names and types are visible in the signature.

```dart
/// Creates a button with the given [label] and [onPressed] callback.
const MyButton({required this.label, this.onPressed});
```

### Getters and Setters
**Document only the getter**, not both. The setter's doc is implied.

```dart
/// The current volume level, from 0.0 to 1.0.
double get volume => _volume;
set volume(double value) => _volume = value.clamp(0.0, 1.0);
```

### Library-Level Comments
Place a doc comment **before** the `library` directive. Include:
- A one-sentence summary
- Terminology explanations
- At least one complete code sample
- Links to the most important classes/functions

```dart
/// Support for client-side HTTP requests.
///
/// This library provides [HttpClient] for making HTTP requests and
/// [HttpResponse] for handling responses.
///
/// ```dart
/// final client = HttpClient();
/// final response = await client.get(Uri.parse('https://example.com'));
/// print(response.statusCode);
/// ```
///
/// See also:
///
/// * [HttpClient], the main entry point for making requests.
library;
```

---

## Cross-References and Formatting

### DO use `[SymbolName]` for in-scope identifiers
Use square brackets to cross-reference types, methods, functions, and parameters. dart doc turns these into hyperlinks.

```dart
/// Throws [ArgumentError] if [value] is negative.
/// See also [clamp] for a non-throwing alternative.
```

### DO use prose for parameters, return values, and exceptions
Don't use `@param`, `@returns`, or `@throws` tags. Explain them in sentences using `[paramName]` references.

```dart
/// Divides [numerator] by [denominator].
///
/// Returns the quotient as a [double]. Throws [ArgumentError] if
/// [denominator] is zero.
double divide(int numerator, int denominator) { ... }
```

### DO put doc comments before metadata annotations

```dart
// GOOD
/// A widget that displays an image.
@immutable
class ImageWidget extends StatelessWidget { ... }

// BAD
@immutable
/// A widget that displays an image.
class ImageWidget extends StatelessWidget { ... }
```

### CONSIDER including code samples
Include a `dart` fenced code block when it significantly aids understanding.

```dart
/// Parses a date string in ISO 8601 format.
///
/// ```dart
/// final date = parseDate('2024-01-15');
/// print(date.year); // 2024
/// ```
DateTime parseDate(String input) { ... }
```

### AVOID redundancy with the declaration
Don't restate what the signature already says. Add information the reader doesn't already have.

```dart
// BAD — tells us nothing new
/// Returns a string representation of this widget.
@override
String toString() => ...

// GOOD — or just omit it if there's truly nothing to add
```

---

## Markdown in Doc Comments

- Use standard markdown (headers, lists, bold, code blocks)
- AVOID excessive markdown — don't use it for visual decoration
- AVOID HTML for formatting
- PREFER `` ``` `` fenced code blocks over indented code blocks
- AVOID markdown in the first sentence summary

---

## Writing Style

- **PREFER brevity** — say as much as needed, no more
- **AVOID abbreviations** unless they're universally known
- **PREFER "this"** over "the" when referring to the current object ("this widget", "this list")
- Omit doc comments that add no value over the declaration itself — silence is better than noise
Loading