Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .claude/hooks/markdown-audit-reminder.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env node
// PostToolUse hook (Write / Edit / MultiEdit). When a Markdown file is edited,
// injects a non-blocking reminder to follow the documentation-authoring rules.
//
// Run via `node --experimental-strip-types` (no build step, no dependencies).
// The path-scoped rule `.claude/rules/docs-authoring.md` is the primary carrier
// of this guidance; this hook is the guaranteed, deterministic backstop.
//
// Type-stripping-safe TypeScript only: type annotations / interfaces, no enums,
// namespaces, or parameter properties.

import { readFileSync } from 'fs';

interface ToolInput {
file_path?: string;
}

interface HookPayload {
tool_name?: string;
tool_input?: ToolInput;
}

const REMINDER =
'This edit changed a Markdown file. Follow `.claude/rules/docs-authoring.md` ' +
'(canonical spec: `.github/prompts/audit-docs.prompt.md`): document only what the ' +
'code provably does (no speculation), no subjective adjectives, reference files as ' +
'clickable markdown links to files (never bare names or directories), keep snippets ' +
'to 3-10 lines, and give every Mermaid diagram `accTitle` + `accDescr`. ' +
'To audit docs against the code, run the `/audit-docs` skill.';

function main(): void {
let payload: HookPayload;
try {
payload = JSON.parse(readFileSync(0, 'utf-8')) as HookPayload;
} catch {
process.exit(0);
}

const toolName = payload.tool_name ?? '';
if (toolName !== 'Write' && toolName !== 'Edit' && toolName !== 'MultiEdit') {
process.exit(0);
}

const filePath = payload.tool_input?.file_path ?? '';
const isMarkdown = filePath.endsWith('.md') || filePath.endsWith('.mdx');
// Skip the agent-tooling tree so editing rules/skills/this hook doesn't nag.
const isAgentTooling = filePath.includes('/.claude/') || filePath.startsWith('.claude/');
if (!isMarkdown || isAgentTooling) {
process.exit(0);
}

process.stdout.write(
JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PostToolUse',
additionalContext: REMINDER,
},
}),
);
process.exit(0);
}

main();
34 changes: 34 additions & 0 deletions .claude/rules/code-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
paths:
- "**/*.ts"
- "**/*.tsx"
---

# Code style

These rules mirror [`.github/copilot-instructions.md`](../../.github/copilot-instructions.md) (the Copilot-side source); keep both in sync. Enforced in CI by `npm run prettier:check`, `npm run eslint:check`, and `npm run tsc`.

## Formatting

- **Tabs, not spaces** for indentation (ESLint errors otherwise).
- Semicolons required; single quotes (including JSX); `printWidth` 120; trailing commas everywhere.
- Imports are sorted automatically by `@trivago/prettier-plugin-sort-imports` — don't hand-order them.
- Prefix intentionally-unused variables/args with `_` (e.g. `_event`) so ESLint ignores them.

## Imports

- **Always use path aliases, never relative paths.** Aliases are defined in [`tsconfig.json`](../../tsconfig.json) and mirrored in [`jest.config.js`](../../jest.config.js):
`@/`, `@components/`, `@configs/`, `@constants/`, `@data/`, `@helpers/`, `@images/`, `@layouts/`, `@styles/`, `@util/`.
- Example: `import Avatar from '@components/banner/Avatar';` — not `'../banner/Avatar'`.
- Import Node built-in modules with the **bare specifier** (`import { readFileSync } from 'fs'`), never the `node:` prefix (`'node:fs'`). Matches the existing convention — e.g. `require('util')` in [`jest/setup.ts`](../../jest/setup.ts).

## Components & styling

- Import SVGs as React components via `@svgr/webpack` (see [`src/images/icons.tsx`](../../src/images/icons.tsx)).
- Components are **Server Components by default**; add `'use client'` only when the component needs hooks, event handlers, or browser APIs.
- Every component has a colocated `.test.tsx` (see [`src/components/banner/Banner.test.tsx`](../../src/components/banner/Banner.test.tsx)).

## TypeScript

- Strict mode is on; types must be explicit (no implicit `any`).
- Do **not** "fix" an existing `any` by swapping it to `unknown` or adding an `eslint-disable` — replace it with a specific concrete type, and respect an `any` that is intentional.
33 changes: 33 additions & 0 deletions .claude/rules/docs-authoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
paths:
- "**/*.md"
- "**/*.mdx"
---

# Documentation authoring

When creating or editing any markdown file, follow the discipline below. These are the always-apply rules distilled from [`.github/prompts/audit-docs.prompt.md`](../../.github/prompts/audit-docs.prompt.md) (the canonical spec). To audit or sync `docs/` against the code as a whole, run the `/audit-docs` skill.

## Accuracy

- **Zero hallucination.** Document only what the code provably does. Read the implementation; don't infer behaviour from a name, type, comment, file location, or familiar pattern.
- **Prove it.** Before writing any technical claim, know the exact file (and ideally lines) that prove it. If you can't, don't write it. Silence beats speculation — no "appears to", "should", "will", or planned/intended behaviour.
- Fix existing statements that contradict the code.

## Style

- **No subjective adjectives** in new prose (important, critical, robust, seamless, powerful, efficient, etc.). State facts.
- High-density, low-volume: explain *why* and *how the system uses it*, not line-by-line narration. Bullets for lists/steps, paragraphs only for intros/complex architecture.
- Document configuration by its **external-facing name** (env var, config key, CLI flag), never the internal variable name.
- No placeholders, TODOs, or empty "add details here" sections.

## Links & code

- Every file reference is a **clickable markdown link to a file**, never a bare filename and never a link to a directory. Link to a file inside the directory (e.g. its `index.md`/`README.md`) instead.
- Use relative links (GitHub-compatible) and verify the path resolves from the doc's own location.
- Don't paste full definitions/class bodies — link to the file. Inline snippets only for a short usage example, a critical config line, or logic that text can't convey (3–10 lines max).

## Mermaid

- Every diagram **must** include both `accTitle` (specific) and `accDescr` (a real description, not "a diagram showing…"). No exceptions.
- Valid Mermaid only; reflect actual current code; pick the diagram type that fits (don't default to `flowchart`).
17 changes: 17 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "node --disable-warning=ExperimentalWarning --experimental-strip-types \"$CLAUDE_PROJECT_DIR/.claude/hooks/markdown-audit-reminder.mts\"",
"statusMessage": "Checking docs-authoring rules"
}
]
}
]
}
}
29 changes: 29 additions & 0 deletions .claude/skills/audit-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: audit-docs
description: Audit and update the project's documentation so it matches the current code. Use when creating or editing Markdown/docs, after implementing a feature, before merging a PR, or whenever asked to audit, sync, fact-check, or refresh documentation. Mirrors `.github/prompts/audit-docs.prompt.md` for Claude Code.
---

# Audit docs

This skill is the Claude Code counterpart to the Copilot prompt [`.github/prompts/audit-docs.prompt.md`](../../../.github/prompts/audit-docs.prompt.md), which is the canonical, fuller spec. **Read that prompt and apply it.** The hard rules also live in [`.claude/rules/docs-authoring.md`](../../rules/docs-authoring.md) and load automatically when editing Markdown. This file is the operating procedure.

## Phases (run in order)

1. **PR sync** — If there are uncommitted changes or an active PR, treat that diff as the source of truth. Identify what the code changes actually do (read the implementation) and update `docs/` to reflect only those changes. Report whether docs changed or were already accurate.
2. **General audit** — Audit the whole [`docs/`](../../../docs/index.md) tree against the current code. Correct statements that contradict the code; add docs only for exported/public APIs or genuinely complex logic that lacks them; remove bloat and redundant narration. Prefer correcting over deleting (delete only if a file describes a removed feature or is unsalvageably wrong). New directories need an `index.md`.
3. **In-code docs** — Scan Markdown outside `docs/`, plus JSDoc/docstrings/module headers and inline comments, for the files you touched. Fix or remove inaccurate/stale content; don't add narration that restates obvious code.

## Hard rules (quick reference)

Full detail in [`.claude/rules/docs-authoring.md`](../../rules/docs-authoring.md):

- **Zero hallucination / prove it.** Document only what the code provably does — read it, don't infer from names, types, comments, or structure. If you can't point to the proof, don't write it. No "appears to" / "should" / planned behaviour.
- **Objective tone.** No subjective adjectives (important, critical, robust, …). Fix existing claims that contradict the code.
- **Links.** Every file reference is a clickable relative markdown link to a *file* (never a bare name, never a directory — link its `index.md`/`README.md`). Verify the path resolves.
- **Snippets.** Link to files instead of pasting definitions; inline only 3–10 lines for a usage example or critical config line.
- **Mermaid.** Every diagram includes `accTitle` and `accDescr`; valid syntax; reflects real code; choose the fitting diagram type.
- **No placeholders or TODOs.**

## Validate

After doc changes, run `npm run lint:markdown` (and `npm run prettier:check` for formatting). Report exactly which files changed, or state that everything was already accurate.
Loading
Loading