Files
waveform-analysis/AGENTS.md
2026-08-10 16:56:21 +08:00

7.6 KiB

Repository Guidelines

Project Overview

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.

Important behavioral contracts:

  • 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.

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

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 and Architecture Conventions

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.

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.

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.

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.

Testing Expectations

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.

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.