@activatus/code-standards 0.0.0-stage → 3.0.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/README.md +199 -2
- package/docs/Guides/_category_.json +4 -0
- package/docs/Guides/component-library-workflow.md +182 -0
- package/docs/Guides/migrating.md +161 -0
- package/docs/Guides/setup.md +158 -0
- package/docs/Standards/_category_.json +4 -0
- package/docs/Standards/agent-skills.md +125 -0
- package/docs/Standards/agent-specs.md +74 -0
- package/docs/Standards/direnv.mdx +249 -0
- package/docs/Standards/documentation.md +314 -0
- package/docs/Standards/editorconfig.md +74 -0
- package/docs/Standards/eslint.md +900 -0
- package/docs/Standards/human-readable-names.md +274 -0
- package/docs/Standards/lint-errors.md +171 -0
- package/docs/Standards/prettier.md +106 -0
- package/docs/Standards/readable-code.md +570 -0
- package/docs/Standards/stylelint.md +193 -0
- package/docs/Standards/styling.md +290 -0
- package/docs/Standards/tech-stack.md +158 -0
- package/docs/Structure/_category_.json +4 -0
- package/docs/Structure/api-routes.md +118 -0
- package/docs/Structure/component-organization.md +526 -0
- package/docs/Structure/folder-structure.md +366 -0
- package/docs/Structure/import-organization.md +158 -0
- package/docs/Structure/naming-conventions.md +334 -0
- package/docs/design-system-components.md +117 -0
- package/docs/intro.md +44 -0
- package/docs/ontology.md +127 -0
- package/docs/templates.mdx +396 -0
- package/docs/version-history.md +338 -0
- package/package.json +60 -3
- package/scripts/renameSymbol.mjs +188 -0
- package/static/templates/.editorconfig +25 -0
- package/static/templates/.envrc +25 -0
- package/static/templates/.nvmrc +1 -0
- package/static/templates/AGENTS.md +163 -0
- package/static/templates/decision-doc.md +19 -0
- package/static/templates/docs/ai/agent-harness.md +17 -0
- package/static/templates/docs/ai/agents.md +17 -0
- package/static/templates/docs/ai/architecture.md +17 -0
- package/static/templates/docs/ai/context.md +17 -0
- package/static/templates/docs/ai/model-routing.md +17 -0
- package/static/templates/docs/ai/models.md +17 -0
- package/static/templates/docs/ai/retrieval.md +17 -0
- package/static/templates/docs/ai/tools.md +17 -0
- package/static/templates/docs/architecture/authentication.md +17 -0
- package/static/templates/docs/architecture/backend.md +17 -0
- package/static/templates/docs/architecture/background-jobs.md +17 -0
- package/static/templates/docs/architecture/backups.md +17 -0
- package/static/templates/docs/architecture/caching.md +17 -0
- package/static/templates/docs/architecture/ci-cd.md +17 -0
- package/static/templates/docs/architecture/disaster-recovery.md +17 -0
- package/static/templates/docs/architecture/environments.md +17 -0
- package/static/templates/docs/architecture/frontend.md +17 -0
- package/static/templates/docs/architecture/hosting.md +17 -0
- package/static/templates/docs/architecture/observability.md +17 -0
- package/static/templates/docs/architecture/realtime.md +17 -0
- package/static/templates/docs/architecture/search.md +17 -0
- package/static/templates/docs/architecture/services.md +17 -0
- package/static/templates/docs/architecture/state-management.md +17 -0
- package/static/templates/docs/architecture/storage.md +17 -0
- package/static/templates/docs/architecture/system.md +17 -0
- package/static/templates/docs/business/buying-trigger.md +17 -0
- package/static/templates/docs/business/customer-value.md +17 -0
- package/static/templates/docs/business/customer.md +17 -0
- package/static/templates/docs/business/defensibility.md +17 -0
- package/static/templates/docs/business/growth.md +17 -0
- package/static/templates/docs/business/pricing.md +17 -0
- package/static/templates/docs/business/revenue-model.md +17 -0
- package/static/templates/docs/business/unit-economics.md +17 -0
- package/static/templates/docs/data/analytics.md +17 -0
- package/static/templates/docs/data/audit.md +17 -0
- package/static/templates/docs/data/database.md +17 -0
- package/static/templates/docs/data/indexing.md +17 -0
- package/static/templates/docs/data/migrations.md +17 -0
- package/static/templates/docs/data/model.md +17 -0
- package/static/templates/docs/data/retention.md +17 -0
- package/static/templates/docs/data/schema.md +17 -0
- package/static/templates/docs/deployment/approval.md +17 -0
- package/static/templates/docs/deployment/live-verification.md +17 -0
- package/static/templates/docs/deployment/process.md +17 -0
- package/static/templates/docs/deployment/rollback.md +17 -0
- package/static/templates/docs/design/design-system.md +17 -0
- package/static/templates/docs/design/errors.md +17 -0
- package/static/templates/docs/design/feedback.md +17 -0
- package/static/templates/docs/design/interactions.md +17 -0
- package/static/templates/docs/design/layout.md +17 -0
- package/static/templates/docs/design/navigation.md +17 -0
- package/static/templates/docs/design/principles.md +17 -0
- package/static/templates/docs/design/responsive.md +17 -0
- package/static/templates/docs/development/branching.md +17 -0
- package/static/templates/docs/development/code-quality.md +17 -0
- package/static/templates/docs/development/coding-standards.md +21 -0
- package/static/templates/docs/development/commits.md +17 -0
- package/static/templates/docs/development/merge-strategy.md +17 -0
- package/static/templates/docs/development/process.md +17 -0
- package/static/templates/docs/development/pull-requests.md +17 -0
- package/static/templates/docs/experience/accessibility.md +17 -0
- package/static/templates/docs/experience/aha-moment.md +17 -0
- package/static/templates/docs/experience/anti-experience.md +17 -0
- package/static/templates/docs/experience/friction.md +17 -0
- package/static/templates/docs/experience/outcomes.md +17 -0
- package/static/templates/docs/experience/principles.md +17 -0
- package/static/templates/docs/experience/retention.md +17 -0
- package/static/templates/docs/experience/sharing.md +17 -0
- package/static/templates/docs/overview/how-it-works.md +17 -0
- package/static/templates/docs/overview/what-is-it.md +17 -0
- package/static/templates/docs/overview/writing-docs.md +16 -0
- package/static/templates/docs/pitch/alternatives.md +17 -0
- package/static/templates/docs/pitch/assumptions.md +17 -0
- package/static/templates/docs/pitch/audience.md +17 -0
- package/static/templates/docs/pitch/concept.md +17 -0
- package/static/templates/docs/pitch/differentiators.md +17 -0
- package/static/templates/docs/pitch/outcomes.md +17 -0
- package/static/templates/docs/pitch/problem.md +17 -0
- package/static/templates/docs/pitch/product-market-fit.md +17 -0
- package/static/templates/docs/pitch/success-criteria.md +17 -0
- package/static/templates/docs/pitch/validation.md +17 -0
- package/static/templates/docs/pitch/value-proposition.md +17 -0
- package/static/templates/docs/pitch/vision.md +17 -0
- package/static/templates/docs/scope/core.md +17 -0
- package/static/templates/docs/scope/exclusions.md +17 -0
- package/static/templates/docs/scope/future.md +17 -0
- package/static/templates/docs/scope/launch.md +17 -0
- package/static/templates/docs/scope/post-launch.md +17 -0
- package/static/templates/docs/scope/priorities.md +17 -0
- package/static/templates/docs/scope/quality-bar.md +17 -0
- package/static/templates/docs/security/audit.md +17 -0
- package/static/templates/docs/security/data-access.md +17 -0
- package/static/templates/docs/security/logging.md +17 -0
- package/static/templates/docs/security/privacy.md +17 -0
- package/static/templates/docs/security/secrets.md +17 -0
- package/static/templates/docs/security/threat-model.md +17 -0
- package/static/templates/docs/testing/end-to-end.md +17 -0
- package/static/templates/docs/testing/integration.md +17 -0
- package/static/templates/docs/testing/regression.md +17 -0
- package/static/templates/docs/testing/security.md +17 -0
- package/static/templates/docs/testing/strategy.md +17 -0
- package/static/templates/docs/testing/test-data.md +17 -0
- package/static/templates/docs/testing/unit.md +17 -0
- package/static/templates/docs/uat/checks.md +17 -0
- package/static/templates/docs/uat/strategy.md +17 -0
- package/static/templates/docs/users/permissions.md +17 -0
- package/static/templates/docs/users/roles.md +17 -0
- package/static/templates/docs/users/user-types.md +17 -0
- package/static/templates/docs/workflows/assignment.md +17 -0
- package/static/templates/docs/workflows/bugfix.md +17 -0
- package/static/templates/docs/workflows/dependencies.md +17 -0
- package/static/templates/docs/workflows/deployment.md +17 -0
- package/static/templates/docs/workflows/development.md +17 -0
- package/static/templates/docs/workflows/planning.md +17 -0
- package/static/templates/docs/workflows/review.md +17 -0
- package/static/templates/docs/workflows/uat.md +17 -0
- package/static/templates/docsSite/docusaurus.config.mjs +144 -0
- package/static/templates/docsSite/gitignore.txt +3 -0
- package/static/templates/docsSite/package.json.txt +42 -0
- package/static/templates/docsSite/pnpm-workspace.yaml +2 -0
- package/static/templates/docsSite/sidebars.mjs +7 -0
- package/static/templates/docsSite/src/css/custom.css +7 -0
- package/static/templates/docsSite/src/pages/index.tsx +9 -0
- package/static/templates/docsSite/static/images/logo.svg +4 -0
- package/static/templates/docsSite/tsconfig.json +7 -0
- package/static/templates/eslint/base/eslint.config.mjs +104 -0
- package/static/templates/eslint/nextjs/eslint.config.mjs +181 -0
- package/static/templates/eslint/react/eslint.config.mjs +173 -0
- package/static/templates/eslint/typescript/eslint.config.mjs +154 -0
- package/static/templates/globals.css +16 -0
- package/static/templates/husky/pre-commit +1 -0
- package/static/templates/next.config.mjs +21 -0
- package/static/templates/prettier.config.mjs +26 -0
- package/static/templates/skills/codeReview.md +31 -0
- package/static/templates/skills/format.md +18 -0
- package/static/templates/skills/lint.md +21 -0
- package/static/templates/skills/lintFix.md +24 -0
- package/static/templates/skills/securityAudit.md +28 -0
- package/static/templates/skills/test.md +24 -0
- package/static/templates/skills/typescript.md +28 -0
- package/static/templates/skills/updateLayout.md +20 -0
- package/static/templates/stylelint/css/stylelint.config.mjs +40 -0
- package/static/templates/stylelint/scss/stylelint.config.mjs +13 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
|
|
2
|
+
import prettier from "eslint-config-prettier";
|
|
3
|
+
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
4
|
+
import nextVitals from "eslint-config-next/core-web-vitals";
|
|
5
|
+
import nextTypescript from "eslint-config-next/typescript";
|
|
6
|
+
import { flatConfigs as importX } from "eslint-plugin-import-x";
|
|
7
|
+
import unicorn from "eslint-plugin-unicorn";
|
|
8
|
+
import globals from "globals";
|
|
9
|
+
|
|
10
|
+
export default [
|
|
11
|
+
{
|
|
12
|
+
ignores: [
|
|
13
|
+
".next/",
|
|
14
|
+
"out/",
|
|
15
|
+
"build/",
|
|
16
|
+
"coverage/",
|
|
17
|
+
"next-env.d.ts",
|
|
18
|
+
"**/vendor/**",
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
...nextVitals,
|
|
22
|
+
...nextTypescript,
|
|
23
|
+
comments.recommended,
|
|
24
|
+
importX.recommended,
|
|
25
|
+
importX.typescript,
|
|
26
|
+
unicorn.configs.recommended,
|
|
27
|
+
{
|
|
28
|
+
languageOptions: {
|
|
29
|
+
globals: { ...globals.browser, ...globals.node },
|
|
30
|
+
},
|
|
31
|
+
settings: {
|
|
32
|
+
// Keep this. eslint-plugin-react crashes on ESLint 10 if it has to detect the version itself.
|
|
33
|
+
// Update the number when the project upgrades React.
|
|
34
|
+
react: { version: "19.0" },
|
|
35
|
+
"import-x/resolver-next": [createTypeScriptImportResolver()],
|
|
36
|
+
},
|
|
37
|
+
rules: {
|
|
38
|
+
"@eslint-community/eslint-comments/require-description":
|
|
39
|
+
"error",
|
|
40
|
+
"func-style": ["error", "expression"],
|
|
41
|
+
"max-depth": ["error", 3],
|
|
42
|
+
"max-lines": [
|
|
43
|
+
"error",
|
|
44
|
+
{ max: 300, skipBlankLines: true, skipComments: true },
|
|
45
|
+
],
|
|
46
|
+
"no-nested-ternary": "error",
|
|
47
|
+
"no-var": "error",
|
|
48
|
+
"prefer-arrow-callback": "error",
|
|
49
|
+
"prefer-const": "error",
|
|
50
|
+
"no-magic-numbers": [
|
|
51
|
+
"error",
|
|
52
|
+
{
|
|
53
|
+
ignore: [-1, 0, 1],
|
|
54
|
+
ignoreArrayIndexes: true,
|
|
55
|
+
ignoreDefaultValues: true,
|
|
56
|
+
enforceConst: true,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
"no-restricted-syntax": [
|
|
60
|
+
"error",
|
|
61
|
+
{
|
|
62
|
+
selector: "ClassDeclaration",
|
|
63
|
+
message: "Use functions, not classes.",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
selector: "ClassExpression",
|
|
67
|
+
message: "Use functions, not classes.",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
selector: "VariableDeclarator > FunctionExpression",
|
|
71
|
+
message: "Use an arrow function.",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
selector: "VariableDeclaration[kind='let']",
|
|
75
|
+
message:
|
|
76
|
+
"Use const. If this value really must be reassigned, disable this rule on this line with a comment saying why.",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
selector: "FunctionDeclaration[params.length>1]",
|
|
80
|
+
message:
|
|
81
|
+
"Use a single object parameter when a function needs more than one value.",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
selector:
|
|
85
|
+
"VariableDeclarator > :matches(ArrowFunctionExpression, FunctionExpression)[params.length>1]",
|
|
86
|
+
message:
|
|
87
|
+
"Use a single object parameter when a function needs more than one value.",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
"import-x/no-cycle": "error",
|
|
91
|
+
"import-x/no-default-export": "error",
|
|
92
|
+
"no-use-before-define": "error",
|
|
93
|
+
"unicorn/default-export-style": "off",
|
|
94
|
+
"unicorn/filename-case": [
|
|
95
|
+
"error",
|
|
96
|
+
{ cases: { camelCase: true, pascalCase: true } },
|
|
97
|
+
],
|
|
98
|
+
"unicorn/name-replacements": [
|
|
99
|
+
"error",
|
|
100
|
+
{
|
|
101
|
+
// Dictionary words: see "Dictionary" in the Human-Readable Names standard.
|
|
102
|
+
replacements: {
|
|
103
|
+
docs: false,
|
|
104
|
+
lib: false,
|
|
105
|
+
props: false,
|
|
106
|
+
ref: false,
|
|
107
|
+
repo: false,
|
|
108
|
+
utils: false,
|
|
109
|
+
},
|
|
110
|
+
// Third-party names, allowed only exactly as they are.
|
|
111
|
+
allowList: { params: true, searchParams: true },
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
"react/function-component-definition": [
|
|
115
|
+
"error",
|
|
116
|
+
{
|
|
117
|
+
namedComponents: "arrow-function",
|
|
118
|
+
unnamedComponents: "arrow-function",
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
"react/jsx-no-bind": "error",
|
|
122
|
+
"react/no-multi-comp": "error",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
files: ["**/*.{ts,tsx}"],
|
|
127
|
+
rules: {
|
|
128
|
+
"no-undef": "off",
|
|
129
|
+
"no-magic-numbers": "off",
|
|
130
|
+
"no-use-before-define": "off",
|
|
131
|
+
"@typescript-eslint/consistent-type-assertions": [
|
|
132
|
+
"error",
|
|
133
|
+
{ assertionStyle: "never" },
|
|
134
|
+
],
|
|
135
|
+
"@typescript-eslint/consistent-type-imports": "error",
|
|
136
|
+
"@typescript-eslint/naming-convention": [
|
|
137
|
+
"error",
|
|
138
|
+
{
|
|
139
|
+
selector: ["typeAlias", "interface"],
|
|
140
|
+
format: ["PascalCase"],
|
|
141
|
+
custom: { regex: "(Props|Type)$", match: true },
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
145
|
+
"@typescript-eslint/no-magic-numbers": [
|
|
146
|
+
"error",
|
|
147
|
+
{
|
|
148
|
+
ignore: [-1, 0, 1],
|
|
149
|
+
ignoreArrayIndexes: true,
|
|
150
|
+
ignoreDefaultValues: true,
|
|
151
|
+
enforceConst: true,
|
|
152
|
+
ignoreEnums: true,
|
|
153
|
+
ignoreNumericLiteralTypes: true,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
157
|
+
"@typescript-eslint/no-use-before-define": "error",
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
files: ["**/*.test.{ts,tsx}"],
|
|
162
|
+
rules: {
|
|
163
|
+
"max-lines": "off",
|
|
164
|
+
"no-magic-numbers": "off",
|
|
165
|
+
"@typescript-eslint/no-magic-numbers": "off",
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
files: [
|
|
170
|
+
"**/*.config.{js,mjs,ts}",
|
|
171
|
+
"**/*.stories.tsx",
|
|
172
|
+
"app/**/{page,layout,template,default,loading,error,global-error,not-found}.tsx",
|
|
173
|
+
],
|
|
174
|
+
rules: { "import-x/no-default-export": "off" },
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
files: ["**/*.config.{js,mjs,ts}"],
|
|
178
|
+
rules: { "unicorn/no-top-level-side-effects": "off" },
|
|
179
|
+
},
|
|
180
|
+
prettier,
|
|
181
|
+
];
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
|
|
3
|
+
import prettier from "eslint-config-prettier";
|
|
4
|
+
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
5
|
+
import { flatConfigs as importX } from "eslint-plugin-import-x";
|
|
6
|
+
import react from "eslint-plugin-react";
|
|
7
|
+
import reactHooks from "eslint-plugin-react-hooks";
|
|
8
|
+
import unicorn from "eslint-plugin-unicorn";
|
|
9
|
+
import globals from "globals";
|
|
10
|
+
import { configs as typescript } from "typescript-eslint";
|
|
11
|
+
|
|
12
|
+
export default [
|
|
13
|
+
{ ignores: ["dist/", "build/", "coverage/", "**/vendor/**"] },
|
|
14
|
+
js.configs.recommended,
|
|
15
|
+
comments.recommended,
|
|
16
|
+
importX.recommended,
|
|
17
|
+
importX.typescript,
|
|
18
|
+
unicorn.configs.recommended,
|
|
19
|
+
...typescript.recommended,
|
|
20
|
+
react.configs.flat.recommended,
|
|
21
|
+
react.configs.flat["jsx-runtime"],
|
|
22
|
+
reactHooks.configs.flat.recommended,
|
|
23
|
+
{
|
|
24
|
+
languageOptions: {
|
|
25
|
+
globals: { ...globals.browser, ...globals.node },
|
|
26
|
+
},
|
|
27
|
+
settings: {
|
|
28
|
+
// Keep this. eslint-plugin-react crashes on ESLint 10 if it has to detect the version itself.
|
|
29
|
+
// Update the number when the project upgrades React.
|
|
30
|
+
react: { version: "19.0" },
|
|
31
|
+
"import-x/resolver-next": [createTypeScriptImportResolver()],
|
|
32
|
+
},
|
|
33
|
+
rules: {
|
|
34
|
+
"@eslint-community/eslint-comments/require-description":
|
|
35
|
+
"error",
|
|
36
|
+
"func-style": ["error", "expression"],
|
|
37
|
+
"max-depth": ["error", 3],
|
|
38
|
+
"max-lines": [
|
|
39
|
+
"error",
|
|
40
|
+
{ max: 300, skipBlankLines: true, skipComments: true },
|
|
41
|
+
],
|
|
42
|
+
"no-nested-ternary": "error",
|
|
43
|
+
"no-var": "error",
|
|
44
|
+
"prefer-arrow-callback": "error",
|
|
45
|
+
"prefer-const": "error",
|
|
46
|
+
"no-magic-numbers": [
|
|
47
|
+
"error",
|
|
48
|
+
{
|
|
49
|
+
ignore: [-1, 0, 1],
|
|
50
|
+
ignoreArrayIndexes: true,
|
|
51
|
+
ignoreDefaultValues: true,
|
|
52
|
+
enforceConst: true,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
"no-restricted-syntax": [
|
|
56
|
+
"error",
|
|
57
|
+
{
|
|
58
|
+
selector: "ClassDeclaration",
|
|
59
|
+
message: "Use functions, not classes.",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
selector: "ClassExpression",
|
|
63
|
+
message: "Use functions, not classes.",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
selector: "VariableDeclarator > FunctionExpression",
|
|
67
|
+
message: "Use an arrow function.",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
selector: "VariableDeclaration[kind='let']",
|
|
71
|
+
message:
|
|
72
|
+
"Use const. If this value really must be reassigned, disable this rule on this line with a comment saying why.",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
selector: "FunctionDeclaration[params.length>1]",
|
|
76
|
+
message:
|
|
77
|
+
"Use a single object parameter when a function needs more than one value.",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
selector:
|
|
81
|
+
"VariableDeclarator > :matches(ArrowFunctionExpression, FunctionExpression)[params.length>1]",
|
|
82
|
+
message:
|
|
83
|
+
"Use a single object parameter when a function needs more than one value.",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
"import-x/no-cycle": "error",
|
|
87
|
+
"import-x/no-default-export": "error",
|
|
88
|
+
"no-use-before-define": "error",
|
|
89
|
+
"unicorn/default-export-style": "off",
|
|
90
|
+
"unicorn/filename-case": [
|
|
91
|
+
"error",
|
|
92
|
+
{ cases: { camelCase: true, pascalCase: true } },
|
|
93
|
+
],
|
|
94
|
+
"unicorn/name-replacements": [
|
|
95
|
+
"error",
|
|
96
|
+
{
|
|
97
|
+
// Dictionary words: see "Dictionary" in the Human-Readable Names standard.
|
|
98
|
+
replacements: {
|
|
99
|
+
docs: false,
|
|
100
|
+
lib: false,
|
|
101
|
+
props: false,
|
|
102
|
+
ref: false,
|
|
103
|
+
repo: false,
|
|
104
|
+
utils: false,
|
|
105
|
+
},
|
|
106
|
+
// Third-party names, allowed only exactly as they are.
|
|
107
|
+
allowList: { params: true, searchParams: true },
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
"react/function-component-definition": [
|
|
111
|
+
"error",
|
|
112
|
+
{
|
|
113
|
+
namedComponents: "arrow-function",
|
|
114
|
+
unnamedComponents: "arrow-function",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
"react/jsx-no-bind": "error",
|
|
118
|
+
"react/no-multi-comp": "error",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
files: ["**/*.{ts,tsx}"],
|
|
123
|
+
rules: {
|
|
124
|
+
"no-undef": "off",
|
|
125
|
+
"no-magic-numbers": "off",
|
|
126
|
+
"no-use-before-define": "off",
|
|
127
|
+
"@typescript-eslint/consistent-type-assertions": [
|
|
128
|
+
"error",
|
|
129
|
+
{ assertionStyle: "never" },
|
|
130
|
+
],
|
|
131
|
+
"@typescript-eslint/consistent-type-imports": "error",
|
|
132
|
+
"@typescript-eslint/naming-convention": [
|
|
133
|
+
"error",
|
|
134
|
+
{
|
|
135
|
+
selector: ["typeAlias", "interface"],
|
|
136
|
+
format: ["PascalCase"],
|
|
137
|
+
custom: { regex: "(Props|Type)$", match: true },
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
141
|
+
"@typescript-eslint/no-magic-numbers": [
|
|
142
|
+
"error",
|
|
143
|
+
{
|
|
144
|
+
ignore: [-1, 0, 1],
|
|
145
|
+
ignoreArrayIndexes: true,
|
|
146
|
+
ignoreDefaultValues: true,
|
|
147
|
+
enforceConst: true,
|
|
148
|
+
ignoreEnums: true,
|
|
149
|
+
ignoreNumericLiteralTypes: true,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
153
|
+
"@typescript-eslint/no-use-before-define": "error",
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
files: ["**/*.test.{ts,tsx}"],
|
|
158
|
+
rules: {
|
|
159
|
+
"max-lines": "off",
|
|
160
|
+
"no-magic-numbers": "off",
|
|
161
|
+
"@typescript-eslint/no-magic-numbers": "off",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
files: ["**/*.config.{js,mjs,ts}", "**/*.stories.tsx"],
|
|
166
|
+
rules: { "import-x/no-default-export": "off" },
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
files: ["**/*.config.{js,mjs,ts}"],
|
|
170
|
+
rules: { "unicorn/no-top-level-side-effects": "off" },
|
|
171
|
+
},
|
|
172
|
+
prettier,
|
|
173
|
+
];
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
|
|
3
|
+
import prettier from "eslint-config-prettier";
|
|
4
|
+
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
5
|
+
import { flatConfigs as importX } from "eslint-plugin-import-x";
|
|
6
|
+
import unicorn from "eslint-plugin-unicorn";
|
|
7
|
+
import globals from "globals";
|
|
8
|
+
import { configs as typescript } from "typescript-eslint";
|
|
9
|
+
|
|
10
|
+
export default [
|
|
11
|
+
{ ignores: ["dist/", "build/", "coverage/", "**/vendor/**"] },
|
|
12
|
+
js.configs.recommended,
|
|
13
|
+
comments.recommended,
|
|
14
|
+
importX.recommended,
|
|
15
|
+
importX.typescript,
|
|
16
|
+
unicorn.configs.recommended,
|
|
17
|
+
...typescript.recommended,
|
|
18
|
+
{
|
|
19
|
+
languageOptions: { globals: { ...globals.node } },
|
|
20
|
+
settings: {
|
|
21
|
+
"import-x/resolver-next": [createTypeScriptImportResolver()],
|
|
22
|
+
},
|
|
23
|
+
rules: {
|
|
24
|
+
"@eslint-community/eslint-comments/require-description":
|
|
25
|
+
"error",
|
|
26
|
+
"func-style": ["error", "expression"],
|
|
27
|
+
"max-depth": ["error", 3],
|
|
28
|
+
"max-lines": [
|
|
29
|
+
"error",
|
|
30
|
+
{ max: 300, skipBlankLines: true, skipComments: true },
|
|
31
|
+
],
|
|
32
|
+
"no-nested-ternary": "error",
|
|
33
|
+
"no-var": "error",
|
|
34
|
+
"prefer-arrow-callback": "error",
|
|
35
|
+
"prefer-const": "error",
|
|
36
|
+
"no-magic-numbers": [
|
|
37
|
+
"error",
|
|
38
|
+
{
|
|
39
|
+
ignore: [-1, 0, 1],
|
|
40
|
+
ignoreArrayIndexes: true,
|
|
41
|
+
ignoreDefaultValues: true,
|
|
42
|
+
enforceConst: true,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
"no-restricted-syntax": [
|
|
46
|
+
"error",
|
|
47
|
+
{
|
|
48
|
+
selector: "ClassDeclaration",
|
|
49
|
+
message: "Use functions, not classes.",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
selector: "ClassExpression",
|
|
53
|
+
message: "Use functions, not classes.",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
selector: "VariableDeclarator > FunctionExpression",
|
|
57
|
+
message: "Use an arrow function.",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
selector: "VariableDeclaration[kind='let']",
|
|
61
|
+
message:
|
|
62
|
+
"Use const. If this value really must be reassigned, disable this rule on this line with a comment saying why.",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
selector: "FunctionDeclaration[params.length>1]",
|
|
66
|
+
message:
|
|
67
|
+
"Use a single object parameter when a function needs more than one value.",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
selector:
|
|
71
|
+
"VariableDeclarator > :matches(ArrowFunctionExpression, FunctionExpression)[params.length>1]",
|
|
72
|
+
message:
|
|
73
|
+
"Use a single object parameter when a function needs more than one value.",
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
"import-x/no-cycle": "error",
|
|
77
|
+
"import-x/no-default-export": "error",
|
|
78
|
+
"no-use-before-define": "error",
|
|
79
|
+
"unicorn/default-export-style": "off",
|
|
80
|
+
"unicorn/filename-case": [
|
|
81
|
+
"error",
|
|
82
|
+
{ cases: { camelCase: true, pascalCase: true } },
|
|
83
|
+
],
|
|
84
|
+
"unicorn/name-replacements": [
|
|
85
|
+
"error",
|
|
86
|
+
{
|
|
87
|
+
// Dictionary words: see "Dictionary" in the Human-Readable Names standard.
|
|
88
|
+
replacements: {
|
|
89
|
+
docs: false,
|
|
90
|
+
lib: false,
|
|
91
|
+
props: false,
|
|
92
|
+
ref: false,
|
|
93
|
+
repo: false,
|
|
94
|
+
utils: false,
|
|
95
|
+
},
|
|
96
|
+
// Third-party names, allowed only exactly as they are.
|
|
97
|
+
allowList: { params: true, searchParams: true },
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
files: ["**/*.{ts,tsx}"],
|
|
104
|
+
rules: {
|
|
105
|
+
"no-undef": "off",
|
|
106
|
+
"no-magic-numbers": "off",
|
|
107
|
+
"no-use-before-define": "off",
|
|
108
|
+
"@typescript-eslint/consistent-type-assertions": [
|
|
109
|
+
"error",
|
|
110
|
+
{ assertionStyle: "never" },
|
|
111
|
+
],
|
|
112
|
+
"@typescript-eslint/consistent-type-imports": "error",
|
|
113
|
+
"@typescript-eslint/naming-convention": [
|
|
114
|
+
"error",
|
|
115
|
+
{
|
|
116
|
+
selector: ["typeAlias", "interface"],
|
|
117
|
+
format: ["PascalCase"],
|
|
118
|
+
custom: { regex: "(Props|Type)$", match: true },
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
122
|
+
"@typescript-eslint/no-magic-numbers": [
|
|
123
|
+
"error",
|
|
124
|
+
{
|
|
125
|
+
ignore: [-1, 0, 1],
|
|
126
|
+
ignoreArrayIndexes: true,
|
|
127
|
+
ignoreDefaultValues: true,
|
|
128
|
+
enforceConst: true,
|
|
129
|
+
ignoreEnums: true,
|
|
130
|
+
ignoreNumericLiteralTypes: true,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
134
|
+
"@typescript-eslint/no-use-before-define": "error",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
files: ["**/*.test.{ts,tsx}"],
|
|
139
|
+
rules: {
|
|
140
|
+
"max-lines": "off",
|
|
141
|
+
"no-magic-numbers": "off",
|
|
142
|
+
"@typescript-eslint/no-magic-numbers": "off",
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
files: ["**/*.config.{js,mjs,ts}", "**/*.stories.tsx"],
|
|
147
|
+
rules: { "import-x/no-default-export": "off" },
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
files: ["**/*.config.{js,mjs,ts}"],
|
|
151
|
+
rules: { "unicorn/no-top-level-side-effects": "off" },
|
|
152
|
+
},
|
|
153
|
+
prettier,
|
|
154
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
@theme {
|
|
4
|
+
--color-brand-primary: #3b82f6;
|
|
5
|
+
--color-brand-primary-hover: #2563eb;
|
|
6
|
+
--color-brand-secondary: #64748b;
|
|
7
|
+
--color-surface: #fff;
|
|
8
|
+
--color-text: #0f172a;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
[data-theme="dark"] {
|
|
12
|
+
--color-brand-primary: #60a5fa;
|
|
13
|
+
--color-brand-primary-hover: #93c5fd;
|
|
14
|
+
--color-surface: #0f172a;
|
|
15
|
+
--color-text: #f8fafc;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pnpm lint
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const DOCS_URL = process.env.DOCS_URL;
|
|
2
|
+
|
|
3
|
+
/** @type {import("next").NextConfig} */
|
|
4
|
+
const nextConfig = {
|
|
5
|
+
async rewrites() {
|
|
6
|
+
// The docs are only served when DOCS_URL is set. It is never set in production.
|
|
7
|
+
if (!DOCS_URL) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return [
|
|
12
|
+
{ source: "/docs", destination: `${DOCS_URL}/docs/` },
|
|
13
|
+
{
|
|
14
|
+
source: "/docs/:path*",
|
|
15
|
+
destination: `${DOCS_URL}/docs/:path*`,
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default nextConfig;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** @type {import("prettier").Config & import("prettier-plugin-tailwindcss").PluginOptions} */
|
|
2
|
+
const config = {
|
|
3
|
+
// Short lines, so code reads well on a phone.
|
|
4
|
+
printWidth: 70,
|
|
5
|
+
// Tabs indent. A tab counts as 2 characters towards the line width.
|
|
6
|
+
useTabs: true,
|
|
7
|
+
tabWidth: 2,
|
|
8
|
+
singleQuote: false,
|
|
9
|
+
trailingComma: "all",
|
|
10
|
+
bracketSpacing: true,
|
|
11
|
+
bracketSameLine: false,
|
|
12
|
+
arrowParens: "always",
|
|
13
|
+
semi: true,
|
|
14
|
+
endOfLine: "lf",
|
|
15
|
+
plugins: ["prettier-plugin-tailwindcss"],
|
|
16
|
+
tailwindStylesheet: "./app/globals.css",
|
|
17
|
+
overrides: [
|
|
18
|
+
{
|
|
19
|
+
// YAML does not allow tabs, and Markdown reads a tab as four spaces.
|
|
20
|
+
files: ["*.md", "*.mdx", "*.yml", "*.yaml"],
|
|
21
|
+
options: { useTabs: false },
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default config;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codeReview
|
|
3
|
+
description: Review changes for bugs and standards compliance
|
|
4
|
+
argument-hint: "[branch, commit or path]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep, Bash(git diff:*), Bash(git log:*), Bash(git status:*), Bash(git merge-base:*)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Review the changes and report problems. Do NOT modify any files.
|
|
9
|
+
|
|
10
|
+
1. Work out what to review:
|
|
11
|
+
- If `$ARGUMENTS` is a file or folder path, review those files.
|
|
12
|
+
- If `$ARGUMENTS` is a branch or commit, review `git diff $ARGUMENTS...HEAD`.
|
|
13
|
+
- If `$ARGUMENTS` is empty, review `git diff main...HEAD` plus the uncommitted changes from `git diff`.
|
|
14
|
+
2. Read `AGENTS.md` for the project's code standards.
|
|
15
|
+
3. Read every changed file in full, not only the changed lines.
|
|
16
|
+
4. Check each change for:
|
|
17
|
+
- **Correctness** — logic errors, unhandled cases, broken error handling
|
|
18
|
+
- **Security** — unvalidated input, secrets in code, missing permission checks
|
|
19
|
+
- **Types** — `any`, non-null `!`, and `as` casts without a comment saying why
|
|
20
|
+
- **Tests** — every new or changed function and component has a test file
|
|
21
|
+
- **Readable code** — files over 300 lines, any name that is not human-readable (folders, files, props, form field `name`s and labels, types, union values, database columns, routes, environment variables and test names as well as variables), functions doing more than one thing, more than one parameter, nesting deeper than three levels, magic numbers
|
|
22
|
+
- **Structure** — reusable functions outside a `utils/` folder, server and client code in one file, inline functions in render
|
|
23
|
+
- **Styling** — hard-coded colours, CSS grid that was not asked for
|
|
24
|
+
5. Report the findings in order of severity: **Must fix**, **Should fix**, **Consider**. For each one give the file and line, what is wrong, and how to fix it.
|
|
25
|
+
6. Finish with a one-line verdict: ready to commit, or not.
|
|
26
|
+
|
|
27
|
+
If there are no changes to review, say so and stop.
|
|
28
|
+
|
|
29
|
+
Do NOT review files in `node_modules/` or `vendor/`. Third-party code is exempt from the standards.
|
|
30
|
+
Do NOT fix anything. Report only.
|
|
31
|
+
Do NOT stage, commit or push.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: format
|
|
3
|
+
description: Format files with Prettier and report what changed
|
|
4
|
+
argument-hint: "[path]"
|
|
5
|
+
allowed-tools: Read, Glob, Bash(pnpm format:*), Bash(git status:*)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Format the project with Prettier and report which files changed.
|
|
9
|
+
|
|
10
|
+
1. Read `package.json` and confirm a `format` script exists.
|
|
11
|
+
2. Run `pnpm format $ARGUMENTS`.
|
|
12
|
+
3. Run `git status --short` to see which files changed.
|
|
13
|
+
4. Report the reformatted files. If nothing changed, say the project was already formatted.
|
|
14
|
+
|
|
15
|
+
If `package.json` has no `format` script, stop and say so.
|
|
16
|
+
|
|
17
|
+
Do NOT change files in `node_modules/` or `vendor/`.
|
|
18
|
+
Do NOT stage, commit or push. Leave every change uncommitted.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lint
|
|
3
|
+
description: Run all linters in check-only mode and report issues
|
|
4
|
+
argument-hint: "[path]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep, Bash(pnpm lint:*)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Run every configured linter and report the issues. Do NOT modify any files.
|
|
9
|
+
|
|
10
|
+
1. Read `package.json` and find the lint scripts (`lint`, and `lint:css` if it exists).
|
|
11
|
+
2. Run each one in check-only mode:
|
|
12
|
+
- ESLint: `pnpm lint $ARGUMENTS`
|
|
13
|
+
- Stylelint, only if the `lint:css` script exists: `pnpm lint:css`
|
|
14
|
+
3. Report the findings grouped by file. For each issue give the line, the rule name and the message, then explain in one plain-English sentence what is wrong and how to fix it. Write for someone who does not read code.
|
|
15
|
+
4. Finish with a one-line total: the number of errors and warnings, and how many are auto-fixable.
|
|
16
|
+
|
|
17
|
+
If `package.json` has no `lint` script, stop and say so. Do NOT fall back to running `eslint` directly.
|
|
18
|
+
|
|
19
|
+
Do NOT fix anything, even issues that are auto-fixable — `/lintFix` does that.
|
|
20
|
+
Do NOT lint or report on files in `node_modules/` or `vendor/`. Third-party code is exempt from the standards.
|
|
21
|
+
Do NOT stage, commit or push.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lintFix
|
|
3
|
+
description: Auto-fix lint and formatting issues, then report
|
|
4
|
+
argument-hint: "[path]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep, Bash(pnpm lint:*), Bash(pnpm format:*), Bash(git status:*), Bash(git diff:*)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Run every linter in fix mode, then the formatter, and report what changed.
|
|
9
|
+
|
|
10
|
+
1. Read `package.json` and find the scripts that exist: `lint:fix`, `lint:css:fix` and `format`.
|
|
11
|
+
2. Run them in this order, skipping any that do not exist:
|
|
12
|
+
- ESLint: `pnpm lint:fix $ARGUMENTS`
|
|
13
|
+
- Stylelint: `pnpm lint:css:fix`
|
|
14
|
+
- Prettier: `pnpm format`
|
|
15
|
+
3. Run `git status --short` and `git diff --stat` to see which files changed.
|
|
16
|
+
4. Report:
|
|
17
|
+
- The files that were changed
|
|
18
|
+
- The issues that remain and could not be fixed automatically, grouped by file
|
|
19
|
+
|
|
20
|
+
If none of the three scripts exist, stop and say so.
|
|
21
|
+
|
|
22
|
+
Do NOT fix the remaining issues by hand. Report them and leave them for the person.
|
|
23
|
+
Do NOT change files in `node_modules/` or `vendor/`. Third-party code is exempt from the standards.
|
|
24
|
+
Do NOT stage, commit or push. Leave every change uncommitted.
|