references/accessibility-ui.md
# Accessibility And Interaction Review
Broken keyboard access, missing accessible names, focus loss, and unreachable content are
correctness defects. Review the rendered behavior and the feature's workflow, including the
primitive defaults and composed props. Missing attributes, handlers, or classes at a call site
do not establish a defect when their owner already supplies them.
## Semantics And Names
- Does the final element preserve the intended action, navigation, or field semantics and its
keyboard behavior? Check the primitive's composition contract before judging its rendered tag.
- Do controls, meaningful images, and icon-only actions have usable text alternatives? Does
decorative content interfere with the resulting name or accessibility tree?
- When labels, help, errors, or hidden text change, read [Accessible names and descriptions].
Check computed names and descriptions in the affected states, including content that unmounts.
A matching `aria-label` string alone does not establish a redundant override.
- For page structure changes, read [Page landmarks] and inspect the composed page with its parent
layouts. Check heading relationships, landmark names, and affected semantic test locators.
## Keyboard, Focus, And Async Transitions
- Can users reach, operate, and leave the changed control or surface by keyboard? Follow
[Keyboard commands] for application hotkeys; widget key behavior belongs to its primitive.
- Is the actual focus target visibly indicated? Read [Styling] for indicator ownership, including
text controls and wrappers around native inputs. Fix the owning component instead of adding
duplicate indicators at call sites.
- Does focus remain useful through pending, success, failure, dismissal, and retry? Check the
focused control, the next keyboard action, and any focus-return target when availability changes.
Follow the [Button contract] for loading and disabled buttons; other controls need their own
interaction contract, not an automatic native-disabled or `aria-disabled` substitution.
- Are unavailable actions blocked through supported pointer and keyboard paths? Check existing
primitive handling before requesting additional event guards.
- Can users understand why they cannot proceed and perceive the status needed to continue?
Keep names available during loading and check the feature-owned feedback path. For Web toasts,
follow [Toasts] rather than requiring a toast or live region for every state change.
## Forms
Read [Forms] when submission, field composition, validation, or reset behavior changes.
- Does the intended form own submission, including keyboard submission? Check final button types
and primitive defaults instead of requiring redundant `type` props at every call site.
- Do the intended values participate in submission and validation, with the right name and
disabled/read-only behavior? Follow the selected control's contract for labels and value types.
- Can users enter the required data with supported input methods, paste, and relevant autofill?
Verify input attributes against the field's purpose rather than applying one input template.
- Are errors associated with their fields, exposed at the right time, and recoverable? Verify
invalid-field focus and reset through the actual form/control integration.
## Overlays And Content Reachability
Read [Overlays] for semantic selection, portals, presence, layering, and dismissal. Use the
[Infotip contract] when an information icon opens an explanation; text length alone does not
choose between Tooltip, Infotip, and Popover.
- Can pointer, keyboard, touch, and assistive-technology users reach content needed for the flow?
A supplementary hover preview must not be the only route to essential information.
- Does the trigger keep its name while closed, and does the open popup have the required name?
Check the selected primitive's contract before adding titles or descriptions.
- Do open/close transitions preserve the intended focus, dismissal, and draft lifetime? Trace the
root and content lifetimes separately; portal placement alone does not reset ancestor state.
## Visual And Runtime Evidence
For changed layouts, check whether long or localized content, supported viewport sizes, zoom,
or forced colors obscure information, controls, or focus. For changed motion, check relevant
reduced-motion behavior and whether interaction remains usable. Report the demonstrated failure,
not the absence of a preferred CSS utility.
When source evidence cannot settle native focus transitions, keyboard behavior, layout, or popup
presence, verify in the browser. Mocked DOM results and type checks alone do not establish those
behaviors. Consult current official Base UI documentation, installed declarations, or browser
and accessibility standards when the relevant local contract does not settle the question.
[Accessible names and descriptions]: ../../../../packages/dify-ui/docs/accessible-names-and-descriptions.md
[Button contract]: ../../../../packages/dify-ui/src/button/README.md
[Forms]: ../../../../packages/dify-ui/docs/forms.md
[Infotip contract]: ../../../../packages/dify-ui/src/infotip/README.md
[Keyboard commands]: ../../../../web/docs/hotkeys.md
[Overlays]: ../../../../packages/dify-ui/docs/overlays.md
[Page landmarks]: ../../../../web/docs/landmarks.md
[Styling]: ../../../../packages/dify-ui/docs/styling.md
[Toasts]: ../../../../web/docs/toasts.md
references/code-quality.md
# Code Quality Review
Use this pack for changed type, styling, or copy contracts. Scope and reporting thresholds come
from the skill entrypoint; do not turn general style preferences into findings.
## Types And Boundaries
[Ownership] defines module boundaries, extraction, props, and domain types; [Data] owns generated
API types. For Dify UI public exports and upstream-derived props, use [Public API authoring].
- Identify the actual type information lost by a widened field, DTO mirror, or assertion. Trace
consumers before proposing a new abstraction or adapter.
- Check that moved imports still use the intended public boundary. Distinguish an application
bypassing that boundary from the implementation that owns a library integration.
- Require a real migration or compatibility need for new aliases and forwarding layers. Check
whether an existing owner can express the behavior with less state or indirection.
## Styling And Copy
- Use [Styling] for tokens, class composition, state callbacks, and focus ownership, and [Overlays]
for portal/layering changes. Report the violated contract or rendered failure, not the absence
of a preferred utility class.
- Apply [Web requirements] to localized strings and supported locales. Keep keys in the owning
feature namespace; aliases are for crossing namespaces. Verify changed keys and interpolation
against their consumers rather than reviewing only the English text.
- Check whether action and recovery copy explains the real next step. A generic label or wording
preference alone is not a defect; establish ambiguity or an applicable naming contract.
[Data]: ../../how-to-write-component/references/data.md
[Overlays]: ../../../../packages/dify-ui/docs/overlays.md
[Ownership]: ../../how-to-write-component/references/ownership.md
[Public API authoring]: ../../../../packages/dify-ui/docs/authoring.md
[Styling]: ../../../../packages/dify-ui/docs/styling.md
[Web requirements]: ../../../../web/AGENTS.md
references/component-architecture.md
# Component Architecture Review
Use the canonical reference for the changed concern. These links share rules; they do not activate the implementation skill or its workflow.
| Concern | Canonical rules |
| --- | --- |
| Vertical modules, public entrypoints, data/handler placement, wrappers, Props, and types | [Ownership] |
| Local/Jotai state, form drafts, route identity, URL state, and persistence | [State] |
| Effects, navigation, memoization, and subscriptions | [Runtime] |
| Hotkeys, focus, and secondary surfaces | [Interactions] |
## Apply Rules In Their Actual Scope
Explicit team conventions are reviewable contracts, including module organization and public API boundaries. Check the documented exception before reporting a violation. Do not infer an exception solely because the code appears to work, or invent a user-facing failure for a convention finding.
- For owner placement, trace the consumers and required lifetime. Establish whether the parent coordinates a snapshot, submission, navigation, shared UI, or persistence before asking to move state or handlers.
- For component boundaries, identify the ownership or encapsulation the proposed extraction would improve; file length alone establishes neither.
- For props and types, check the domain contract and public API. Do not report private props typing style alone; declaration/export syntax matters only for a documented package rule or concrete type, export, or framework defect.
- For state and Effects, trace the source of truth, external synchronization target, and mount/reset boundary. Controlledness alone does not prove that a draft is lifted or persisted; follow the form and overlay contracts linked by [State].
- For navigation, distinguish ordinary links from mutation success, guarded redirects, command flows, and submission side effects.
## Preserve Existing Product Contracts
During refactors, trace the interaction being moved through its real consumer. Navigation, sidebar, dropdown, webapp-list, and app-switching changes must preserve expansion controls, hover persistence, pin/delete actions, routing, keyboard/focus handling, and open-state ownership where present.
Check that the changed owner still handles reachable empty, loading, and missing optional-data states, and that primitive wrappers preserve accessible semantics and the public controlled-state contract. Report the actual lost behavior or explicit rule violation; use the package testing policy when assessing regression coverage.
[Interactions]: ../../how-to-write-component/references/interactions.md
[Ownership]: ../../how-to-write-component/references/ownership.md
[Runtime]: ../../how-to-write-component/references/runtime.md
[State]: ../../how-to-write-component/references/state.md
references/data-query-contracts.md
# Data, Query, And Contract Review
[Data and queries] owns generated-client, Query options, mutation/cache, imperative access, SSR, authentication, and tenant rules. [State ownership] owns URL state and persistence. Read only the reference needed by the diff; reading a shared reference does not activate its implementation skill.
## Generated Contracts And Query Conventions
Review explicit team conventions as contracts, including direct generated options, `skipToken` for missing required input, and shared cache policy. A lint rule may enforce part of a convention; neither a green lint result nor a suppression proves the full contract is satisfied.
- Establish whether the changed call belongs to a new or migrated surface and whether the generated operation is ready. Check deprecated markers, schema shape, and the real UI consumer before prescribing a migration.
- Distinguish a pass-through wrapper from a feature hook with actual orchestration. Check whether an independent execution condition or Promise composition justifies the documented query/mutation exception.
- Trace generated input and output types through their boundaries. Identify the exact DTO mirror, field widening, placeholder input, or lost intentional empty value when reporting a violation.
- Check whether a local mutation callback owns feature feedback or replaces shared invalidation, retry, or cache defaults. Match optimistic changes to the current list/detail owner.
- Trace feature feedback and shared error handling before adding or keeping a toast; apply the [Toast contract] to the result visible to the user.
## Imperative Access And SSR
- Check freshness, projection, retries, and the caller's execution condition separately against [Data and queries]. Trace Promise ownership to distinguish an awaited hard gate from soft prefetching with an explicit failure owner.
- For Server Components, identify who renders the data and who may revalidate it. Check dehydration, the same-key client consumer, error handling, and the intended Suspense/server-rendered-content contract when the diff changes streaming.
- For auth, setup, roles, branding, or availability, trace authoritative data and the loading/fallback path. A static redirect or placeholder value cannot stand in for a request-dependent decision.
- Check server-side authorization and request/tenant isolation independently of rendering performance, including server actions and shared caches.
## Tenant, URL, And Persistence Boundaries
- Trace the current workspace-switch flow and cache lifetime before reporting missing identity in a query key. Verify backend meaning before treating `workspace_id` and `tenant_id` as interchangeable.
- For URL and storage changes, identify whether the value is shareable navigation state, live app state, a one-shot signal, or a low-frequency preference. Apply [State ownership] to that category and verify its write/reset owner.
Report the violated rule and applicable scope or the concrete failing path. Do not invent runtime impact when the finding is a team-convention violation.
[Data and queries]: ../../how-to-write-component/references/data.md
[State ownership]: ../../how-to-write-component/references/state.md
[Toast contract]: ../../../../web/docs/toasts.md
references/dify-ui.md
# Dify UI Review Routing
Use this reference for changes to `packages/dify-ui/` or its application consumers. Review the
contract owned by the changed layer: upstream behavior, Dify primitive integration, or feature
composition.
## Find The Owner
- Package changes follow [Package rules]; Web consumers follow [Web rules]. Keep their respective
package boundaries and application requirements in scope.
- If the affected contract is known, read its owner guide directly. Use the [Package index] only
to discover available primitives, public subpaths, or the matching guide; do not load every guide.
- Trace implementation, public types, tests, and stories as needed to decide a candidate. If they
disagree with documentation, establish which contract applies before reporting a violation.
- For upstream-derived behavior, check the installed API and current official [Base UI docs].
Do not assume the latest upstream example matches the installed version or Dify wrapper.
## Check The Changed Boundary
- Does a wrapper preserve the public types, value relationships, events, and anatomy its consumers
rely on? Follow the package's public API authoring contract when that surface changes.
- Does `render` composition forward the required props and ref, preserve event handling, and read
state from the owning part? Use the styling and upstream composition contracts to check callback
merging; do not introduce parallel React state merely to reproduce primitive state styles.
- Does the change preserve the documented owner of focus, positioning, portals, and dismissal?
Check shared fixes at that owner and feature-specific composition at the consumer. Consult the
overlay contract for presence and the form/control contract for labels, values, and validation.
- For custom primitive integrations, trace the upstream APIs they actually use and verify the
resulting public behavior. A thin passthrough and a Dify-authored Field/Form integration have
different responsibilities; test those responsibilities without duplicating upstream coverage.
Report an observable defect or an applicable explicit contract violation. Do not turn a preferred
composition, a newer upstream example, or a missing call-site style into a finding on its own.
[Base UI docs]: https://base-ui.com/react
[Package index]: ../../../../packages/dify-ui/README.md
[Package rules]: ../../../../packages/dify-ui/AGENTS.md
[Web rules]: ../../../../web/AGENTS.md
references/performance.md
# Performance Review
Use [Runtime] for ownership, Effects, request concurrency, optional surfaces, and subscription rules. Use [Data and queries] for cache, SSR, authentication, and tenant boundaries. These references own the rules; this pack adds evidence questions.
## Establish The Cost
Report a reachable cost with a causal path, such as request ordering, bundle output, repeated expensive computation, or browser rendering evidence. A missing optimization alone is not a finding.
- For waterfalls, establish that the requests are independent and on the user-visible critical path. Preserve execution conditions and failure ownership when proposing concurrency or streaming.
- For eager imports, identify the module's cost and when the feature needs it. Check actual bundler behavior before treating a barrel import or dynamic path as a bundle regression.
- For server work, identify duplicated requests or serialized data and the request-local owner that can safely deduplicate them.
- For subscriptions and rendering, trace the changing value to the affected consumer before proposing narrower state, selectors, or memoization.
- For lists, layout, and motion, establish the supported data size or interaction and the rendering cost. Do not request virtualization, caching, or an animation rewrite solely because a particular API or CSS property appears.
## Distinguish Value And Reference Identity
- TanStack Query keys are hashed by value by default. Recreating an equivalent key or generated input/options object does not itself create a new query or justify `useMemo`; inspect the key's values and query policy. See [Query keys].
- Query `select` functions can recompute when their reference changes. Require a stable selector only when that recomputation has a demonstrated cost. The top-level query result is intentionally not referentially stable; read the fields the consumer needs. See [Query render optimizations].
- For React dependencies, memoized children, and library APIs, identify the specific consumer whose behavior or cost depends on reference identity. First check that an Effect belongs there; do not use memoization to hide an ownership or dependency problem.
[Data and queries]: data-query-contracts.md
[Query keys]: https://tanstack.com/query/latest/docs/framework/react/guides/query-keys
[Query render optimizations]: https://tanstack.com/query/latest/docs/framework/react/guides/render-optimizations
[Runtime]: ../../how-to-write-component/references/runtime.md
references/testing.md
# Testing Review Rules
Use `web/docs/test.md` for tests owned by `web/` and `packages/dify-ui/docs/testing.md` for tests owned by Dify UI. These owners define their test boundaries, environments, and checks; this reference only adds review questions.
## Request Missing Tests When Risk Justifies Them
Flag missing coverage when a change alters a reachable contract such as:
- User interaction, navigation, form submission, validation, or permissions.
- Query or mutation behavior, URL state, persistence, or one-shot signals.
- Loading, error, empty, and recovery states that users can encounter.
- A hidden surface whose close-and-reopen behavior changes whether in-progress state resets or persists.
- Accessibility-critical labels, keyboard flow, focus, disabled state, or overlay behavior.
- A regression-prone business rule or bug fix that can be reproduced through a public boundary.
Do not request tests for mechanical changes, pass-through wrappers, implementation details, or incidental visual styling. Low coverage alone is not a finding.
## Flag Low-Value or Fragile Tests
Flag tests that:
- Assert internal state, refs, hook usage, effect dependencies, private DOM structure, or cosmetic classes.
- Exist only to render a component, exercise a prop, or cover generic invalid inputs without a product scenario.
- Mock away the behavior under review or use mocks that do not match the public contract.
- Add production `data-testid` attributes where semantic markup would work.
- Use fake timers without timer behavior, leave async work unawaited, or leak shared state.
- Duplicate a contract already protected at a more useful owner boundary.
## Review the Test Boundary
- Prefer semantic queries and accessible names.
- Prefer real feature components when integration semantics matter.
- Check mocks against the owning package's policy; allowed mocks must preserve the public contract and leave the behavior under review real.
- Apply the owning package's admission policy before requesting new automation. Real-browser verification can be a one-off review; a simulator limitation alone does not justify a permanent test.
- Check that assertions prove the claimed outcome and add evidence beyond existing tests; a browser runtime does not make weak assertions stronger.
Treat test quality, determinism, and regression value as the review criteria. Do not use test count or coverage percentage as a proxy for quality.
SKILL.md
---
name: frontend-code-review
description: Review frontend code under `web/` or `packages/dify-ui/` when the user explicitly requests a review or audit. Supports PRs, branches, pending changes, files, and pasted diffs. Do not use for implementation-only requests, diagnosis without review intent, or backend-only code.
---
# Frontend Code Review
Review the requested scope for concrete defects and violations of explicit project contracts. This skill owns review decisions; its references route to canonical rules without activating another skill's implementation workflow.
## Evidence First
1. Resolve the requested target and scope. For a PR or branch, establish its actual base and head; do not assume the tracking branch is the review base. Include local edits only when they belong to the requested scope. Give delegated reviewers the same scope and revisions.
2. Read the changed code, its behavior owner, and the applicable scoped `AGENTS.md`. For a diff review, distinguish introduced or re-exposed defects from unrelated existing issues; a file audit may include existing defects.
3. Trace affected consumers and contracts. When logic is removed or moved, identify the behavior it preserved and where that responsibility now lives. Check affected public types, examples, and tests when they decide correctness.
4. Verify candidates against actual defaults, guards, reachable states, and documented exceptions. Report an observable failure, security boundary violation, or concrete maintenance cost. Explicit team conventions are also contracts: establish their scope without inventing user impact to justify them.
## Rule Routing
Read only the packs for contracts affected by the change, not every topic present in a file:
- Changes to semantics, naming, keyboard/focus, forms, pending states, or responsive interaction: [`references/accessibility-ui.md`][accessibility]
- Changes to Dify UI composition, public API, primitive behavior, or state styling: [`references/dify-ui.md`][dify-ui]
- Changes to component/module ownership, props, state, Effects, or navigation: [`references/component-architecture.md`][component-architecture]
- Generated clients, Query, mutations, auth, SSR, URL state, or persistence: [`references/data-query-contracts.md`][data-query]
- Test files or a concrete missing-regression-test finding: [`references/testing.md`][testing]
- Bundle, waterfall, rendering, or subscription cost supported by evidence: [`references/performance.md`][performance]
- Changes to type boundaries, styling composition, or localized copy not covered above: [`references/code-quality.md`][code-quality]
Follow a known contract directly; use an index only to discover its owner. Project documents define local requirements; installed dependencies and their public APIs establish version-specific behavior. Resolve disagreements with implementation and tests rather than treating existing code as the standard. For unresolved framework, browser, or accessibility behavior, consult current official documentation or standards; use a targeted guidance search when it helps locate them.
## Severity And Output
- **P0**: critical impact requiring immediate intervention, such as widespread unavailability, severe data loss, or a security/privacy breach.
- **P1**: major reachable failure of a primary workflow or public contract that should block delivery.
- **P2**: narrower correctness, accessibility, performance, or test defect; concrete maintenance cost; or a material violation of an explicit project contract.
- **P3**: minor actionable cleanup; omit unless the user requested a thorough audit.
Choose severity by impact, reachability, and recovery, not by topic; accessibility failures are correctness defects. Lead with verified findings ordered by severity. Include a tight file and line reference, the triggering scenario or applicable project rule, and a concrete fix direction. Deduplicate findings with the same cause. State material verification gaps separately; lack of verification is not itself a defect. When no findings remain, say so briefly. Do not add praise sections, speculative risks, or an unsolicited offer to implement fixes.
[accessibility]: references/accessibility-ui.md
[code-quality]: references/code-quality.md
[component-architecture]: references/component-architecture.md
[data-query]: references/data-query-contracts.md
[dify-ui]: references/dify-ui.md
[performance]: references/performance.md
[testing]: references/testing.md