diff --git a/AGENTS.md b/AGENTS.md index fe1a61f..4a655a9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,57 +1,130 @@ # Repository Guidelines -## Project Structure & Module Organization +## Project Overview -This repository is a Vue 3 + TypeScript waveform component library with a Vite demo. -Production exports are defined in `src/index.ts`; demo entry points are `src/main.ts` and -`src/App.vue`. The main chart is `src/components/WaveformChart.vue`, with focused modules under -`src/components/{core,data,rendering,interaction,annotation}`. Shared types live in `src/types`, -data normalization and chart logic in `src/core` and `src/utils`, styles in `src/styles.css`, and -sample data in `src/data`. Tests are colocated with implementation files (`*.test.ts`), with shared -setup in `src/test/setup.ts`. `dist/` and `dist-demo/` are generated; do not edit them. +This repository is a Vue 3, TypeScript, and D3 waveform component library with a Vite demo. +The published package is `waveform-analysis`; its supported public surface is exported from +`src/index.ts`. The demo is a consumer of that library code, not part of the public API. -## Build, Test, and Development Commands +Important behavioral contracts: -Use pnpm (the lockfile is `pnpm-lock.yaml`) and Node.js 22 as CI does. +- Treat waveform input as immutable. Replace the `data` reference to refresh normalization, + domains, caches, and the viewport; do not rely on in-place array mutation. +- X coordinates are stored in seconds. `timeUnit` and X-axis formatters affect display only and + must not alter raw coordinates, zoom domains, or emitted event values. +- Give every multi-series waveform a unique, stable `id`. Visibility, annotations, axes, and + state retention use normalized series IDs. +- Annotations and hidden-series state are controlled by the consumer. Emit replacement arrays; + persistence belongs to the host application. +- Rendering may downsample visible SVG geometry, but domains, nearest-point lookup, tooltips, + annotations, and error ranges must continue to use the full normalized data. + +## Repository Layout + +- `src/index.ts`: deliberate package exports for components, types, core helpers, and utilities. +- `src/components/WaveformChart.vue`: top-level chart composition and public prop/event boundary. +- `src/components/core/`: layout, domains, grids, presentation state, and chart controllers. +- `src/components/data/`: component-facing data types and data-layer exports. +- `src/components/rendering/`: SVG tracks, axes, series, legends, hover layers, and styles. +- `src/components/interaction/`: viewport, zoom, hover, tooltip, and interaction hosts. +- `src/components/annotation/`: annotation types, serialization, editing, layout, and interaction. +- `src/core/`: package-level normalization and rendering/downsampling logic. +- `src/types/`: shared public data and chart types. +- `src/utils/`: domains, formatting, geometry, sampling, and waveform ID helpers. +- `src/demo/`, `src/App.vue`: controls and the main interactive demo workspace. +- `src/router.ts`, `src/DemoRouterApp.vue`, `src/views/`: hash-based demo routes and focused demos. +- `src/data/`: simulated demo data; `src/test/`: shared Vitest setup and test helpers. +- `scripts/`: repository checks and declaration-build cleanup scripts. +- `docs/` and root Markdown notes: supporting or historical documentation; verify claims against + current source, tests, `README.md`, and `package.json` before relying on them. + +Tests are colocated as `*.test.ts`. The large chart suite is split under +`src/components/waveformChartCases/`; add focused cases there instead of rebuilding a monolithic +chart test file. + +## Toolchain and Commands + +Use Node.js 22 and pnpm 10.32.1, matching CI. Keep `pnpm-lock.yaml` synchronized with +`package.json` and use the locked install in automation. ```bash -pnpm install # Install locked dependencies -pnpm dev # Start the Vite demo server -pnpm typecheck # Run vue-tsc checks -pnpm lint # Run ESLint with zero warnings allowed -pnpm test # Run Vitest once -pnpm test:coverage # Run tests and enforce coverage thresholds -pnpm build # Type-check and build library plus demo bundles -pnpm preview # Preview the production demo build +pnpm install --frozen-lockfile # Reproduce the CI dependency graph +pnpm dev # Start the Vite demo +pnpm typecheck # Run vue-tsc project checks +pnpm check:file-length # Enforce the 400-line limit under src/ +pnpm lint # Run ESLint with zero warnings allowed +pnpm test # Run Vitest once +pnpm test:coverage # Run tests and enforce coverage thresholds +pnpm build # Type-check and build library, declarations, and demo +pnpm pack --dry-run # Inspect the publishable package contents +pnpm preview # Preview dist-demo/ +pnpm format # Apply the repository Prettier configuration ``` -Run `pnpm format` to apply the repository Prettier configuration. +For a narrow change, run the closest test file while iterating, then run the full relevant gates +before handoff. Do not describe a check as passing unless it actually ran. -## Coding Style & Naming Conventions +## Coding and Architecture Conventions -Use TypeScript and Vue 3 Composition API with two-space indentation, single quotes, no semicolons, -and a 100-column print width. Prettier and ESLint are authoritative. -Use PascalCase for Vue components, component filenames, and types; use camelCase for functions, -variables, and composables (for example, `useWaveformData`). Keep public exports deliberate and -preserve stable series IDs for multi-channel data. +Use Vue 3 Composition API and strict TypeScript. Follow the repository Prettier configuration: +two-space indentation, single quotes, no semicolons, and a 100-column print width. Use PascalCase +for Vue components and types, and camelCase for functions, composables, variables, and props in +TypeScript. Vue template props and events use kebab-case. -## Testing Guidelines +ESLint enforces a maximum of 400 physical lines for files under `src/`; the standalone length +check applies the same limit to all text files below `src/`. Split code by existing ownership +boundaries when a file approaches the limit. Keep rendering, layout, interaction, annotation, and +data concerns in their existing modules rather than adding more orchestration to +`WaveformChart.vue`. -Vitest with `@vue/test-utils` and jsdom is used. Name tests `*.test.ts` beside the -code they cover. Exercise normalization, rendering/layout helpers, formatting, and component -interactions, including empty, non-finite, and multi-series inputs. Coverage thresholds are 80% -for lines/statements/functions and 75% for branches; run `pnpm test:coverage` before submitting. +Use the `@/` alias for internal `src/` imports where it improves clarity. Keep public exports +explicit: adding a type or helper internally does not make it supported API. When changing a +public prop, event, type, formatter, serialization format, or package export, update `src/index.ts`, +tests, and `README.md` together. Preserve backwards compatibility unless the task explicitly calls +for a breaking change. -## Commit & Pull Request Guidelines +Do not hand-edit generated output in `dist/`, `dist-demo/`, `coverage/`, or `.vite/`. Library peers +are externalized by `vite.lib.config.ts`; validate packaging after dependency or export changes. -The current history contains only `first commit`, so no established convention exists yet. Use short, -imperative messages, preferably scoped (for example, `feat(chart): ...`, `fix(annotation): ...`, or -`test: ...`). Pull requests should explain API or user-visible changes, list verification commands, -link an issue or plan, and include screenshots or a short recording for visual changes. Keep generated -files and unrelated refactors out of the change. +## Testing Expectations -## CI and Configuration +Vitest runs in jsdom with `@vue/test-utils`; shared setup is in `src/test/setup.ts`. Coverage uses +V8 and must remain at least 80% for lines, statements, and functions, and 75% for branches. -GitHub Actions runs install, typecheck, lint, coverage, build, and `pnpm pack --dry-run` on pushes and -pull requests. Do not commit secrets or local environment files; review the staged file list before -opening a pull request. +Cover behavior at the narrowest useful layer: + +- normalization: empty, invalid, non-finite, unsorted, duplicate-ID, and multi-series inputs; +- layout and domains: display modes, overlays, fixed ranges, pagination, margins, and small sizes; +- formatting: endpoint/tick consistency, time units, scientific notation, and custom formatters; +- rendering: downsampling, styles, points, error bars, axes, grids, legends, and clean view; +- interaction: wheel/box zoom, zoom-out, pan, reset, hover, visibility, and presentation mode; +- annotations: CRUD, serialization validation, drag offsets, reprojection, and hidden series. + +Avoid brittle assertions against incidental SVG structure when a user-visible or emitted behavior +can be asserted instead. Add regression coverage for every bug fix. + +## Build, CI, and Release + +`pnpm build` produces the ESM/CJS library and CSS in `dist/`, declarations in `dist/types/`, and the +demo in `dist-demo/`. GitHub CI runs frozen install, typecheck, file-length checks, lint, coverage, +build, and `pnpm pack --dry-run` on pushes and pull requests. + +Use short Conventional Commit-style messages consistent with current history, for example +`feat(chart): support ...`, `fix(annotation): handle ...`, or `test: cover ...`. Keep generated +files, local settings, and unrelated refactors out of commits. Review `git status` and the staged +diff before committing. Pull requests should explain public or user-visible effects, list commands +actually run, link the relevant issue or plan, and include screenshots or a short recording for +visual changes. + +Releases are triggered by annotated tags matching `vX.Y.Z` or a semver prerelease such as +`vX.Y.Z-rc.1`. The tag version must exactly match `package.json`. The Gitea workflow validates, +tests, builds, packs, publishes to both configured npm registries, creates checksums and a release, +and deploys the demo only for stable versions. Do not create or push a release tag until the version +commit and full release checks are complete. + +## Change Discipline + +Keep edits scoped to the request and preserve unrelated worktree changes. Do not commit secrets, +local environment files, IDE state, logs, or registry credentials. For visual behavior changes, +verify both the reusable component and the relevant demo route at representative desktop and small +container sizes; state clearly when browser verification was not performed.