add-feature
Skill261 starsChanged 12 days agoApache-2.0View on GitHub
Add a new UI feature to the nvcf-ui app — folder structure, routing, data loading, lazy-loading, testing, and completion checklist. Use when creating a new feature folder, adding a page or view, wiring routes, building a new screen, or deciding whether to extend an existing feature vs create a new one. Also use when the user asks to build something new in the UI, even if they don't say "feature" explicitly.
26 other projects use a version of this.
Adopted by
Most recently taken up by
- subhashkhileri/agntreetheir own version, first seen Oct 25, 2026
- WhatIfWeDigDeeper/claude-code-courseratheir own version, first seen Oct 20, 2026
- NumericalEarth/Breeze.jltheir own version, first seen Oct 17, 2026
- CliMA/Oceananigans.jltheir own version, first seen Oct 17, 2026
- PopKult/claude-skillstheir own version, first seen Oct 15, 2026
- AlaaMousa05/billtheir own version, first seen Oct 15, 2026
Other versions26 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 26
- fullstackhero/dotnet-starter-kit★ 6.9ksame name
- JamieMason/syncpack★ 2.1ksame name
- CliMA/Oceananigans.jl★ 1.4ksame name
- OpusGameLabs/game-creator★ 360same name
- microsoft/SqlScriptDOM★ 284same name
- NumericalEarth/Breeze.jl★ 90same name
- nikandr-surkov/ai-saas-starter★ 16same name
- Azure/azure-functions-agents-runtime★ 13same name
- aiqadam/qadam-flow★ 5same name
- subhashkhileri/agntree★ 5same name
16 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository133 other files it gives its agents.
- AGENTS.mdAGENTS.md
- ai-tooling/AGENTS.mdAGENTS.md
- deploy/helm/cassandra/AGENTS.mdAGENTS.md
- deploy/helm/cert-manager/AGENTS.mdAGENTS.md
- deploy/helm/cloud-functions/AGENTS.mdAGENTS.md
- deploy/helm/cloud-tasks/AGENTS.mdAGENTS.md
- deploy/helm/encrypted-secret-store/AGENTS.mdAGENTS.md
- deploy/helm/icms/AGENTS.mdAGENTS.md
- deploy/helm/llm-request-router/AGENTS.mdAGENTS.md
- deploy/helm/nats/AGENTS.mdAGENTS.md
- deploy/helm/notary/AGENTS.mdAGENTS.md
- deploy/helm/nvcf-pki/AGENTS.mdAGENTS.md
- deploy/helm/openbao/AGENTS.mdAGENTS.md
- deploy/helm/vanity-gateway/AGENTS.mdAGENTS.md
- deploy/releases/AGENTS.mdAGENTS.md
- deploy/stacks/AGENTS.mdAGENTS.md
- deploy/stacks/observability/AGENTS.mdAGENTS.md
- deploy/stacks/stargate-dev/AGENTS.mdAGENTS.md
- deploy/stacks/stargate-dev/benchmark/AGENTS.mdAGENTS.md
- docs/AGENTS.mdAGENTS.md
- docs/overview/samples/scripts/AGENTS.mdAGENTS.md
- examples/AGENTS.mdAGENTS.md
- infra/cassandra/AGENTS.mdAGENTS.md
- infra/openbao/AGENTS.mdAGENTS.md
- infra/openbao/plugins/vault-plugin-secrets-jwt/AGENTS.mdAGENTS.md
- infra/openbao/tests/AGENTS.mdAGENTS.md
- migrations/cassandra/AGENTS.mdAGENTS.md
- migrations/openbao/AGENTS.mdAGENTS.md
- src/compute-plane-services/byoo-otel-collector/AGENTS.mdAGENTS.md
- src/compute-plane-services/ess-agent/AGENTS.mdAGENTS.md
- src/compute-plane-services/image-credential-helper/AGENTS.mdAGENTS.md
- src/compute-plane-services/nvca/AGENTS.mdAGENTS.md
- src/compute-plane-services/nvsnap/docs/AGENTS.mdAGENTS.md
- src/compute-plane-services/nvstor/AGENTS.mdAGENTS.md
- src/compute-plane-services/request-trace-uploader/AGENTS.mdAGENTS.md
- src/control-plane-services/admin-token-issuer-proxy/AGENTS.mdAGENTS.md
- src/control-plane-services/api-keys/AGENTS.mdAGENTS.md
- src/control-plane-services/cloud-functions/AGENTS.mdAGENTS.md
- src/control-plane-services/cloud-tasks/AGENTS.mdAGENTS.md
- src/control-plane-services/encrypted-secret-store/AGENTS.mdAGENTS.md
- src/control-plane-services/function-autoscaler/AGENTS.mdAGENTS.md
- src/control-plane-services/function-autoscaler/local_env/AGENTS.mdAGENTS.md
- src/control-plane-services/instance-cluster-management/AGENTS.mdAGENTS.md
- src/control-plane-services/nats-auth-callout/AGENTS.mdAGENTS.md
- src/control-plane-services/notary/AGENTS.mdAGENTS.md
- src/invocation-plane-services/grpc-proxy/AGENTS.mdAGENTS.md
- src/invocation-plane-services/http-invocation/AGENTS.mdAGENTS.md
- src/invocation-plane-services/llm-api-gateway/AGENTS.mdAGENTS.md
- src/invocation-plane-services/ratelimiter/AGENTS.mdAGENTS.md
- src/invocation-plane-services/vanity-gateway/AGENTS.mdAGENTS.md
- src/libraries/go/lib/AGENTS.mdAGENTS.md
- src/libraries/go/worker/AGENTS.mdAGENTS.md
- src/libraries/java/nv-boot-parent/AGENTS.mdAGENTS.md
- src/libraries/python/nv-cloud-function-helpers/AGENTS.mdAGENTS.md
- src/libraries/rust/nvcf-info/AGENTS.mdAGENTS.md
- src/libraries/rust/stargate/AGENTS.mdAGENTS.md
- src/uis/nvcf-ui/AGENTS.mdAGENTS.md
- src/uis/nvcf-ui/helm/AGENTS.mdAGENTS.md
- tests/bdd/AGENTS.mdAGENTS.md
- tools/AGENTS.mdAGENTS.md
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. 0 are common, 3 are distinctive, and 12 are very specific to this project.
0
Common
Most of the 24 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 27
All source files need Apache 2.0 license headers.
- Very specific: line 49
Not every subfolder is required — add components/, hooks/, types/ only when needed
- Very specific: line 81
Use generated Zod schemas for validateSearch when params map to API query params.
- Very specific: line 104
Use suspense hook variants (useGetWidgetsSuspense) — the loader already ensured data, so these resolve immediately or suspend if cache is …
- Very specific: line 118
Tabbed views: use a layout route with <Outlet />, each tab is a child route with its own loader and lazy-loaded component.
- Distinctive: line 122
Check for existing components/patterns that could be reused or graduated before building new ones
- Very specific: line 123
Create features/<name>/ with the relevant files — a view component and routes.tsx if the feature has routes, or just components//hooks/ if …
- Very specific: line 124
If the feature has routes: define routes in routes.tsx using createRoute with .lazy(), then wire the subtree into router.tsx.
- Distinctive: line 125
Use generated hooks and query options for data fetching
- Very specific: line 126
Add tests for view components and any non-trivial logic.
- Very specific: line 127
Add MSW scenarios in mocks/scenarios/<name>/ for key UI states
- Very specific: line 128
Run task license:add to apply license headers to new files
- Very specific: line 132
Run task ui:lint:fix and fix any errors
- Very specific: line 133
Run task ui:test and verify tests pass
- Distinctive: line 134
If either fails, fix the issues and rerun until clean
“Common” is measured: kept by at least 6 in 10 of the 24 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Adding a UI Feature
For all component selection, layout decisions, and styling — invoke the kaizen-ui skill.
Gotchas
- This project uses code-based routing, not file-based. Do not use
createFileRouteor the TanStack Router Vite plugin — usecreateRouteandcreateLazyRoute. - View components are named by view type (e.g.
WidgetsList,WidgetDetail), never with aPagesuffix. router.tsxis pure composition — it only imports and wires route trees. Do not put route definitions or loaders inrouter.tsx.rootRoute.tsxis separate fromrouter.tsxto avoid circular imports. Layout routes that span multiple features live atsrc/root, not in a feature folder.- Generated hooks, schemas, and mocks live in
ui/src/generated/— never edit these files. If the endpoint you need doesn't have generated hooks, update the appropriate spec inspec/(control-plane-openapi.yaml,nvcf-openapi.yaml, orsis-openapi.yaml) then runtask generate. - All source files need Apache 2.0 license headers. Run
task license:addbefore committing.
When to Create a New Feature Folder
- New domain (new data, new concepts, new API surface) → new feature folder
- Composition of existing domains (e.g. a home page assembling widgets) → new thin feature folder
- Extension of an existing domain (e.g. a "Create Function" page) → new route/component in the existing feature folder
Feature Folder Structure
A feature is a domain boundary, not a route. Each feature is self-contained under ui/src/features/<name>/:
features/<name>/
├── components/ # Smaller building blocks (badges, cards)
├── hooks/ # Feature-scoped hooks
├── types/ # Feature-scoped types
├── routes.tsx # Route definitions, loaders, search validation (optional)
├── <View>.tsx # Route-level view components (PascalCase, named by view type)
└── utils.ts # Feature-scoped helpers (when needed)- Not every subfolder is required — add
components/,hooks/,types/only when needed - A feature may not have routes at all — it may only export hooks and components for other features
- Helpers go inline in the component file by default. Extract to a feature-root file only when shared across multiple files in the same feature
Route Splitting Pattern
Each route is split across two files:
routes.tsx — route definition, search params, loader. In the main bundle.
import { createRoute } from "@tanstack/react-router";
import { appLayoutRoute } from "~/appLayout";
import { queryClient } from "~/lib/queryClient";
import { getGetWidgetsQueryOptions } from "~/generated/api/widgets/widgets";
import { GetWidgetsParams } from "~/generated/model/getWidgetsParams.zod";
const widgetsRoute = createRoute({
getParentRoute: () => appLayoutRoute,
path: "widgets",
validateSearch: GetWidgetsParams.catch({ status: "active" }),
loaderDeps: ({ search }) => search,
loader: ({ deps }) =>
queryClient.ensureQueryData({
...getGetWidgetsQueryOptions(deps),
revalidateIfStale: true,
}),
}).lazy(() => import("./WidgetsList").then((m) => m.WidgetsListRoute));
export const widgetsRouteTree = widgetsRoute;- Use generated Zod schemas for
validateSearchwhen params map to API query params. For UI-only search params, define inline. loaderDepsdeclares which search params the loader depends on — the loader re-runs when these change.ensureQueryDatawithrevalidateIfStale: trueavoids flashing stale content.- For multiple data sources:
ensureQueryData(awaited) for primary data,prefetchQuery(no await) for below-the-fold data.
<View>.tsx — lazy-loaded component, pending, and error states.
import { createLazyRoute } from "@tanstack/react-router";
import { useGetWidgetsSuspense } from "~/generated/api/widgets/widgets";
function WidgetsList() {
const { status } = widgetsRoute.useSearch();
const { data } = useGetWidgetsSuspense({ status });
// render...
}
export const WidgetsListRoute = createLazyRoute("/widgets")({
component: WidgetsList,
pendingComponent: () => <div>Loading...</div>,
});- Use suspense hook variants (
useGetWidgetsSuspense) — the loader already ensured data, so these resolve immediately or suspend if cache is stale. - For prefetched (non-blocking) data, wrap the consumer in a
<Suspense>boundary with a fallback.
Lazy-Loading Rules
- Page routes with view code → always lazy-load via
createLazyRoute - Layout routes that just render
<Outlet />→ keep in main bundle - Components within a page → never lazy-load; already in the route's chunk
Layout Routes
- Single feature → in that feature's
routes.tsx - Multiple features → at
src/root alongsiderootRoute.tsx
Tabbed views: use a layout route with <Outlet />, each tab is a child route with its own loader and lazy-loaded component.
Steps
- Check for existing components/patterns that could be reused or graduated before building new ones
- Create
features/<name>/with the relevant files — a view component androutes.tsxif the feature has routes, or justcomponents//hooks/if routeless - If the feature has routes: define routes in
routes.tsxusingcreateRoutewith.lazy(), then wire the subtree intorouter.tsx. If it introduces a new top-level route, add aNavItementry inrootRoute.tsx - Use generated hooks and query options for data fetching
- Add tests for view components and any non-trivial logic. Use
renderWithRouterfrom~/testing/renderfor route-level views, standardrenderfor standalone components - Add MSW scenarios in
mocks/scenarios/<name>/for key UI states - Run
task license:addto apply license headers to new files
Validate Before Finishing
- Run
task ui:lint:fixand fix any errors - Run
task ui:testand verify tests pass - If either fails, fix the issues and rerun until clean
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

