@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
package/README.md
CHANGED
|
@@ -1,3 +1,200 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🦘 Activatus Code Standards
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**One way of doing things, written down, so nobody has to guess.**
|
|
4
|
+
|
|
5
|
+
This is the rulebook for how we write code at Activatus. It's a docs site, a pile of copy-paste config files, and a set of lint rules that'll dob you in before your reviewer has to.
|
|
6
|
+
|
|
7
|
+
The whole point: you should be able to wander into any Activatus project at 4pm on a Friday and know exactly where everything lives, like walking into a mate's shed and finding the 10mm socket first go.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🤔 Why this exists
|
|
12
|
+
|
|
13
|
+
Every team says they've got standards. Most of them live in one bloke's head and a Slack thread from 2022.
|
|
14
|
+
|
|
15
|
+
Ours live here. If it's not in this repo, it's not a standard, it's an opinion.
|
|
16
|
+
|
|
17
|
+
- 🧠 **Readable by humans.** If a new starter can't follow a file, the file's wrong, not the new starter.
|
|
18
|
+
- 🤖 **Readable by AI.** Claude Code and friends follow the same rules we do. No special treatment.
|
|
19
|
+
- 🚨 **Enforced by the linter where we can.** Rules that rely on everyone remembering are rules that get forgotten.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📦 Using it in a project
|
|
24
|
+
|
|
25
|
+
The standards ship as an npm package, published on npm (npmjs.com) and installed with pnpm, so an AI agent reads the exact version a project uses, straight from `node_modules`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add -D @activatus/code-standards
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then tell your agent: **"Follow the Activatus Code Standards. Start with `node_modules/@activatus/code-standards/docs/Guides/setup.md`."** It prints a numbered list of the standards, you say which ones you don't want, and it sets up the rest. You never touch the terminal.
|
|
32
|
+
|
|
33
|
+
The package version is the standards version: `2.0.0` is version 2.
|
|
34
|
+
|
|
35
|
+
> 🔢 **Updating a project to newer standards?** Run `pnpm update @activatus/code-standards --latest`, then point the agent at the **[Version History](https://activatus-code-standards.vercel.app/version-history)**: it reads only the versions newer than the project's, does exactly what each one says, and bumps the number. Cheaper than shouting the whole pub a round.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 🚀 Get it running
|
|
40
|
+
|
|
41
|
+
You'll need **Node 20+** and **pnpm**.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm install
|
|
45
|
+
pnpm start
|
|
46
|
+
pnpm serve
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
That fires up the site locally with hot reload. Easy as.
|
|
50
|
+
|
|
51
|
+
The live site is at **[activatus-code-standards.vercel.app](https://activatus-code-standards.vercel.app)**. That's the link to share.
|
|
52
|
+
|
|
53
|
+
| Command | What it does |
|
|
54
|
+
| ---------------- | -------------------------------------------- |
|
|
55
|
+
| `pnpm start` | 🔥 Dev server with hot reload |
|
|
56
|
+
| `pnpm build` | 📦 Builds the static site into `build/` |
|
|
57
|
+
| `pnpm serve` | 👀 Serves the built site so you can check it |
|
|
58
|
+
| `pnpm typecheck` | 🔍 Runs TypeScript over the site config |
|
|
59
|
+
| `pnpm format` | ✨ Formats everything with Prettier |
|
|
60
|
+
|
|
61
|
+
> 🔎 **Search only works on the built site.** Run `pnpm build` then `pnpm serve` if you want to test it. It won't show up in `pnpm start`, so don't go thinking you've broken it.
|
|
62
|
+
|
|
63
|
+
> 🐌 **Install carking it on a slow connection?** One of the packages is a big unit. Run `pnpm install --fetch-timeout 600000` and go put the kettle on.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 📚 What's in the box
|
|
68
|
+
|
|
69
|
+
| Section | What you'll find |
|
|
70
|
+
| ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| 📋 **Templates** | Ready-to-copy `AGENTS.md`, ESLint, Prettier, Stylelint and friends |
|
|
72
|
+
| 📖 **Ontology** | The code words we use and what each one means |
|
|
73
|
+
| 🔢 **[Version History](https://activatus-code-standards.vercel.app/version-history)** | What changed in each version, and what a project has to do about it. Updating a project? Read only the versions newer than the one in its `AGENTS.md` |
|
|
74
|
+
| 🧭 **Guides** | Setting up a new project, dragging an old one up to scratch, and how design becomes code |
|
|
75
|
+
| 📏 **Standards** | Readable code, linting, formatting, styling, commits, the tech stack and AI agent rules |
|
|
76
|
+
| 🏗️ **Structure** | Folders, components, naming, imports and API routes |
|
|
77
|
+
| 🧩 **[Design System Components](https://activatus-code-standards.vercel.app/design-system-components)** | Every standard component and its props, so each project builds them the same way |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## ⚡ The rules, at pub-yarn speed
|
|
82
|
+
|
|
83
|
+
The full detail's on the site. This is the version you'd tell someone over a schooner.
|
|
84
|
+
|
|
85
|
+
### ✍️ Writing code
|
|
86
|
+
|
|
87
|
+
- 📄 **No file over 300 lines.** If it's longer, it's doing two jobs. Split it. (Test files get a leave pass.)
|
|
88
|
+
- 🗣️ **Every name is real English words.** Variables, props, form fields, types, files, folders, the lot. `button`, not `btn`. We're not paying by the letter. The one exception: names someone else owns, like Linear's `id` or Node's `cwd` option.
|
|
89
|
+
- 🔒 **Always `const`.** Need `let`? Fine, but leave a comment saying why, or the linter knocks it back.
|
|
90
|
+
- 🏹 **Arrow functions everywhere.** `const Button = () => {}`. The word `function` is clutter, so we don't use it.
|
|
91
|
+
- 🔄 **No circular imports. Ever.** If two files import each other, pull the shared bit into a third file.
|
|
92
|
+
- 🎯 **A function does one thing.** If you need the word "and" to describe it, it's two functions.
|
|
93
|
+
- 🧪 **Every function and component gets a test file.** One test file, one thing tested. No test, not finished.
|
|
94
|
+
- 🚫 **Functions, never classes.** Not even a little one.
|
|
95
|
+
- 📦 **One parameter per function.** Need more? Pass an object, so the call explains itself.
|
|
96
|
+
- 🚪 **Return early.** Deal with the dodgy cases up top instead of nesting four `if`s deep like a set of Russian dolls.
|
|
97
|
+
- 🔢 **No magic numbers.** `MAXIMUM_RETRY_ATTEMPTS`, not a random `3` sitting there like it owns the place.
|
|
98
|
+
- 🏷️ **Type names end in `Props` or `Type`.** So you can tell what you're looking at.
|
|
99
|
+
- 💬 **Comments explain why, not what.** And no commented-out code. Git remembers, you don't have to.
|
|
100
|
+
|
|
101
|
+
### 🎨 Styling
|
|
102
|
+
|
|
103
|
+
- 🌬️ **Tailwind for everything.**
|
|
104
|
+
- 📐 **Flexbox first.** Split layouts into child components. Only use CSS grid if someone specifically asks for it.
|
|
105
|
+
- 🎨 **Colours come from the global palette. Full stop.** No hard-coded hex, no one-off values. If the colour's not in the palette, it's not in the build.
|
|
106
|
+
|
|
107
|
+
### 📖 Docs
|
|
108
|
+
|
|
109
|
+
- 📝 **Docs are plain Markdown in `docs/`, and every file is a Decision Doc.** Same folders in every project. Agents read the files; humans browse them at `/docs`.
|
|
110
|
+
- 🔒 **`/docs` only exists when `DOCS_URL` is set.** It's never set in production, so the docs never leak onto a live site.
|
|
111
|
+
- ✅ **Not finished until the docs are updated.** Change how something works, fix the doc in the same change.
|
|
112
|
+
|
|
113
|
+
### 🤖 Workflow is the project's call
|
|
114
|
+
|
|
115
|
+
- 🧭 **Branches, commit messages, Pull Requests and whether AI agents may commit are up to each project.** Every team runs its work differently, so it goes in the project's own `AGENTS.md` and docs, not here. These standards are the base for the code itself.
|
|
116
|
+
|
|
117
|
+
### 📦 Third-party code
|
|
118
|
+
|
|
119
|
+
- 📦 **Third-party code is exempt.** Anything in `node_modules/` or `vendor/` isn't ours. Don't lint it, don't tidy it, leave it be.
|
|
120
|
+
|
|
121
|
+
### 🗂️ Structure
|
|
122
|
+
|
|
123
|
+
- 🐫 **Code files are camelCase.** Components are PascalCase (`Button.tsx`) inside a camelCase folder (`button/`).
|
|
124
|
+
- 🔗 **If it becomes a URL, it's kebab-case.** Route folders and doc files (`background-jobs.md`). CSS variables too.
|
|
125
|
+
- 🧰 **Reusable functions live in `utils/`.** Global, section or component level, one folder per function, with an `index.ts` so imports stay tidy.
|
|
126
|
+
- 📍 **Components live where they're used.** Design System Components in `components/ui/`, anything used on more than one page in `components/shared/`, and one-page components in that page's own `components/` folder. No feature folders.
|
|
127
|
+
- 🧱 **Components follow the same order every time.** Imports, component, variables, state, effects, render. No inline functions in the render.
|
|
128
|
+
- 🔀 **Server and client code live in separate files.** The server one wraps the client one.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 📋 Just want the files?
|
|
133
|
+
|
|
134
|
+
Fair enough. Head to the **Templates** page on the site, or grab them straight from [`static/templates/`](static/templates):
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
static/templates/
|
|
138
|
+
├── AGENTS.md # 🤖 Context file for AI agents
|
|
139
|
+
├── skills/ # 🛠️ Eight ready-made agent skills
|
|
140
|
+
├── docs/ # 📖 The full set of Decision Doc templates, one per standard folder
|
|
141
|
+
├── docsSite/ # 🌐 Docusaurus viewer that shows docs/ at /docs
|
|
142
|
+
├── eslint/ # 🚨 Four flavours: base, typescript, react, nextjs
|
|
143
|
+
├── stylelint/ # 💅 CSS and SCSS
|
|
144
|
+
├── prettier.config.mjs # ✨ Formatting
|
|
145
|
+
├── globals.css # 🎨 Tailwind + starter colour palette
|
|
146
|
+
├── .editorconfig # ⌨️ Editor whitespace rules
|
|
147
|
+
├── .nvmrc / .envrc # 🟢 Node version switching
|
|
148
|
+
└── husky/pre-commit # 🚦 Lint before every commit
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Copy them. Don't retype them. The ESLint ones have been run against real code, so they actually work, which is more than you can say for most configs floating around the internet.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 🗺️ Finding your way around this repo
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
.
|
|
159
|
+
├── docs/ # 📝 Every page on the site, as Markdown
|
|
160
|
+
│ ├── Guides/
|
|
161
|
+
│ ├── Standards/
|
|
162
|
+
│ └── Structure/
|
|
163
|
+
├── static/
|
|
164
|
+
│ ├── images/ # 🖼️ Logo and favicon
|
|
165
|
+
│ └── templates/ # 📋 The copy-paste files
|
|
166
|
+
├── src/css/custom.css # 🎨 Site theme overrides
|
|
167
|
+
├── docusaurus.config.mjs # ⚙️ Site config
|
|
168
|
+
└── sidebars.mjs # 📑 Sidebar (builds itself from docs/)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Built with [Docusaurus](https://docusaurus.io). The sidebar generates itself from the folders, so there's no menu file to forget about.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## ✏️ Changing a standard
|
|
176
|
+
|
|
177
|
+
Reckon a rule's wrong, or there's one missing? Good. Standards that never change are standards nobody reads.
|
|
178
|
+
|
|
179
|
+
1. 🌿 **Branch off `main`**, named after the ticket (`ACT-14-update-eslint-page`), or `type/short-description` if there's no ticket (`docs/update-eslint-page`).
|
|
180
|
+
2. 📝 **Edit or add a Markdown file in `docs/`.** Name it in kebab-case (`naming-conventions.md`, not `namingConventions.md`), because the file name becomes the page's URL. Yes, we follow our own rules here.
|
|
181
|
+
3. 📋 **Changing a config?** Edit the file in `static/templates/` and the matching page in `docs/Standards/` so the two don't drift apart.
|
|
182
|
+
4. 🔢 **Add a version** to `docs/version-history.md`: what changed, and what a project has to do about it. Bump the major version in `package.json` to match (version 3 is `3.0.0`), and publish it to npm (npmjs.com) once it's merged. We use pnpm for everything, so that's `pnpm publish`, which lands in the same npm registry as `npm publish`. Projects read only the new versions, so if it's not in there, nobody hears about it.
|
|
183
|
+
5. 🔨 **Run `pnpm build`.** It fails on broken links, so you'll know quick smart if you've stuffed one.
|
|
184
|
+
6. 🚀 **Open a pull request** and say why the change makes life better.
|
|
185
|
+
|
|
186
|
+
A good rule of thumb: if you can't explain the rule to a new starter in one sentence, it's not ready.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 🚧 Before this goes live
|
|
191
|
+
|
|
192
|
+
- [ ] 🖼️ **Swap in the real logo.** `static/images/logo.svg` is a stand-in.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 💚 The short version
|
|
197
|
+
|
|
198
|
+
Write code the next person can read. Test it. Keep it small. Follow the pattern.
|
|
199
|
+
|
|
200
|
+
Do that and we'll all get home on time.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 1
|
|
3
|
+
sidebar_label: "Workflow"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Component & Design-to-Code Workflow
|
|
7
|
+
|
|
8
|
+
How components get from design into a project: where they come from, what we are allowed to change, and how AI automation fits without producing drift.
|
|
9
|
+
|
|
10
|
+
:::tip[The one-line summary]
|
|
11
|
+
|
|
12
|
+
**Every project builds on the same shadcn components. How a component works stays identical everywhere — only how it looks changes from project to project.**
|
|
13
|
+
|
|
14
|
+
:::
|
|
15
|
+
|
|
16
|
+
## How it fits together
|
|
17
|
+
|
|
18
|
+
| Layer | What it is | Owned by |
|
|
19
|
+
| --------------------- | -------------------------------------------------------------------------------------------------- | ------------- |
|
|
20
|
+
| **Claude Design** | Where designs are produced, using shadcn components and the project's colour palette. | Design |
|
|
21
|
+
| **shadcn/ui** | The source of every base component. Added to a project with the shadcn CLI. | — |
|
|
22
|
+
| **`components/ui/`** | The project's own copy of those components, converted to our standards and styled for the project. | Dev |
|
|
23
|
+
| **CMS components** | Wrappers that connect `components/ui/` to a CMS such as Storyblok. | Dev |
|
|
24
|
+
| **CMS project space** | Supplies content and data to the project. | Dev + Content |
|
|
25
|
+
|
|
26
|
+
## Each project has its own components
|
|
27
|
+
|
|
28
|
+
**There is no shared component library.** Each project adds the shadcn components it needs straight into its own `components/ui/` folder.
|
|
29
|
+
|
|
30
|
+
Our projects are different products, so a shared library is not worth its upkeep yet. We will build one later — see [Future-proofing](#future-proofing). What keeps the projects consistent until then is one rule.
|
|
31
|
+
|
|
32
|
+
## Same component, different paint
|
|
33
|
+
|
|
34
|
+
**The way a component works is identical in every project. Only the way it looks changes.**
|
|
35
|
+
|
|
36
|
+
| | Rule | Examples |
|
|
37
|
+
| ---------------- | ---------------- | ---------------------------------------------------------------------------- |
|
|
38
|
+
| **How it works** | ❌ Do not change | Props and their names, variants, behaviour, keyboard handling, accessibility |
|
|
39
|
+
| **How it looks** | ✅ Change freely | Colours, spacing, corner radius, typography, shadows |
|
|
40
|
+
|
|
41
|
+
A `Button` in one Activatus project takes the same props and behaves the same way as a `Button` in any other. A developer or an AI agent who knows one project's components knows them all.
|
|
42
|
+
|
|
43
|
+
- **Keep shadcn's props exactly as they ship.** Do not rename, remove or repurpose a prop.
|
|
44
|
+
- **Style through the [global colour palette](/Standards/styling#-colours-always-come-from-global-variables)** and Tailwind classes. Per-project branding is a palette change, not a component rewrite.
|
|
45
|
+
- **Need different behaviour?** Build a new component that wraps the base one. Do not change the base component.
|
|
46
|
+
|
|
47
|
+
Keeping the components identical is also what makes a shared library possible later — see [Future-proofing](#future-proofing).
|
|
48
|
+
|
|
49
|
+
## Adding a shadcn component
|
|
50
|
+
|
|
51
|
+
**shadcn is where a component starts. What lives in `components/ui/` is ours.**
|
|
52
|
+
|
|
53
|
+
The shadcn CLI copies source code into the project. From that moment it is **our code, not third-party code**: we own it, and it follows every standard. It never goes in `vendor/`.
|
|
54
|
+
|
|
55
|
+
The CLI writes files in shadcn's format, which breaks our standards — kebab-case file names, many components in one file, no folder, no types file and no tests. **Convert them in the same change that adds them.** Never leave raw CLI output in the project.
|
|
56
|
+
|
|
57
|
+
### Before and after
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
❌ What the shadcn CLI writes
|
|
61
|
+
components/ui/
|
|
62
|
+
├── button.tsx
|
|
63
|
+
└── dropdown-menu.tsx # 15 components in one file
|
|
64
|
+
|
|
65
|
+
✅ What we keep
|
|
66
|
+
components/ui/
|
|
67
|
+
├── button/
|
|
68
|
+
│ ├── Button.tsx
|
|
69
|
+
│ ├── Button.test.tsx
|
|
70
|
+
│ ├── types.ts
|
|
71
|
+
│ └── index.ts
|
|
72
|
+
└── dropdownMenu/
|
|
73
|
+
├── DropdownMenu.tsx
|
|
74
|
+
├── DropdownMenu.test.tsx
|
|
75
|
+
├── types.ts
|
|
76
|
+
├── index.ts
|
|
77
|
+
├── dropdownMenuTrigger/
|
|
78
|
+
├── dropdownMenuContent/
|
|
79
|
+
└── dropdownMenuItem/
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Converting a component
|
|
83
|
+
|
|
84
|
+
1. **Add it** with the shadcn CLI.
|
|
85
|
+
2. **Keep only the parts the project uses.** A shadcn file often exports many components. Delete the ones that are not used — if one is needed later, add it again and convert it the same way.
|
|
86
|
+
3. **Give each component its own folder and file**: a camelCase folder with a PascalCase file (`button/Button.tsx`). One component per file — sub-components get [their own folders](/Structure/component-organization#nested-components) inside the parent.
|
|
87
|
+
4. **Add the standard files** to each folder: `types.ts`, `index.ts` and a test file. See [Component Organization](/Structure/component-organization).
|
|
88
|
+
5. **Apply the code standards**: named exports, type names ending in `Props` or `Type`, full English names for our own variables.
|
|
89
|
+
6. **Leave the props and behaviour alone.** Converting changes the file layout and the styling, never [how the component works](#same-component-different-paint).
|
|
90
|
+
7. **Use the global colour palette.** Replace shadcn's colour classes with colours from [the palette](/Standards/styling#-colours-always-come-from-global-variables).
|
|
91
|
+
8. **Move shared helpers to `utils/`.** shadcn's `cn` helper lives in the [global `utils/` folder](/Structure/folder-structure#-utils), not in `lib/utilities.ts`.
|
|
92
|
+
9. **Run `pnpm lint` and `pnpm test`.** The converted component must pass both.
|
|
93
|
+
|
|
94
|
+
### What is still third-party
|
|
95
|
+
|
|
96
|
+
The packages a shadcn component imports — Radix UI and the like — stay in `node_modules/` and are [exempt from the standards](/Standards/eslint#third-party-code-is-exempt). Only the component source that the CLI copies into the project becomes ours.
|
|
97
|
+
|
|
98
|
+
## The design → code loop
|
|
99
|
+
|
|
100
|
+
1. **Design in Claude Design** using shadcn components and the project's palette.
|
|
101
|
+
2. **A new component is needed** → [look before you build](#1-look-before-you-build), then add it from shadcn and [convert it](#converting-a-component).
|
|
102
|
+
3. **A new look is needed** → change the palette or the component's classes. The props stay as they are.
|
|
103
|
+
4. **Something shadcn does not provide** → build it in `components/ui/` from existing components, following [Component Organization](/Structure/component-organization).
|
|
104
|
+
|
|
105
|
+
:::caution[Design and code are decoupled]
|
|
106
|
+
|
|
107
|
+
A design change does **not** automatically change the code. Component changes are made deliberately, in a reviewed change.
|
|
108
|
+
|
|
109
|
+
:::
|
|
110
|
+
|
|
111
|
+
## AI automation: governed, not soup
|
|
112
|
+
|
|
113
|
+
Soup comes from letting AI generate components freely for every screen. We prevent it by making `components/ui/` a **hard constraint** and pointing automation at composition.
|
|
114
|
+
|
|
115
|
+
- **Base components** come from shadcn and are converted once. AI does not invent a new button, input or dialog.
|
|
116
|
+
- **Page composition** is where AI does the heavy lifting: assembling pages from the components already in `components/ui/`.
|
|
117
|
+
|
|
118
|
+
**Guardrails:** typed props, lint rules (no hard-coded colours, no inline styles) and tests. **Gap-loop:** when a component is missing, AI _flags it_ and adds it from shadcn, instead of inventing one.
|
|
119
|
+
|
|
120
|
+
## Maintenance
|
|
121
|
+
|
|
122
|
+
- **Foundation upgrades** (Tailwind, Radix, React) are done per project, and proven with the project's tests.
|
|
123
|
+
- **Updating a shadcn component** means adding it again from shadcn and converting it again. Because the props were never changed, the update drops in.
|
|
124
|
+
|
|
125
|
+
## Future-proofing
|
|
126
|
+
|
|
127
|
+
**We know we are building the same components more than once.** Each project has its own copy today. One day those copies will be pulled out into a single shared repository that every project installs.
|
|
128
|
+
|
|
129
|
+
That refactor is **planned, but not now**. Until then, two things stop each project from reinventing the same component differently, and keep the eventual refactor cheap.
|
|
130
|
+
|
|
131
|
+
### 1. Look before you build
|
|
132
|
+
|
|
133
|
+
Before building any component, check these in order and stop at the first match:
|
|
134
|
+
|
|
135
|
+
| # | Look in | If it is there |
|
|
136
|
+
| --- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
137
|
+
| 1 | The project's own `components/ui/` | Use it |
|
|
138
|
+
| 2 | The [Design System Components](/design-system-components) | Build it to the listed variants and props |
|
|
139
|
+
| 3 | Another Activatus project | Copy the component's whole folder — code, types and tests — then restyle it |
|
|
140
|
+
| 4 | shadcn | Add it and [convert it](#converting-a-component) |
|
|
141
|
+
| 5 | Nowhere | Build it, and **add it to the [Design System Components](/design-system-components)** so the next project builds it the same way |
|
|
142
|
+
|
|
143
|
+
**Copying a finished component from another Activatus project is encouraged.** Rebuilding one from memory is how two projects end up with two different buttons.
|
|
144
|
+
|
|
145
|
+
### 2. Build every component to be lifted out
|
|
146
|
+
|
|
147
|
+
A component in `components/ui/` must be able to move to another project — or to a shared library — by copying its folder and changing nothing but its styling.
|
|
148
|
+
|
|
149
|
+
| Rule | Why |
|
|
150
|
+
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
151
|
+
| **Everything comes in through props.** No fetching data, no reading global state | The component cannot depend on one project's data |
|
|
152
|
+
| **No imports from the project's pages, shared components, services, stores or `app/` folder** | Those do not exist in the next project |
|
|
153
|
+
| **It may import only** other `components/ui/` components, the global `utils/` folder and installed packages | These travel with it |
|
|
154
|
+
| **No project names, client names or business rules inside it** | A `Button` knows nothing about invoices |
|
|
155
|
+
| **Its types and tests live in its folder** | They move when the folder moves |
|
|
156
|
+
| **Its props match the [Design System Components](/design-system-components)** | Every project's copy is interchangeable |
|
|
157
|
+
|
|
158
|
+
Logic that belongs to one project goes in a **page or shared component** (in the page's `components/` folder, or `components/shared/`) that wraps the base component and passes it props. See [Where components live](/Structure/folder-structure#-where-components-live). The base component stays clean.
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
// ✅ Good — the base component takes props; the page component knows about invoices
|
|
162
|
+
// app/(billing)/components/invoiceTable/InvoiceTable.tsx
|
|
163
|
+
<DataTable
|
|
164
|
+
rows={invoices}
|
|
165
|
+
columns={INVOICE_COLUMNS}
|
|
166
|
+
onRowSelect={handleInvoiceSelect}
|
|
167
|
+
/>;
|
|
168
|
+
|
|
169
|
+
// ❌ Bad — a base component that fetches invoices cannot be reused anywhere else
|
|
170
|
+
// components/ui/dataTable/DataTable.tsx
|
|
171
|
+
const invoices = await getInvoices();
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### When the shared library gets built
|
|
175
|
+
|
|
176
|
+
Not on a date — on a signal. It is time to build it when any of these becomes true:
|
|
177
|
+
|
|
178
|
+
- The same bug has to be fixed in the same component in more than one project.
|
|
179
|
+
- Keeping the projects' components in step is taking real time.
|
|
180
|
+
- A new project would copy most of its `components/ui/` from an existing one.
|
|
181
|
+
|
|
182
|
+
Because every project followed the two rules above, the refactor is then a matter of moving folders, not rewriting components.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 3
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Migrating an Existing Project
|
|
6
|
+
|
|
7
|
+
Migrating an established codebase to the shared standards is best done in stages to keep PRs reviewable.
|
|
8
|
+
|
|
9
|
+
**Already following the standards, and just updating to a newer version?** You don't need this whole guide. Read the [Version History](/version-history) from your project's version onward, and do only what it lists.
|
|
10
|
+
|
|
11
|
+
## Before you start: third-party code is exempt
|
|
12
|
+
|
|
13
|
+
The standards apply to **code we write**, not to packages we pull in. Do not lint, reformat, rename or restructure third-party code — see [Third-party code is exempt](/Standards/eslint#third-party-code-is-exempt).
|
|
14
|
+
|
|
15
|
+
- `node_modules/` is ignored automatically.
|
|
16
|
+
- Third-party code copied into the repo belongs in a `vendor/` folder, which the configs ignore.
|
|
17
|
+
- Add `vendor/` to `.prettierignore` too.
|
|
18
|
+
- **shadcn components are not third-party.** They are our code: convert them to the standards rather than moving them to `vendor/`. See [Adding a shadcn component](/Guides/component-library-workflow#adding-a-shadcn-component).
|
|
19
|
+
|
|
20
|
+
## Stage 1 — Prettier (formatting only)
|
|
21
|
+
|
|
22
|
+
Formatting changes are safe to land in one big PR because they don't change behaviour.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add -D prettier prettier-plugin-tailwindcss
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Add `prettier.config.mjs` — see the [Prettier page](/Standards/prettier) for the full file contents.
|
|
29
|
+
|
|
30
|
+
Format everything at once:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm prettier --write .
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Commit it on its own, following the project's commit message format. This keeps the formatting diff isolated, making future `git blame` useful.
|
|
37
|
+
|
|
38
|
+
Add a `.prettierignore` if you have generated files you don't want touched:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
dist/
|
|
42
|
+
build/
|
|
43
|
+
coverage/
|
|
44
|
+
vendor/
|
|
45
|
+
*.generated.ts
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Stage 2 — EditorConfig
|
|
49
|
+
|
|
50
|
+
Add the `.editorconfig` file. No code changes needed — your editor will handle it on next save.
|
|
51
|
+
|
|
52
|
+
## Stage 3 — ESLint
|
|
53
|
+
|
|
54
|
+
Add the [standard config](/Standards/eslint) for your project type, then start in warn-only mode to see what you're dealing with. Add a block before `prettier`:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
export default [
|
|
58
|
+
// ...
|
|
59
|
+
{
|
|
60
|
+
rules: {
|
|
61
|
+
// temporarily downgrade errors to warnings during migration
|
|
62
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
63
|
+
"unicorn/filename-case": "warn",
|
|
64
|
+
"unicorn/name-replacements": "warn",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
prettier,
|
|
68
|
+
];
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Run `pnpm lint` and triage the output. Fix issues in thematic PRs (e.g. all `any` removals together). Once clean, remove the overrides.
|
|
72
|
+
|
|
73
|
+
## Stage 4 — Names
|
|
74
|
+
|
|
75
|
+
Renaming is the biggest job in most migrations, and the easiest place to get confused. Every name we write becomes [Human-Readable Names](/Standards/human-readable-names). Work through it in this order.
|
|
76
|
+
|
|
77
|
+
### 1. Decide what stays
|
|
78
|
+
|
|
79
|
+
Before renaming anything, sort the short names into three piles:
|
|
80
|
+
|
|
81
|
+
| Pile | What to do | Where to check |
|
|
82
|
+
| ---------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------- |
|
|
83
|
+
| **A dictionary word** — `id`, `docs`, `app`, `url`, `api` | Leave it | [Dictionary](/Standards/human-readable-names#dictionary) |
|
|
84
|
+
| **A third-party name** — React's `ref`, Next.js's `params`, shadcn/ui's `cn`, Linear's `pageInfo`, Node's `cwd` option | Leave it exactly as it is | [Third-party names](/Standards/human-readable-names#third-party-names) |
|
|
85
|
+
| **Our own shorthand** — `btn`, `lib/`, `helpers/`, `utilities/` | Rename it | The [Never / Always](/Standards/human-readable-names#never--always) table |
|
|
86
|
+
|
|
87
|
+
**Not sure which pile?** Don't guess and don't rename it. Ask, and if it is a dictionary word, [add it to the dictionary](/Standards/human-readable-names#adding-a-word-to-the-dictionary) first. Everyone then makes the same call.
|
|
88
|
+
|
|
89
|
+
### 2. The common renames
|
|
90
|
+
|
|
91
|
+
These come up in nearly every project:
|
|
92
|
+
|
|
93
|
+
| Before | After |
|
|
94
|
+
| -------------------------------------- | -------------------------------------------- |
|
|
95
|
+
| `utilities/`, `helpers/`, `helpers.ts` | `utils/`, or a file named after what it does |
|
|
96
|
+
| `ButtonProperties`, `properties` | `ButtonProps`, `props` |
|
|
97
|
+
| `MAX_`, `MIN_` | `MAXIMUM_`, `MINIMUM_` |
|
|
98
|
+
| `"sm" \| "md" \| "lg"` | `"small" \| "medium" \| "large"` |
|
|
99
|
+
| `auth`, `useAuth` | `authentication`, `useAuthentication` |
|
|
100
|
+
| `(e) =>`, `(i) =>` | `(event) =>`, `(index) =>` |
|
|
101
|
+
|
|
102
|
+
`docs/`, `docsSite/`, `DOCS_URL` and `pnpm docs:dev` already follow the standard. Leave them.
|
|
103
|
+
|
|
104
|
+
### 3. Rename in this order, one pull request each
|
|
105
|
+
|
|
106
|
+
1. **Folders**, with `git mv` so the history follows the files. Fix the imports in the same pull request.
|
|
107
|
+
2. **Types**, so the `@typescript-eslint/naming-convention` errors clear.
|
|
108
|
+
3. **Variables, functions and properties.** Use your editor's **Rename Symbol** (F2), not find-and-replace: it renames every use and nothing else. An agent working from the command line has no editor, so it uses the [rename script](#renaming-from-the-command-line) instead.
|
|
109
|
+
4. **Everything the linter can't see** — form fields, union values, routes, scripts, environment variables. Search for each one by hand.
|
|
110
|
+
|
|
111
|
+
### 4. Names that leave the codebase
|
|
112
|
+
|
|
113
|
+
Some names are used outside the code. Renaming them needs more than a code change:
|
|
114
|
+
|
|
115
|
+
- **Database columns** need a migration.
|
|
116
|
+
- **Environment variables** must be renamed in every `.env.local` and in Vercel's settings too, or the app gets an empty value.
|
|
117
|
+
- **API routes and request fields** used by another app need both names to work until that app is updated.
|
|
118
|
+
- **Routes people have bookmarked** need a redirect from the old path.
|
|
119
|
+
|
|
120
|
+
Write each of these up in the pull request so nobody gets caught out.
|
|
121
|
+
|
|
122
|
+
### Renaming from the command line
|
|
123
|
+
|
|
124
|
+
An AI agent working in a terminal has no editor, so it cannot press F2. The package ships a script that does the same job, using the project's own TypeScript and the same rename engine as the editor:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs <file> <currentName> <newName>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Rename a type everywhere it is used
|
|
132
|
+
node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs components/ui/button/types.ts ButtonProperties ButtonProps
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- **Give it the file where the name is declared.** It renames that symbol and every use of it, across the whole project, and leaves anything else with the same name alone.
|
|
136
|
+
- **Shorthand stays correct.** `{ properties }` becomes `{ properties: props }`, so objects keep their shape.
|
|
137
|
+
- **It only renames TypeScript and JavaScript names.** Folders, files, form fields, routes and environment variables still need renaming by hand.
|
|
138
|
+
- **It cannot reach keys in plain object literals that aren't typed**, such as the expected value in a test's `toEqual({ properties: … })`. Search the tests for the old name and fix those keys by hand.
|
|
139
|
+
- **Run the type check and tests after each batch** of renames.
|
|
140
|
+
|
|
141
|
+
## Stage 5 — AGENTS.md
|
|
142
|
+
|
|
143
|
+
Copy the [AGENTS.md template](/templates#agents) to the project root and replace every `[placeholder]`. Agree the standards with the person first ([Setup, step 3](/Guides/setup#3-agree-the-standards)), and set the code standards version from the [Version History](/version-history).
|
|
144
|
+
|
|
145
|
+
## Stage 6 — Agent skills
|
|
146
|
+
|
|
147
|
+
Copy the eight [standard skill files](/templates#skills) into `.agents/skills/`, and again into `.claude/commands/`.
|
|
148
|
+
|
|
149
|
+
## Stage 7 — Docs
|
|
150
|
+
|
|
151
|
+
Move the project's existing documentation into the standard [`docs/` folders](/Standards/documentation#-the-folders), rewriting each as a [Decision Doc](/Standards/documentation#-the-doc-format), then add the [`docsSite/` viewer](/Standards/documentation#-setting-it-up) so it shows at `/docs`.
|
|
152
|
+
|
|
153
|
+
## Stage 8 — Lint before every commit
|
|
154
|
+
|
|
155
|
+
Add the Husky hook that runs `pnpm lint` before every commit. Add it **last**, once the project passes `pnpm lint`. See [Lint before every commit](/Standards/lint-errors#lint-before-every-commit).
|
|
156
|
+
|
|
157
|
+
## Tips
|
|
158
|
+
|
|
159
|
+
- **Don't mix formatting and logic changes** in the same PR.
|
|
160
|
+
- **Exclude generated files** from ESLint with `// eslint-disable-file` or `.eslintignore`-equivalent glob ignores in the config.
|
|
161
|
+
- **Fix new-file compliance first**: agree that all _new_ files must pass the full ruleset even before the migration is complete.
|