@1aboveio/skills 0.10.0
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/LICENSE +3 -0
- package/README.md +90 -0
- package/bin/1aboveio-skills.mjs +18 -0
- package/package.json +28 -0
- package/runtime/skills/distribution/generated/recipes.json +1189 -0
- package/runtime/skills/distribution/scripts/bundles.mjs +280 -0
- package/runtime/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
- package/skills/backend/airflow-dag-develop/LICENSE +3 -0
- package/skills/backend/airflow-dag-develop/SKILL.md +111 -0
- package/skills/backend/app-debug/LICENSE +3 -0
- package/skills/backend/app-debug/SKILL.md +109 -0
- package/skills/backend/app-debug/references/common-errors.md +128 -0
- package/skills/backend/python-backend/LICENSE +3 -0
- package/skills/backend/python-backend/SKILL.md +326 -0
- package/skills/cicd-pipeline/cloud-build/LICENSE +3 -0
- package/skills/cicd-pipeline/cloud-build/SKILL.md +707 -0
- package/skills/cicd-pipeline/cloud-debug/LICENSE +3 -0
- package/skills/cicd-pipeline/cloud-debug/SKILL.md +316 -0
- package/skills/cicd-pipeline/cloud-debug/references/build-failures.md +238 -0
- package/skills/cicd-pipeline/cloud-debug/references/deploy-failures.md +376 -0
- package/skills/cicd-pipeline/cloud-debug/references/pipeline-failures.md +378 -0
- package/skills/cicd-pipeline/cloud-deploy/LICENSE +3 -0
- package/skills/cicd-pipeline/cloud-deploy/SKILL.md +229 -0
- package/skills/cicd-pipeline/cloud-deploy/references/config-templates.md +257 -0
- package/skills/cicd-pipeline/docker/LICENSE +3 -0
- package/skills/cicd-pipeline/docker/SKILL.md +126 -0
- package/skills/cicd-pipeline/google-cloud/LICENSE +3 -0
- package/skills/cicd-pipeline/google-cloud/SKILL.md +118 -0
- package/skills/cicd-pipeline/google-cloud/references/gcs.md +469 -0
- package/skills/cicd-pipeline/google-cloud/references/iam.md +451 -0
- package/skills/cicd-pipeline/google-cloud/references/project.md +349 -0
- package/skills/cicd-pipeline/google-cloud/references/secrets.md +336 -0
- package/skills/cicd-pipeline/google-cloud/references/vpc.md +312 -0
- package/skills/cicd-pipeline/google-cloud/scripts/create-sa.sh +36 -0
- package/skills/cicd-pipeline/google-cloud/scripts/gcp-config.sh +31 -0
- package/skills/cicd-pipeline/google-cloud/scripts/grant-iap.sh +41 -0
- package/skills/cicd-pipeline/google-cloud/scripts/setup-secrets.sh +48 -0
- package/skills/cicd-pipeline/mergify/LICENSE +3 -0
- package/skills/cicd-pipeline/mergify/SKILL.md +138 -0
- package/skills/cicd-pipeline/mergify/assets/templates/mergify.yml +237 -0
- package/skills/cicd-pipeline/mergify/assets/templates/ruleset.json +46 -0
- package/skills/cicd-pipeline/mergify/references/branch-protection.md +277 -0
- package/skills/cicd-pipeline/mergify/references/configuration.md +183 -0
- package/skills/cicd-pipeline/mergify/references/diagnosis.md +73 -0
- package/skills/cicd-pipeline/mergify/references/traps.md +78 -0
- package/skills/cicd-pipeline/mergify/references/watch-contract.md +218 -0
- package/skills/cicd-pipeline/mergify/scripts/audit-core.mjs +131 -0
- package/skills/cicd-pipeline/mergify/scripts/audit.mjs +4 -0
- package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery-core.mjs +663 -0
- package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs +4 -0
- package/skills/cicd-pipeline/podman/LICENSE +3 -0
- package/skills/cicd-pipeline/podman/SKILL.md +70 -0
- package/skills/cicd-pipeline/podman/agents/openai.yaml +4 -0
- package/skills/cicd-pipeline/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
- package/skills/cicd-pipeline/podman/assets/templates/podman-service-override.conf +3 -0
- package/skills/cicd-pipeline/podman/references/compose-compatibility.md +70 -0
- package/skills/cicd-pipeline/podman/references/networking-and-ports.md +74 -0
- package/skills/cicd-pipeline/podman/references/rootless-services-and-sockets.md +156 -0
- package/skills/cicd-pipeline/podman/references/troubleshooting.md +98 -0
- package/skills/engineering/e2e-test/LICENSE +3 -0
- package/skills/engineering/e2e-test/SKILL.md +156 -0
- package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +272 -0
- package/skills/engineering/e2e-test/assets/ci-gates.github.yml +451 -0
- package/skills/engineering/e2e-test/assets/e2e-workflow.yml +282 -0
- package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
- package/skills/engineering/e2e-test/references/authoring/playwright-config.md +71 -0
- package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +219 -0
- package/skills/engineering/e2e-test/references/authoring/test-skipping.md +44 -0
- package/skills/engineering/e2e-test/references/ci-integration.md +121 -0
- package/skills/engineering/e2e-test/references/ci-playwright-container.md +280 -0
- package/skills/engineering/e2e-test/references/debugging.md +36 -0
- package/skills/engineering/e2e-test/references/presentation-sweep.md +131 -0
- package/skills/engineering/e2e-test/references/reviewing.md +39 -0
- package/skills/engineering/e2e-test/references/route-discovery.md +50 -0
- package/skills/engineering/e2e-test/references/route-manifest.md +44 -0
- package/skills/engineering/e2e-test/scripts/detect-routes-fastapi.py +290 -0
- package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
- package/skills/engineering/e2e-test/scripts/post-visual-evidence.mjs +158 -0
- package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
- package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
- package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
- package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
- package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +148 -0
- package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
- package/skills/engineering/e2e-test/scripts/presentation-visual.mjs +84 -0
- package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +75 -0
- package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
- package/skills/engineering/engineering-runtime/LICENSE +3 -0
- package/skills/engineering/engineering-runtime/SKILL.md +10 -0
- package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
- package/skills/engineering/engineering-runtime/coherence/workflow.json +553 -0
- package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
- package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
- package/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
- package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
- package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
- package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
- package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +576 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +166 -0
- package/skills/engineering/ensure-coverage/LICENSE +3 -0
- package/skills/engineering/ensure-coverage/SKILL.md +136 -0
- package/skills/engineering/ensure-coverage/evals/evals.json +125 -0
- package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +91 -0
- package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +83 -0
- package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
- package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
- package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
- package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +25 -0
- package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
- package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +87 -0
- package/skills/engineering/ensure-coverage/references/depth/test-smells.md +23 -0
- package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +164 -0
- package/skills/engineering/ensure-coverage/references/enforcement/hooks.md +85 -0
- package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +109 -0
- package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +33 -0
- package/skills/engineering/ensure-coverage/references/presentation/axis.md +78 -0
- package/skills/engineering/ensure-coverage/references/presentation/runner-contract.md +74 -0
- package/skills/engineering/ensure-coverage/references/process/audit-mode.md +33 -0
- package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
- package/skills/engineering/ensure-coverage/references/process/review-contract-template.md +119 -0
- package/skills/engineering/ensure-coverage/references/process/scope-class.md +178 -0
- package/skills/engineering/ensure-coverage/references/process/test-strategy.md +55 -0
- package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +45 -0
- package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +93 -0
- package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +178 -0
- package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +101 -0
- package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +358 -0
- package/skills/engineering/ensure-coverage/scripts/coverage-checklist.mjs +494 -0
- package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +663 -0
- package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
- package/skills/engineering/ensure-coverage/scripts/evidence-block.mjs +367 -0
- package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +269 -0
- package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
- package/skills/engineering/ensure-coverage/scripts/package-lock.json +76 -0
- package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
- package/skills/engineering/ensure-coverage/scripts/scope-class.mjs +554 -0
- package/skills/engineering/harness-runtime/LICENSE +3 -0
- package/skills/engineering/harness-runtime/SKILL.md +18 -0
- package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
- package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
- package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
- package/skills/engineering/harness-runtime/contracts.md +15 -0
- package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
- package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
- package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
- package/skills/engineering/harness-runtime/index.mjs +767 -0
- package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
- package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
- package/skills/engineering/harness-runtime/references/model-catalog-seed.json +159 -0
- package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
- package/skills/engineering/implement-and-pr/LICENSE +3 -0
- package/skills/engineering/implement-and-pr/SKILL.md +176 -0
- package/skills/engineering/implement-and-pr/references/ci-iteration.md +10 -0
- package/skills/engineering/implement-and-pr/references/closeout.md +27 -0
- package/skills/engineering/implement-and-pr/references/contract-complete-fix-rounds.md +34 -0
- package/skills/engineering/implement-and-pr/references/evidence-rules.md +39 -0
- package/skills/engineering/implement-and-pr/references/incremental-plan.md +16 -0
- package/skills/engineering/implement-and-pr/references/self-review.md +23 -0
- package/skills/engineering/implement-and-pr/references/tdd-mode.md +18 -0
- package/skills/engineering/resolve-issues/LICENSE +3 -0
- package/skills/engineering/resolve-issues/SKILL.md +167 -0
- package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +448 -0
- package/skills/engineering/resolve-issues/references/breaker.md +82 -0
- package/skills/engineering/resolve-issues/references/deliverables.md +27 -0
- package/skills/engineering/resolve-issues/references/delivery.md +108 -0
- package/skills/engineering/resolve-issues/references/evidence-lane.md +21 -0
- package/skills/engineering/resolve-issues/references/exact-head-ci.md +287 -0
- package/skills/engineering/resolve-issues/references/fan-out.md +33 -0
- package/skills/engineering/resolve-issues/references/finalization.md +68 -0
- package/skills/engineering/resolve-issues/references/guarantees.md +10 -0
- package/skills/engineering/resolve-issues/references/high-risk.md +29 -0
- package/skills/engineering/resolve-issues/references/incidents/848/README.md +156 -0
- package/skills/engineering/resolve-issues/references/intake.md +86 -0
- package/skills/engineering/resolve-issues/references/integration-gate.md +53 -0
- package/skills/engineering/resolve-issues/references/interference.md +87 -0
- package/skills/engineering/resolve-issues/references/loop.md +134 -0
- package/skills/engineering/resolve-issues/references/model-catalog.md +9 -0
- package/skills/engineering/resolve-issues/references/postmortem.md +27 -0
- package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +41 -0
- package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +48 -0
- package/skills/engineering/resolve-issues/references/pre-flight.md +41 -0
- package/skills/engineering/resolve-issues/references/regression-checklist.md +26 -0
- package/skills/engineering/resolve-issues/references/run-state.md +288 -0
- package/skills/engineering/resolve-issues/references/sandboxed-testing.md +48 -0
- package/skills/engineering/resolve-issues/references/spawn-contract.md +96 -0
- package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +40 -0
- package/skills/engineering/resolve-issues/references/why.md +653 -0
- package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +49 -0
- package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +721 -0
- package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +962 -0
- package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +220 -0
- package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +420 -0
- package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +256 -0
- package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +168 -0
- package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
- package/skills/engineering/resolve-issues/scripts/doctrine.mjs +62 -0
- package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +191 -0
- package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +413 -0
- package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +332 -0
- package/skills/engineering/resolve-issues/scripts/finalize.mjs +488 -0
- package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +3307 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +16 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +51 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +17 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +166 -0
- package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +92 -0
- package/skills/engineering/resolve-issues/scripts/guide-index.mjs +73 -0
- package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +159 -0
- package/skills/engineering/resolve-issues/scripts/interference.mjs +427 -0
- package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
- package/skills/engineering/resolve-issues/scripts/next-operations.mjs +419 -0
- package/skills/engineering/resolve-issues/scripts/postmortem.mjs +909 -0
- package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +322 -0
- package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +415 -0
- package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +697 -0
- package/skills/engineering/resolve-issues/scripts/report.mjs +494 -0
- package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +172 -0
- package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +79 -0
- package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +334 -0
- package/skills/engineering/resolve-issues/scripts/run-state.mjs +4784 -0
- package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +395 -0
- package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +290 -0
- package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +170 -0
- package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +293 -0
- package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +197 -0
- package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +127 -0
- package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +893 -0
- package/skills/engineering/resolve-issues/scripts/workspaces.mjs +829 -0
- package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +290 -0
- package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +80 -0
- package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +102 -0
- package/skills/engineering/resolve-release/LICENSE +3 -0
- package/skills/engineering/resolve-release/SKILL.md +112 -0
- package/skills/engineering/resolve-release/references/assembly.md +137 -0
- package/skills/engineering/resolve-release/references/auto-when-green.md +56 -0
- package/skills/engineering/resolve-release/references/candidate.md +167 -0
- package/skills/engineering/resolve-release/references/exposure.md +178 -0
- package/skills/engineering/resolve-release/references/handoff.md +24 -0
- package/skills/engineering/resolve-release/references/postmortem.md +230 -0
- package/skills/engineering/resolve-release/references/preflight.md +207 -0
- package/skills/engineering/resolve-release/references/principles.md +94 -0
- package/skills/engineering/resolve-release/references/regression-checklist.md +36 -0
- package/skills/engineering/resolve-release/references/related-skills.md +12 -0
- package/skills/engineering/resolve-release/references/routing.md +149 -0
- package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +285 -0
- package/skills/engineering/resolve-release/references/versioning.md +202 -0
- package/skills/engineering/resolve-release/references/why.md +53 -0
- package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +389 -0
- package/skills/engineering/resolve-release/scripts/build-changes.mjs +209 -0
- package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +407 -0
- package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +904 -0
- package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +81 -0
- package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +612 -0
- package/skills/engineering/resolve-release/scripts/close-attempt.mjs +135 -0
- package/skills/engineering/resolve-release/scripts/closeout-release.mjs +161 -0
- package/skills/engineering/resolve-release/scripts/doctrine.mjs +106 -0
- package/skills/engineering/resolve-release/scripts/durable-processing.mjs +522 -0
- package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +659 -0
- package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +1014 -0
- package/skills/engineering/resolve-release/scripts/finalize-release.mjs +526 -0
- package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +169 -0
- package/skills/engineering/resolve-release/scripts/green-gate.mjs +599 -0
- package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +752 -0
- package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +56 -0
- package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +1538 -0
- package/skills/engineering/resolve-release/scripts/postmortem.mjs +381 -0
- package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +498 -0
- package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +326 -0
- package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +272 -0
- package/skills/engineering/resolve-release/scripts/report.mjs +417 -0
- package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +114 -0
- package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +238 -0
- package/skills/engineering/resolve-release/scripts/review-packet.mjs +503 -0
- package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +263 -0
- package/skills/engineering/resolve-release/scripts/version-assert.mjs +339 -0
- package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +485 -0
- package/skills/engineering/resolve-release/scripts/version.mjs +1199 -0
- package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +449 -0
- package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +21 -0
- package/skills/engineering/resolve-release/vendor/README.md +60 -0
- package/skills/engineering/resolve-release/vendor/acorn.mjs +6233 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +341 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +70 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +7 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +2033 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +2033 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +7 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +49 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +5 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +549 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +549 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +36 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +47 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +82 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +11 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +22 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +11 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +11 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +25 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +85 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +85 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +20 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +20 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +61 -0
- package/skills/engineering/review-pr/LICENSE +3 -0
- package/skills/engineering/review-pr/SKILL.md +123 -0
- package/skills/engineering/review-pr/references/adversarial-reviewer-prompt.md +42 -0
- package/skills/engineering/review-pr/references/code-correctness.md +5 -0
- package/skills/engineering/review-pr/references/contract-freshness.md +9 -0
- package/skills/engineering/review-pr/references/coordination.md +18 -0
- package/skills/engineering/review-pr/references/domain-hazards.md +123 -0
- package/skills/engineering/review-pr/references/finding-themes.md +7 -0
- package/skills/engineering/review-pr/references/github-posting.md +98 -0
- package/skills/engineering/review-pr/references/golden-path-smoke.md +5 -0
- package/skills/engineering/review-pr/references/incremental-output.md +16 -0
- package/skills/engineering/review-pr/references/inputs-and-discovery.md +31 -0
- package/skills/engineering/review-pr/references/output-format.md +99 -0
- package/skills/engineering/review-pr/references/over-mock-screen.md +7 -0
- package/skills/engineering/review-pr/references/promotion-prs.md +16 -0
- package/skills/engineering/review-pr/references/re-review.md +18 -0
- package/skills/engineering/review-pr/references/review-method.md +199 -0
- package/skills/engineering/review-pr/references/review-mode.md +30 -0
- package/skills/engineering/review-pr/references/review-posture.md +53 -0
- package/skills/engineering/review-pr/references/round1-depth.md +62 -0
- package/skills/engineering/review-pr/references/scripts.md +17 -0
- package/skills/engineering/review-pr/references/workflow.md +16 -0
- package/skills/engineering/review-pr/schemas/findings.schema.json +282 -0
- package/skills/engineering/review-pr/scripts/finding-contract.mjs +285 -0
- package/skills/engineering/review-pr/scripts/post-review.mjs +405 -0
- package/skills/engineering/review-pr/scripts/pr-context.mjs +207 -0
- package/skills/engineering/review-pr/scripts/scan-diff.mjs +365 -0
- package/skills/engineering/review-pr/scripts/theme-contract.mjs +57 -0
- package/skills/engineering/smoke/LICENSE +3 -0
- package/skills/engineering/smoke/SKILL.md +131 -0
- package/skills/engineering/smoke/assets/smoke.manifest.example.json +53 -0
- package/skills/engineering/smoke/references/manifest.md +192 -0
- package/skills/engineering/smoke/scripts/smoke.mjs +713 -0
- package/skills/fullstack/better-auth/LICENSE +3 -0
- package/skills/fullstack/better-auth/SKILL.md +601 -0
- package/skills/fullstack/better-auth/references/feishu-api.md +270 -0
- package/skills/fullstack/monorepo/LICENSE +3 -0
- package/skills/fullstack/monorepo/SKILL.md +465 -0
- package/skills/fullstack/nextjs-fullstack/LICENSE +3 -0
- package/skills/fullstack/nextjs-fullstack/SKILL.md +210 -0
- package/skills/fullstack/nextjs-fullstack/conventions.md +318 -0
- package/skills/fullstack/nextjs-fullstack/frontend-conventions.md +61 -0
- package/skills/fullstack/nextjs-fullstack/nextjs16.md +287 -0
- package/skills/fullstack/nextjs-fullstack/server-actions.md +409 -0
- package/skills/fullstack/prisma-setup/LICENSE +3 -0
- package/skills/fullstack/prisma-setup/SKILL.md +180 -0
- package/skills/fullstack/prisma-setup/nextjs.md +258 -0
- package/skills/fullstack/prisma-setup/turborepo.md +301 -0
- package/skills/fullstack/shadcn/LICENSE +3 -0
- package/skills/fullstack/shadcn/SKILL.md +119 -0
- package/skills/fullstack/shadcn/assets/shadcn-small.png +0 -0
- package/skills/fullstack/shadcn/assets/shadcn.png +0 -0
- package/skills/fullstack/shadcn/cli.md +411 -0
- package/skills/fullstack/shadcn/customization.md +224 -0
- package/skills/fullstack/shadcn/evals/evals.json +90 -0
- package/skills/fullstack/shadcn/mcp.md +101 -0
- package/skills/fullstack/shadcn/rules/base-vs-radix.md +323 -0
- package/skills/fullstack/shadcn/rules/component-selection.md +67 -0
- package/skills/fullstack/shadcn/rules/composition.md +195 -0
- package/skills/fullstack/shadcn/rules/data-table.md +201 -0
- package/skills/fullstack/shadcn/rules/forms.md +255 -0
- package/skills/fullstack/shadcn/rules/icons.md +103 -0
- package/skills/fullstack/shadcn/rules/styling.md +167 -0
- package/skills/fullstack/zod-v4/LICENSE +3 -0
- package/skills/fullstack/zod-v4/SKILL.md +287 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Architectural Conventions
|
|
2
|
+
|
|
3
|
+
## Directory & Naming
|
|
4
|
+
|
|
5
|
+
### DB Client
|
|
6
|
+
|
|
7
|
+
`lib/db/client.ts` or `lib/prisma.ts`:
|
|
8
|
+
- Export singleton Prisma client
|
|
9
|
+
- Standard safeguards for dev hot-reload
|
|
10
|
+
|
|
11
|
+
### Repositories / DAL
|
|
12
|
+
|
|
13
|
+
Location: `lib/repositories/` or `dal/`
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
lib/repositories/
|
|
17
|
+
├── userRepository.ts
|
|
18
|
+
├── orderRepository.ts
|
|
19
|
+
└── index.ts
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Naming: `<entity>Repository.ts`
|
|
23
|
+
Functions: `getUserById`, `listOrdersByUser`, `createOrder`
|
|
24
|
+
|
|
25
|
+
### Server Actions
|
|
26
|
+
|
|
27
|
+
Group by feature:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
app/(dashboard)/settings/actions.ts
|
|
31
|
+
app/(shop)/orders/[orderId]/actions.ts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Export named actions:
|
|
35
|
+
- `export async function updateProfile(...)`
|
|
36
|
+
- `export async function createOrder(...)`
|
|
37
|
+
|
|
38
|
+
### Schemas & Types
|
|
39
|
+
|
|
40
|
+
- Shared Zod schemas: `lib/schemas/**`
|
|
41
|
+
- Domain types/DTOs: `lib/types/**`
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## TypeScript Rules
|
|
46
|
+
|
|
47
|
+
- `strict: true` in `tsconfig.json`
|
|
48
|
+
- All **exported** functions must have explicit return types
|
|
49
|
+
- Prefer **type aliases** over interfaces for simple data shapes
|
|
50
|
+
- Use `async`/`await`, avoid `.then/.catch` chaining
|
|
51
|
+
- Prefer **named exports** for repositories, actions, helpers
|
|
52
|
+
|
|
53
|
+
### Error Types
|
|
54
|
+
|
|
55
|
+
Define in `lib/errors.ts`:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
export class NotFoundError extends Error {
|
|
59
|
+
constructor(message: string) {
|
|
60
|
+
super(message);
|
|
61
|
+
this.name = 'NotFoundError';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class PermissionDeniedError extends Error {
|
|
66
|
+
constructor(message: string) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.name = 'PermissionDeniedError';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Server Actions - Detailed
|
|
76
|
+
|
|
77
|
+
### File Setup
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
'use server';
|
|
81
|
+
|
|
82
|
+
import { z } from 'zod';
|
|
83
|
+
import { auth } from '@/lib/auth';
|
|
84
|
+
import { userRepository } from '@/lib/repositories';
|
|
85
|
+
import { NotFoundError, PermissionDeniedError } from '@/lib/errors';
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Input Validation
|
|
89
|
+
|
|
90
|
+
Always use Zod:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const schema = z.object({
|
|
94
|
+
name: z.string().min(1),
|
|
95
|
+
email: z.string().email(),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
export async function updateUser(input: unknown) {
|
|
99
|
+
const parsed = schema.safeParse(input);
|
|
100
|
+
if (!parsed.success) {
|
|
101
|
+
return { success: false, error: { code: 'VALIDATION_ERROR', message: parsed.error.message } };
|
|
102
|
+
}
|
|
103
|
+
// ...
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Auth Pattern
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
const session = await auth();
|
|
111
|
+
if (!session?.user) {
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error: { code: 'UNAUTHENTICATED', message: 'Please sign in.' },
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// For permissions
|
|
119
|
+
if (session.user.role !== 'ADMIN') {
|
|
120
|
+
return { success: false, error: { code: 'FORBIDDEN', message: 'Admins only.' } };
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Standard Response Shape
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
export type ActionError = {
|
|
128
|
+
code: string;
|
|
129
|
+
message: string;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export type ActionResult<TData = unknown> = {
|
|
133
|
+
success: boolean;
|
|
134
|
+
data?: TData;
|
|
135
|
+
error?: ActionError;
|
|
136
|
+
};
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Error Mapping
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
try {
|
|
143
|
+
const data = await someRepositoryCall(...);
|
|
144
|
+
if (!data) {
|
|
145
|
+
return { success: false, error: { code: 'NOT_FOUND', message: 'Resource not found.' } };
|
|
146
|
+
}
|
|
147
|
+
return { success: true, data };
|
|
148
|
+
} catch (err) {
|
|
149
|
+
if (err instanceof PermissionDeniedError) {
|
|
150
|
+
return { success: false, error: { code: 'FORBIDDEN', message: err.message } };
|
|
151
|
+
}
|
|
152
|
+
console.error(err);
|
|
153
|
+
return { success: false, error: { code: 'INTERNAL_ERROR', message: 'Something went wrong.' } };
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Data Access Layer (Prisma)
|
|
160
|
+
|
|
161
|
+
### General Rules
|
|
162
|
+
|
|
163
|
+
- No Next.js imports (`next/headers`, etc.)
|
|
164
|
+
- No auth logic - DAL is unaware of current user
|
|
165
|
+
- No Zod schemas - inputs already validated
|
|
166
|
+
- No logging - callers decide when to log
|
|
167
|
+
|
|
168
|
+
### Repository Functions
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// lib/repositories/userRepository.ts
|
|
172
|
+
import { db } from '../db/client';
|
|
173
|
+
import type { User } from '@prisma/client';
|
|
174
|
+
|
|
175
|
+
export async function getUserById(userId: string): Promise<User | null> {
|
|
176
|
+
return db.user.findUnique({
|
|
177
|
+
where: { id: userId },
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export async function updateUserProfile(
|
|
182
|
+
userId: string,
|
|
183
|
+
data: { name?: string | null; avatarUrl?: string | null }
|
|
184
|
+
): Promise<User> {
|
|
185
|
+
return db.user.update({
|
|
186
|
+
where: { id: userId },
|
|
187
|
+
data,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Transactions
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
export async function createOrderWithItems(args: { ... }): Promise<Order> {
|
|
196
|
+
return db.$transaction(async (tx) => {
|
|
197
|
+
const order = await tx.order.create({ ... });
|
|
198
|
+
await tx.orderItem.createMany({ ... });
|
|
199
|
+
return order;
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Handling "Not Found"
|
|
205
|
+
|
|
206
|
+
- For queries: Return `null`
|
|
207
|
+
- For update/delete: Let Prisma throw, use-case layer catches and maps to NOT_FOUND
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Auth Integration (Better Auth)
|
|
212
|
+
|
|
213
|
+
- Use auth **only in server actions/API routes**
|
|
214
|
+
- Load session/user, enforce roles/permissions
|
|
215
|
+
- Do **not** pass auth/session objects into DAL
|
|
216
|
+
- Pass only **primitive IDs** (userId, tenantId) to repositories
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Testing Conventions
|
|
221
|
+
|
|
222
|
+
### Unit Tests (Vitest)
|
|
223
|
+
|
|
224
|
+
- Scope: Single function in isolation
|
|
225
|
+
- Location: `<filename>.test.ts` alongside source
|
|
226
|
+
- Mock all external dependencies
|
|
227
|
+
- Follow AAA: Arrange, Act, Assert
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// lib/utils/formatCurrency.test.ts
|
|
231
|
+
import { describe, it, expect } from 'vitest';
|
|
232
|
+
import { formatCurrency } from './formatCurrency';
|
|
233
|
+
|
|
234
|
+
describe('formatCurrency', () => {
|
|
235
|
+
it('should format positive numbers', () => {
|
|
236
|
+
expect(formatCurrency(1234.56, 'USD')).toBe('$1,234.56');
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Integration Tests
|
|
242
|
+
|
|
243
|
+
- Scope: Server actions with mocked database
|
|
244
|
+
- Location: `<feature>/actions.test.ts`
|
|
245
|
+
- Test full flow: validation -> auth -> logic -> response
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// app/(dashboard)/settings/actions.test.ts
|
|
249
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
250
|
+
import { updateProfile } from './actions';
|
|
251
|
+
import * as userDal from '@/dal/user';
|
|
252
|
+
import * as auth from '@/lib/auth';
|
|
253
|
+
|
|
254
|
+
vi.mock('@/dal/user');
|
|
255
|
+
vi.mock('@/lib/auth');
|
|
256
|
+
|
|
257
|
+
describe('updateProfile', () => {
|
|
258
|
+
it('should return UNAUTHENTICATED when no session', async () => {
|
|
259
|
+
vi.mocked(auth.auth).mockResolvedValue(null);
|
|
260
|
+
const result = await updateProfile({ name: 'Test' });
|
|
261
|
+
expect(result.success).toBe(false);
|
|
262
|
+
expect(result.error?.code).toBe('UNAUTHENTICATED');
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### E2E Tests (Playwright)
|
|
268
|
+
|
|
269
|
+
- Location: `e2e/` at project root
|
|
270
|
+
- Focus on critical user journeys
|
|
271
|
+
- Use `data-testid` attributes
|
|
272
|
+
- Use Page Object Model for selectors
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
// e2e/auth.spec.ts
|
|
276
|
+
import { test, expect } from '@playwright/test';
|
|
277
|
+
|
|
278
|
+
test('should allow sign in', async ({ page }) => {
|
|
279
|
+
await page.goto('/login');
|
|
280
|
+
await page.getByTestId('email-input').fill('test@example.com');
|
|
281
|
+
await page.getByTestId('password-input').fill('password123');
|
|
282
|
+
await page.getByTestId('submit-button').click();
|
|
283
|
+
await expect(page).toHaveURL('/dashboard');
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Test Organization
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
├── lib/utils/
|
|
291
|
+
│ ├── formatCurrency.ts
|
|
292
|
+
│ └── formatCurrency.test.ts # Unit
|
|
293
|
+
├── dal/
|
|
294
|
+
│ ├── user.ts
|
|
295
|
+
│ └── user.test.ts # Integration
|
|
296
|
+
├── app/(dashboard)/settings/
|
|
297
|
+
│ ├── actions.ts
|
|
298
|
+
│ └── actions.test.ts # Integration
|
|
299
|
+
└── e2e/
|
|
300
|
+
├── auth.spec.ts # E2E
|
|
301
|
+
└── fixtures/
|
|
302
|
+
└── auth.ts
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Testing Do / Don't
|
|
306
|
+
|
|
307
|
+
**Do:**
|
|
308
|
+
- Write unit tests for utilities
|
|
309
|
+
- Write integration tests for server actions
|
|
310
|
+
- Use `data-testid` for E2E
|
|
311
|
+
- Mock external dependencies
|
|
312
|
+
- Keep tests deterministic
|
|
313
|
+
|
|
314
|
+
**Don't:**
|
|
315
|
+
- Don't test implementation details
|
|
316
|
+
- Don't duplicate coverage in E2E
|
|
317
|
+
- Don't use `sleep()` in E2E
|
|
318
|
+
- Don't share mutable state between tests
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Frontend Conventions (UI, state, feedback)
|
|
2
|
+
|
|
3
|
+
Our preferences for building UI in this stack — *which patterns we reach for and why*. The **components themselves come from the `shadcn` skill** (component selection + composition rules); this file is the convention layer on top. Server/data architecture lives in [conventions.md](conventions.md) and [server-actions.md](server-actions.md).
|
|
4
|
+
|
|
5
|
+
> When a convention needs a component, defer to `shadcn`. When it needs a Server Action / DAL / auth, defer to this skill's core.
|
|
6
|
+
|
|
7
|
+
## URL state — `nuqs`
|
|
8
|
+
|
|
9
|
+
Prefer **URL search params (via `nuqs`)** for any UI state that should be shareable, refresh-safe, or readable on the server: list **filters, sort, pagination**, tab selection, search queries, and "open panel/dialog" state.
|
|
10
|
+
|
|
11
|
+
- **Why:** in the App Router, `searchParams` is readable in an RSC, so the server can filter/sort/paginate and the page is linkable and refresh-safe. Local `useState` for these loses on refresh and can't be server-rendered.
|
|
12
|
+
- Keep genuinely ephemeral state (hover, focus, uncommitted form text) in React state — not everything belongs in the URL.
|
|
13
|
+
- **Setup:** wrap the app once in `NuqsAdapter` (`nuqs/adapters/next/app`) in the root layout. Parse on the server with the `nuqs` server parsers; read/write on the client with `useQueryState` / `useQueryStates`.
|
|
14
|
+
- This is the same URL-state layer the data table uses → `shadcn` → `rules/data-table.md`.
|
|
15
|
+
|
|
16
|
+
## Data fetching & cache — RSC first, **SWR** for client
|
|
17
|
+
|
|
18
|
+
- **Default:** fetch on the server (RSC / DAL), mutate via Server Actions — no client fetch.
|
|
19
|
+
- **When you genuinely need client fetching** (polling, infinite scroll, data that changes outside the request, client-only widgets), use **SWR** for caching/revalidation.
|
|
20
|
+
- **Why:** SWR gives stale-while-revalidate, request dedup, and focus revalidation without hand-rolling a cache — but it's the *exception*, not the default (see [Core Principles](SKILL.md)).
|
|
21
|
+
- After a Server Action mutates server data, prefer `revalidatePath` / `revalidateTag`; call SWR `mutate()` only for client-cached keys.
|
|
22
|
+
|
|
23
|
+
## Async feedback — Progress/Skeleton for reads, **Sonner** for writes
|
|
24
|
+
|
|
25
|
+
- **Reads (queries / navigation / loading):** show a **Skeleton** or **Progress** placeholder (and `loading.tsx` / `Suspense` at route level). Never a toast for "loading."
|
|
26
|
+
- **Writes (mutations / Server Actions):** report the *result* with a **Sonner** toast — `toast.success(...)` on success, `toast.error(result.error?.message)` on failure (the `ActionResult` shape in [server-actions.md](server-actions.md)). Pair with the button's `isPending` for the in-flight state.
|
|
27
|
+
- **Why:** loading is a *state of the page* → inline placeholder; a mutation result is a *transient event* → toast. Mixing them (toast for loading, inline text for a save result) reads wrong.
|
|
28
|
+
- Components (`Skeleton` / `Progress` / `Spinner` / `sonner`) are shadcn — see its "Feedback" selection + composition rules.
|
|
29
|
+
|
|
30
|
+
## File upload — drag-and-drop dropzone
|
|
31
|
+
|
|
32
|
+
- Prefer a **drag-and-drop dropzone** (with a click-to-browse fallback) over a bare `<input type="file">`.
|
|
33
|
+
- **Component:** use the shadcn-registry dropzone / file-upload component → `shadcn` skill (add via its CLI, then fix imports to the project aliases).
|
|
34
|
+
- **Upload handling:** send to a **Server Action** or a `route.ts` handler; validate type/size with **Zod** at the boundary; store via the project's storage client. Show per-file **Progress** and a **Sonner** toast on done/fail.
|
|
35
|
+
- Keep the upload action in the use-case layer (`actions.ts`) and the storage call in a `lib` client — same layering as [conventions.md](conventions.md).
|
|
36
|
+
|
|
37
|
+
## Portal app shell — sidebar + header
|
|
38
|
+
|
|
39
|
+
The standard layout for an authenticated portal/dashboard:
|
|
40
|
+
|
|
41
|
+
- **Sidebar** for primary navigation (collapsible) — the shadcn `Sidebar` block.
|
|
42
|
+
- **Header**, right-aligned, carries three controls: a **theme toggle**, a **locale (i18n) switcher**, and a **profile menu** (`DropdownMenu`) showing the signed-in user + sign-out.
|
|
43
|
+
- Profile data + sign-out come from the **session (better-auth)** — load the session in the **RSC layout** and pass primitives down; don't fetch it client-side.
|
|
44
|
+
- Theme toggle via `next-themes`; the i18n switcher drives the locale → see [Internationalization](#internationalization-i18n) below.
|
|
45
|
+
- Put the shell in a **route-group layout** (e.g. `app/(portal)/layout.tsx`) so every portal page inherits sidebar + header.
|
|
46
|
+
- The components (Sidebar, DropdownMenu, Button) and their composition rules live in `shadcn`; this is just the *arrangement we standardize on*.
|
|
47
|
+
|
|
48
|
+
## Internationalization (i18n)
|
|
49
|
+
|
|
50
|
+
When the app is multi-locale:
|
|
51
|
+
|
|
52
|
+
- **Library:** use an App Router–native i18n library (e.g. `next-intl`) so messages are **server-readable in RSC**, not a client-only context that re-renders the tree.
|
|
53
|
+
- **Locale routing:** prefer a `[locale]` route segment (`app/[locale]/...`) — the locale is in the URL, so it's shareable, server-rendered, and SEO-correct. Middleware negotiates and redirects to a default locale.
|
|
54
|
+
- **Messages:** per-locale catalogs (e.g. `messages/en.json`, `messages/zh.json`), namespaced by feature (not one flat file); load the active locale once in the root layout and provide it.
|
|
55
|
+
- **The header switcher** (the i18n button in the app shell) changes the active locale by pushing the new `[locale]` segment (or a locale cookie). If you keep locale as a search param instead of a segment, that's the [URL state](#url-state--nuqs) convention.
|
|
56
|
+
- **Translate at the edges, not in the DAL:** the DAL/use-case layer returns stable keys and data; UI resolves copy via the i18n hook / `getTranslations`. Don't bake localized strings into Server Actions or repositories (keeps the DAL framework-agnostic, per [conventions.md](conventions.md)).
|
|
57
|
+
|
|
58
|
+
## List / index pages
|
|
59
|
+
|
|
60
|
+
- Default to a **data table with filter + sort + pagination** for any portal list/index page (users, orders, records…), **not** a hand-rolled list — and drive its state through URL params (`nuqs`, above) so it's server-rendered and shareable.
|
|
61
|
+
- **Implementation:** `shadcn` → `rules/data-table.md` (DiceUI `@diceui/data-table` for server-side; plain `Table` only for a trivial static list).
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Next.js 16 Patterns
|
|
2
|
+
|
|
3
|
+
**Framework:** `next@16` | **React:** `react@19`
|
|
4
|
+
|
|
5
|
+
This spec overrides any assumptions about older Next.js versions.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Server Components (Default)
|
|
10
|
+
|
|
11
|
+
All components are Server Components unless marked `"use client"`.
|
|
12
|
+
|
|
13
|
+
Good for:
|
|
14
|
+
- Data fetching
|
|
15
|
+
- Calling server actions
|
|
16
|
+
- Rendering HTML/JSX
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
// app/dashboard/page.tsx
|
|
20
|
+
export default async function DashboardPage() {
|
|
21
|
+
const data = await getDashboardData();
|
|
22
|
+
return <div>Dashboard: {data.title}</div>;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Client Components
|
|
29
|
+
|
|
30
|
+
Use `"use client"` only when you **need**:
|
|
31
|
+
- Event handlers (`onClick`, `onChange`)
|
|
32
|
+
- React state/effects (`useState`, `useEffect`)
|
|
33
|
+
- Browser APIs (`window`, `document`, `localStorage`)
|
|
34
|
+
- Third-party UI libs requiring DOM
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
// app/dashboard/components/theme-toggle.tsx
|
|
38
|
+
'use client';
|
|
39
|
+
|
|
40
|
+
import { useState } from 'react';
|
|
41
|
+
|
|
42
|
+
export function ThemeToggle() {
|
|
43
|
+
const [dark, setDark] = useState(false);
|
|
44
|
+
return (
|
|
45
|
+
<button onClick={() => setDark(v => !v)}>
|
|
46
|
+
{dark ? 'Dark' : 'Light'}
|
|
47
|
+
</button>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Rule:** Do NOT mark entire routes as client by default.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Data Fetching
|
|
57
|
+
|
|
58
|
+
### Async Server Components (Preferred)
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
// app/users/[id]/page.tsx
|
|
62
|
+
import { getUserById } from '@/data/user';
|
|
63
|
+
|
|
64
|
+
export default async function UserPage({ params }: { params: { id: string } }) {
|
|
65
|
+
const user = await getUserById(params.id);
|
|
66
|
+
|
|
67
|
+
if (!user) {
|
|
68
|
+
return <div>User not found</div>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return <div>{user.email}</div>;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### React 19 `use()` Hook
|
|
76
|
+
|
|
77
|
+
For unwrapping promises in Server Components:
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
import { use } from 'react';
|
|
81
|
+
import { getUserById } from '@/data/user';
|
|
82
|
+
|
|
83
|
+
export default function UserPage({ params }: { params: { id: string } }) {
|
|
84
|
+
const user = use(getUserById(params.id));
|
|
85
|
+
return <div>{user.email}</div>;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Rules:**
|
|
90
|
+
- `use()` is Server Component only
|
|
91
|
+
- Do NOT use `use()` inside `"use client"` components
|
|
92
|
+
|
|
93
|
+
### Client-side Fetching (Rare)
|
|
94
|
+
|
|
95
|
+
Only when:
|
|
96
|
+
- Data must refresh without navigation
|
|
97
|
+
- Real-time/highly interactive behavior
|
|
98
|
+
|
|
99
|
+
Use standard patterns (`fetch`, `SWR`) inside a small client component.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Server Actions
|
|
104
|
+
|
|
105
|
+
Primary way to handle mutations and forms.
|
|
106
|
+
|
|
107
|
+
### Location
|
|
108
|
+
|
|
109
|
+
Colocate with route: `app/foo/bar/actions.ts`
|
|
110
|
+
|
|
111
|
+
### Example
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// app/users/new/actions.ts
|
|
115
|
+
'use server';
|
|
116
|
+
|
|
117
|
+
export async function createUser(prevState: any, formData: FormData) {
|
|
118
|
+
const email = String(formData.get('email') ?? '');
|
|
119
|
+
if (!email) {
|
|
120
|
+
return { error: 'Email is required' };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// DB operation
|
|
124
|
+
// await prisma.user.create({ data: { email } });
|
|
125
|
+
|
|
126
|
+
return { error: null };
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Page with useActionState
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
// app/users/new/page.tsx
|
|
134
|
+
import { useActionState } from 'react';
|
|
135
|
+
import { createUser } from './actions';
|
|
136
|
+
|
|
137
|
+
export default function NewUserPage() {
|
|
138
|
+
const [state, formAction] = useActionState(createUser, { error: null });
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<form action={formAction}>
|
|
142
|
+
<input name="email" placeholder="email@example.com" />
|
|
143
|
+
{state.error && <p className="text-red-500">{state.error}</p>}
|
|
144
|
+
<button type="submit">Create User</button>
|
|
145
|
+
</form>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Rules:**
|
|
151
|
+
- Actions return **serializable objects** (no classes, no functions)
|
|
152
|
+
- Prefer `{ error: string | null, data?: ... }` shapes
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Route Handlers (API)
|
|
157
|
+
|
|
158
|
+
Use when you need an HTTP API (external services, non-form clients).
|
|
159
|
+
|
|
160
|
+
Location: `app/**/route.ts`
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// app/api/users/route.ts
|
|
164
|
+
import { NextRequest } from 'next/server';
|
|
165
|
+
|
|
166
|
+
export async function GET(req: NextRequest) {
|
|
167
|
+
const id = new URL(req.url).searchParams.get('id');
|
|
168
|
+
|
|
169
|
+
if (!id) {
|
|
170
|
+
return Response.json({ error: 'Missing id' }, { status: 400 });
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// const user = await prisma.user.findUnique({ where: { id } });
|
|
174
|
+
return Response.json({ ok: true });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export async function POST(req: NextRequest) {
|
|
178
|
+
const body = await req.json();
|
|
179
|
+
// handle mutation
|
|
180
|
+
return Response.json({ ok: true }, { status: 201 });
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Rules:**
|
|
185
|
+
- Use `Response.json()` with explicit `status`
|
|
186
|
+
- Validate incoming JSON
|
|
187
|
+
- Don't leak internal error details
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Layouts & Navigation
|
|
192
|
+
|
|
193
|
+
### Layouts
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// app/dashboard/layout.tsx
|
|
197
|
+
export default function DashboardLayout({
|
|
198
|
+
children,
|
|
199
|
+
}: {
|
|
200
|
+
children: React.ReactNode;
|
|
201
|
+
}) {
|
|
202
|
+
return <section className="dashboard">{children}</section>;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Navigation
|
|
207
|
+
|
|
208
|
+
Use `next/navigation` in Client Components:
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
'use client';
|
|
212
|
+
|
|
213
|
+
import { useRouter } from 'next/navigation';
|
|
214
|
+
|
|
215
|
+
export function GoBackButton() {
|
|
216
|
+
const router = useRouter();
|
|
217
|
+
return <button onClick={() => router.back()}>Back</button>;
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Rule:** Do NOT use `next/router`.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Error & Loading States
|
|
226
|
+
|
|
227
|
+
### Loading UI
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
// app/dashboard/loading.tsx
|
|
231
|
+
export default function Loading() {
|
|
232
|
+
return <div>Loading dashboard...</div>;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Error Boundary
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
// app/dashboard/error.tsx
|
|
240
|
+
'use client';
|
|
241
|
+
|
|
242
|
+
export default function DashboardError({ error }: { error: Error }) {
|
|
243
|
+
return <div>Something went wrong: {error.message}</div>;
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Rule:** `error.tsx` is always a Client Component.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## File Conventions
|
|
252
|
+
|
|
253
|
+
| File | Purpose |
|
|
254
|
+
|------|---------|
|
|
255
|
+
| `page.tsx` | Page component |
|
|
256
|
+
| `layout.tsx` | Layout wrapper |
|
|
257
|
+
| `route.ts` | API handler |
|
|
258
|
+
| `actions.ts` | Server actions |
|
|
259
|
+
| `schema.ts` | Validation schemas |
|
|
260
|
+
| `loading.tsx` | Loading UI |
|
|
261
|
+
| `error.tsx` | Error boundary |
|
|
262
|
+
| `components/` | Route-scoped components |
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Forbidden Patterns
|
|
267
|
+
|
|
268
|
+
| Pattern | Replacement |
|
|
269
|
+
|---------|-------------|
|
|
270
|
+
| `pages/` directory | `app/` only |
|
|
271
|
+
| `getServerSideProps` | Async Server Components |
|
|
272
|
+
| `getStaticProps` | Async Server Components |
|
|
273
|
+
| `getInitialProps` | Server Components |
|
|
274
|
+
| `next/router` | `next/navigation` |
|
|
275
|
+
| `_app.tsx`, `_document.tsx` | Layouts in App Router |
|
|
276
|
+
| Full-page client components | Server Components default |
|
|
277
|
+
| `useEffect` for initial data | Server Components |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Editing Rules
|
|
282
|
+
|
|
283
|
+
1. **Minimal diffs** - Don't rewrite whole files
|
|
284
|
+
2. **This spec wins** - Override training data if conflicts
|
|
285
|
+
3. **Preserve behavior** - Don't change logic unless requested
|
|
286
|
+
4. **No new dependencies** - Without explicit instruction
|
|
287
|
+
5. **Prefer Server Components** for data, Server Actions for mutations
|