@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,195 @@
|
|
|
1
|
+
# Component Composition
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Items always inside their Group component
|
|
6
|
+
- Callouts use Alert
|
|
7
|
+
- Empty states use Empty component
|
|
8
|
+
- Toast notifications use sonner
|
|
9
|
+
- Choosing between overlay components
|
|
10
|
+
- Dialog, Sheet, and Drawer always need a Title
|
|
11
|
+
- Card structure
|
|
12
|
+
- Button has no isPending or isLoading prop
|
|
13
|
+
- TabsTrigger must be inside TabsList
|
|
14
|
+
- Avatar always needs AvatarFallback
|
|
15
|
+
- Use Separator instead of raw hr or border divs
|
|
16
|
+
- Use Skeleton for loading placeholders
|
|
17
|
+
- Use Badge instead of custom styled spans
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Items always inside their Group component
|
|
22
|
+
|
|
23
|
+
Never render items directly inside the content container.
|
|
24
|
+
|
|
25
|
+
**Incorrect:**
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
<SelectContent>
|
|
29
|
+
<SelectItem value="apple">Apple</SelectItem>
|
|
30
|
+
<SelectItem value="banana">Banana</SelectItem>
|
|
31
|
+
</SelectContent>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Correct:**
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<SelectContent>
|
|
38
|
+
<SelectGroup>
|
|
39
|
+
<SelectItem value="apple">Apple</SelectItem>
|
|
40
|
+
<SelectItem value="banana">Banana</SelectItem>
|
|
41
|
+
</SelectGroup>
|
|
42
|
+
</SelectContent>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This applies to all group-based components:
|
|
46
|
+
|
|
47
|
+
| Item | Group |
|
|
48
|
+
|------|-------|
|
|
49
|
+
| `SelectItem`, `SelectLabel` | `SelectGroup` |
|
|
50
|
+
| `DropdownMenuItem`, `DropdownMenuLabel`, `DropdownMenuSub` | `DropdownMenuGroup` |
|
|
51
|
+
| `MenubarItem` | `MenubarGroup` |
|
|
52
|
+
| `ContextMenuItem` | `ContextMenuGroup` |
|
|
53
|
+
| `CommandItem` | `CommandGroup` |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Callouts use Alert
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
<Alert>
|
|
61
|
+
<AlertTitle>Warning</AlertTitle>
|
|
62
|
+
<AlertDescription>Something needs attention.</AlertDescription>
|
|
63
|
+
</Alert>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Empty states use Empty component
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<Empty>
|
|
72
|
+
<EmptyHeader>
|
|
73
|
+
<EmptyMedia variant="icon"><FolderIcon /></EmptyMedia>
|
|
74
|
+
<EmptyTitle>No projects yet</EmptyTitle>
|
|
75
|
+
<EmptyDescription>Get started by creating a new project.</EmptyDescription>
|
|
76
|
+
</EmptyHeader>
|
|
77
|
+
<EmptyContent>
|
|
78
|
+
<Button>Create Project</Button>
|
|
79
|
+
</EmptyContent>
|
|
80
|
+
</Empty>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Toast notifications use sonner
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { toast } from "sonner"
|
|
89
|
+
|
|
90
|
+
toast.success("Changes saved.")
|
|
91
|
+
toast.error("Something went wrong.")
|
|
92
|
+
toast("File deleted.", {
|
|
93
|
+
action: { label: "Undo", onClick: () => undoDelete() },
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Choosing between overlay components
|
|
100
|
+
|
|
101
|
+
| Use case | Component |
|
|
102
|
+
|----------|-----------|
|
|
103
|
+
| Focused task that requires input | `Dialog` |
|
|
104
|
+
| Destructive action confirmation | `AlertDialog` |
|
|
105
|
+
| Side panel with details or filters | `Sheet` |
|
|
106
|
+
| Mobile-first bottom panel | `Drawer` |
|
|
107
|
+
| Quick info on hover | `HoverCard` |
|
|
108
|
+
| Small contextual content on click | `Popover` |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Dialog, Sheet, and Drawer always need a Title
|
|
113
|
+
|
|
114
|
+
`DialogTitle`, `SheetTitle`, `DrawerTitle` are required for accessibility. Use `className="sr-only"` if visually hidden.
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
<DialogContent>
|
|
118
|
+
<DialogHeader>
|
|
119
|
+
<DialogTitle>Edit Profile</DialogTitle>
|
|
120
|
+
<DialogDescription>Update your profile.</DialogDescription>
|
|
121
|
+
</DialogHeader>
|
|
122
|
+
...
|
|
123
|
+
</DialogContent>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Card structure
|
|
129
|
+
|
|
130
|
+
Use full composition — don't dump everything into `CardContent`:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
<Card>
|
|
134
|
+
<CardHeader>
|
|
135
|
+
<CardTitle>Team Members</CardTitle>
|
|
136
|
+
<CardDescription>Manage your team.</CardDescription>
|
|
137
|
+
</CardHeader>
|
|
138
|
+
<CardContent>...</CardContent>
|
|
139
|
+
<CardFooter>
|
|
140
|
+
<Button>Invite</Button>
|
|
141
|
+
</CardFooter>
|
|
142
|
+
</Card>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Button has no isPending or isLoading prop
|
|
148
|
+
|
|
149
|
+
Compose with `Spinner` + `data-icon` + `disabled`:
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
<Button disabled>
|
|
153
|
+
<Spinner data-icon="inline-start" />
|
|
154
|
+
Saving...
|
|
155
|
+
</Button>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## TabsTrigger must be inside TabsList
|
|
161
|
+
|
|
162
|
+
Never render `TabsTrigger` directly inside `Tabs` — always wrap in `TabsList`:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<Tabs defaultValue="account">
|
|
166
|
+
<TabsList>
|
|
167
|
+
<TabsTrigger value="account">Account</TabsTrigger>
|
|
168
|
+
<TabsTrigger value="password">Password</TabsTrigger>
|
|
169
|
+
</TabsList>
|
|
170
|
+
<TabsContent value="account">...</TabsContent>
|
|
171
|
+
</Tabs>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Avatar always needs AvatarFallback
|
|
177
|
+
|
|
178
|
+
Always include `AvatarFallback` for when the image fails to load:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
<Avatar>
|
|
182
|
+
<AvatarImage src="/avatar.png" alt="User" />
|
|
183
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
184
|
+
</Avatar>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Use existing components instead of custom markup
|
|
190
|
+
|
|
191
|
+
| Instead of | Use |
|
|
192
|
+
|---|---|
|
|
193
|
+
| `<hr>` or `<div className="border-t">` | `<Separator />` |
|
|
194
|
+
| `<div className="animate-pulse">` with styled divs | `<Skeleton className="h-4 w-3/4" />` |
|
|
195
|
+
| `<span className="rounded-full bg-green-100 ...">` | `<Badge variant="secondary">` |
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Data Tables & List Pages
|
|
2
|
+
|
|
3
|
+
**On a portal list/index page the data table is DiceUI's — that's the default.** Choosing a bare `Table` there is the decision that needs justifying, not the other way round. Away from list pages it's a judgment call: DiceUI once the table needs server-side filter/sort/paginate, plain `Table` when it's display.
|
|
4
|
+
|
|
5
|
+
DiceUI DataTable is built on **TanStack Table** and isn't bundled with shadcn, so it needs an explicit install — a setup step, not a reason to reconsider it. DiceUI components are shadcn-style, so the skill's [Critical Rules](../SKILL.md#critical-rules) (semantic colors, `gap-*`, `data-icon`, `cn()`, etc.) still apply to anything you add or edit.
|
|
6
|
+
|
|
7
|
+
## Which to use
|
|
8
|
+
|
|
9
|
+
| Case | Use |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Portal list/index page | **DiceUI DataTable** (`@diceui/data-table`) — default |
|
|
12
|
+
| Large/remote dataset — filter/sort/paginate on the **server**, shareable URLs | **DiceUI DataTable** |
|
|
13
|
+
| A few rows, static/read-only, nothing to slice | shadcn **`Table`** |
|
|
14
|
+
| "I'll just wire `useReactTable` with a custom toolbar" | That's DiceUI, reimplemented without the URL state. Use DiceUI |
|
|
15
|
+
|
|
16
|
+
## URL state is the point
|
|
17
|
+
|
|
18
|
+
`nuqs` isn't an implementation detail you can swap out — `useDataTable` calls `useQueryState` internally, so it's a hard dependency and the app must be wrapped once in `NuqsAdapter` or the hook throws.
|
|
19
|
+
|
|
20
|
+
That coupling is deliberate, and it's the reason to pick DiceUI in the first place. Filters, sort, and page are exactly the state people bookmark, paste into a ticket, and expect to survive a refresh. Keeping them in `useState` loses all of that *and* strands the values on the client, where the server query that actually needs them can't see them. Put them in the URL and the RSC page re-reads them on every navigation for free.
|
|
21
|
+
|
|
22
|
+
Corollary: don't keep a `useState` copy alongside the URL values. Two sources of truth is what makes the back button feel broken.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
Use the project's package runner (`npx`/`pnpm dlx`/`bunx --bun`). The **URL form works with no config** — but the `.json` extension is **required**; an extensionless registry URL 404s.
|
|
27
|
+
|
|
28
|
+
The data-table items are served from **tablecn.com** (`diceui.com/r/<name>.json` 308-redirects there, so either host works; tablecn is canonical):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx shadcn@latest add "https://tablecn.com/r/data-table.json"
|
|
32
|
+
# optional add-ons:
|
|
33
|
+
npx shadcn@latest add "https://tablecn.com/r/data-table-sort-list.json"
|
|
34
|
+
npx shadcn@latest add "https://tablecn.com/r/data-table-filter-list.json"
|
|
35
|
+
npx shadcn@latest add "https://tablecn.com/r/data-table-filter-menu.json"
|
|
36
|
+
# row-selection action bar (this one lives on diceui.com, not tablecn):
|
|
37
|
+
npx shadcn@latest add "https://diceui.com/r/action-bar.json"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The `@diceui/...` namespace form (`npx shadcn@latest add @diceui/data-table`) only resolves if `components.json` declares the registry. Prefer `npx shadcn@latest registry add "@diceui=https://diceui.com/r/{name}.json"` over hand-editing, and use exactly this template:
|
|
41
|
+
|
|
42
|
+
```jsonc
|
|
43
|
+
// components.json
|
|
44
|
+
{
|
|
45
|
+
"registries": {
|
|
46
|
+
"@diceui": "https://diceui.com/r/{name}.json"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
> **Do not use the `{style}` form.** shadcn's public registry index lists `@diceui` as `https://diceui.com/r/{style}/{name}.json`. That template breaks the data-table items — the CLI substitutes the project's full style (e.g. `radix-nova`) and the resulting URL 404s. `{name}.json` resolves every DiceUI item, including the style-segmented ones.
|
|
52
|
+
|
|
53
|
+
### Dependencies the registry doesn't declare
|
|
54
|
+
|
|
55
|
+
The item declares `@tanstack/react-table`, `nuqs`, and `lucide-react`, and its registry dependencies (`badge`, `button`, `calendar`, `command`, `dropdown-menu`, `input`, `popover`, `select`, `separator`, `slider`, `table`) come in automatically. But the shipped files import more than that, and the gap doesn't surface until the build fails on a missing module:
|
|
56
|
+
|
|
57
|
+
| Package | Needed by | Declared? |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `zod` | `lib/parsers.ts` in the base item and both filter add-ons | **No — install it** |
|
|
60
|
+
| `@dnd-kit/core`, `@dnd-kit/modifiers`, `@dnd-kit/sortable`, `@dnd-kit/utilities` | `ui/sortable.tsx`, pulled in by `data-table-sort-list` and `data-table-filter-list` | **No — install them** |
|
|
61
|
+
| `radix-ui` | `ui/sortable.tsx` | Only implicitly. Fine on a `radix` base; on a `base`/`aria` project you must add it |
|
|
62
|
+
| `react-day-picker`, `date-fns` | date filters | Yes — via the `calendar` registry dependency |
|
|
63
|
+
|
|
64
|
+
So after adding, install the gaps with the project's package manager — e.g. `pnpm add zod` for the base item, plus the four `@dnd-kit/*` packages if you took either add-on.
|
|
65
|
+
|
|
66
|
+
`npx shadcn@latest migrate radix` converts a project still on individual `@radix-ui/react-*` packages to the unified `radix-ui`.
|
|
67
|
+
|
|
68
|
+
If the project's `iconLibrary` isn't `lucide`, run `npx shadcn@latest migrate icons --from lucide --to <lib>` over the added files rather than rewriting the imports by hand.
|
|
69
|
+
|
|
70
|
+
After adding, follow the skill's review step: rewrite third-party import paths to the project `aliases`, swap icons to the project `iconLibrary`, and verify composition against the Critical Rules.
|
|
71
|
+
|
|
72
|
+
## Server-side rendering pattern (Next.js App Router)
|
|
73
|
+
|
|
74
|
+
Three pieces, in this order. (The broader URL-state convention — when to keep state in the URL vs React at all — lives in the project's `nextjs-fullstack` skill → `frontend-conventions.md`.)
|
|
75
|
+
|
|
76
|
+
1) Wrap the app once with the nuqs adapter (root layout). **Not a setup detail you can defer** — `useDataTable` throws without it, and the failure surfaces inside the table component, far from the missing provider:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
// app/layout.tsx
|
|
80
|
+
import { NuqsAdapter } from "nuqs/adapters/next/app";
|
|
81
|
+
|
|
82
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
83
|
+
return (
|
|
84
|
+
<html lang="en">
|
|
85
|
+
<body>
|
|
86
|
+
<NuqsAdapter>{children}</NuqsAdapter>
|
|
87
|
+
</body>
|
|
88
|
+
</html>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
2) Parse search params and fetch on the server — an RSC page, no `"use client"`.
|
|
94
|
+
|
|
95
|
+
**Parse with the same parsers the client writes with; don't hand-read `searchParams`.** `sort` and (in advanced mode) `filters` are **JSON-encoded** in the URL, not `field:asc` strings — `getSortingStateParser` does a `JSON.parse` and validates the shape with zod, rejecting unknown column ids. Read them as plain strings on the server and you get a silent mismatch: the URL updates, the page re-renders, and the sort quietly never applies. Build a loader from the shipped parsers so both sides share one definition:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
// app/(portal)/users/search-params.ts
|
|
99
|
+
import { createLoader, parseAsInteger, parseAsString } from "nuqs/server";
|
|
100
|
+
import { getSortingStateParser } from "@/lib/parsers";
|
|
101
|
+
|
|
102
|
+
export const usersSearchParams = {
|
|
103
|
+
page: parseAsInteger.withDefault(1),
|
|
104
|
+
perPage: parseAsInteger.withDefault(10),
|
|
105
|
+
sort: getSortingStateParser<User>().withDefault([{ id: "createdAt", desc: true }]),
|
|
106
|
+
status: parseAsString.withDefault(""), // one entry per filterable column id
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export const loadUsersSearchParams = createLoader(usersSearchParams);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
// app/(portal)/users/page.tsx
|
|
114
|
+
import { loadUsersSearchParams } from "./search-params";
|
|
115
|
+
|
|
116
|
+
export default async function UsersPage({
|
|
117
|
+
searchParams,
|
|
118
|
+
}: {
|
|
119
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
120
|
+
}) {
|
|
121
|
+
const sp = await loadUsersSearchParams(searchParams); // typed: page, perPage, sort, filters
|
|
122
|
+
const { rows, pageCount } = await getUsers(sp); // do the filter/sort/paginate IN the query
|
|
123
|
+
return <UsersTable data={rows} pageCount={pageCount} />;
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
3) Build the table on the client with `useDataTable` (needs `"use client"` when the project has `rsc: true`):
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
"use client";
|
|
131
|
+
import { useDataTable } from "@/hooks/use-data-table"; // paths follow your resolvedPaths/aliases
|
|
132
|
+
import { DataTable } from "@/components/data-table/data-table";
|
|
133
|
+
import { DataTableToolbar } from "@/components/data-table/data-table-toolbar";
|
|
134
|
+
import { columns } from "./columns";
|
|
135
|
+
|
|
136
|
+
export function UsersTable({ data, pageCount }: { data: User[]; pageCount: number }) {
|
|
137
|
+
const { table } = useDataTable({
|
|
138
|
+
data,
|
|
139
|
+
columns, // TanStack column defs; see the column contract below
|
|
140
|
+
pageCount, // REQUIRED — server-driven page count
|
|
141
|
+
getRowId: (row) => row.id,
|
|
142
|
+
initialState: { sorting: [{ id: "createdAt", desc: true }] },
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<DataTable table={table}>
|
|
147
|
+
<DataTableToolbar table={table} />
|
|
148
|
+
{/* advanced: pass enableAdvancedFilter to useDataTable, then
|
|
149
|
+
<DataTableAdvancedToolbar table={table}>
|
|
150
|
+
<DataTableFilterList table={table} />
|
|
151
|
+
<DataTableSortList table={table} />
|
|
152
|
+
</DataTableAdvancedToolbar> */}
|
|
153
|
+
</DataTable>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### The column contract (easy to get wrong)
|
|
159
|
+
|
|
160
|
+
`useDataTable` sets `defaultColumn: { enableColumnFilter: false }`. A column is **not** filterable until you opt in, and the toolbar's filter control is chosen from `meta`:
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
{
|
|
164
|
+
id: "status", // `id` must be set — the URL filter key is the column id
|
|
165
|
+
accessorKey: "status",
|
|
166
|
+
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
|
|
167
|
+
enableColumnFilter: true, // required, or the column gets no filter
|
|
168
|
+
meta: {
|
|
169
|
+
label: "Status", // shown in the toolbar / view options
|
|
170
|
+
variant: "multiSelect", // drives the filter control
|
|
171
|
+
options: [ // presence of `options` → array parser (comma-separated in the URL)
|
|
172
|
+
{ label: "Active", value: "active" },
|
|
173
|
+
{ label: "Banned", value: "banned" },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Other `meta` fields: `placeholder`, `range` (`[min, max]` for slider/range filters), `unit`, `icon`.
|
|
180
|
+
|
|
181
|
+
### What the hook actually does
|
|
182
|
+
|
|
183
|
+
- **`pageCount` is required** (typed `Required<Pick<TableOptions, "pageCount">>`), and the hook hardcodes `manualPagination`, `manualSorting`, and `manualFiltering` to `true`. **There is no client-side mode** — the server always does the work.
|
|
184
|
+
- It returns `{ table, shallow, debounceMs, throttleMs }`, not just `table`. The toolbar components consume the extra fields.
|
|
185
|
+
- URL keys it reads/writes: `page`, `perPage`, `sort`, plus one key per filterable column id. In advanced mode (`enableAdvancedFilter: true`) per-column keys are replaced by a single `filters` key plus `joinOperator`. Rename any of them via `queryKeys`.
|
|
186
|
+
- Other options: `initialState`, `queryKeys`, `history` (`"push"` | `"replace"`, default `"replace"`), `debounceMs` (300), `throttleMs` (50), `clearOnDefault`, `enableAdvancedFilter`, `scroll`, `shallow`, `startTransition`.
|
|
187
|
+
- `enableRowSelection` is on by default.
|
|
188
|
+
|
|
189
|
+
## Components
|
|
190
|
+
|
|
191
|
+
`useDataTable` (hook) · `DataTable` (accepts an `actionBar` prop for the row-selection bar) · `DataTableToolbar` / `DataTableAdvancedToolbar` · `DataTableFilterList` / `DataTableFilterMenu` · `DataTableSortList` · `DataTableColumnHeader` · `DataTableViewOptions` · `DataTablePagination` · `DataTableFacetedFilter` · `DataTableSliderFilter` · `DataTableDateFilter` · `DataTableRangeFilter` · `DataTableSkeleton`.
|
|
192
|
+
|
|
193
|
+
`DataTableAdvancedToolbar`, `DataTableFilterList`, and `DataTableRangeFilter` ship with the `data-table-filter-list` / `data-table-filter-menu` add-ons, not the base item.
|
|
194
|
+
|
|
195
|
+
## Small, local datasets
|
|
196
|
+
|
|
197
|
+
`useDataTable` cannot do client-side pagination — it always requires `pageCount` and always runs manual mode. For a small in-memory dataset, either compute `pageCount` yourself and slice locally, or skip DiceUI and use shadcn `Table` with plain TanStack `useReactTable`.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
Imports and paths above are **illustrative** — use the actual destinations from `npx shadcn@latest info` (`config.resolvedPaths`) and the project `aliases`. The DiceUI API evolves; confirm the current props/exports at <https://diceui.com/docs/components/radix/data-table> before implementing. (`npx shadcn@latest docs` only resolves first-party shadcn components, not DiceUI ones.)
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Forms & Inputs
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- The Field family (what each part is for)
|
|
6
|
+
- Forms use FieldGroup + Field
|
|
7
|
+
- InputGroup requires InputGroupInput/InputGroupTextarea
|
|
8
|
+
- Buttons inside inputs use InputGroupButton + InputGroupAddon
|
|
9
|
+
- Option sets (2–7 choices) use ToggleGroup
|
|
10
|
+
- FieldSet + FieldLegend for grouping related fields
|
|
11
|
+
- Field validation and disabled states
|
|
12
|
+
- Error messages use FieldError
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## The Field family
|
|
17
|
+
|
|
18
|
+
Knowing the full export list prevents the two common failures: hand-rolling a part that already exists, and putting text in the wrong slot.
|
|
19
|
+
|
|
20
|
+
| Component | Use for |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `Field` | One control + its label/description/error. Props: `orientation="vertical" \| "horizontal" \| "responsive"` |
|
|
23
|
+
| `FieldGroup` | Vertical stack of `Field`s. This is the form's layout primitive |
|
|
24
|
+
| `FieldLabel` | The label. Pair with `htmlFor` |
|
|
25
|
+
| `FieldTitle` | A heading for a field that has no single focusable control (e.g. a labelled `ToggleGroup`) |
|
|
26
|
+
| `FieldDescription` | Helper text — muted, informational. **Not for errors** |
|
|
27
|
+
| `FieldError` | The error message. Renders `role="alert"` in destructive color |
|
|
28
|
+
| `FieldContent` | Wraps label+description when a control sits beside them (horizontal layouts) |
|
|
29
|
+
| `FieldSet` + `FieldLegend` | Groups related checkboxes/radios/switches |
|
|
30
|
+
| `FieldSeparator` | Divider between fields |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Forms use FieldGroup + Field
|
|
35
|
+
|
|
36
|
+
Always use `FieldGroup` + `Field` — never raw `div` with `space-y-*`:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<FieldGroup>
|
|
40
|
+
<Field>
|
|
41
|
+
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
42
|
+
<Input id="email" type="email" />
|
|
43
|
+
</Field>
|
|
44
|
+
<Field>
|
|
45
|
+
<FieldLabel htmlFor="password">Password</FieldLabel>
|
|
46
|
+
<Input id="password" type="password" />
|
|
47
|
+
</Field>
|
|
48
|
+
</FieldGroup>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Use `Field orientation="horizontal"` for settings pages. Use `FieldLabel className="sr-only"` for visually hidden labels.
|
|
52
|
+
|
|
53
|
+
**Choosing form controls:**
|
|
54
|
+
|
|
55
|
+
- Simple text input → `Input`
|
|
56
|
+
- Dropdown with predefined options → `Select`
|
|
57
|
+
- Searchable dropdown → `Combobox`
|
|
58
|
+
- Native HTML select (no JS) → `native-select`
|
|
59
|
+
- Boolean toggle → `Switch` (for settings) or `Checkbox` (for forms)
|
|
60
|
+
- Single choice from few options → `RadioGroup`
|
|
61
|
+
- Toggle between 2–5 options → `ToggleGroup` + `ToggleGroupItem`
|
|
62
|
+
- OTP/verification code → `InputOTP`
|
|
63
|
+
- Multi-line text → `Textarea`
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## InputGroup requires InputGroupInput/InputGroupTextarea
|
|
68
|
+
|
|
69
|
+
Never use raw `Input` or `Textarea` inside an `InputGroup`.
|
|
70
|
+
|
|
71
|
+
**Incorrect:**
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<InputGroup>
|
|
75
|
+
<Input placeholder="Search..." />
|
|
76
|
+
</InputGroup>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Correct:**
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { InputGroup, InputGroupInput } from "@/components/ui/input-group"
|
|
83
|
+
|
|
84
|
+
<InputGroup>
|
|
85
|
+
<InputGroupInput placeholder="Search..." />
|
|
86
|
+
</InputGroup>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Buttons inside inputs use InputGroupButton + InputGroupAddon
|
|
92
|
+
|
|
93
|
+
Never place a `Button` directly inside or adjacent to an `Input` with custom positioning.
|
|
94
|
+
|
|
95
|
+
Two details make or break this one:
|
|
96
|
+
|
|
97
|
+
- Use **`InputGroupButton`**, not `Button`. It presets `variant="ghost"` and an input-scaled `size` — a plain `Button` inside an addon is too tall for the group and keeps its solid fill.
|
|
98
|
+
- `InputGroupAddon` defaults to `align="inline-start"`. A **trailing** control needs `align="inline-end"`, or it silently renders on the left. Also available: `block-start` / `block-end`, which turn the group into a column (useful for a toolbar under a textarea).
|
|
99
|
+
|
|
100
|
+
**Incorrect:**
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
<div className="relative">
|
|
104
|
+
<Input placeholder="Search..." className="pr-10" />
|
|
105
|
+
<Button className="absolute right-0 top-0" size="icon">
|
|
106
|
+
<SearchIcon />
|
|
107
|
+
</Button>
|
|
108
|
+
</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Correct:**
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import {
|
|
115
|
+
InputGroup, InputGroupInput, InputGroupAddon, InputGroupButton,
|
|
116
|
+
} from "@/components/ui/input-group" // use the project's aliases.ui
|
|
117
|
+
|
|
118
|
+
<InputGroup>
|
|
119
|
+
<InputGroupAddon>
|
|
120
|
+
<SearchIcon />
|
|
121
|
+
</InputGroupAddon>
|
|
122
|
+
<InputGroupInput placeholder="Search..." />
|
|
123
|
+
<InputGroupAddon align="inline-end">
|
|
124
|
+
<InputGroupButton size="icon-xs" aria-label="Clear">
|
|
125
|
+
<XIcon />
|
|
126
|
+
</InputGroupButton>
|
|
127
|
+
</InputGroupAddon>
|
|
128
|
+
</InputGroup>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`InputGroupText` is there for static affixes (`https://`, `.com`, a unit) — those aren't buttons and shouldn't be.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Option sets (2–7 choices) use ToggleGroup
|
|
136
|
+
|
|
137
|
+
Don't manually loop `Button` components with active state.
|
|
138
|
+
|
|
139
|
+
**Incorrect:**
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
const [selected, setSelected] = useState("daily")
|
|
143
|
+
|
|
144
|
+
<div className="flex gap-2">
|
|
145
|
+
{["daily", "weekly", "monthly"].map((option) => (
|
|
146
|
+
<Button
|
|
147
|
+
key={option}
|
|
148
|
+
variant={selected === option ? "default" : "outline"}
|
|
149
|
+
onClick={() => setSelected(option)}
|
|
150
|
+
>
|
|
151
|
+
{option}
|
|
152
|
+
</Button>
|
|
153
|
+
))}
|
|
154
|
+
</div>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Correct:**
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
|
|
161
|
+
|
|
162
|
+
<ToggleGroup>
|
|
163
|
+
<ToggleGroupItem value="daily">Daily</ToggleGroupItem>
|
|
164
|
+
<ToggleGroupItem value="weekly">Weekly</ToggleGroupItem>
|
|
165
|
+
<ToggleGroupItem value="monthly">Monthly</ToggleGroupItem>
|
|
166
|
+
</ToggleGroup>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`spacing` defaults to `2` on both bases, so don't pass it just to restate the default. Pass `spacing={0}` when you want the segmented-control look — joined items with shared borders and squared inner corners.
|
|
170
|
+
|
|
171
|
+
Combine with `Field` for labelled toggle groups. A `ToggleGroup` has no single focusable control to point a `FieldLabel` at, so use `FieldTitle` plus `aria-labelledby`:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
<Field orientation="horizontal">
|
|
175
|
+
<FieldTitle id="theme-label">Theme</FieldTitle>
|
|
176
|
+
<ToggleGroup aria-labelledby="theme-label" spacing={0}>
|
|
177
|
+
<ToggleGroupItem value="light">Light</ToggleGroupItem>
|
|
178
|
+
<ToggleGroupItem value="dark">Dark</ToggleGroupItem>
|
|
179
|
+
<ToggleGroupItem value="system">System</ToggleGroupItem>
|
|
180
|
+
</ToggleGroup>
|
|
181
|
+
</Field>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
> **Note:** `defaultValue` and `type`/`multiple` props differ between base and radix. See [base-vs-radix.md](./base-vs-radix.md#togglegroup).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## FieldSet + FieldLegend for grouping related fields
|
|
189
|
+
|
|
190
|
+
Use `FieldSet` + `FieldLegend` for related checkboxes, radios, or switches — not `div` with a heading:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
<FieldSet>
|
|
194
|
+
<FieldLegend variant="label">Preferences</FieldLegend>
|
|
195
|
+
<FieldDescription>Select all that apply.</FieldDescription>
|
|
196
|
+
<FieldGroup className="gap-3">
|
|
197
|
+
<Field orientation="horizontal">
|
|
198
|
+
<Checkbox id="dark" />
|
|
199
|
+
<FieldLabel htmlFor="dark" className="font-normal">Dark mode</FieldLabel>
|
|
200
|
+
</Field>
|
|
201
|
+
</FieldGroup>
|
|
202
|
+
</FieldSet>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Field validation and disabled states
|
|
208
|
+
|
|
209
|
+
Both attributes are needed — `data-invalid`/`data-disabled` styles the field (label, description), while `aria-invalid`/`disabled` styles the control and carries the state to assistive tech.
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
// Invalid.
|
|
213
|
+
<Field data-invalid>
|
|
214
|
+
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
215
|
+
<Input id="email" aria-invalid />
|
|
216
|
+
<FieldError>Enter a valid email address.</FieldError>
|
|
217
|
+
</Field>
|
|
218
|
+
|
|
219
|
+
// Disabled.
|
|
220
|
+
<Field data-disabled>
|
|
221
|
+
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
222
|
+
<Input id="email" disabled />
|
|
223
|
+
</Field>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Works for all controls: `Input`, `Textarea`, `Select`, `Checkbox`, `RadioGroupItem`, `Switch`, `Slider`, `NativeSelect`, `InputOTP`.
|
|
227
|
+
|
|
228
|
+
**Drive it from state, don't conditionally spread.** `Field` styles on `data-[invalid=true]`, and React serializes a boolean `data-*` value to the string `"true"`/`"false"`. So a plain expression is enough — `data-invalid={false}` leaves the attribute in the DOM as `"false"` and correctly stays unstyled. There's no need for the `{...(bad && { "data-invalid": true })}` trick people reach for:
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
<Field data-invalid={!!errors.email}>
|
|
232
|
+
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
233
|
+
<Input id="email" aria-invalid={!!errors.email} />
|
|
234
|
+
<FieldError errors={errors.email ? [errors.email] : undefined} />
|
|
235
|
+
</Field>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Error messages use FieldError
|
|
241
|
+
|
|
242
|
+
`FieldError` is not a styled `FieldDescription` — it renders `role="alert"`, so screen readers announce the failure when it appears. `FieldDescription` is muted helper text with no live-region semantics, so an error placed there is invisible to assistive tech and the wrong color.
|
|
243
|
+
|
|
244
|
+
It takes either children or an `errors` array:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
// Plain message.
|
|
248
|
+
<FieldError>Passwords do not match.</FieldError>
|
|
249
|
+
|
|
250
|
+
// From a validation library — the array shape is `{ message?: string }[]`,
|
|
251
|
+
// which is exactly what react-hook-form / Zod resolvers hand back.
|
|
252
|
+
<FieldError errors={[errors.password, errors.confirm]} />
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Two behaviors worth relying on rather than reimplementing: it returns `null` when there's nothing to show (no empty-state guard needed at the call site), and given multiple errors it de-duplicates by message and renders a bulleted list.
|