@mrciphersmith/keryx 0.2.164 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/cli.js +82540 -50300
- package/dist/core.js +28967 -18937
- package/package.json +2 -2
- package/src/gdgraph/affected-report.ts +141 -0
- package/src/gdgraph/build.ts +170 -23
- package/src/gdgraph/service.ts +6 -0
- package/src/gdgraph/staleness.ts +253 -45
- package/src/gdskills/bundled/agents/codebase-navigator.md +55 -0
- package/src/gdskills/bundled/agents/design-advisor.md +64 -0
- package/src/gdskills/bundled/agents/docs-maintainer.md +56 -0
- package/src/gdskills/bundled/agents/end-to-end-tester.md +56 -0
- package/src/gdskills/bundled/agents/error-path-auditor.md +57 -0
- package/src/gdskills/bundled/agents/go-build-fixer.md +52 -0
- package/src/gdskills/bundled/agents/go-code-auditor.md +49 -0
- package/src/gdskills/bundled/agents/performance-auditor.md +63 -0
- package/src/gdskills/bundled/agents/python-build-fixer.md +52 -0
- package/src/gdskills/bundled/agents/python-code-auditor.md +49 -0
- package/src/gdskills/bundled/agents/refactoring-steward.md +61 -0
- package/src/gdskills/bundled/agents/security-auditor.md +62 -0
- package/src/gdskills/bundled/agents/test-first-driver.md +61 -0
- package/src/gdskills/bundled/agents/work-planner.md +62 -0
- package/src/gdskills/bundled/install-manifest.json +797 -0
- package/src/gdskills/bundled/rules/core/model-selection.mdc +51 -0
- package/src/gdskills/bundled/rules/core/skill-lifecycle.mdc +29 -1
- package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-rules/SKILL.md +267 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +26 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +75 -247
- package/src/gdskills/bundled/skills/review/review-orchestrator/output-contract.schema.json +19 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +10 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +5 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-backend.md +50 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md +52 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/review-report.md +143 -0
- package/src/gdskills/bundled/stacks/angular/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/angular/governance/eval.json +1751 -0
- package/src/gdskills/bundled/stacks/angular/governance/scout.json +32 -0
- package/src/gdskills/bundled/stacks/angular/pack.json +55 -0
- package/src/gdskills/bundled/stacks/angular/rules/coding-style.mdc +82 -0
- package/src/gdskills/bundled/stacks/angular/rules/patterns.mdc +84 -0
- package/src/gdskills/bundled/stacks/angular/rules/security.mdc +70 -0
- package/src/gdskills/bundled/stacks/angular/rules/testing.mdc +73 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-build-fix/SKILL.md +127 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-code-review/SKILL.md +98 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-code-review/evals.json +73 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-implementation/SKILL.md +112 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-testing/SKILL.md +102 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-testing/evals.json +71 -0
- package/src/gdskills/bundled/stacks/go/agent-refs.json +3 -0
- package/src/gdskills/bundled/stacks/go/governance/eval.json +1745 -0
- package/src/gdskills/bundled/stacks/go/governance/scout.json +31 -0
- package/src/gdskills/bundled/stacks/go/pack.json +41 -0
- package/src/gdskills/bundled/stacks/go/rules/coding-style.mdc +85 -0
- package/src/gdskills/bundled/stacks/go/rules/patterns.mdc +65 -0
- package/src/gdskills/bundled/stacks/go/rules/security.mdc +73 -0
- package/src/gdskills/bundled/stacks/go/rules/testing.mdc +68 -0
- package/src/gdskills/bundled/stacks/go/skills/go-build-fix/SKILL.md +138 -0
- package/src/gdskills/bundled/stacks/go/skills/go-build-fix/evals.json +75 -0
- package/src/gdskills/bundled/stacks/go/skills/go-code-review/SKILL.md +121 -0
- package/src/gdskills/bundled/stacks/go/skills/go-code-review/evals.json +72 -0
- package/src/gdskills/bundled/stacks/go/skills/go-implementation/SKILL.md +122 -0
- package/src/gdskills/bundled/stacks/go/skills/go-implementation/evals.json +76 -0
- package/src/gdskills/bundled/stacks/go/skills/go-testing/SKILL.md +126 -0
- package/src/gdskills/bundled/stacks/go/skills/go-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/mobx/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/mobx/governance/eval.json +904 -0
- package/src/gdskills/bundled/stacks/mobx/governance/scout.json +18 -0
- package/src/gdskills/bundled/stacks/mobx/pack.json +28 -0
- package/src/gdskills/bundled/stacks/mobx/rules/coding-style.mdc +91 -0
- package/src/gdskills/bundled/stacks/mobx/rules/patterns.mdc +122 -0
- package/src/gdskills/bundled/stacks/mobx/rules/security.mdc +56 -0
- package/src/gdskills/bundled/stacks/mobx/rules/testing.mdc +63 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-observable-testing/SKILL.md +124 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-observable-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-store-implementation/SKILL.md +149 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-store-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/nestjs/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/nestjs/governance/eval.json +1308 -0
- package/src/gdskills/bundled/stacks/nestjs/governance/scout.json +34 -0
- package/src/gdskills/bundled/stacks/nestjs/pack.json +53 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/coding-style.mdc +70 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/patterns.mdc +83 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/security.mdc +73 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/testing.mdc +69 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-build-fix/SKILL.md +157 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-build-fix/evals.json +70 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-implementation/SKILL.md +129 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-implementation/evals.json +71 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-testing/SKILL.md +143 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-testing/evals.json +69 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/governance/eval.json +2413 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/governance/scout.json +42 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/pack.json +42 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/coding-style.mdc +69 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/patterns.mdc +88 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/security.mdc +72 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/testing.mdc +64 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-build-fix/SKILL.md +147 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-build-fix/evals.json +75 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-code-review/SKILL.md +118 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-code-review/evals.json +76 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-implementation/SKILL.md +135 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-implementation/evals.json +78 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-testing/SKILL.md +116 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-testing/evals.json +75 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-upgrade-migration/SKILL.md +134 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-upgrade-migration/evals.json +76 -0
- package/src/gdskills/bundled/stacks/python/agent-refs.json +3 -0
- package/src/gdskills/bundled/stacks/python/governance/eval.json +1758 -0
- package/src/gdskills/bundled/stacks/python/governance/scout.json +34 -0
- package/src/gdskills/bundled/stacks/python/pack.json +41 -0
- package/src/gdskills/bundled/stacks/python/rules/coding-style.mdc +63 -0
- package/src/gdskills/bundled/stacks/python/rules/patterns.mdc +88 -0
- package/src/gdskills/bundled/stacks/python/rules/security.mdc +84 -0
- package/src/gdskills/bundled/stacks/python/rules/testing.mdc +77 -0
- package/src/gdskills/bundled/stacks/python/skills/python-build-fix/SKILL.md +144 -0
- package/src/gdskills/bundled/stacks/python/skills/python-build-fix/evals.json +74 -0
- package/src/gdskills/bundled/stacks/python/skills/python-code-review/SKILL.md +155 -0
- package/src/gdskills/bundled/stacks/python/skills/python-code-review/evals.json +72 -0
- package/src/gdskills/bundled/stacks/python/skills/python-implementation/SKILL.md +143 -0
- package/src/gdskills/bundled/stacks/python/skills/python-implementation/evals.json +78 -0
- package/src/gdskills/bundled/stacks/python/skills/python-testing/SKILL.md +132 -0
- package/src/gdskills/bundled/stacks/python/skills/python-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/react/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/react/governance/eval.json +2188 -0
- package/src/gdskills/bundled/stacks/react/governance/scout.json +40 -0
- package/src/gdskills/bundled/stacks/react/pack.json +42 -0
- package/src/gdskills/bundled/stacks/react/rules/coding-style.mdc +58 -0
- package/src/gdskills/bundled/stacks/react/rules/patterns.mdc +79 -0
- package/src/gdskills/bundled/stacks/react/rules/security.mdc +70 -0
- package/src/gdskills/bundled/stacks/react/rules/testing.mdc +60 -0
- package/src/gdskills/bundled/stacks/react/skills/react-build-fix/SKILL.md +139 -0
- package/src/gdskills/bundled/stacks/react/skills/react-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/react/skills/react-code-review/SKILL.md +148 -0
- package/src/gdskills/bundled/stacks/react/skills/react-code-review/evals.json +74 -0
- package/src/gdskills/bundled/stacks/react/skills/react-implementation/SKILL.md +140 -0
- package/src/gdskills/bundled/stacks/react/skills/react-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/react/skills/react-testing/SKILL.md +142 -0
- package/src/gdskills/bundled/stacks/react/skills/react-testing/evals.json +83 -0
- package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/SKILL.md +155 -0
- package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/evals.json +74 -0
- package/src/gdskills/bundled/stacks/ts-js-node/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/ts-js-node/governance/eval.json +2155 -0
- package/src/gdskills/bundled/stacks/ts-js-node/governance/scout.json +40 -0
- package/src/gdskills/bundled/stacks/ts-js-node/pack.json +41 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/coding-style.mdc +73 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/patterns.mdc +61 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/security.mdc +71 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/testing.mdc +63 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/SKILL.md +137 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/evals.json +73 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/SKILL.md +124 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/evals.json +74 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/SKILL.md +152 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/evals.json +71 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/SKILL.md +127 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/evals.json +72 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/SKILL.md +134 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/evals.json +70 -0
- package/src/gdskills/bundled/stacks/vue/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/vue/governance/eval.json +2215 -0
- package/src/gdskills/bundled/stacks/vue/governance/scout.json +42 -0
- package/src/gdskills/bundled/stacks/vue/pack.json +42 -0
- package/src/gdskills/bundled/stacks/vue/rules/coding-style.mdc +73 -0
- package/src/gdskills/bundled/stacks/vue/rules/patterns.mdc +84 -0
- package/src/gdskills/bundled/stacks/vue/rules/security.mdc +60 -0
- package/src/gdskills/bundled/stacks/vue/rules/testing.mdc +69 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-build-fix/SKILL.md +137 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-code-review/SKILL.md +120 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-code-review/evals.json +71 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-implementation/SKILL.md +122 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-implementation/evals.json +72 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-testing/SKILL.md +115 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-testing/evals.json +72 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue2-to-vue3-migration/SKILL.md +135 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue2-to-vue3-migration/evals.json +71 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "Use when implementing a new page, route, or data-fetching feature in a Next.js App Router or Nuxt 3+ project: choosing Server vs. Client Components ('use client' placement), a Nuxt composable/page fetching data with useFetch/useAsyncData, a Server Action ('use server') or Nuxt server/api route, or a route's rendering mode (static/ISR/revalidate vs. Nuxt's ssr/routeRules). Not for plain React component logic with no meta-framework routing/data concern (use react-implementation), plain Vue SFC logic outside Nuxt's routing/server layer (use vue-implementation), or fixing an existing build/type error (use nextjs-nuxt-build-fix).",
|
|
4
|
+
"decision": "use",
|
|
5
|
+
"topMatch": "nextjs-nuxt/nextjs-nuxt-testing",
|
|
6
|
+
"recordedAt": "2026-09-25T06:43:38.521Z",
|
|
7
|
+
"skillName": "nextjs-nuxt-implementation",
|
|
8
|
+
"justification": "extends react-implementation/vue-implementation coverage to Next.js App Router / Nuxt 3 routing+data-fetching specifically; existing react/vue implementation skills explicitly excluded via disclaimer, no meta-framework skill exists"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "Use when writing or fixing tests for a Next.js App Router page/Server Action or a Nuxt page/composable/server route: testing a Server Component's rendered output, a Client Component's interactivity with React Testing Library, a Nuxt composable that calls useFetch/useAsyncData with @nuxt/test-utils' mountSuspended, or a server/api handler's auth and validation paths. Not for plain React/Vue component unit tests with no meta-framework routing, SSR, or server-route concern (use react-testing/vue-testing), and not for implementing the feature under test (use nextjs-nuxt-implementation).",
|
|
12
|
+
"decision": "use",
|
|
13
|
+
"topMatch": "nextjs-nuxt/nextjs-nuxt-implementation",
|
|
14
|
+
"recordedAt": "2026-09-25T06:43:51.459Z",
|
|
15
|
+
"skillName": "nextjs-nuxt-testing",
|
|
16
|
+
"justification": "mutual same-pack overlap with nextjs-nuxt-implementation (both describe the same App Router/Nuxt surface, scores 0.594/0.621); accepted per flow 318 journal as a lexical-scorer limitation applied to two genuinely distinct skill categories (implement vs. test), not a duplicate skill"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "Use when reviewing a diff that touches Next.js App Router files ('use client'/'use server' directives, Route Handlers, revalidatePath/revalidateTag) or Nuxt files (composables, server/api routes, nuxt.config.ts routeRules/runtimeConfig) for meta-framework-specific risk: a misplaced Server/Client boundary, a composable called outside setup context, a hydration-mismatch-prone render, a rendering-mode choice that doesn't match the data's actual freshness need, or an unauthenticated Server Action/server route. Does not edit code. Not for general React/Vue component review with no App Router/Nuxt-specific concern (use review-frontend or a react/vue pack review skill), and not for NestJS backend review (use review-backend).",
|
|
20
|
+
"decision": "fork",
|
|
21
|
+
"topMatch": "nextjs-nuxt/nextjs-nuxt-implementation",
|
|
22
|
+
"recordedAt": "2026-09-25T06:43:59.476Z",
|
|
23
|
+
"skillName": "nextjs-nuxt-code-review",
|
|
24
|
+
"justification": "shares review vocabulary with review-frontend/review-backend/vue/react review skills but scoped specifically to App Router / Nuxt meta-framework files (Server Actions, routeRules, composables) that no existing review skill covers"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "Use when resolving a Next.js build/type error ('use client'/'use server' boundary violation, a Server Component importing a client-only hook, an invalid Route Handler export) or a Nuxt build/type error (an auto-imported composable/component that fails to resolve, a nuxi typecheck failure, a hydration-mismatch warning) blocking `next build` or `nuxi build`. Applies the smallest root-cause fix and never silences it with ssr: false, suppressHydrationWarning, or a widened tsconfig. Not for generic tsc/ESM module-resolution errors with no meta-framework cause (use nodejs-build-fix), and not for implementing a new feature (use nextjs-nuxt-implementation).",
|
|
28
|
+
"decision": "fork",
|
|
29
|
+
"topMatch": "ts-js-node/nodejs-build-fix",
|
|
30
|
+
"recordedAt": "2026-09-25T06:44:07.524Z",
|
|
31
|
+
"skillName": "nextjs-nuxt-build-fix",
|
|
32
|
+
"justification": "shares generic build-fix vocabulary with nodejs-build-fix but is scoped to Next.js/Nuxt-specific compile failures (Server/Client boundary violations, composable auto-import resolution, nuxi typecheck) that nodejs-build-fix's own disclaimer explicitly excludes"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"query": "Use when migrating a Next.js project from the Pages Router to the App Router, upgrading a Next.js major version, or migrating a Nuxt 2 project to Nuxt 3+ (Options API to Composition API, the Vuex-to-Pinia move, module/plugin API changes). Covers rewriting data-fetching (getServerSideProps/getStaticProps to Server Components and route rendering config; asyncData/fetch to useAsyncData/useFetch), routing conventions, and rendering-mode equivalents between the old and new APIs. Not for a same-version bug fix or new feature (use nextjs-nuxt-implementation/nextjs-nuxt-build-fix), and not for a plain React/Vue version bump with no meta-framework routing change (use react-upgrade-migration or the vue pack's migration skill).",
|
|
36
|
+
"decision": "fork",
|
|
37
|
+
"topMatch": "nextjs-nuxt/nextjs-nuxt-implementation",
|
|
38
|
+
"recordedAt": "2026-09-25T06:44:07.697Z",
|
|
39
|
+
"skillName": "nextjs-nuxt-upgrade-migration",
|
|
40
|
+
"justification": "shares Next.js/Nuxt vocabulary with nextjs-nuxt-implementation but is scoped specifically to version-migration mechanics (Pages->App Router, Vue 2 Options API->Vue 3 Composition API, Vuex->Pinia) that react-upgrade-migration's own disclaimer explicitly excludes for the meta-framework case"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "nextjs-nuxt",
|
|
3
|
+
"family": "framework",
|
|
4
|
+
"extends": ["react", "vue"],
|
|
5
|
+
"modules": ["nextjs-nuxt-rules", "nextjs-nuxt-skills"],
|
|
6
|
+
"detectionMarkers": ["nextjs", "nuxt"],
|
|
7
|
+
"provenance": {
|
|
8
|
+
"origin": "authored",
|
|
9
|
+
"sourceRef": "flow 318, Wave 4 batch 2"
|
|
10
|
+
},
|
|
11
|
+
"stability": "experimental",
|
|
12
|
+
"skills": {
|
|
13
|
+
"implement": ["nextjs-nuxt-implementation"],
|
|
14
|
+
"test": ["nextjs-nuxt-testing"],
|
|
15
|
+
"review": ["nextjs-nuxt-code-review"],
|
|
16
|
+
"build-fix": ["nextjs-nuxt-build-fix"],
|
|
17
|
+
"migrate": ["nextjs-nuxt-upgrade-migration"]
|
|
18
|
+
},
|
|
19
|
+
"agentProfile": {
|
|
20
|
+
"displayName": "Next.js / Nuxt",
|
|
21
|
+
"auditFocus": [
|
|
22
|
+
"a Next.js Server Component importing browser-only APIs, hooks, or event handlers with no 'use client' boundary, or a 'use client' pushed higher up the tree than the leaf that actually needs it",
|
|
23
|
+
"a Nuxt composable (a useX function) called outside a component's setup()/<script setup> context, a plugin, or middleware, where it cannot access Nuxt's injection context",
|
|
24
|
+
"a server-only secret read without the framework's public-var guard (a bare env var reaching the client instead of NEXT_PUBLIC_-prefixed, or Nuxt's private runtimeConfig read from a component instead of its public: block)",
|
|
25
|
+
"a data-fetch that re-runs on every request when the route was clearly meant to be static/ISR (Next's revalidate) or Nuxt's cached/prerendered, or a page marked static that actually needs per-request data",
|
|
26
|
+
"a Server Action ('use server') or Nuxt server route (server/api/**) with no auth/authorization check before it touches data",
|
|
27
|
+
"a component rendering a nondeterministic value (Date.now(), Math.random(), locale-dependent formatting) directly in its render path, which mismatches between server and client hydration"
|
|
28
|
+
],
|
|
29
|
+
"buildCommands": [
|
|
30
|
+
"the project's type-check script (tsc --noEmit for Next.js, or nuxi typecheck for Nuxt)",
|
|
31
|
+
"next build (Next.js) or nuxi build (Nuxt) — read the framework's own build output for prerender, route, and boundary errors, not just exit code",
|
|
32
|
+
"the project's lint script (next lint / eslint-config-next, or @nuxt/eslint-config)",
|
|
33
|
+
"the project's test script (Jest or Vitest with React Testing Library, or Vitest with Vue Test Utils/@nuxt/test-utils)"
|
|
34
|
+
],
|
|
35
|
+
"fixGuardrails": [
|
|
36
|
+
"never move a 'use client' directive up to a shared layout or ancestor component to silence a Server/Client Component boundary error — narrow it to the actual leaf that needs browser APIs, state, or event handlers",
|
|
37
|
+
"never hand-import or re-path a Nuxt auto-imported composable/component to unblock a type or resolution error when the real fix is registering or exporting it correctly (checking nuxt.config.ts's imports/components dirs)",
|
|
38
|
+
"never rename a server-only secret under NEXT_PUBLIC_ or into Nuxt's public runtimeConfig just to make it reachable from client code that shouldn't have it",
|
|
39
|
+
"never delete or skip a failing SSR/hydration test, or wrap a hydration mismatch in suppressHydrationWarning/<ClientOnly>, to reach a green build instead of fixing the nondeterministic render"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.tsx", "**/*.jsx", "**/*.vue"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js / Nuxt coding style
|
|
9
|
+
|
|
10
|
+
Narrows `core-common-rules`' stack-agnostic style rules to the two
|
|
11
|
+
meta-frameworks this pack covers: Next.js (App Router, React) and Nuxt
|
|
12
|
+
(Vue 3). Applies to `.tsx`/`.jsx` (Next.js) and `.vue` (Nuxt) files — a
|
|
13
|
+
project using only one of the two frameworks still gets guidance scoped to
|
|
14
|
+
that framework from the sections below; a monorepo with both gets both.
|
|
15
|
+
|
|
16
|
+
## File and directory naming
|
|
17
|
+
|
|
18
|
+
- Next.js App Router: route segment folders are `kebab-case`
|
|
19
|
+
(`app/order-history/page.tsx`); reserved file names (`page.tsx`,
|
|
20
|
+
`layout.tsx`, `loading.tsx`, `error.tsx`, `route.ts`) stay exactly as the
|
|
21
|
+
framework requires them — do not rename them for house style.
|
|
22
|
+
- Nuxt: page files under `pages/` are `kebab-case` and map to routes by
|
|
23
|
+
file-system convention (`pages/order-history.vue` ->
|
|
24
|
+
`/order-history`); a dynamic segment is `pages/orders/[id].vue`, a
|
|
25
|
+
catch-all `pages/[...slug].vue`. Component files are `PascalCase.vue`.
|
|
26
|
+
- Composables (Nuxt) and custom hooks (Next.js/React) both start with
|
|
27
|
+
`use` (`useOrderTotals.ts`, `useOrderTotals`), one export per file for a
|
|
28
|
+
non-trivial composable/hook.
|
|
29
|
+
|
|
30
|
+
## Component and directive placement
|
|
31
|
+
|
|
32
|
+
- Next.js: every component file is a Server Component by default; add
|
|
33
|
+
`'use client'` as the FIRST line of a file only when that file itself
|
|
34
|
+
needs browser state (`useState`, `useEffect`), event handlers, or a
|
|
35
|
+
browser-only API — not because an ancestor or descendant needs it. Keep
|
|
36
|
+
the directive on the smallest leaf component that actually needs it.
|
|
37
|
+
- Nuxt: use `<script setup lang="ts">` for new single-file components
|
|
38
|
+
instead of the Options API or a bare `<script>` with `defineComponent` —
|
|
39
|
+
it is the current idiomatic form and gives auto-imported
|
|
40
|
+
`ref`/`computed`/`watch` without explicit imports.
|
|
41
|
+
- Type props explicitly: Next.js components take a typed `props` object
|
|
42
|
+
(an interface or inline type, not `any`); Nuxt SFCs declare props with
|
|
43
|
+
`defineProps<{ ... }>()` (the type-only generic form), not the runtime
|
|
44
|
+
object form, for anything beyond a trivial component.
|
|
45
|
+
|
|
46
|
+
## Imports and auto-imports
|
|
47
|
+
|
|
48
|
+
- Nuxt auto-imports composables from `composables/`, components from
|
|
49
|
+
`components/`, and utils from `utils/` — do not hand-import something
|
|
50
|
+
Nuxt already auto-imports (it adds a redundant, easily-stale import
|
|
51
|
+
line); DO explicitly import anything outside those conventional
|
|
52
|
+
directories.
|
|
53
|
+
- Next.js has no auto-import convention — import explicitly, using the
|
|
54
|
+
project's configured path aliases (`@/components/...`) instead of long
|
|
55
|
+
relative chains once the project has one configured.
|
|
56
|
+
|
|
57
|
+
## Formatting and typing
|
|
58
|
+
|
|
59
|
+
- Format with the project's configured formatter (Prettier is standard for
|
|
60
|
+
both ecosystems); do not hand-format around one that is already
|
|
61
|
+
configured.
|
|
62
|
+
- Avoid `any` for props, route params, and fetch responses in either
|
|
63
|
+
framework — type route params from Next.js's generated `PageProps`
|
|
64
|
+
types (or the project's own param type) and Nuxt's `useRoute().params`
|
|
65
|
+
by name, not by casting.
|
|
66
|
+
- Server-only code (`'use server'` files, Nuxt `server/` routes) and
|
|
67
|
+
client-only code should not share a barrel import file that re-exports
|
|
68
|
+
both — that is how a server-only secret or a `node:` import ends up
|
|
69
|
+
bundled into client JavaScript.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.tsx", "**/*.jsx", "**/*.vue"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js / Nuxt patterns
|
|
9
|
+
|
|
10
|
+
Idiomatic meta-framework design for Next.js's App Router and Nuxt 3+ —
|
|
11
|
+
routing conventions, rendering-mode choice, and data fetching, covering
|
|
12
|
+
both where their concerns diverge and where they converge. Narrows
|
|
13
|
+
`core-common-rules`; framework-agnostic design patterns still come from
|
|
14
|
+
there.
|
|
15
|
+
|
|
16
|
+
## Server/client boundary (Next.js) and setup context (Nuxt)
|
|
17
|
+
|
|
18
|
+
- Fetch data in Server Components (no `'use client'`) by default; push
|
|
19
|
+
`'use client'` only to the interactive leaf (a button, a form, a chart
|
|
20
|
+
that needs a browser API) so the rest of the tree stays server-rendered
|
|
21
|
+
and out of the client bundle.
|
|
22
|
+
- Pass data down from a Server Component to a Client Component as plain
|
|
23
|
+
serializable props — a Client Component cannot `await` a server-only
|
|
24
|
+
data call itself; if it needs fresh data after mount, call a Route
|
|
25
|
+
Handler (`app/api/.../route.ts`) or a Server Action, not a re-implemented
|
|
26
|
+
server-only fetch client-side.
|
|
27
|
+
- A Server Action is declared with `'use server'` (file-level or inline in
|
|
28
|
+
an async function) and can be called directly from a form's `action`
|
|
29
|
+
prop or a Client Component's event handler; mutate, then call
|
|
30
|
+
`revalidatePath()`/`revalidateTag()` so the affected route re-renders
|
|
31
|
+
with fresh data in the same round trip — don't hand-roll a client-side
|
|
32
|
+
refetch-after-mutation when a Server Action + revalidate already covers
|
|
33
|
+
it.
|
|
34
|
+
- Nuxt composables (`useX`) must be called synchronously during a
|
|
35
|
+
component's `setup()` (top level of `<script setup>`), a plugin, or
|
|
36
|
+
middleware — never inside an `async` callback, a `setTimeout`, or after
|
|
37
|
+
an `await` inside setup, because Nuxt resolves a composable's injection
|
|
38
|
+
context (route, app, Pinia store) synchronously at call time.
|
|
39
|
+
|
|
40
|
+
## Rendering modes
|
|
41
|
+
|
|
42
|
+
- Next.js: a route is static by default (build-time render, cached);
|
|
43
|
+
reading `cookies()`/`headers()`/a `searchParams` prop, or an uncached
|
|
44
|
+
`fetch`, opts it into dynamic per-request rendering. Use
|
|
45
|
+
`export const revalidate = <seconds>` for ISR when the data is allowed
|
|
46
|
+
to go stale for a bounded window rather than forcing full dynamic
|
|
47
|
+
rendering.
|
|
48
|
+
- Nuxt: `ssr: true` (default) renders on each request; `routeRules` in
|
|
49
|
+
`nuxt.config.ts` set per-route rendering (`{ '/blog/**': { isr: 3600 } }`
|
|
50
|
+
for ISR-like caching, `{ '/app/**': { ssr: false } }` for an SPA-only
|
|
51
|
+
section, `{ '/': { prerender: true } }` for static). Choose the rule per
|
|
52
|
+
route instead of setting `ssr: false` globally when only part of the app
|
|
53
|
+
needs it.
|
|
54
|
+
- Both frameworks: a component that needs data on first paint should fetch
|
|
55
|
+
it where the framework already renders (Server Component / `useFetch`),
|
|
56
|
+
not fetch client-side after an empty shell — that trade-off (an extra
|
|
57
|
+
client round trip, a loading flash) should be a deliberate choice, not
|
|
58
|
+
the default from not knowing the server-fetch path exists.
|
|
59
|
+
|
|
60
|
+
## Data fetching
|
|
61
|
+
|
|
62
|
+
- Next.js: `fetch()` inside a Server Component is deduplicated and cached
|
|
63
|
+
by the framework across a single render pass — prefer it over a
|
|
64
|
+
third-party data-fetching library for simple server-side reads unless
|
|
65
|
+
the project already standardizes on one (e.g. a query library for
|
|
66
|
+
client-side cache/mutation needs).
|
|
67
|
+
- Nuxt: use `useFetch`/`useAsyncData` for data a page needs during SSR
|
|
68
|
+
(they dedupe across server and client and hydrate without a second
|
|
69
|
+
request); a plain `$fetch` call inside `onMounted` only re-fetches
|
|
70
|
+
client-side and loses SSR — use it for a genuinely client-only,
|
|
71
|
+
post-interaction call (e.g. in response to a click), not initial page
|
|
72
|
+
data.
|
|
73
|
+
- Both: key async data explicitly (`useAsyncData('orders', ...)` in Nuxt;
|
|
74
|
+
a stable cache key in whatever client-side query library Next.js code
|
|
75
|
+
uses) — an unkeyed or auto-keyed-by-reference call can silently refetch
|
|
76
|
+
or fail to dedupe across re-renders/navigations.
|
|
77
|
+
|
|
78
|
+
## Anti-patterns
|
|
79
|
+
|
|
80
|
+
- Marking an entire page or layout `'use client'` to fix one interactive
|
|
81
|
+
child, instead of isolating the directive to that child.
|
|
82
|
+
- Reaching for `ssr: false` on a whole Nuxt page to work around a
|
|
83
|
+
hydration mismatch instead of finding the actual nondeterministic
|
|
84
|
+
render source.
|
|
85
|
+
- Storing derived/computed state in a `ref`/`useState` and syncing it with
|
|
86
|
+
an effect/`watch`, instead of computing it inline with `computed()` or
|
|
87
|
+
during render — both frameworks' reactivity systems already handle
|
|
88
|
+
derivation without an effect.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.tsx", "**/*.jsx", "**/*.vue", "**/*.ts"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js / Nuxt security
|
|
9
|
+
|
|
10
|
+
Stack-specific risks for Next.js's App Router and Nuxt's server layer, with
|
|
11
|
+
the safe pattern to use instead of each. Narrows `core-common-rules`;
|
|
12
|
+
generic web risks (XSS, CSRF fundamentals) still come from there — this
|
|
13
|
+
file covers where each framework's own boundary can leak.
|
|
14
|
+
|
|
15
|
+
## Environment variable and secret exposure
|
|
16
|
+
|
|
17
|
+
- Next.js: only a variable prefixed `NEXT_PUBLIC_` is inlined into the
|
|
18
|
+
client bundle; every other `process.env.*` read in a file that ships to
|
|
19
|
+
the client is `undefined` at runtime, which itself is a signal — but the
|
|
20
|
+
real risk is the reverse: never prefix a secret (API key, DB URL, signing
|
|
21
|
+
secret) with `NEXT_PUBLIC_` just to make a client read succeed, and never
|
|
22
|
+
read a non-`NEXT_PUBLIC_` secret from a file that lacks a `'use server'`/
|
|
23
|
+
server-only boundary and could be pulled into a client bundle by an
|
|
24
|
+
import chain.
|
|
25
|
+
- Nuxt: `nuxt.config.ts`'s `runtimeConfig` splits `public` (sent to the
|
|
26
|
+
client) from the top-level/private keys (server-only). Never move a
|
|
27
|
+
secret into the `public` block to reach it from a component — read it
|
|
28
|
+
server-side only (`server/api/*` handlers, or a server-only composable)
|
|
29
|
+
and expose only the derived, non-sensitive result to the client.
|
|
30
|
+
|
|
31
|
+
## Server Actions and server routes
|
|
32
|
+
|
|
33
|
+
- Every Next.js Server Action (`'use server'`) and Nuxt `server/api/**`
|
|
34
|
+
handler is a public HTTP endpoint even though it looks like an internal
|
|
35
|
+
function call — re-check auth/authorization inside the action/handler
|
|
36
|
+
itself; do not rely on the calling component having already checked,
|
|
37
|
+
since the endpoint is reachable directly.
|
|
38
|
+
- Re-validate every argument a Server Action or Nuxt server route receives
|
|
39
|
+
server-side (type, ownership, range) even when the client already
|
|
40
|
+
validated the form — client-side validation is a UX affordance, not a
|
|
41
|
+
security boundary.
|
|
42
|
+
- Nuxt: read cookies/headers via `useRequestEvent()`/`getCookie(event, ...)`
|
|
43
|
+
inside `server/api/**`, not by trusting a value the client sent in the
|
|
44
|
+
request body for something that should be derived from an authenticated
|
|
45
|
+
session.
|
|
46
|
+
|
|
47
|
+
## Rendering and injection
|
|
48
|
+
|
|
49
|
+
- Next.js: `dangerouslySetInnerHTML` with unsanitized user content is an
|
|
50
|
+
XSS vector in a Server Component exactly as much as a Client one —
|
|
51
|
+
server rendering does not sanitize it; run it through a sanitizer (e.g.
|
|
52
|
+
DOMPurify server-side) before it reaches the prop, or avoid raw HTML
|
|
53
|
+
injection entirely.
|
|
54
|
+
- Nuxt/Vue: `v-html` with unsanitized user content is the equivalent risk
|
|
55
|
+
in a `.vue` template — sanitize before binding, never bind raw user
|
|
56
|
+
input directly.
|
|
57
|
+
- Both: a value interpolated into a `<script>` tag, an inline event
|
|
58
|
+
handler string, or a redirect URL built from user input (open-redirect
|
|
59
|
+
risk) needs the same scrutiny as any other untrusted-input sink — encode
|
|
60
|
+
or allowlist, don't string-concatenate.
|
|
61
|
+
|
|
62
|
+
## Route and middleware auth
|
|
63
|
+
|
|
64
|
+
- Next.js: `middleware.ts` runs on the Edge runtime and can check auth
|
|
65
|
+
before a route renders, but it cannot be the ONLY check — a Server
|
|
66
|
+
Component/Route Handler that skips its own auth check because
|
|
67
|
+
"middleware already handles it" breaks the moment middleware's matcher
|
|
68
|
+
config changes; check again where the data is actually read.
|
|
69
|
+
- Nuxt: a route middleware (`defineNuxtRouteMiddleware`) guards
|
|
70
|
+
client-side navigation but does not protect the underlying
|
|
71
|
+
`server/api/**` endpoint — protect the API handler itself, not just the
|
|
72
|
+
page route.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.tsx", "**/*.jsx", "**/*.vue"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js / Nuxt testing
|
|
9
|
+
|
|
10
|
+
Test layout, runner, and mocking conventions for Next.js and Nuxt
|
|
11
|
+
projects. Narrows `core-common-rules`; generic test-writing guidance
|
|
12
|
+
(determinism, one behavior per test) still comes from there.
|
|
13
|
+
|
|
14
|
+
## Layout and runner
|
|
15
|
+
|
|
16
|
+
- Co-locate a component/page test next to what it tests
|
|
17
|
+
(`app/orders/page.test.tsx`, `pages/orders.test.ts` next to
|
|
18
|
+
`orders.vue`, or a project's existing `__tests__`/`tests` convention —
|
|
19
|
+
match what the project already does rather than introducing a second
|
|
20
|
+
layout).
|
|
21
|
+
- Next.js: Jest or Vitest with React Testing Library is standard for
|
|
22
|
+
component/page tests; a Server Component that only renders server-side
|
|
23
|
+
(no interactivity) is usually tested by rendering its resolved output or
|
|
24
|
+
through an integration/e2e test, since RTL's `render()` alone does not
|
|
25
|
+
execute the App Router's server data-fetching lifecycle.
|
|
26
|
+
- Nuxt: Vitest with `@nuxt/test-utils` (`mountSuspended` for a component
|
|
27
|
+
that uses auto-imported composables or Nuxt context) or Vue Test Utils
|
|
28
|
+
directly for a plain, context-free component. Use `@nuxt/test-utils`'s
|
|
29
|
+
`mountSuspended`/`renderSuspended` when the component under test calls
|
|
30
|
+
`useFetch`/`useAsyncData`/a Nuxt composable — a plain Vue Test Utils
|
|
31
|
+
`mount()` has no Nuxt runtime context to resolve those against.
|
|
32
|
+
|
|
33
|
+
## Mocking the network boundary
|
|
34
|
+
|
|
35
|
+
- Mock at the network boundary (MSW, or the project's existing HTTP mock
|
|
36
|
+
layer) for a component/page test that calls `fetch`/`useFetch` — not by
|
|
37
|
+
mocking the framework's data-fetching hook itself, which tests the mock
|
|
38
|
+
instead of the component's actual request/response handling.
|
|
39
|
+
- A Server Action or Nuxt server route under test should be called
|
|
40
|
+
through its real handler with a mocked downstream dependency (database
|
|
41
|
+
client, external API), not have its entire body replaced by a stub —
|
|
42
|
+
the goal is proving the handler's own auth/validation logic runs, not
|
|
43
|
+
just that some function returns the expected shape.
|
|
44
|
+
|
|
45
|
+
## Determinism and fixtures
|
|
46
|
+
|
|
47
|
+
- Freeze or inject time (`vi.setSystemTime`, a clock passed as a
|
|
48
|
+
parameter) for any test touching a component that renders `Date.now()`-
|
|
49
|
+
or locale-dependent output — the same nondeterminism that causes a
|
|
50
|
+
hydration mismatch in the app causes a flaky test in CI.
|
|
51
|
+
- Use fixtures/factories for route params, `searchParams`, and Nuxt route
|
|
52
|
+
objects (`useRoute()` mocked with a realistic shape) instead of
|
|
53
|
+
hand-built partial objects that happen to satisfy today's test but drift
|
|
54
|
+
from the real router's shape.
|
|
55
|
+
|
|
56
|
+
## Coverage expectations
|
|
57
|
+
|
|
58
|
+
- Cover: the interactive/client boundary (event handlers, form
|
|
59
|
+
submission, a Server Action's success and validation-failure paths, a
|
|
60
|
+
Nuxt composable's loading/error/data states), not just the happy-path
|
|
61
|
+
render.
|
|
62
|
+
- Do not chase coverage on generated framework files (`layout.tsx` that
|
|
63
|
+
only renders `{children}`, an empty `error.vue`) — spend test budget on
|
|
64
|
+
logic the project actually wrote.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs-nuxt-build-fix
|
|
3
|
+
description: "Use when resolving a Next.js build/type error ('use client'/'use server' boundary violation, a Server Component importing a client-only hook, an invalid Route Handler export) or a Nuxt build/type error (an auto-imported composable/component that fails to resolve, a nuxi typecheck failure, a hydration-mismatch warning) blocking `next build` or `nuxi build`. Applies the smallest root-cause fix and never silences it with ssr: false, suppressHydrationWarning, or a widened tsconfig. Not for generic tsc/ESM module-resolution errors with no meta-framework cause (use nodejs-build-fix), and not for implementing a new feature (use nextjs-nuxt-implementation)."
|
|
4
|
+
triggers:
|
|
5
|
+
- "fix this use client server component boundary error"
|
|
6
|
+
- "next build fails with a Server Component importing useState"
|
|
7
|
+
- "nuxi typecheck fails on this auto-imported composable"
|
|
8
|
+
- "fix this hydration mismatch warning in Next.js"
|
|
9
|
+
- "route handler export is invalid in this Next.js app router file"
|
|
10
|
+
- "nuxt build can't resolve this composable"
|
|
11
|
+
- "fix this Next.js build error about async component"
|
|
12
|
+
metadata:
|
|
13
|
+
origin: authored
|
|
14
|
+
category: build-fix
|
|
15
|
+
version: "1.0.0"
|
|
16
|
+
compatible_harnesses: "claude,codex,cursor,zed,opencode"
|
|
17
|
+
license: "MIT"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Next.js / Nuxt build-fix
|
|
21
|
+
|
|
22
|
+
Resolve a `next build`/`nuxi build`/`nuxi typecheck` failure caused by a
|
|
23
|
+
meta-framework-specific boundary or resolution error. Applies the
|
|
24
|
+
smallest change that fixes the actual root cause — never a change that
|
|
25
|
+
merely makes the build stop complaining. See `rules/patterns.mdc` for the
|
|
26
|
+
boundary/composable-context rules a correct fix should restore.
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
### Step 1: Reproduce the failure
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Next.js
|
|
34
|
+
npx tsc --noEmit
|
|
35
|
+
npx next build
|
|
36
|
+
|
|
37
|
+
# Nuxt
|
|
38
|
+
npx nuxi typecheck
|
|
39
|
+
npx nuxi build
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Run the project's own `package.json` scripts if they wrap these
|
|
43
|
+
differently. Capture the exact error and file:line before changing
|
|
44
|
+
anything.
|
|
45
|
+
|
|
46
|
+
### Step 2: Classify the failure
|
|
47
|
+
|
|
48
|
+
- **Server/Client boundary error** (Next.js): "You're importing a
|
|
49
|
+
component that needs `useState`/`useEffect`/an event handler. This
|
|
50
|
+
React hook only works in a Client Component" or similar — a Server
|
|
51
|
+
Component (no `'use client'`) imports something that needs the client
|
|
52
|
+
runtime.
|
|
53
|
+
- **Server-only import reaching the client** (Next.js): a build error or
|
|
54
|
+
warning about a Node-only module (`fs`, `node:crypto`) or a
|
|
55
|
+
`'use server'`-only import ending up in a client bundle.
|
|
56
|
+
- **Invalid Route Handler shape** (Next.js): `route.ts` exporting
|
|
57
|
+
something other than the recognized HTTP method functions
|
|
58
|
+
(`GET`/`POST`/etc.), or missing the required async signature.
|
|
59
|
+
- **Auto-import resolution failure** (Nuxt): `nuxi typecheck`/build
|
|
60
|
+
cannot resolve a composable/component that should be auto-imported —
|
|
61
|
+
usually a naming mismatch, wrong directory, or a missing `export`.
|
|
62
|
+
- **Composable-context error** (Nuxt): "must be called within a
|
|
63
|
+
`setup()`" or similar — a composable was invoked outside the
|
|
64
|
+
synchronous setup window.
|
|
65
|
+
- **Hydration mismatch warning**: server-rendered HTML text/attributes
|
|
66
|
+
don't match the client's first render.
|
|
67
|
+
|
|
68
|
+
### Step 3: Find the root cause
|
|
69
|
+
|
|
70
|
+
- Boundary error: find which import in the Server Component actually
|
|
71
|
+
needs the client runtime, and trace whether it belongs in a smaller
|
|
72
|
+
extracted Client Component, or whether the whole file was mistakenly
|
|
73
|
+
missing `'use client'`.
|
|
74
|
+
- Auto-import failure: check the file lives in a directory Nuxt actually
|
|
75
|
+
scans (`composables/`, `components/`, `utils/` by default, or a
|
|
76
|
+
configured `imports`/`components` dir in `nuxt.config.ts`) and exports
|
|
77
|
+
what's being imported under the expected name.
|
|
78
|
+
- Hydration mismatch: trace the mismatched text/attribute back to its
|
|
79
|
+
source — usually `Date.now()`, `Math.random()`, `typeof window`
|
|
80
|
+
branching, or a locale-dependent format called during render.
|
|
81
|
+
|
|
82
|
+
### Step 4: Apply the smallest correct fix
|
|
83
|
+
|
|
84
|
+
- Boundary error: add `'use client'` to the smallest component that
|
|
85
|
+
actually needs it (extracting it into its own file if it's currently
|
|
86
|
+
bundled with server-only siblings) — not to the whole page/layout.
|
|
87
|
+
- Server-only import leak: move the server-only code behind its own
|
|
88
|
+
`'use server'` file or a `server/`-only module, and pass only the
|
|
89
|
+
derived, safe result down as a prop.
|
|
90
|
+
- Route Handler shape: export the correct named HTTP method function
|
|
91
|
+
with the framework's expected signature — not a default export or a
|
|
92
|
+
renamed function.
|
|
93
|
+
- Auto-import failure: fix the file's location/export name/registration
|
|
94
|
+
— not a hand-added explicit import that routes around Nuxt's
|
|
95
|
+
convention, unless the project has deliberately disabled auto-imports.
|
|
96
|
+
- Composable-context error: move the call to the synchronous top level
|
|
97
|
+
of `setup()`/a plugin/middleware — not a workaround that stores the
|
|
98
|
+
composable's return value in a ref before the async point instead of
|
|
99
|
+
fixing the call site.
|
|
100
|
+
- Hydration mismatch: make the value deterministic across server and
|
|
101
|
+
client (compute it once and pass it down, or gate the
|
|
102
|
+
client-only-varying part behind a mount-effect check) — not
|
|
103
|
+
`suppressHydrationWarning` or Nuxt's `<ClientOnly>`/`ssr: false` used as
|
|
104
|
+
a blanket cover for the mismatch.
|
|
105
|
+
|
|
106
|
+
### Step 5: Verify and report
|
|
107
|
+
|
|
108
|
+
Re-run the exact command from Step 1; confirm it exits 0 with no new
|
|
109
|
+
warnings. Report the root cause and the fix, not just "build passes now".
|
|
110
|
+
|
|
111
|
+
## Rules
|
|
112
|
+
|
|
113
|
+
- Follow `rules/patterns.mdc` for the boundary/composable-context/
|
|
114
|
+
rendering-mode conventions a fix must restore.
|
|
115
|
+
- ALWAYS fix the root cause with the smallest change confined to the
|
|
116
|
+
files the failure actually touches.
|
|
117
|
+
- NEVER add `suppressHydrationWarning`, wrap a component in
|
|
118
|
+
`<ClientOnly>`, or set `ssr: false` on a route as a way to silence a
|
|
119
|
+
hydration mismatch instead of fixing the nondeterministic render.
|
|
120
|
+
- NEVER move a `'use client'` directive up to a shared layout/ancestor,
|
|
121
|
+
or hand-import around a broken Nuxt auto-import, just to make the
|
|
122
|
+
build pass without understanding why resolution failed.
|
|
123
|
+
- NEVER widen `tsconfig.json`'s `strict`/`moduleResolution` or disable a
|
|
124
|
+
Next.js/Nuxt build check globally to route around one file's error.
|
|
125
|
+
|
|
126
|
+
## Red Flags
|
|
127
|
+
|
|
128
|
+
| Rationalization | Why it is wrong |
|
|
129
|
+
|---|---|
|
|
130
|
+
| "I'll add suppressHydrationWarning here, the mismatch is harmless" | Hides the actual nondeterministic render source instead of fixing it; a "harmless" mismatch today can silently grow |
|
|
131
|
+
| "Easiest fix: mark the whole layout 'use client', then the boundary error goes away for sure" | Ships the entire subtree to the client and defeats server rendering for content that never needed it |
|
|
132
|
+
| "This composable won't auto-import, I'll just hand-import it from a relative path to unblock the build" | Routes around the actual misconfiguration (wrong directory, missing export) instead of fixing it, and drifts from the project's own auto-import convention |
|
|
133
|
+
| "I'll set ssr: false on this Nuxt page, that always clears a hydration error" | Turns off server rendering for the route entirely instead of fixing the one nondeterministic value causing the mismatch |
|
|
134
|
+
|
|
135
|
+
## Verification
|
|
136
|
+
|
|
137
|
+
Do not report the fix done until all of the following hold:
|
|
138
|
+
|
|
139
|
+
- The exact command that reproduced the failure in Step 1 now exits 0
|
|
140
|
+
with no new warnings.
|
|
141
|
+
- No `suppressHydrationWarning`, `<ClientOnly>`/`ssr: false` used as a
|
|
142
|
+
blanket workaround, or widened `tsconfig.json` setting was added.
|
|
143
|
+
- A `'use client'` directive, if added, sits on the smallest component
|
|
144
|
+
that needs it, not a shared ancestor.
|
|
145
|
+
- The report states the actual root cause (which import/call needed
|
|
146
|
+
client/setup context, or which directory/export was wrong), not just
|
|
147
|
+
"fixed the build".
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"triggers": {
|
|
3
|
+
"positive": [
|
|
4
|
+
"This Server Component in my Next.js app imports useState, and the build keeps failing because of it, what's the actual fix?",
|
|
5
|
+
"Every time this Next.js page renders, the console throws a hydration mismatch error, and I need to actually fix the root cause instead of suppressing it.",
|
|
6
|
+
"Running nuxi typecheck, I keep getting a failure because it can't resolve this auto-imported composable, how do I fix the build?",
|
|
7
|
+
"This Next.js route.ts file has an invalid export and won't build",
|
|
8
|
+
"Fix this nuxt build error about a composable being called outside setup",
|
|
9
|
+
"My next build is failing because a Server Component in this file imports a browser-only API, what's the correct fix?",
|
|
10
|
+
"Nuxt build can't find this component even though it's in the components folder"
|
|
11
|
+
],
|
|
12
|
+
"negative": [
|
|
13
|
+
"Add a new Next.js server action for creating an order",
|
|
14
|
+
"Review this Next.js server action for missing auth checks",
|
|
15
|
+
"Write a test for this Nuxt composable",
|
|
16
|
+
"Migrate this Nuxt 2 project to Nuxt 3",
|
|
17
|
+
"Fix this Vite build error in a plain Vue component with no Nuxt involved",
|
|
18
|
+
"Fix this generic tsc module resolution error in a Node script"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"scenarios": [
|
|
22
|
+
{
|
|
23
|
+
"id": "no-suppress-hydration-warning",
|
|
24
|
+
"prompt": "My Next.js page shows a hydration mismatch warning in the console because it renders new Date().toLocaleTimeString() directly in the component. What's the right fix?",
|
|
25
|
+
"strictness": "high",
|
|
26
|
+
"expected_behavior": [
|
|
27
|
+
{ "grader": "regex", "value": "suppressHydrationWarning" },
|
|
28
|
+
{
|
|
29
|
+
"grader": "judge",
|
|
30
|
+
"rubric": "A correct answer fixes the actual nondeterminism -- making the time value consistent between server and client (e.g. computing it once and passing it down, or only rendering the time after mount on the client) -- rather than adding suppressHydrationWarning to hide the warning.",
|
|
31
|
+
"pass_criteria": [
|
|
32
|
+
"Names a concrete fix for the nondeterminism itself: e.g. only render the live time after the component mounts client-side (using a mounted-state check or an effect), or pass a server-computed timestamp down as a stable prop instead of calling new Date() during render on both sides",
|
|
33
|
+
"Shows or names the specific code change (the mounted-flag pattern, useEffect setting state after mount, or the prop being passed) rather than only describing the idea in the abstract"
|
|
34
|
+
],
|
|
35
|
+
"fail_criteria": [
|
|
36
|
+
"Recommends adding suppressHydrationWarning as the fix -- mentioning it only to say it should not be used here is not a failure"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"calibration": {
|
|
41
|
+
"known_right": "The mismatch happens because new Date().toLocaleTimeString() evaluates once on the server (at render/build time) and again on the client during hydration, producing two different strings for the same node. Don't paper over it with suppressHydrationWarning -- instead make the client-rendered time appear only after mount, so the server and initial client render agree (both render nothing or a static placeholder), and the live value fills in afterward:\n\nconst [time, setTime] = useState<string | null>(null);\nuseEffect(() => { setTime(new Date().toLocaleTimeString()); }, []);\nreturn <span>{time ?? '--:--:--'}</span>;\n\nThis way the server HTML and the client's first render both show the placeholder, hydration matches, and the real time appears right after mount.",
|
|
42
|
+
"known_wrong": "Easiest fix: add suppressHydrationWarning to the element rendering the time. React will stop complaining about the mismatch and the time still displays correctly on the client, so functionally nothing is lost.",
|
|
43
|
+
"vague": "You should make the time rendering consistent between server and client instead of just silencing the warning.",
|
|
44
|
+
"subtle_wrong": "Fix the root cause by moving the Date().toLocaleTimeString() call into a useMemo with an empty dependency array instead of calling new Date() inline in the JSX: const time = useMemo(() => new Date().toLocaleTimeString(), []); return <span>{time}</span>;. Memoizing it means the value is computed exactly once per mount rather than on every render, so the server and client agree on a single stable value."
|
|
45
|
+
},
|
|
46
|
+
"anti_patterns": ["suppressHydrationWarning"]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "narrow-use-client-not-widen",
|
|
50
|
+
"prompt": "Next.js flags a Server/Client boundary build error because a small icon-button inside my Server Component page uses the useState hook, and that hook needs client-side rendering to run at all. How should I fix it?",
|
|
51
|
+
"strictness": "high",
|
|
52
|
+
"expected_behavior": [
|
|
53
|
+
{ "grader": "regex", "value": "'use client'" },
|
|
54
|
+
{
|
|
55
|
+
"grader": "judge",
|
|
56
|
+
"rubric": "A correct answer adds 'use client' to the small icon-button component itself (extracting it into its own file if needed), not to the parent page/layout, so only the component that actually needs client state gets the directive.",
|
|
57
|
+
"pass_criteria": [
|
|
58
|
+
"States that 'use client' should be added to the icon-button component's own file, not the parent page",
|
|
59
|
+
"Names extracting the icon-button into its own component file if it currently isn't one, so the directive can be scoped to just it"
|
|
60
|
+
],
|
|
61
|
+
"fail_criteria": [
|
|
62
|
+
"Recommends adding 'use client' to the page or a shared parent/layout component as the fix -- mentioning that as something to avoid is not a failure"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"calibration": {
|
|
67
|
+
"known_right": "The fix is to add 'use client' to the icon-button component itself, not to the page. If the icon-button isn't already its own file, extract it into one (e.g. IconButton.tsx) and put 'use client' as the first line of that file -- that's the component that actually calls useState, so it's the one that needs the client boundary. Leave the page (page.tsx) with no directive so it stays a Server Component and everything else on the page keeps rendering server-side. Pass any props the icon-button needs down from the page as usual.",
|
|
68
|
+
"known_wrong": "Just add 'use client' to the top of the page.tsx file that contains it -- that's the fastest way to make the error go away without having to split anything into a new file.",
|
|
69
|
+
"vague": "Add 'use client' somewhere so the hook works, ideally not too broadly.",
|
|
70
|
+
"subtle_wrong": "I'd add 'use client' to the layout.tsx that wraps this page, since that's one level up from the page itself and technically not the page file -- that should satisfy the boundary requirement while being less invasive than touching the page directly."
|
|
71
|
+
},
|
|
72
|
+
"anti_patterns": []
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|