blob: 4cd918876a4bf7a311f04f8cac236e3b39dfe8eb [file] [view] [edit]
# AGENTS.md
Guidance for AI coding agents working in this repository. Tool-agnostic; `CLAUDE.md` points here.
Bootstrap v6.0.0-alpha1 CSS/JS framework.
Sass source in `scss/`, TypeScript source in `js/src/`, docs site in `site/` (Astro 5 + MDX).
## Quick commands
- `npm start` dev server (watch + Astro on port 9001)
- `npm run dist` full CSS + JS build
- `npm run css` compile, prefix, minify CSS
- `npm run js` compile + minify JS
- `npm run css-lint` / `npm run js-lint` lint
- `npm run docs-build` build docs site
- `npm test` full test suite (lint + dist + tests + docs)
## Writing style
Use ASD-STE100 Simplified Technical English for all prose: replies to the user, docs, code comments, commit messages, and PR text.
- Write short sentences. Use approximately 20 words or fewer.
- Give one instruction per sentence.
- Use the active voice. Name the actor.
- Use simple verbs. Do not use a complex verb when a simple one works.
- Use one term for one thing. Keep terms the same across the project.
- Keep paragraphs short. Cover one topic per paragraph.
## Reply length
Be extremely brief. Report the result, not the journey.
- Target 75 words or fewer. Hard cap 150 words, and only for a genuinely multi-part answer.
- Answer in the first sentence. Then stop.
- Give one supporting fact per claim, at most. Cut the rest.
- Do not narrate your process, tool calls, or verification steps. Report a check only when it failed or changed the outcome.
- Do not restate the work you just did. The user reads the diff, the commit, and the PR.
- State a finding once. Never repeat it in a summary or closing line.
- No headings. No tables. Use a list of 5 items or fewer only when the answer is a real list.
- Cut praise, apologies, hedging, and filler such as "great question" or "worth noting".
- Do not explain what you did not do, or list caveats the user did not ask about.
- Do not offer next steps unless the user asks or the work is blocked.
- Expand only when the user asks for detail, or asks you to teach.
## Teaching
Act as a teacher for JavaScript, TypeScript, React, and all JavaScript-family topics.
- When the work hits a new problem, concept, or language feature, stop and explain it.
- Keep each explanation short and plain. Define jargon on first use.
- Use a small code example when it makes the idea clear.
- Assume strong HTML/CSS knowledge. Do not assume deep JS internals knowledge.
## SCSS conventions
- Variable naming: `$component-state-property-size` (e.g., `$nav-link-disabled-color`)
- Module system: `@use` / `@forward` only never `@import`
- Token system: component tokens are SCSS maps of CSS custom properties, merged via `defaults()`, output via `@include tokens($map)` on the component root selector
- Disallowed: raw `border-radius` / `transition` properties (use mixins), `lighten()` / `darken()`, `border: none` / `outline: none`
- Order: `@use` `@forward` `$variables` `--custom-properties` declarations rules
- Variables use `!default` (except locals)
- CSS layers: `colors, theme, config, root, reboot, layout, content, forms, components, custom, helpers, utilities`
- Logical properties: prefer `padding-inline-start` over `padding-left`, etc.
- Modern CSS: `color-mix()`, `light-dark()`, range media queries (`@media (width >= 1024px)`)
- Doc markers: `// scss-docs-start name` / `// scss-docs-end name` for docs extraction
## JavaScript/TypeScript conventions
- Source is TypeScript (`js/src/**/*.ts`, entry `js/src/index.ts`); ESM-only, no semicolons, 2-space indent
- Imports use `.js` extensions (standard TS ESM style); Rolldown resolves them to `.ts` via `resolve.extensionAlias`, Vitest via the `tsResolve` plugin in `js/tests/vitest.config.mts`
- Dist builds use Rolldown (`build/rolldown.config.mjs`, `build/build-plugins.mjs`) with built-in TS transforms; `build/browser-targets.mjs` derives the browser floors from `.browserslistrc` at build time, so there is nothing to keep in sync. Rollup and Babel are gone from the repo Vitest transforms the specs itself
- Strict tsconfig with `verbatimModuleSyntax` + `erasableSyntaxOnly`; `tsc` only type-checks and emits `.d.ts` (`npm run js-typecheck`, `npm run js-emit-types`)
- Components extend `BaseComponent` (which extends `Config`); per-component config `type XxxConfig` typed off `Default`, refined on the class via `protected declare _config: XxxConfig`
- Instance fields use `declare` (no runtime emit); constructor `element` param stays optional to keep `typeof Component` assignable to `typeof BaseComponent`
- Every `_`-prefixed instance member is `protected` (never `private`, so subclasses keep access); public API methods and statics stay public. This keeps the internals out of the published `.d.ts` surface
- Constants: `NAME`, `DATA_KEY`, `EVENT_KEY`, `VERSION`
- DOM utilities via `dom/event-handler.ts`, `dom/selector-engine.ts`, `dom/manipulator.ts`
- Floating UI for positioning (dropdown, tooltip, popover)
- Tests: Vitest browser mode (real Chromium via Playwright), config in `js/tests/vitest.config.mts`, specs in `js/tests/unit/*.spec.js` (plain JS, bundled against the TS sources). `js/tests/vitest-setup.js` maps the Jasmine API the specs are written against onto Vitest note `spyOn` stubs by default, unlike `vi.spyOn`. Async specs return a promise; Vitest 4 dropped `done`. Coverage is Istanbul over all of `js/src`, thresholds 90/88/90/90
- Type-level API tests in `js/tests/types/` `api.ts` checks the source (`npm run js-typecheck`), `consumer.ts` checks the shipped `js/dist/*.d.ts` through the package `exports` map (`npm run js-typecheck-dist`, after the build). Keep the two in sync
## Docs conventions
- Astro 5 + MDX in `site/src/content/docs/`
- Frontmatter schema: `title` (required), `description` (required), `toc`, `aliases`, `added`, `mdn`, `reference`, etc.
- Shortcodes: `Example`, `Callout`, `Code`, `Details`
- Internal links: `[[docsref:/path/]]`
- JS component "Dependencies" tables are auto-generated add a `### Dependencies` heading with `<JsDependencies component="<js-src-basename>" />` (before `### Options`) on any doc for a `js/src/*.ts` component. The table is derived at build time by walking the component's import graph in `site/src/libs/js-dependencies.ts`; never hand-write the file list. When a new source file or third-party package enters the graph, add its human-readable label to `FILE_DESCRIPTIONS` / `PACKAGE_DESCRIPTIONS` in that lib (the build throws if a label is missing).
## Formatting
- 2 spaces, UTF-8, LF line endings, trim trailing whitespace, final newline
- Preserve smart punctuation (curly apostrophes U+2019, curly quotes) — never replace with ASCII equivalents
- Use `StrReplace` for targeted edits; avoid full-file rewrites on MDX files to protect typography
## Workflow
- Validate after changes: `npm run css-lint`, `npm run js-lint`, `npm run dist`, `npm run docs-build`
- Keep config files in sync: `config.yml`, `site/src/libs/config.ts` (Zod schema), `build/rolldown.config.mjs`, `build/generate-sri.mjs`, `package.json`
- For rebases/conflicts: favor base branch structure, layer feature changes on top
## Commits & PRs
- Commit messages: direct, succinct prose explaining why the change was made.
- PR descriptions: direct bulleted lists, minimal fluff — one bullet per notable change.
- Reference related issues/PRs explicitly with `Fixes #{issue}`, `Closes #{issue}`, or `Supersedes #{pr}`.
- No "Test plan" section and no extra headings — just the bullets and the references.
## Do not edit
Built output in `dist/`, `_site/`, `js/dist/` — these are generated.