mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-11 19:47:12 +03:00
feat(skills): add React and Vite tool expertise
Squash-merge verified React and Vite expertise at exact head d4fd6cf70d. Required validate and paired evaluation checks passed; advisory droid review had no blocking findings.
This commit is contained in:
@@ -1031,6 +1031,15 @@
|
||||
"strict": false,
|
||||
"description": "Query, search, and download public datasets and civic information for the City of Raleigh. Use for live ArcGIS Hub catalog discovery, ArcGIS FeatureServer and MapServer queries, ImageServer imagery exports, official Raleigh geocoding, GoRaleigh transit feeds, guest-public development records, public RaleighNC.gov content, eSCRIBE public meetings, Raleigh fire reports and inspections, and the Raleigh-Wake ECC active incident feed. Do not use for private data, authenticated operations, payments, submissions, bulk crawling, or non-public portals."
|
||||
},
|
||||
{
|
||||
"name": "react",
|
||||
"source": "./",
|
||||
"skills": [
|
||||
"./react"
|
||||
],
|
||||
"strict": false,
|
||||
"description": "Operate React applications as a named tool: inspect and diagnose React/Vite projects, design component boundaries and state flow, implement accessible responsive UI, and verify behavior with the project's tests. Use when a task explicitly involves React, JSX/TSX, React hooks, React Router, Vite React configuration, or React build failures. Do not use for framework-agnostic frontend strategy (route to frontend-engineering), browser automation (route to playwright), accessibility policy or audits (route to web-accessibility), or non-React mobile apps (route to mobile-development)."
|
||||
},
|
||||
{
|
||||
"name": "release-engineering",
|
||||
"source": "./",
|
||||
@@ -1337,6 +1346,15 @@
|
||||
"strict": false,
|
||||
"description": "Implement and deliver an authorized change end to end — verify, open the PR, merge, and confirm post-merge state — using live-state gates, durable interruption handoffs, and live-state-first resumption. Use when a user grants end-to-end delivery authority for a specific change and the work may cross tool-call limits, context exhaustion, worker loss, or session interruptions before the delivery boundary is reached. Do not use for plain fixes with no delivery directive, for granting merge or post-merge authority the user did not grant, or for designing release pipelines (use release-engineering for that)."
|
||||
},
|
||||
{
|
||||
"name": "vite",
|
||||
"source": "./",
|
||||
"skills": [
|
||||
"./vite"
|
||||
],
|
||||
"strict": false,
|
||||
"description": "Operate Vite projects: inspect versions and configuration, run bounded development and production builds, diagnose dependency and asset failures, and configure environment-aware frontend delivery. Use when a task names Vite, vite.config, Vite plugins, import.meta.env, dev-server behavior, or Vite build output. Do not use for frontend architecture or visual implementation (route to frontend-engineering), CI/platform provisioning (route to platform-engineering), browser automation (route to playwright), or accessibility design (route to web-accessibility)."
|
||||
},
|
||||
{
|
||||
"name": "vllm",
|
||||
"source": "./",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"./pydanticai",
|
||||
"./qa-methodology",
|
||||
"./raleigh",
|
||||
"./react",
|
||||
"./release-engineering",
|
||||
"./remote-systems-administration",
|
||||
"./research-and-vault",
|
||||
@@ -166,6 +167,7 @@
|
||||
"./vercel-eve",
|
||||
"./verification-methodology",
|
||||
"./verified-delivery",
|
||||
"./vite",
|
||||
"./vllm",
|
||||
"./web-accessibility",
|
||||
"./woodpecker-ci",
|
||||
|
||||
@@ -472,6 +472,9 @@ QA and SDET methodology for senior-to-principal engineers — test strategy, aut
|
||||
|
||||
Query, search, and download public datasets from the City of Raleigh Open Data portal. Wraps the ArcGIS REST API to access 170+ datasets — crime reports, food inspections, building permits, bike lanes, parks, zoning, traffic, budgets, and more. No API key needed. Ships a Python CLI with catalog, search, info, query, download, and categories commands.
|
||||
|
||||
### [react](react/SKILL.md)
|
||||
React-specific component, hooks, state-flow, rendering, accessibility boundaries, testing, diagnostics, and Vite integration workflows.
|
||||
|
||||
### [release-engineering](release-engineering/SKILL.md)
|
||||
|
||||
Senior-to-principal release engineering methodology — release process models and CD pipelines, progressive delivery and feature flags, versioning and artifacts, readiness gates, rollback planning, change-governance and compliance evidence, DORA metrics, and multi-team release coordination. Ships 15 references, 6 templates, 4 assets, 5 stdlib-only Python CLIs, and 8 evals.
|
||||
@@ -608,6 +611,10 @@ Replace completion claims with a disciplined evidence trail that shows what was
|
||||
|
||||
Deliver an authorized change end to end — implement, verify, merge, and confirm the merged state — without losing the thread when a hard limit interrupts the work.
|
||||
|
||||
### [vite](vite/SKILL.md)
|
||||
|
||||
Vite-specific configuration, plugins, modes, environment boundaries, dependency optimization, development server diagnostics, builds, previews, and deployment verification.
|
||||
|
||||
### [vllm](vllm/SKILL.md)
|
||||
|
||||
Operate, configure, benchmark, and troubleshoot vLLM inference servers: Docker and Kubernetes deployment, quantization-aware model configuration (tensor parallelism, KV cache), the OpenAI-compatible API surface, throughput/latency benchmarking, continuous batching tuning, GPU operation, and upgrade/rollback. Ships a read-only `vllm-health` probe (`--json`), serving-config and benchmark-run-record templates, 7 dated references, tests, and 6 evals. Routes serving methodology to ml-engineering and the llama.cpp stack to llama-cpp.
|
||||
|
||||
@@ -30,6 +30,8 @@ Frontend engineering is the craft of building the user-facing layer of applicati
|
||||
| Mobile app implementation (iOS/Android/Flutter/React Native) | Mobile platform work — scaffolding, builds and code signing, device/emulator testing, store submission, mobile lifecycle — route to [mobile-development](../mobile-development/SKILL.md); this skill owns web frontends |
|
||||
| Build tooling — bundler config, TypeScript config, linting, formatting, dev environment | CI/CD pipeline infrastructure — that's the platform-engineer |
|
||||
|
||||
For React component and hooks work, load [react](../react/SKILL.md); for Vite config, modes, plugins, and builds, load [vite](../vite/SKILL.md). This skill remains the owner of framework-neutral architecture and frontend strategy.
|
||||
|
||||
## Reference Files
|
||||
|
||||
| Reference | When to load |
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
- [pydanticai](pydanticai/SKILL.md): Build type-safe AI agents and graph-based workflows with PydanticAI and PydanticGraph. Agent creation, function tools, capabilities, dependency injection, structured output, streaming, multi-agent patterns, testing, evals, and graph state machines. Use whenever you are building agents, tool-using LLM workflows, or graph-based state machines in Python. Do not use this skill for unrelated requests; route to the nearest named specialist.
|
||||
- [qa-methodology](qa-methodology/SKILL.md): Design and apply QA methodology for software teams: test strategy, regression testing, CI failure triage, test automation, quality gates and metrics, risk-based testing, exploratory testing, test design techniques, AI code quality gates (independent verification, acceptance-criteria testability review for agentic Spec-Driven Development), mutation-guided test hardening and review evidence (surviving mutants, weak assertions, diff-aware mutation testing), agentic eval design (dataset test design, judge-as-system-under-test, flaky-eval discipline), QA career levels (Senior/Staff/Principal), and SDET engineering (test infrastructure, gTAA, CI/CD integration). Do not use for root-cause debugging of production incidents, security implementation or threat modeling, or evaluation framework governance and statistical analysis — route those to systematic-debugging, secure-software-engineering, and agent-evals-and-observability respectively.
|
||||
- [raleigh](raleigh/SKILL.md): Query, search, and download public datasets and civic information for the City of Raleigh. Use for live ArcGIS Hub catalog discovery, ArcGIS FeatureServer and MapServer queries, ImageServer imagery exports, official Raleigh geocoding, GoRaleigh transit feeds, guest-public development records, public RaleighNC.gov content, eSCRIBE public meetings, Raleigh fire reports and inspections, and the Raleigh-Wake ECC active incident feed. Do not use for private data, authenticated operations, payments, submissions, bulk crawling, or non-public portals.
|
||||
- [react](react/SKILL.md): Operate React applications as a named tool: inspect and diagnose React/Vite projects, design component boundaries and state flow, implement accessible responsive UI, and verify behavior with the project's tests. Use when a task explicitly involves React, JSX/TSX, React hooks, React Router, Vite React configuration, or React build failures. Do not use for framework-agnostic frontend strategy (route to frontend-engineering), browser automation (route to playwright), accessibility policy or audits (route to web-accessibility), or non-React mobile apps (route to mobile-development).
|
||||
- [release-engineering](release-engineering/SKILL.md): Design, automate, and operate end-to-end software releases: release process models and pipelines (trunk-based development, CD stages, release trains), progressive delivery and feature flags, versioning and artifact management (SemVer, conventional commits, changelogs, SBOM/provenance), readiness and quality gates, rollback and recovery planning, change-management and audit compliance (SOC 2, SOX, PCI), DORA metrics, and multi-team release coordination. Do not use for application feature implementation (backend-engineering/frontend-engineering), production incident root-cause debugging or on-call/SLO operations (systematic-debugging / site-reliability-engineering), security implementation or threat modeling (secure-software-engineering), or internal developer platform construction (platform-engineering).
|
||||
- [remote-systems-administration](remote-systems-administration/SKILL.md): Administer and troubleshoot remote Linux, FreeBSD, NetBSD, OpenBSD, and macOS systems safely, one host or a fleet at a time. Use when a task requires SSH, Ansible, Paramiko, POSIX diagnostics, service management, software updates, system configuration, firewall changes, or evidence-led remote operations. Do not use for local-only desktop administration, container or cluster orchestration (route to kubernetes), or cloud consoles that expose no remote shell.
|
||||
- [research-and-vault](research-and-vault/SKILL.md): Chain web research, atomic extraction, and durable note capture when the same research-to-notes sequence must repeat. Do not use this skill to design or evaluate an investigation; use `research-methodology` for research questions, methods, and evidence assessment.
|
||||
@@ -150,6 +151,7 @@
|
||||
- [vercel-eve](vercel-eve/SKILL.md): Build, develop, deploy, self-host, secure, and troubleshoot durable backend AI agents with Vercel Eve. Use when creating an Eve agent, adding tools, skills, subagents, channels, schedules, sandboxing, durable sessions, observability, or deploying Eve on Vercel or a Node host. Do not use for the separate Vercel AI SDK Agent APIs such as ToolLoopAgent or WorkflowAgent; use an AI SDK-specific skill for those.
|
||||
- [verification-methodology](verification-methodology/SKILL.md): Verify work against explicit criteria using direct, source-faithful evidence, reproducible checks, and clear verdicts. Use before declaring an artifact, implementation, or claim complete; do not use for exploratory research without pass/fail criteria.
|
||||
- [verified-delivery](verified-delivery/SKILL.md): Implement and deliver an authorized change end to end — verify, open the PR, merge, and confirm post-merge state — using live-state gates, durable interruption handoffs, and live-state-first resumption. Use when a user grants end-to-end delivery authority for a specific change and the work may cross tool-call limits, context exhaustion, worker loss, or session interruptions before the delivery boundary is reached. Do not use for plain fixes with no delivery directive, for granting merge or post-merge authority the user did not grant, or for designing release pipelines (use release-engineering for that).
|
||||
- [vite](vite/SKILL.md): Operate Vite projects: inspect versions and configuration, run bounded development and production builds, diagnose dependency and asset failures, and configure environment-aware frontend delivery. Use when a task names Vite, vite.config, Vite plugins, import.meta.env, dev-server behavior, or Vite build output. Do not use for frontend architecture or visual implementation (route to frontend-engineering), CI/platform provisioning (route to platform-engineering), browser automation (route to playwright), or accessibility design (route to web-accessibility).
|
||||
- [vllm](vllm/SKILL.md): Operate, configure, benchmark, and troubleshoot vLLM inference servers: Docker and Kubernetes deployment, quantization-aware model configuration (tensor parallelism, KV cache), OpenAI-compatible API serving, throughput and latency benchmarking, continuous batching tuning, GPU operation, and upgrade/rollback. Use when deploying or running a vLLM server (vllm serve, vllm/vllm-openai), sizing a model and its KV cache for GPUs, selecting quantization and parallelism, serving via /v1 endpoints, measuring serving throughput or latency, tuning batching, or diagnosing GPU, OOM, or startup failures in a vLLM deployment. Do not use for model training, fine-tuning, evaluation-set design, or engine-selection methodology (that is ml-engineering), or for operating the llama.cpp stack with GGUF models (that is llama-cpp); other inference engines (TGI, Ollama, Triton) are out of scope.
|
||||
- [web-accessibility](web-accessibility/SKILL.md): Design, build, and review accessible web interfaces with native semantics, keyboard and focus behavior, forms and recovery, responsive input, motion, assistive-technology testing, and WCAG 2.2-informed evidence. Use for a11y, WCAG, ARIA, screen-reader, keyboard, focus, dialog, form, widget, or accessibility review work across frameworks. Do not use this skill for unrelated requests; route to the nearest named specialist.
|
||||
- [woodpecker-ci](woodpecker-ci/SKILL.md): Operate Woodpecker CI from installation through production troubleshooting: configure servers and agents, connect Forgejo/Gitea or another forge, write and validate pipelines, manage secrets and plugins, use Docker or Kubernetes backends, run the CLI, and diagnose failed builds. Use when setting up, administering, or debugging Woodpecker CI. Do not use this skill for unrelated requests; route to the nearest named specialist.
|
||||
|
||||
+1
-1
@@ -141,7 +141,7 @@ Exit codes: 0 ok, 1 analysis error, 2 usage error, 127 dependency (node/playwrig
|
||||
## When not to use
|
||||
|
||||
- **Test strategy, framework selection, or QA process** — route to [qa-methodology](../qa-methodology/SKILL.md).
|
||||
- **Frontend component/state/architecture design or implementation guidance** — route to [frontend-engineering](../frontend-engineering/SKILL.md).
|
||||
- **Frontend component/state/architecture design or implementation guidance** — route to [frontend-engineering](../frontend-engineering/SKILL.md); React-specific component and hooks work routes to [react](../react/SKILL.md).
|
||||
- **Cloudflare/DDoS-GUARD challenge bypass** — route to [flaresolverr](../flaresolverr/SKILL.md).
|
||||
- **Load/performance testing at scale** (k6, Locust, Gatling, JMeter) — that methodology lives under `qa-methodology`'s performance-testing reference.
|
||||
- **Raw HTTP retrieval of static content** — use a plain HTTP client; Playwright is for JavaScript-rendered pages and browser workflows.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# react — Build and diagnose React applications
|
||||
|
||||
## Why Install This Skill
|
||||
|
||||
React projects accumulate framework-specific failure modes: hooks that resynchronize unnecessarily, stale requests that overwrite newer data, routes that break under a subpath, and Vite environment values accidentally shipped to browsers. This skill gives your agent a focused operating loop for those problems.
|
||||
|
||||
After installation, your agent can inspect a React/Vite project safely, make component and state changes that fit its existing conventions, protect accessible interaction states, and verify the result with the project's own checks. It also includes a read-only doctor for quick diagnostics without installing dependencies or exposing environment values.
|
||||
|
||||
## What You Get
|
||||
|
||||
| Directory | Purpose |
|
||||
|---|---|
|
||||
| `SKILL.md` | React-specific implementation workflow, guardrails, handoffs, and verification steps |
|
||||
| `references/component-and-state.md` | Component boundaries, hooks, effects, async state, and forms |
|
||||
| `references/vite-diagnostics.md` | Vite environment, build, asset-base, and deployment diagnostics |
|
||||
| `scripts/react-doctor.py` | Bounded Python diagnostic with human-readable or JSON output |
|
||||
| `scripts/test_react_doctor.py` | Offline tests for diagnostic behavior and safety guarantees |
|
||||
| `evals/evals.json` | Six substantive output-quality cases for React and Vite work |
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
python3 scripts/react-doctor.py --json .
|
||||
python3 scripts/react-doctor.py .
|
||||
```
|
||||
|
||||
The doctor reads project files only. It does not install packages, run scripts, contact the network, or print environment values.
|
||||
|
||||
## Triggers
|
||||
|
||||
Load this skill when working with React, JSX/TSX, hooks, React Router, Vite React configuration, React component/state implementation, or React build failures. Use it for a focused project diagnosis before editing.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.8+ for the bundled diagnostic and tests.
|
||||
- Node.js and the project's package manager for application builds and tests.
|
||||
- Existing React/Vite project files; no API key is required.
|
||||
- Use `frontend-engineering` for framework-agnostic frontend architecture, `playwright` for browser automation, and `web-accessibility` for dedicated accessibility audits.
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
---
|
||||
name: react
|
||||
description: >-
|
||||
Operate React applications as a named tool: inspect and diagnose React/Vite
|
||||
projects, design component boundaries and state flow, implement accessible
|
||||
responsive UI, and verify behavior with the project's tests. Use when a task
|
||||
explicitly involves React, JSX/TSX, React hooks, React Router, Vite React
|
||||
configuration, or React build failures. Do not use for framework-agnostic
|
||||
frontend strategy (route to frontend-engineering), browser automation (route
|
||||
to playwright), accessibility policy or audits (route to web-accessibility),
|
||||
or non-React mobile apps (route to mobile-development).
|
||||
license: MIT
|
||||
compatibility: >-
|
||||
The bundled diagnostic script uses Python 3.8+ standard library only. Running
|
||||
or building an application requires its repository package manager and Node.js.
|
||||
metadata:
|
||||
tags: react, jsx, tsx, vite, hooks, components, router, frontend
|
||||
source: https://react.dev/
|
||||
---
|
||||
|
||||
# React Application Engineering
|
||||
|
||||
Use this skill for the React-specific implementation layer. Preserve the
|
||||
project's existing React version, package manager, build scripts, styling
|
||||
conventions, and routing model unless the user asks for a migration.
|
||||
|
||||
## Operating loop
|
||||
|
||||
1. **Diagnose before editing.** Run `scripts/react-doctor.py --json [PROJECT]` and
|
||||
inspect `package.json`, source entry points, Vite config, TypeScript config,
|
||||
routes, and test scripts. The diagnostic is bounded and read-only.
|
||||
2. **Define the component contract.** Identify the page/feature boundary,
|
||||
inputs and outputs, owned state, server state, loading/empty/error/success
|
||||
states, and side effects. Keep reusable components independent of route
|
||||
globals and avoid passing state through unrelated layers.
|
||||
3. **Implement with explicit data flow.** Prefer local state for local behavior,
|
||||
context only for genuinely cross-cutting concerns, and the existing server
|
||||
state/cache solution for remote data. Keep effects for synchronization with
|
||||
external systems; derive values during render rather than storing duplicates.
|
||||
4. **Keep UI resilient.** Render a useful loading, empty, error, and success
|
||||
experience. Cancel or ignore stale async work, handle aborts, and avoid
|
||||
setting state after an obsolete request. Preserve stable keys and avoid
|
||||
mutating props or state.
|
||||
5. **Build for the browser.** Use semantic HTML, keyboard-operable controls,
|
||||
visible focus, responsive layout, and stable accessible names. For detailed
|
||||
accessibility requirements, load [web-accessibility](../web-accessibility/SKILL.md).
|
||||
6. **Verify in layers.** Run the narrowest existing unit/component test, then
|
||||
lint/typecheck, then the production build. For browser-level flows use
|
||||
[playwright](../playwright/SKILL.md), not ad hoc browser automation. Report
|
||||
the exact commands and any environment-dependent checks that were skipped.
|
||||
|
||||
## React-specific rules
|
||||
|
||||
- Hooks run unconditionally and in the same order on every render; never call
|
||||
them in branches, loops, event handlers, or nested functions.
|
||||
- Effects synchronize with external systems. Do not use an effect to calculate
|
||||
a value that can be derived from props/state, or to mirror props into state
|
||||
without a clear user-editing requirement.
|
||||
- Use functional updates when the next state depends on the previous state.
|
||||
Give list items stable keys from domain identity, not array indexes when the
|
||||
list can reorder, insert, or delete.
|
||||
- Treat event handlers as user intent and keep them separate from render-time
|
||||
computation. Disable or guard duplicate submissions and expose pending state.
|
||||
- Keep API response validation and transformation at the integration boundary;
|
||||
components should consume a typed, predictable view model.
|
||||
- Do not add a state library or router solely because it is popular. First map
|
||||
ownership and use the project's existing choices.
|
||||
- In Vite, expose only intentionally public variables using the project's
|
||||
documented prefix (normally `VITE_`); never put secrets in client bundles.
|
||||
Read [references/vite-diagnostics.md](references/vite-diagnostics.md) for
|
||||
environment, build, and deployment checks.
|
||||
|
||||
## Routing and handoffs
|
||||
|
||||
- Component architecture, responsive implementation, performance budgets, and
|
||||
general frontend testing: [frontend-engineering](../frontend-engineering/SKILL.md).
|
||||
- Browser E2E authoring, locator choice, network interception, and Playwright
|
||||
runs: [playwright](../playwright/SKILL.md).
|
||||
- Semantic structure, keyboard/focus behavior, WCAG acceptance evidence, and
|
||||
accessibility audits: [web-accessibility](../web-accessibility/SKILL.md).
|
||||
- React Native, Expo, Android, or iOS implementation: [mobile-development](../mobile-development/SKILL.md).
|
||||
|
||||
## Reference routing
|
||||
|
||||
| Load when | Reference |
|
||||
|---|---|
|
||||
| Choosing component boundaries, state ownership, effects, or async UI behavior | `references/component-and-state.md` |
|
||||
| Diagnosing Vite env exposure, dependency versions, build output, or deployment paths | `references/vite-diagnostics.md` |
|
||||
|
||||
## Included script
|
||||
|
||||
`scripts/react-doctor.py` is a read-only, dependency-free diagnostic. Run
|
||||
`scripts/react-doctor.py --help` for options. It accepts a project directory,
|
||||
checks common React/Vite signals, and emits human-readable or bounded JSON
|
||||
output. It does not install packages, execute project scripts, access the
|
||||
network, or print environment values.
|
||||
|
||||
## Completion boundary
|
||||
|
||||
Stop when the requested React change is implemented, the project's relevant
|
||||
checks have run, and remaining failures are reported with their command and
|
||||
root-cause evidence. Do not broaden a component task into a framework migration
|
||||
or an accessibility audit without explicit scope.
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"skill_name": "react",
|
||||
"evals": [
|
||||
{
|
||||
"id": "component-state-boundary",
|
||||
"prompt": "Design a React dashboard filter component that fetches results and has loading, empty, error, and success states.",
|
||||
"expected_output": "A component/state plan that assigns ownership, avoids duplicated derived state, and describes each async UI state.",
|
||||
"assertions": ["Identifies local, URL, and server state separately", "Includes loading, empty, error, and success behavior", "Avoids an unnecessary effect for derived values"]
|
||||
},
|
||||
{
|
||||
"id": "stale-request-protection",
|
||||
"prompt": "Fix a React search hook where a slower response for the previous query overwrites the current query results.",
|
||||
"expected_output": "A hook implementation or patch using abort or an active-request guard, with cleanup and intentional cancellation handling.",
|
||||
"assertions": ["Prevents stale responses from committing state", "Cleans up the obsolete request", "Does not present abort cancellation as a user error"]
|
||||
},
|
||||
{
|
||||
"id": "vite-secret-boundary",
|
||||
"prompt": "Diagnose why a Vite app exposes an API token in its browser bundle and propose a safe fix.",
|
||||
"expected_output": "A diagnosis that treats client env values as public, removes the secret from client code, and routes privileged access through a server boundary.",
|
||||
"assertions": ["Explains compile-time Vite env substitution", "Never recommends shipping a secret under a public prefix", "Includes a way to rotate the exposed credential"]
|
||||
},
|
||||
{
|
||||
"id": "subpath-routing-build",
|
||||
"prompt": "A React Router app works at localhost root but its JS and CSS 404 when deployed under /portal/. Debug the Vite deployment.",
|
||||
"expected_output": "A bounded diagnostic covering Vite base, generated asset URLs, and host-side SPA history fallback, followed by a preview verification.",
|
||||
"assertions": ["Checks the Vite base setting", "Checks SPA fallback for deep links", "Verifies the built output at the deployed subpath"]
|
||||
},
|
||||
{
|
||||
"id": "accessible-react-control",
|
||||
"prompt": "Implement an expandable React disclosure with keyboard support and a focus-safe error message.",
|
||||
"expected_output": "A semantic button/disclosure implementation with an accessible name, aria-expanded linkage, visible focus, and an announced error path.",
|
||||
"assertions": ["Uses native button semantics", "Keeps aria-expanded and controlled-region linkage synchronized", "Routes detailed WCAG review to web-accessibility"]
|
||||
},
|
||||
{
|
||||
"id": "verification-handoff",
|
||||
"prompt": "Add a React form feature and verify it without installing new dependencies or using browser automation unnecessarily.",
|
||||
"expected_output": "A verification sequence using existing project scripts, then build, with Playwright reserved for browser-level flows and failures reported exactly.",
|
||||
"assertions": ["Inspects package scripts and existing conventions first", "Runs focused checks before the production build", "Routes browser E2E work to playwright rather than inventing ad hoc automation"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
# React Component And State Patterns
|
||||
|
||||
## Start with ownership
|
||||
|
||||
Describe each value as one of local UI state, server/cache state, URL state, or
|
||||
cross-cutting application state. Keep state at the lowest common owner. If a
|
||||
value is derived from other values, compute it during render or in a memoized
|
||||
calculation when measurement proves the calculation costly; do not create a
|
||||
second source of truth.
|
||||
|
||||
A practical component boundary usually owns one interaction or visual contract.
|
||||
Split when a component has unrelated state machines, repeated markup, or an
|
||||
API that requires consumers to understand implementation details. Keep domain
|
||||
transformations outside presentational components when they can be tested
|
||||
without a browser.
|
||||
|
||||
## Effects and asynchronous work
|
||||
|
||||
Before adding `useEffect`, name the external system it synchronizes with:
|
||||
network, subscription, timer, browser API, or imperative widget. If none exists,
|
||||
prefer render derivation or an event handler. Every effect should have a cleanup
|
||||
when it creates a subscription, timer, listener, or request that can outlive the
|
||||
render.
|
||||
|
||||
For a request keyed by an input, use an abort signal or an active-request guard,
|
||||
handle abort as non-error cancellation, and ensure a late response cannot replace
|
||||
newer data. Model `status` explicitly (`idle`, `pending`, `success`, `error`) and
|
||||
render all meaningful states. Avoid catching an error only to log it and leave a
|
||||
permanently pending screen.
|
||||
|
||||
## Interaction contracts
|
||||
|
||||
Use controlled inputs when validation, submission, or external reset is part of
|
||||
the feature; otherwise an uncontrolled input with a ref may be simpler. Keep
|
||||
submit handlers idempotent, disable or guard while pending, and preserve the
|
||||
user's entered data on recoverable errors. Announce validation and server errors
|
||||
through the accessible structure, not only a color or toast.
|
||||
|
||||
For lists, key rows with stable domain identity. If a row has local state, an
|
||||
index key can transfer that state to another record after sorting or deletion.
|
||||
Use functional updates for transitions based on prior state, especially when
|
||||
multiple events may batch.
|
||||
|
||||
## Verification checklist
|
||||
|
||||
- Hooks are unconditional and dependencies reflect values read from the effect.
|
||||
- No derived state or duplicated server state is introduced without a reason.
|
||||
- Loading, empty, error, retry, and success states are represented where relevant.
|
||||
- Async cleanup prevents stale writes and treats cancellation intentionally.
|
||||
- Buttons and links use native semantics; keyboard and focus behavior is tested.
|
||||
- Component tests cover user-visible behavior; browser flows are delegated to
|
||||
[playwright](../../playwright/SKILL.md).
|
||||
- Dedicated semantic and WCAG review is delegated to
|
||||
[web-accessibility](../../web-accessibility/SKILL.md).
|
||||
@@ -0,0 +1,51 @@
|
||||
# Vite Diagnostics And Release Checks
|
||||
|
||||
## Environment values
|
||||
|
||||
Vite substitutes client-exposed variables at build time. Only variables with the
|
||||
configured public prefix (commonly `VITE_`) should be read by browser code.
|
||||
Treat every such value as public: it is not a secret merely because it lives in
|
||||
`.env`. Keep credentials and server-only configuration outside the client
|
||||
bundle. Check `.env.example`, Vite config, deployment configuration, and the
|
||||
actual built assets for accidental exposure.
|
||||
|
||||
Vite loads mode-specific files with a defined precedence. Confirm the intended
|
||||
mode (`development`, `production`, or a custom mode) and do not assume a local
|
||||
`.env` matches CI. When diagnosing a value, inspect its name and source without
|
||||
printing its value. Re-run the build after changing env configuration because
|
||||
substitution is compile-time.
|
||||
|
||||
## Build and asset paths
|
||||
|
||||
Inspect `base` in `vite.config.*` when the app is served below `/`. A wrong base
|
||||
usually appears as 404s for module, CSS, or asset URLs after deployment even
|
||||
though the root-local dev server works. Validate the generated HTML and asset
|
||||
references against the real deployment path. For SPA history fallback, confirm
|
||||
the host serves the app entry point for non-root routes; Vite does not configure
|
||||
that server rule for every deployment target.
|
||||
|
||||
## Dependency and output checks
|
||||
|
||||
Use the project's package manager lockfile and scripts. Check that `react` and
|
||||
`react-dom` versions are compatible and that duplicate React copies are not
|
||||
being pulled into the bundle, which can produce invalid hook call errors. Do not
|
||||
blindly delete lockfiles or upgrade dependencies while diagnosing.
|
||||
|
||||
For release verification, run the existing typecheck/lint/test commands before
|
||||
`vite build`, inspect warnings, and use a preview server for a smoke check at
|
||||
the deployed base path. Keep source maps and reports out of user-facing output
|
||||
unless the project intentionally publishes them.
|
||||
|
||||
## Safe diagnostic sequence
|
||||
|
||||
1. Record the package manager and available scripts from `package.json`.
|
||||
2. Identify the active mode and public-prefix configuration without exposing
|
||||
values.
|
||||
3. Inspect `base`, route fallback, and generated asset URLs.
|
||||
4. Check lockfile consistency and React package version alignment.
|
||||
5. Run the narrowest reproducible check, then the production build.
|
||||
6. Confirm the browser flow with [playwright](../../playwright/SKILL.md) when
|
||||
route, asset, or navigation behavior is involved.
|
||||
7. Ask [frontend-engineering](../../frontend-engineering/SKILL.md) for broader
|
||||
performance/component strategy and [web-accessibility](../../web-accessibility/SKILL.md)
|
||||
for a dedicated accessibility audit.
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Bounded, read-only diagnostics for React/Vite projects."""
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
MAX_BYTES = 512 * 1024
|
||||
TEXT_FILES = ("package.json", "vite.config.js", "vite.config.ts", "vite.config.mjs", "vite.config.cjs", "tsconfig.json")
|
||||
|
||||
def read_text(root, name):
|
||||
path = root / name
|
||||
try:
|
||||
if not path.is_file() or path.stat().st_size > MAX_BYTES:
|
||||
return None
|
||||
return path.read_text(encoding="utf-8")
|
||||
except (OSError, UnicodeError):
|
||||
return None
|
||||
|
||||
def diagnose(root):
|
||||
result = {"project": str(root), "checks": [], "warnings": []}
|
||||
package_text = read_text(root, "package.json")
|
||||
package = None
|
||||
if package_text is None:
|
||||
result["warnings"].append("package.json is missing or exceeds the read limit")
|
||||
else:
|
||||
try:
|
||||
package = json.loads(package_text)
|
||||
if not isinstance(package, dict):
|
||||
raise ValueError("not an object")
|
||||
deps = {**package.get("dependencies", {}), **package.get("devDependencies", {})}
|
||||
result["checks"].append({"name": "package-json", "status": "ok"})
|
||||
result["checks"].append({"name": "react-dependencies", "status": "ok" if "react" in deps and "react-dom" in deps else "warning"})
|
||||
except (ValueError, TypeError, json.JSONDecodeError):
|
||||
result["warnings"].append("package.json is not valid JSON")
|
||||
config_name = next((name for name in TEXT_FILES[1:5] if read_text(root, name) is not None), None)
|
||||
result["checks"].append({"name": "vite-config", "status": "ok" if config_name else "info", "file": config_name})
|
||||
source_files = []
|
||||
for directory in (root / "src", root / "app"):
|
||||
if directory.is_dir():
|
||||
source_files.extend(p for p in directory.rglob("*") if p.is_file() and p.suffix in {".jsx", ".tsx", ".js", ".ts"})
|
||||
result["checks"].append({"name": "source-entry", "status": "ok" if source_files else "warning", "file_count": len(source_files)})
|
||||
env_names = set()
|
||||
for path in root.glob(".env*"):
|
||||
text = read_text(root, path.name) or ""
|
||||
env_names.update(re.findall(r"^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=", text, re.MULTILINE))
|
||||
result["checks"].append({"name": "public-env-names", "status": "ok", "names": sorted(n for n in env_names if n.startswith("VITE_"))})
|
||||
if any(not n.startswith("VITE_") for n in env_names):
|
||||
result["warnings"].append(".env files contain non-public names; keep them server-side and never import secrets into client code")
|
||||
lockfiles = [name for name in ("package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock") if (root / name).is_file()]
|
||||
result["checks"].append({"name": "lockfile", "status": "ok" if lockfiles else "warning", "files": lockfiles})
|
||||
return result
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(description="Read-only React/Vite project diagnostics")
|
||||
parser.add_argument("project", nargs="?", default=".")
|
||||
parser.add_argument("--json", action="store_true", dest="as_json")
|
||||
args = parser.parse_args(argv)
|
||||
root = Path(args.project).expanduser().resolve()
|
||||
if not root.is_dir():
|
||||
print("ERROR: project directory does not exist", file=sys.stderr)
|
||||
return 2
|
||||
result = diagnose(root)
|
||||
if args.as_json:
|
||||
print(json.dumps(result, sort_keys=True))
|
||||
else:
|
||||
print("React/Vite doctor: " + result["project"])
|
||||
for check in result["checks"]:
|
||||
print("- {name}: {status}".format(**check))
|
||||
for warning in result["warnings"]:
|
||||
print("WARNING: " + warning)
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Offline tests for the read-only React doctor."""
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPT = Path(__file__).with_name("react-doctor.py")
|
||||
|
||||
class DoctorTests(unittest.TestCase):
|
||||
def run_doctor(self, root, *args):
|
||||
return subprocess.run([sys.executable, str(SCRIPT), *args, str(root)], capture_output=True, text=True)
|
||||
|
||||
def test_json_reports_react_vite_signals_without_values(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
(root / "package.json").write_text(json.dumps({"dependencies": {"react": "18", "react-dom": "18"}}), encoding="utf-8")
|
||||
(root / "vite.config.ts").write_text("export default {}", encoding="utf-8")
|
||||
(root / "src").mkdir()
|
||||
(root / "src/App.tsx").write_text("export default function App() {}", encoding="utf-8")
|
||||
(root / ".env.local").write_text("VITE_PUBLIC=visible\nSECRET=do-not-print\n", encoding="utf-8")
|
||||
output = self.run_doctor(root, "--json")
|
||||
self.assertEqual(output.returncode, 0)
|
||||
report = json.loads(output.stdout)
|
||||
self.assertEqual(report["checks"][0]["status"], "ok")
|
||||
env_check = next(check for check in report["checks"] if check["name"] == "public-env-names")
|
||||
self.assertIn("VITE_PUBLIC", env_check["names"])
|
||||
self.assertNotIn("do-not-print", output.stdout)
|
||||
|
||||
def test_missing_project_is_usage_error(self):
|
||||
output = self.run_doctor(Path("/definitely/not/a/project"))
|
||||
self.assertEqual(output.returncode, 2)
|
||||
self.assertIn("does not exist", output.stderr)
|
||||
|
||||
def test_malformed_package_is_reported(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
(root / "package.json").write_text("{broken", encoding="utf-8")
|
||||
output = self.run_doctor(root, "--json")
|
||||
self.assertEqual(output.returncode, 0)
|
||||
self.assertTrue(any("not valid JSON" in warning for warning in json.loads(output.stdout)["warnings"]))
|
||||
|
||||
def test_help_is_available(self):
|
||||
output = subprocess.run([sys.executable, str(SCRIPT), "--help"], capture_output=True, text=True)
|
||||
self.assertEqual(output.returncode, 0)
|
||||
self.assertIn("read-only", output.stdout.lower())
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,51 @@
|
||||
# Vite Skill - Operate Vite projects safely
|
||||
|
||||
## Why Install This Skill
|
||||
|
||||
Vite is fast, but small configuration mistakes can produce broken asset URLs, leaked client variables, inaccessible dev servers, or builds that only work from the repository root. This skill gives your agent a practical inspect, change, build, and verify workflow for Vite projects.
|
||||
|
||||
After installation, your agent can identify the real Vite and Node toolchain, reason about modes and `import.meta.env`, diagnose plugins and module resolution, validate `base` paths and output directories, and check the built artifact instead of treating an exit code as the whole result.
|
||||
|
||||
## What You Get
|
||||
|
||||
| Path | Purpose |
|
||||
|---|---|
|
||||
| `SKILL.md` | Vite operating contract, boundaries, workflow, and routing |
|
||||
| `references/config-and-environments.md` | Config, plugins, modes, env files, aliases, and public assets |
|
||||
| `references/build-and-deploy.md` | Production builds, asset paths, SPA hosting, and dependency failures |
|
||||
| `references/dev-server-and-diagnostics.md` | Dev server, proxy, preview, host safety, and troubleshooting |
|
||||
| `scripts/vite-doctor` | Bounded JSON diagnostic for Node, package manager, Vite, config, and env names |
|
||||
| `scripts/test_vite_doctor.py` | Deterministic tests for the diagnostic script |
|
||||
| `evals/evals.json` | Five output-quality evaluation cases |
|
||||
|
||||
## Quick Start
|
||||
|
||||
From a Vite project, run the diagnostic without exposing environment values:
|
||||
|
||||
```sh
|
||||
/path/to/vite/scripts/vite-doctor --project . --json
|
||||
```
|
||||
|
||||
Then use the package manager script already declared by the project:
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
## Triggers
|
||||
|
||||
Load this skill when a task involves:
|
||||
|
||||
- `vite`, `vite.config.*`, Vite plugins, or a Vite migration
|
||||
- `import.meta.env`, modes, `.env` loading, or public assets
|
||||
- Vite dev server, proxy, preview, or host/port behavior
|
||||
- Production build failures, chunk output, `base`, or static deployment
|
||||
- Checking the installed Node, package manager, or Vite version
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.8+ for `scripts/vite-doctor`
|
||||
- Node.js and the project's package manager for Vite commands
|
||||
- A supported Vite version and framework plugin as declared by the project
|
||||
- Network access only when installing approved dependencies or consulting documentation
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: vite
|
||||
description: >-
|
||||
Operate Vite projects: inspect versions and configuration, run bounded development
|
||||
and production builds, diagnose dependency and asset failures, and configure
|
||||
environment-aware frontend delivery. Use when a task names Vite, vite.config,
|
||||
Vite plugins, import.meta.env, dev-server behavior, or Vite build output. Do not
|
||||
use for frontend architecture or visual implementation (route to frontend-engineering),
|
||||
CI/platform provisioning (route to platform-engineering), browser automation
|
||||
(route to playwright), or accessibility design (route to web-accessibility).
|
||||
license: MIT
|
||||
compatibility: Requires Python 3.8+ for the bundled diagnostic script; Node.js and the project's package manager are required for Vite commands.
|
||||
metadata:
|
||||
source: https://vite.dev/guide/
|
||||
spec: https://vite.dev/config/
|
||||
---
|
||||
|
||||
# Vite Operations
|
||||
|
||||
Use this skill for the Vite toolchain itself: project discovery, config and plugin behavior, environment loading, dev-server diagnostics, production builds, and asset/deployment boundaries. Keep application architecture and UI implementation with [frontend-engineering](../frontend-engineering/SKILL.md), infrastructure and CI design with [platform-engineering](../platform-engineering/SKILL.md), browser tests with [playwright](../playwright/SKILL.md), and accessibility implementation/review with [web-accessibility](../web-accessibility/SKILL.md).
|
||||
|
||||
## Operating contract
|
||||
|
||||
1. **Discover before changing.** Read `package.json`, lockfile, `vite.config.*`, `tsconfig*.json`, scripts, framework plugin, and deployment assumptions. Identify the package manager from the lockfile; do not invent a command.
|
||||
2. **Check the actual toolchain.** Run `scripts/vite-doctor --json` from this skill or the project root to capture Node, package-manager, Vite package, config, and environment evidence. A Vite version in documentation is not proof of the installed version.
|
||||
3. **Keep configuration explicit.** Review `root`, `base`, `resolve.alias`, plugins, `server.host/port`, `preview`, `build.outDir`, `build.rollupOptions`, and `define`. Treat `define` and `import.meta.env` as compile-time/public data; never place secrets in `VITE_*` variables or client bundles.
|
||||
4. **Build before claiming success.** Use the project's existing script (normally `npm run build`, `pnpm build`, `yarn build`, or `bun run build`) with a bounded timeout. Inspect output files and warnings, then exercise the built app at its deployed base path when possible.
|
||||
5. **Treat mutations as gated.** Read-only discovery may proceed. Before installing packages, editing config, deleting output, starting a server, or changing deployment settings, confirm the target, scope, and rollback path. Prefer a new output directory or version-controlled change and never overwrite a user's uncommitted work.
|
||||
6. **Keep evidence bounded.** Summarize logs and errors; do not paste `.env` contents, tokens, full bundles, or generated dependency trees.
|
||||
|
||||
## Common workflow
|
||||
|
||||
- **New project or migration:** verify Node and package manager, inspect the existing app entry point, choose the framework plugin, preserve the lockfile, and use the official Vite scaffold only when the target directory is empty or explicitly approved.
|
||||
- **Config change:** make the smallest change, explain why `base` and asset paths remain correct, and run a production build. Config files are executable code; do not load arbitrary config values into `define`.
|
||||
- **Environment issue:** distinguish `.env`, `.env.local`, mode-specific files, and process environment. Only variables prefixed `VITE_` are exposed by default; restart the dev server after changes. Validate required values without printing their values.
|
||||
- **Dev-server issue:** check port/host/proxy and whether the request is same-origin. A server reachable from another device may require an explicit host and network policy review; do not expose it casually.
|
||||
- **Build issue:** capture the first actionable error, check plugin and Node/Vite compatibility, clear only reproducible caches after approval, and rerun the smallest failing command. Do not paper over a module-resolution failure with broad alias changes.
|
||||
- **Deployment issue:** confirm `base`, SPA fallback, static asset caching, and the hosting platform's output directory. A successful build does not prove deep links or client routing work.
|
||||
|
||||
## Reference routing
|
||||
|
||||
| Load when | Reference |
|
||||
|---|---|
|
||||
| Config, plugins, modes, env variables, aliases, or public assets | `references/config-and-environments.md` |
|
||||
| Build output, dependency failures, performance, or deployment | `references/build-and-deploy.md` |
|
||||
| Dev server, proxy, preview, diagnostics, or safe operations | `references/dev-server-and-diagnostics.md` |
|
||||
|
||||
## Verification boundary
|
||||
|
||||
A Vite task is complete when the requested config or artifact exists, the relevant command exits successfully, and the boundary is checked: build output for builds, a reachable route and assets for deployment, and user-visible browser behavior through [playwright](../playwright/SKILL.md) for E2E claims. State any untested browser, host, mode, or deployment assumption explicitly.
|
||||
|
||||
## When not to use
|
||||
|
||||
- Frontend component architecture, state, responsive UI, or general web implementation: [frontend-engineering](../frontend-engineering/SKILL.md).
|
||||
- Infrastructure, CI runners, containers, hosting topology, or release policy: [platform-engineering](../platform-engineering/SKILL.md).
|
||||
- Authoring or operating browser automation: [playwright](../playwright/SKILL.md).
|
||||
- WCAG audits, accessible interaction design, or semantic accessibility remediation: [web-accessibility](../web-accessibility/SKILL.md).
|
||||
- Rollup internals or a non-Vite bundler migration: use the relevant tool or methodology skill; Vite-specific behavior may still be consulted for an existing Vite project.
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"skill_name": "vite",
|
||||
"evals": [
|
||||
{
|
||||
"id": "diagnose-build-failure",
|
||||
"prompt": "A Vite production build fails with a module not found error after a dependency upgrade. Explain the investigation and safe fix.",
|
||||
"expected_output": "An evidence-first diagnosis that identifies the package manager and lockfile, records Node/Vite/plugin versions, checks the import and workspace dependency declaration, and distinguishes config, resolution, plugin, and typecheck failures. It avoids deleting the lockfile or adding broad aliases, makes the smallest approved change, and reruns the declared build with a bounded timeout.",
|
||||
"assertions": [
|
||||
"The response inspects package manager, lockfile, Node, Vite, and plugin evidence",
|
||||
"The response checks the import and workspace dependency before changing aliases",
|
||||
"The response forbids deleting the lockfile as a first fix",
|
||||
"The response reruns the declared production build and reports the boundary result"
|
||||
],
|
||||
"case_set": "regression"
|
||||
},
|
||||
{
|
||||
"id": "env-secret-boundary",
|
||||
"prompt": "We need to expose a public API URL in a Vite React app, but the same .env file also contains a private API token. What should change?",
|
||||
"expected_output": "The response explains that only intentionally prefixed variables such as VITE_API_URL are exposed to client code, while a private token must remain server-side and must not be placed in VITE_* variables, define, committed files, or logs. It verifies variable presence without printing values and restarts the dev server after env changes.",
|
||||
"assertions": [
|
||||
"Public VITE-prefixed configuration is distinguished from private secrets",
|
||||
"The private token is kept server-side and excluded from define, bundles, commits, and logs",
|
||||
"The response validates presence without printing values",
|
||||
"The response notes that the dev server must restart after env changes"
|
||||
],
|
||||
"case_set": "release"
|
||||
},
|
||||
{
|
||||
"id": "base-path-deployment",
|
||||
"prompt": "The Vite build works at localhost root but fails when deployed under /docs/ and client-side deep links return 404. Give a verification and remediation plan.",
|
||||
"expected_output": "A plan that checks the configured base against the hosting prefix, inspects generated HTML and dynamic asset URLs, confirms the exact outDir is published, and configures SPA fallback or a host-compatible routing strategy. It verifies the root and a deep route through preview or the deployed boundary, rather than treating build success as sufficient.",
|
||||
"assertions": [
|
||||
"The response aligns base with the /docs/ hosting prefix",
|
||||
"The response checks generated HTML, dynamic imports, and the exact output directory",
|
||||
"The response addresses SPA fallback for deep links",
|
||||
"The response verifies root and deep routes at the deployed boundary"
|
||||
],
|
||||
"case_set": "regression"
|
||||
},
|
||||
{
|
||||
"id": "dev-host-exposure",
|
||||
"prompt": "A teammate wants to run vite --host 0.0.0.0 so a phone can access the app. What should we inspect and what risks must be acknowledged?",
|
||||
"expected_output": "The response treats binding all interfaces as a scoped exposure change: inspect host, port, strictPort, proxy, firewall/network scope, and whether development endpoints or upstream targets become reachable. It proposes the narrowest approved host and verifies access from the intended device without exposing credentials or assuming preview is production-safe.",
|
||||
"assertions": [
|
||||
"Binding all interfaces is identified as an exposure and network-scope change",
|
||||
"Host, port, proxy, and network controls are inspected before changing them",
|
||||
"The response chooses the narrowest approved access and verifies the intended device",
|
||||
"The response does not expose credentials or call vite preview a production server"
|
||||
],
|
||||
"case_set": "release"
|
||||
},
|
||||
{
|
||||
"id": "browser-and-accessibility-boundary",
|
||||
"prompt": "We changed vite.config.ts and want to claim the app still works and remains accessible. Which checks belong in the Vite workflow and which skills should handle the rest?",
|
||||
"expected_output": "The response runs config validation and a production build, inspects output paths, and uses Vite preview for production-like serving. It routes browser user-flow assertions to Playwright and WCAG or semantic accessibility review to web-accessibility, while routing UI architecture to frontend-engineering and CI or hosting topology to platform-engineering.",
|
||||
"assertions": [
|
||||
"The Vite workflow includes config/build and output-path verification",
|
||||
"Browser user-flow claims are routed to Playwright",
|
||||
"Accessibility claims are routed to web-accessibility",
|
||||
"UI architecture and CI/hosting concerns are routed to frontend-engineering and platform-engineering"
|
||||
],
|
||||
"case_set": "dev"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# Vite Builds And Deployment
|
||||
|
||||
## Build diagnosis
|
||||
|
||||
Start with the first actionable error from the project's declared build script. Record Node, package-manager, Vite, framework-plugin, and lockfile evidence before changing dependencies. Typical layers are: config loading, dependency resolution, plugin transform, TypeScript/type checking, asset URL generation, chunking, and output writing.
|
||||
|
||||
Do not fix a missing module by adding a broad alias or deleting the lockfile. Check whether the import is misspelled, whether the dependency is declared in the correct workspace, whether an optional peer is missing, and whether the package manager install is reproducible. Only reinstall or clear a cache after confirming the cache is generated and the target is safe to remove.
|
||||
|
||||
## Output contract
|
||||
|
||||
`build.outDir` is relative to the Vite root unless configured otherwise. Confirm that deployment publishes that exact directory and does not accidentally publish source or a stale prior build. Keep generated output out of source control unless the host explicitly requires it.
|
||||
|
||||
`base` rewrites asset URLs. A root-relative build can work locally and fail under `/docs/` or a reverse proxy prefix. Verify HTML references, CSS URLs, dynamic imports, and client-side router fallback under the real prefix. Static hosting needs an SPA fallback for routes that are not physical files; alternatively use a routing strategy compatible with the host.
|
||||
|
||||
Treat build warnings as evidence, not noise. Review large chunks, dynamic-import boundaries, circular dependencies, and mixed ESM/CJS warnings. Performance budgets and UI architecture route to [frontend-engineering](../../frontend-engineering/SKILL.md); CI and hosting topology route to [platform-engineering](../../platform-engineering/SKILL.md).
|
||||
|
||||
## Safe verification sequence
|
||||
|
||||
1. Run typecheck/lint where declared.
|
||||
2. Run the package manager's build script with a bounded timeout.
|
||||
3. List output files and inspect generated HTML for expected asset paths.
|
||||
4. Start preview only on the intended interface and port.
|
||||
5. Check the deployed or previewed root and representative deep route with [Playwright](../../playwright/SKILL.md).
|
||||
6. Run accessibility checks through [web-accessibility](../../web-accessibility/SKILL.md) when the task makes accessibility claims.
|
||||
|
||||
A successful build proves compilation and output generation, not correct routing, browser behavior, or accessibility.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Vite Configuration And Environments
|
||||
|
||||
## Inspect the loading model
|
||||
|
||||
Vite loads `vite.config.js`, `vite.config.ts`, or an equivalent config from the project root unless the command supplies another root/config. Read the package script and config together: a monorepo may set `root`, and a config may be asynchronous or mode-aware.
|
||||
|
||||
Common precedence for variables loaded by Vite is mode-specific local, mode-specific, general local, then general env files, with existing process environment taking precedence. Confirm the exact behavior against the installed Vite version before relying on subtle precedence. `.env*` files are loaded at startup, so restart the dev server after edits.
|
||||
|
||||
Only variables with the configured public prefix (normally `VITE_`) are exposed to client code through `import.meta.env`. This is an exposure boundary, not a secret store. Keep API keys, passwords, signing material, and internal credentials server-side. Do not print env values in diagnostics or commit `.env.local`.
|
||||
|
||||
## Config review checklist
|
||||
|
||||
- `base` matches the URL prefix where static files are served; use `/` for domain-root hosting and a repository path only when hosting requires it.
|
||||
- `root` and `publicDir` point at intended directories; public files are copied as-is and should not contain secrets.
|
||||
- Aliases resolve consistently in Vite, TypeScript, tests, and the editor; prefer absolute filesystem paths in config.
|
||||
- Framework plugins match the framework and installed Vite major; inspect plugin peer dependencies before upgrading.
|
||||
- `define` contains only deliberate compile-time constants. Never interpolate untrusted or secret process values into it.
|
||||
- `server.proxy` is development-only unless the deployment has an equivalent reverse proxy; document target and path rewriting.
|
||||
- `resolve.dedupe` and dependency optimization settings are added only for a demonstrated duplicate or prebundle problem.
|
||||
|
||||
## Modes and scripts
|
||||
|
||||
Keep mode selection explicit (`vite --mode staging`, `vite build --mode production`) and ensure the build script's mode matches the deployment contract. Avoid assuming `NODE_ENV` selects a Vite mode. Test required variables by name and presence, not by logging their values.
|
||||
|
||||
For SSR or library mode, use the project's framework and package contract: client-only assumptions about `import.meta.env`, HTML entry files, and `outDir` may not apply. A library build has different externalization and output expectations than an application build.
|
||||
|
||||
## Change and verify
|
||||
|
||||
Make one config change at a time. Run the project's typecheck/lint if available, then a production build. Inspect the generated HTML and asset references under `outDir`; if `base` is non-root, test a deep link and an asset URL at that prefix. Route browser-level verification to [Playwright](../../playwright/SKILL.md) and accessibility verification to [web-accessibility](../../web-accessibility/SKILL.md).
|
||||
@@ -0,0 +1,21 @@
|
||||
# Vite Dev Server And Diagnostics
|
||||
|
||||
## Dev versus preview
|
||||
|
||||
`vite` serves the source graph with hot module replacement and development middleware. `vite preview` serves the already-built output and is useful for checking production-like asset paths; it is not a production server. Read scripts and config before invoking either.
|
||||
|
||||
Inspect `server.host`, `server.port`, `server.strictPort`, `server.open`, `server.proxy`, and `preview` settings. Binding to localhost limits access to the local machine. Binding to all interfaces can expose source, proxy targets, or development endpoints to the LAN; do so only with an explicit scope and network review. Never treat `--host 0.0.0.0` as a harmless default.
|
||||
|
||||
## Diagnostic order
|
||||
|
||||
1. Run `scripts/vite-doctor --project PATH --json` and record tool availability without printing variable values.
|
||||
2. Read `package.json`, lockfile, config, and workspace boundaries.
|
||||
3. Reproduce with the smallest declared command and a bounded timeout.
|
||||
4. Classify the failure as config, dependency, plugin transform, server bind/proxy, browser runtime, or deployment routing.
|
||||
5. Change one layer, rerun, and preserve the first useful error.
|
||||
|
||||
For proxy failures, verify the browser request URL, configured rewrite, target reachability, and CORS/auth expectations separately. A dev proxy can hide a production CORS or reverse-proxy issue. For HMR failures, inspect websocket URL, host/port, proxy upgrades, and browser console; do not immediately disable HMR.
|
||||
|
||||
## Script boundary
|
||||
|
||||
The bundled doctor is read-only and bounded. It reports Node and package-manager version commands, installed Vite package metadata, config filenames, package-manager lockfiles, and environment variable names (not values). It does not install packages, start servers, read `.env` contents, or modify the project. Use it before any potentially mutating command.
|
||||
@@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPT = Path(__file__).with_name("vite-doctor")
|
||||
|
||||
|
||||
class ViteDoctorTest(unittest.TestCase):
|
||||
def run_doctor(self, project: Path, *extra: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
[str(SCRIPT), "--project", str(project), "--json", *extra],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
def test_reports_lock_config_and_names_without_env_values(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
project = Path(directory)
|
||||
(project / "package.json").write_text(
|
||||
json.dumps({"devDependencies": {"vite": "^6.0.0"}}), encoding="utf-8"
|
||||
)
|
||||
(project / "pnpm-lock.yaml").write_text("lockfileVersion: 9\n", encoding="utf-8")
|
||||
(project / "vite.config.ts").write_text("export default {}\n", encoding="utf-8")
|
||||
(project / ".env.local").write_text("VITE_PUBLIC=do-not-print\nSECRET=never-print\n", encoding="utf-8")
|
||||
result = self.run_doctor(project)
|
||||
self.assertEqual(0, result.returncode)
|
||||
payload = json.loads(result.stdout)
|
||||
self.assertEqual("pnpm", payload["package_manager"]["name"])
|
||||
self.assertEqual(["vite.config.ts"], payload["config_files"])
|
||||
self.assertEqual([".env.local"], payload["env_file_names"])
|
||||
self.assertIn("^6.0.0", json.dumps(payload))
|
||||
self.assertNotIn("do-not-print", result.stdout)
|
||||
self.assertNotIn("never-print", result.stdout)
|
||||
|
||||
def test_missing_project_is_bounded_error(self) -> None:
|
||||
result = self.run_doctor(Path("/path/that/does/not/exist"))
|
||||
self.assertEqual(1, result.returncode)
|
||||
self.assertIn("not a directory", result.stderr)
|
||||
|
||||
def test_invalid_timeout_is_usage_error(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
result = self.run_doctor(Path(directory), "--timeout", "0")
|
||||
self.assertEqual(2, result.returncode)
|
||||
self.assertIn("positive", result.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only, bounded diagnostics for a Vite project."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
LOCKFILES = {
|
||||
"package-lock.json": "npm",
|
||||
"pnpm-lock.yaml": "pnpm",
|
||||
"yarn.lock": "yarn",
|
||||
"bun.lock": "bun",
|
||||
"bun.lockb": "bun",
|
||||
}
|
||||
MANAGERS = {
|
||||
"npm": ["npm", "--version"],
|
||||
"pnpm": ["pnpm", "--version"],
|
||||
"yarn": ["yarn", "--version"],
|
||||
"bun": ["bun", "--version"],
|
||||
}
|
||||
|
||||
|
||||
def bounded_version(command: list[str], timeout: float) -> dict[str, object]:
|
||||
executable = shutil.which(command[0])
|
||||
result: dict[str, object] = {"available": executable is not None}
|
||||
if executable is None:
|
||||
return result
|
||||
try:
|
||||
completed = subprocess.run(
|
||||
command, capture_output=True, text=True, timeout=timeout, check=False
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
result["error"] = "timeout"
|
||||
return result
|
||||
value = (completed.stdout or completed.stderr).strip().splitlines()
|
||||
if value:
|
||||
result["version"] = value[0][:200]
|
||||
result["exit_code"] = completed.returncode
|
||||
return result
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--project", default=".", help="Vite project directory")
|
||||
parser.add_argument("--timeout", type=float, default=3.0, help="Version probe timeout")
|
||||
parser.add_argument("--json", action="store_true", help="Emit JSON (default)")
|
||||
args = parser.parse_args()
|
||||
if args.timeout <= 0:
|
||||
parser.error("--timeout must be positive")
|
||||
project = Path(args.project).expanduser().resolve()
|
||||
if not project.is_dir():
|
||||
print(json.dumps({"error": f"project is not a directory: {project}"}), file=sys.stderr)
|
||||
return 1
|
||||
|
||||
package_file = project / "package.json"
|
||||
package_data: dict[str, object] = {}
|
||||
errors: list[str] = []
|
||||
if package_file.is_file():
|
||||
try:
|
||||
loaded = json.loads(package_file.read_text(encoding="utf-8"))
|
||||
if isinstance(loaded, dict):
|
||||
package_data = loaded
|
||||
else:
|
||||
errors.append("package.json is not an object")
|
||||
except (OSError, json.JSONDecodeError) as exc:
|
||||
errors.append(f"cannot read package.json: {exc}")
|
||||
else:
|
||||
errors.append("package.json not found")
|
||||
|
||||
lockfiles = [name for name in LOCKFILES if (project / name).is_file()]
|
||||
manager_name = LOCKFILES[lockfiles[0]] if lockfiles else None
|
||||
configs = sorted(
|
||||
path.name for path in project.iterdir()
|
||||
if path.is_file() and path.name.startswith("vite.config")
|
||||
)
|
||||
dependencies: dict[str, object] = {}
|
||||
for section in ("dependencies", "devDependencies", "optionalDependencies"):
|
||||
values = package_data.get(section)
|
||||
if isinstance(values, dict) and "vite" in values:
|
||||
dependencies[section] = values["vite"]
|
||||
|
||||
payload = {
|
||||
"project": str(project),
|
||||
"package_json": package_file.is_file(),
|
||||
"package_manager": {
|
||||
"name": manager_name,
|
||||
"lockfiles": lockfiles,
|
||||
"version": bounded_version(MANAGERS[manager_name], args.timeout)
|
||||
if manager_name else None,
|
||||
},
|
||||
"node": bounded_version(["node", "--version"], args.timeout),
|
||||
"vite_dependency": dependencies,
|
||||
"vite_installed": (project / "node_modules" / "vite" / "package.json").is_file(),
|
||||
"config_files": configs,
|
||||
"env_file_names": sorted(
|
||||
path.name for path in project.iterdir()
|
||||
if path.is_file() and path.name.startswith(".env")
|
||||
),
|
||||
"errors": errors,
|
||||
}
|
||||
print(json.dumps(payload, indent=2, sort_keys=True))
|
||||
return 1 if errors else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -59,4 +59,4 @@ Stop when each acceptance criterion has direct evidence or a recorded failed, bl
|
||||
|
||||
- For Hugo template architecture, theme-wide layout, or CMS rendering concerns, use [hugo-theme](../hugo-theme/SKILL.md) and its [design/accessibility reference](../hugo-theme/references/design-accessibility.md).
|
||||
- For evidence gathering, scope decisions, or user-facing behavior outside accessibility, use [product-discovery](../product-discovery/SKILL.md), [product-methodology](../product-methodology/SKILL.md), or [product-design-and-ux](../product-design-and-ux/SKILL.md). Keep this skill responsible for accessibility interaction and conformance depth.
|
||||
- For framework or library APIs, consult the current official documentation after defining this skill's semantic and interaction contract.
|
||||
- For framework or library APIs, consult the current official documentation after defining this skill's semantic and interaction contract. React implementation details route to [react](../react/SKILL.md); Vite configuration routes to [vite](../vite/SKILL.md).
|
||||
|
||||
Reference in New Issue
Block a user