@activatus/code-standards 3.0.2 → 3.0.5
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 +15 -13
- package/docs/Guides/component-library-workflow.md +16 -16
- package/docs/Guides/migrating.md +18 -16
- package/docs/Guides/setup.md +9 -7
- package/docs/Standards/agent-skills.md +2 -2
- package/docs/Standards/agent-specs.md +3 -3
- package/docs/Standards/documentation.md +7 -7
- package/docs/Standards/eslint.md +321 -155
- package/docs/Standards/human-readable-names.md +15 -3
- package/docs/Standards/lint-errors.md +13 -12
- package/docs/Standards/readable-code.md +82 -43
- package/docs/Standards/stylelint.md +4 -4
- package/docs/Standards/styling.md +8 -8
- package/docs/Standards/tech-stack.md +1 -1
- package/docs/Structure/api-routes.md +3 -3
- package/docs/Structure/component-organization.md +19 -18
- package/docs/Structure/folder-structure.md +131 -12
- package/docs/Structure/naming-conventions.md +10 -8
- package/docs/design-system-components.md +3 -3
- package/docs/intro.md +20 -20
- package/docs/ontology.md +32 -31
- package/docs/templates.mdx +12 -12
- package/docs/version-history.md +77 -42
- package/package.json +19 -4
- package/static/templates/AGENTS.md +6 -5
- package/static/templates/docs/overview/writing-docs.md +1 -1
- package/static/templates/eslint/base/eslint.config.mjs +57 -33
- package/static/templates/eslint/nextjs/eslint.config.mjs +80 -32
- package/static/templates/eslint/react/eslint.config.mjs +76 -33
- package/static/templates/eslint/typescript/eslint.config.mjs +76 -33
|
@@ -65,7 +65,11 @@ project-root/
|
|
|
65
65
|
│ │ ├── rateLimit.ts
|
|
66
66
|
│ │ └── session.ts
|
|
67
67
|
│ ├── validation/ # Schemas that check input
|
|
68
|
-
│ ├── constants/ # Constants shared across the app
|
|
68
|
+
│ ├── constants/ # Constants shared across the app: see Constants below
|
|
69
|
+
│ │ ├── routes.ts # r: every link
|
|
70
|
+
│ │ ├── strings.ts # s: every piece of static text
|
|
71
|
+
│ │ ├── noData.ts # Stand-in data for local development
|
|
72
|
+
│ │ └── index.ts
|
|
69
73
|
│ ├── errors/ # Error types and handlers shared across the app
|
|
70
74
|
│ └── types/ # Types shared across the app; a component's own types stay in its types.ts
|
|
71
75
|
├── utils/ # Reusable functions used across the app
|
|
@@ -131,12 +135,12 @@ project-root/
|
|
|
131
135
|
|
|
132
136
|
**A component lives where it is used.** There are no feature folders: a component either belongs to one page, to one section, or is shared.
|
|
133
137
|
|
|
134
|
-
| Used by
|
|
135
|
-
|
|
|
136
|
-
| **Every project the same way** — the [Design System Components](/design-system-components) | `components/ui/` | `components/ui/button/` |
|
|
137
|
-
| **More than one page** of this project
|
|
138
|
-
| **A few pages in one section**
|
|
139
|
-
| **One page only**
|
|
138
|
+
| Used by | Lives in | Example |
|
|
139
|
+
| ----------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------- |
|
|
140
|
+
| **Every project the same way** — the [Design System Components](/docs/design-system-components) | `components/ui/` | `components/ui/button/` |
|
|
141
|
+
| **More than one page** of this project | `components/shared/` | `components/shared/siteHeader/` |
|
|
142
|
+
| **A few pages in one section** | A `components/` folder in that section's route group | `app/(billing)/components/invoiceTable/` |
|
|
143
|
+
| **One page only** | A `components/` folder in that page's route folder | `app/account-settings/components/accountForm/` |
|
|
140
144
|
|
|
141
145
|
A route group is a folder in brackets, such as `(billing)`. It groups pages without changing their URLs: `app/(billing)/invoices/page.tsx` is served at `/invoices`.
|
|
142
146
|
|
|
@@ -168,7 +172,7 @@ project-root/
|
|
|
168
172
|
### Rules
|
|
169
173
|
|
|
170
174
|
- **Start where it is used, and move it when it is shared.** A new component goes in its page's `components/` folder. When a second page in the same section needs it, move it to the section's `components/` folder. When a page in another section needs it, move it to `components/shared/`.
|
|
171
|
-
- **`components/ui/` is only for [Design System Components](/design-system-components).** They take everything through props and import nothing from the project, so they can be copied into another project unchanged. See [Reusable by design](/Structure/component-organization#reusable-by-design).
|
|
175
|
+
- **`components/ui/` is only for [Design System Components](/docs/design-system-components).** They take everything through props and import nothing from the project, so they can be copied into another project unchanged. See [Reusable by design](/docs/Structure/component-organization#reusable-by-design).
|
|
172
176
|
- **A page or shared component wraps Design System Components.** It holds this project's logic and data, and passes props down.
|
|
173
177
|
- **Never group by type** (`atoms/`, `molecules/`, `organisms/`). Group by where a component is used.
|
|
174
178
|
|
|
@@ -262,9 +266,124 @@ Add the export to `utils/index.ts` whenever you add a function.
|
|
|
262
266
|
|
|
263
267
|
- **Start local, promote when shared.** A function begins in the component's `utils/`. When another component in the same section needs it, move its folder to the section's `utils/`. When anything outside the section needs it, move it to the global `utils/`.
|
|
264
268
|
- **One function per folder**, with the folder and file named after the function (`formatCurrency/formatCurrency.ts`), plus its test file and an `index.ts`.
|
|
265
|
-
- **Every function has a test file** in the same folder. See [Readable Code](/Standards/readable-code#every-function-and-component-has-a-test-file).
|
|
269
|
+
- **Every function has a test file** in the same folder. See [Readable Code](/docs/Standards/readable-code#every-function-and-component-has-a-test-file).
|
|
266
270
|
- **Import from the `utils` folder**, never from the files inside it.
|
|
267
|
-
- **Keep UI files clean.** If a function could be written in another file, it does not belong in the component file. See [Writing a component](/Structure/component-organization#-writing-a-component).
|
|
271
|
+
- **Keep UI files clean.** If a function could be written in another file, it does not belong in the component file. See [Writing a component](/docs/Structure/component-organization#-writing-a-component).
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## 🔤 Constants: `r`, `s`, noData and numbers {#constants}
|
|
276
|
+
|
|
277
|
+
Every link, every piece of text on screen and every piece of stand-in data lives in `lib/constants/`, never written straight into a component:
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
lib/constants/
|
|
281
|
+
├── routes.ts # r: every link
|
|
282
|
+
├── strings.ts # s: every piece of static text
|
|
283
|
+
├── noData.ts # Stand-in data for local development
|
|
284
|
+
├── durations.ts # Shared numbers, one file per topic
|
|
285
|
+
└── index.ts # Exports all of them
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
A file outside the folder imports everything it needs in one line:
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
import { NO_DATA_INSIGHTS, r, s } from "@/lib/constants";
|
|
292
|
+
|
|
293
|
+
<a href={r.contact}>{s.contact}</a>;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### `r`: routes
|
|
297
|
+
|
|
298
|
+
**`r` holds every link the app uses**: its own pages, outside sites, and `mailto:`, `tel:` and `sms:` links.
|
|
299
|
+
|
|
300
|
+
```ts title="lib/constants/routes.ts"
|
|
301
|
+
export const r = {
|
|
302
|
+
contact: "/contact",
|
|
303
|
+
email: "mailto:mail@example.com",
|
|
304
|
+
insights: "/insights",
|
|
305
|
+
linkedIn: "https://www.linkedin.com/in/example",
|
|
306
|
+
sms: "sms:+61400000000",
|
|
307
|
+
};
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
- **A dynamic route starts from its `r` route.** Build the changing part where it is used: `` `${r.insights}/${insight.slug}` ``.
|
|
311
|
+
- **Name each key after the place it goes**, in camelCase: `r.myStory`, `r.linkedIn`.
|
|
312
|
+
|
|
313
|
+
### `s`: strings
|
|
314
|
+
|
|
315
|
+
**`s` holds every piece of static text** shown on screen: headings, buttons, labels, aria-labels, page titles and descriptions, and longer Markdown copy.
|
|
316
|
+
|
|
317
|
+
```ts title="lib/constants/strings.ts"
|
|
318
|
+
export const s = {
|
|
319
|
+
contact: "CONTACT",
|
|
320
|
+
emailAriaLabel: "Email Tom",
|
|
321
|
+
pageNotFound: "PAGE NOT FOUND",
|
|
322
|
+
pageNotFoundDescription:
|
|
323
|
+
"The page you are looking for does not exist",
|
|
324
|
+
};
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
- **The keys of `s` are the site's translation keys.** When a site gets more languages, each key is translated into each language. Name each key after what the text says or does, and never use one key for two different jobs.
|
|
328
|
+
- **Only real copy goes in `s`.** Dummy text belongs in `noData.ts`.
|
|
329
|
+
|
|
330
|
+
### noData: stand-in data for local development
|
|
331
|
+
|
|
332
|
+
**`noData.ts` stands in for outside data while you work locally**, when the CMS, database or API can't be reached, such as when you have no internet. Every page still renders with something that looks real.
|
|
333
|
+
|
|
334
|
+
```ts title="lib/constants/noData.ts"
|
|
335
|
+
const DUMMY_HEADING = "A heading for local development";
|
|
336
|
+
const DUMMY_SLUG = "/insights";
|
|
337
|
+
|
|
338
|
+
export const NO_DATA_INSIGHT = {
|
|
339
|
+
heading: DUMMY_HEADING,
|
|
340
|
+
slug: DUMMY_SLUG,
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export const NO_DATA_INSIGHTS = [NO_DATA_INSIGHT];
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
const insights =
|
|
348
|
+
query?.insights ??
|
|
349
|
+
(IS_LOCAL_DEVELOPMENT ? NO_DATA_INSIGHTS : []);
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
`IS_LOCAL_DEVELOPMENT` is a constant in `lib/constants/`: `export const IS_LOCAL_DEVELOPMENT = process.env.NODE_ENV === "development";`.
|
|
353
|
+
|
|
354
|
+
- **Local development only.** noData is never shown in production. Where the real data is missing in production, show the page's empty state.
|
|
355
|
+
- **Name each export `NO_DATA_` plus the exact thing it stands in for**: singular for one item, plural for a list. `NO_DATA_INSIGHT` and `NO_DATA_INSIGHTS`, `NO_DATA_EVENT`, `NO_DATA_TOPICS`.
|
|
356
|
+
- **Shape it exactly like the real response**, so the code using it cannot tell the difference.
|
|
357
|
+
- **Dummy values sit at the top of `noData.ts`** as their own constants, `DUMMY_HEADING` and the rest. They are never added to `s`.
|
|
358
|
+
- **noData is for the whole site.** All of it lives in this one file.
|
|
359
|
+
|
|
360
|
+
### Numbers: named, and kept by topic
|
|
361
|
+
|
|
362
|
+
**A number other than `-1`, `0` or `1` gets a name**, such as `MAXIMUM_RETRY_ATTEMPTS`. Those three mean "nothing", "one more" and "not found", so they read clearly as they are. Any other number was chosen by someone, and its name says what it controls. ESLint checks this with `no-magic-numbers`.
|
|
363
|
+
|
|
364
|
+
There is no `n` object. Text and links are one kind of thing each, but numbers are not: a retry limit, a cookie lifetime and a page size have nothing in common. Put each number where its meaning lives:
|
|
365
|
+
|
|
366
|
+
| Used by | Where it goes | Example |
|
|
367
|
+
| ------------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
368
|
+
| One file | At the top of that file | `const MAXIMUM_NESTING_DEPTH = 3;` in `eslint.config.mjs` |
|
|
369
|
+
| More than one file | `lib/constants/`, in a file named after its topic | `lib/constants/durations.ts`, `lib/constants/limits.ts`, `lib/constants/httpStatus.ts` |
|
|
370
|
+
|
|
371
|
+
```ts title="lib/constants/durations.ts"
|
|
372
|
+
export const COOKIE_DURATION_DAYS = 30;
|
|
373
|
+
export const SESSION_TIMEOUT_MILLISECONDS = 900_000;
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
- **Start in the file that uses it**, and move it to `lib/constants/` when a second file needs it.
|
|
377
|
+
- **Never a `numbers.ts`** or any other file of unrelated values. Name the file after the topic.
|
|
378
|
+
- **Put the unit in the name**: `_MILLISECONDS`, `_DAYS`, `_PIXELS`.
|
|
379
|
+
|
|
380
|
+
### Rules
|
|
381
|
+
|
|
382
|
+
- **Named exports only:** `export const r`, `export const s`. No default exports.
|
|
383
|
+
- **Files outside `lib/constants/` import from `@/lib/constants`**, all in one import line.
|
|
384
|
+
- **Files inside `lib/constants/` import each other directly**, `import { s } from "./strings";`, never through `index.ts`. See [Inside a folder, import files directly](/docs/Structure/import-organization#2-inside-a-folder-import-files-directly).
|
|
385
|
+
- **`r` and `s` are the only single-letter names allowed anywhere.** See [Human-Readable Names](/docs/Standards/human-readable-names#r-and-s).
|
|
386
|
+
- **Other constants**, such as numbers, are `SCREAMING_SNAKE_CASE`: see [Naming Conventions](/docs/Structure/naming-conventions#constants).
|
|
268
387
|
|
|
269
388
|
---
|
|
270
389
|
|
|
@@ -310,7 +429,7 @@ project-root/
|
|
|
310
429
|
└── docsSite/ # The viewer: Docusaurus config, no content
|
|
311
430
|
```
|
|
312
431
|
|
|
313
|
-
See [Documentation](/Standards/documentation) for the full list of folders, the doc format, and how docs are displayed and kept up to date.
|
|
432
|
+
See [Documentation](/docs/Standards/documentation) for the full list of folders, the doc format, and how docs are displayed and kept up to date.
|
|
314
433
|
|
|
315
434
|
Name documentation folders and files in **kebab-case** (`background-jobs.md`), not camelCase (`backgroundJobs.md`). The name becomes the page's URL on the docs site.
|
|
316
435
|
|
|
@@ -345,7 +464,7 @@ Avoid these anti-patterns:
|
|
|
345
464
|
|
|
346
465
|
## 📚 Naming Conventions
|
|
347
466
|
|
|
348
|
-
See [Naming Conventions](/Structure/naming-conventions) for detailed file and folder naming rules.
|
|
467
|
+
See [Naming Conventions](/docs/Structure/naming-conventions) for detailed file and folder naming rules.
|
|
349
468
|
|
|
350
469
|
**Quick reference:**
|
|
351
470
|
|
|
@@ -6,9 +6,9 @@ sidebar_position: 5
|
|
|
6
6
|
|
|
7
7
|
Consistent naming conventions make codebases easier to navigate, understand, and maintain.
|
|
8
8
|
|
|
9
|
-
**Every name must be human-readable** — folders, files, props, form fields, types, database columns, everything. See [Human-Readable Names](/Standards/human-readable-names).
|
|
9
|
+
**Every name must be human-readable** — folders, files, props, form fields, types, database columns, everything. See [Human-Readable Names](/docs/Standards/human-readable-names).
|
|
10
10
|
|
|
11
|
-
This page covers **how** a name is written. **Which words** to use comes from the [Ontology](/ontology): a Decision Doc is `decisionDoc` in code and `decision_doc` in the database, never `docDecision` or `decisionFile`.
|
|
11
|
+
This page covers **how** a name is written. **Which words** to use comes from the [Ontology](/docs/ontology): a Decision Doc is `decisionDoc` in code and `decision_doc` in the database, never `docDecision` or `decisionFile`.
|
|
12
12
|
|
|
13
13
|
## File Naming
|
|
14
14
|
|
|
@@ -154,6 +154,8 @@ const apiTimeout = 5000;
|
|
|
154
154
|
const cookieDays = 30;
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
+
**`r` and `s` are the exception:** the routes and strings objects are lowercase single letters, with camelCase keys, `r.myStory` and `s.pageNotFound`. Stand-in data follows the normal rule: `NO_DATA_INSIGHTS`. See [Constants](/docs/Structure/folder-structure#constants).
|
|
158
|
+
|
|
157
159
|
### CSS Modules
|
|
158
160
|
|
|
159
161
|
**Use camelCase** with `.module.css` suffix:
|
|
@@ -184,11 +186,11 @@ form-components.module.css
|
|
|
184
186
|
--spacing_unit: 0.25rem;
|
|
185
187
|
```
|
|
186
188
|
|
|
187
|
-
See [CSS Styling](/Standards/styling#css-variables).
|
|
189
|
+
See [CSS Styling](/docs/Standards/styling#css-variables).
|
|
188
190
|
|
|
189
191
|
### Documentation
|
|
190
192
|
|
|
191
|
-
**Use kebab-case** for documentation files. The [docs site](/Standards/documentation) turns each file name into the page's URL, so a doc file is named the way a URL is written:
|
|
193
|
+
**Use kebab-case** for documentation files. The [docs site](/docs/Standards/documentation) turns each file name into the page's URL, so a doc file is named the way a URL is written:
|
|
192
194
|
|
|
193
195
|
```tsx
|
|
194
196
|
✅ Good
|
|
@@ -208,7 +210,7 @@ ProductMarketFit.md
|
|
|
208
210
|
|
|
209
211
|
### Variables
|
|
210
212
|
|
|
211
|
-
**Use camelCase**, and [full English words](/Standards/readable-code#names-are-full-english-words) — no shorthand:
|
|
213
|
+
**Use camelCase**, and [full English words](/docs/Standards/readable-code#names-are-full-english-words) — no shorthand:
|
|
212
214
|
|
|
213
215
|
```ts
|
|
214
216
|
✅ Good
|
|
@@ -226,7 +228,7 @@ const item_count = 10;
|
|
|
226
228
|
|
|
227
229
|
### Functions
|
|
228
230
|
|
|
229
|
-
Every function is an [arrow function](/Standards/readable-code#arrow-functions-everywhere).
|
|
231
|
+
Every function is an [arrow function](/docs/Standards/readable-code#arrow-functions-everywhere).
|
|
230
232
|
|
|
231
233
|
**Use camelCase** with descriptive verbs:
|
|
232
234
|
|
|
@@ -282,7 +284,7 @@ interface api_response { }
|
|
|
282
284
|
interface UserCardData { }
|
|
283
285
|
```
|
|
284
286
|
|
|
285
|
-
See [Readable Code](/Standards/readable-code#type-names-say-what-they-are).
|
|
287
|
+
See [Readable Code](/docs/Standards/readable-code#type-names-say-what-they-are).
|
|
286
288
|
|
|
287
289
|
---
|
|
288
290
|
|
|
@@ -331,4 +333,4 @@ Use ESLint and Prettier to enforce these conventions automatically:
|
|
|
331
333
|
- **simple-import-sort** - Import ordering
|
|
332
334
|
- **@typescript-eslint** - TypeScript naming rules
|
|
333
335
|
|
|
334
|
-
See [ESLint](/Standards/eslint) and [Prettier](/Standards/prettier) configuration for setup.
|
|
336
|
+
See [ESLint](/docs/Standards/eslint) and [Prettier](/docs/Standards/prettier) configuration for setup.
|
|
@@ -7,15 +7,15 @@ sidebar_label: "Design System Components"
|
|
|
7
7
|
|
|
8
8
|
**This page is the contract for how every Activatus component works.** It lists each standard component with its variants and key props.
|
|
9
9
|
|
|
10
|
-
We do not share component code between projects yet, so this page is what keeps them the same. Every project builds its components to the props listed here. See [Future-proofing](/Guides/component-library-workflow#future-proofing) for why.
|
|
10
|
+
We do not share component code between projects yet, so this page is what keeps them the same. Every project builds its components to the props listed here. See [Future-proofing](/docs/Guides/component-library-workflow#future-proofing) for why.
|
|
11
11
|
|
|
12
12
|
## How to use this page
|
|
13
13
|
|
|
14
14
|
- **Before building a component, look it up here.** If it is listed, build it with these variants and props — the same names, the same meaning. Do not invent your own.
|
|
15
|
-
- **Do not rename, remove or repurpose a listed prop.** Projects differ in how a component looks, never in [how it works](/Guides/component-library-workflow#same-component-different-paint).
|
|
15
|
+
- **Do not rename, remove or repurpose a listed prop.** Projects differ in how a component looks, never in [how it works](/docs/Guides/component-library-workflow#same-component-different-paint).
|
|
16
16
|
- **Building a component that is not listed?** Add it to this page in the same piece of work, so the next project builds it the same way.
|
|
17
17
|
- **A project needs something a listed component does not do?** Add the prop or variant here first, then build it. The reference changes before the code does.
|
|
18
|
-
- **How to write each component** — its folder, files, the order inside the file, tests and stories — is in [Component Organization](/Structure/component-organization). This page says _what_ each component takes; that page says _how_ every component is written.
|
|
18
|
+
- **How to write each component** — its folder, files, the order inside the file, tests and stories — is in [Component Organization](/docs/Structure/component-organization). This page says _what_ each component takes; that page says _how_ every component is written.
|
|
19
19
|
|
|
20
20
|
This applies to everyone building components, **including AI agents**.
|
|
21
21
|
|
package/docs/intro.md
CHANGED
|
@@ -10,35 +10,35 @@ This site documents the shared code standards used across all Activatus projects
|
|
|
10
10
|
|
|
11
11
|
## What's included
|
|
12
12
|
|
|
13
|
-
| Standard | Config
|
|
14
|
-
| -------------------- |
|
|
15
|
-
| Human-Readable Names | [Naming rule](/Standards/human-readable-names) | Every name is whole, readable words — variables, props, form fields, files, folders, everything |
|
|
16
|
-
| Readable Code | [Readability rules](/Standards/readable-code) | File length, naming, single-purpose functions and tests |
|
|
17
|
-
| Documentation | [Docs standard](/Standards/documentation) | How project docs are written and shown at `/docs` |
|
|
18
|
-
| ESLint | [`eslint.config.mjs`](/Standards/eslint) | Linting rules for JS/TS/React/Next.js |
|
|
19
|
-
| Fixing Lint Errors | [Error guide](/Standards/lint-errors) | What each lint error means and how to fix it |
|
|
20
|
-
| Prettier | [`prettier.config.mjs`](/Standards/prettier) | Code formatting |
|
|
21
|
-
| Stylelint | [`stylelint.config.mjs`](/Standards/stylelint) | Linting rules for CSS/SCSS/CSS Modules |
|
|
22
|
-
| EditorConfig | [`.editorconfig`](/Standards/editorconfig) | Editor-level whitespace rules |
|
|
23
|
-
| direnv + nvm | [`.envrc` / `.nvmrc`](/Standards/direnv) | Automatic Node version switching on `cd` |
|
|
24
|
-
| AGENTS.md | [`AGENTS.md`](/Standards/agent-specs) | AI agent context and agent skills |
|
|
25
|
-
| CSS Styling | [Styling guide](/Standards/styling) | Tailwind CSS, flexbox-first layout and global colour variables |
|
|
26
|
-
| Tech Stack | [Tech stack](/Standards/tech-stack) | The frameworks, libraries and versions we build on |
|
|
27
|
-
|
|
28
|
-
Project layout is covered under **Structure**: [folder structure](/Structure/folder-structure), [component organization](/Structure/component-organization), [naming conventions](/Structure/naming-conventions), [import organization](/Structure/import-organization) and [API routes](/Structure/api-routes).
|
|
13
|
+
| Standard | Config | Purpose |
|
|
14
|
+
| -------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
15
|
+
| Human-Readable Names | [Naming rule](/docs/Standards/human-readable-names) | Every name is whole, readable words — variables, props, form fields, files, folders, everything |
|
|
16
|
+
| Readable Code | [Readability rules](/docs/Standards/readable-code) | File length, naming, single-purpose functions and tests |
|
|
17
|
+
| Documentation | [Docs standard](/docs/Standards/documentation) | How project docs are written and shown at `/docs` |
|
|
18
|
+
| ESLint | [`eslint.config.mjs`](/docs/Standards/eslint) | Linting rules for JS/TS/React/Next.js |
|
|
19
|
+
| Fixing Lint Errors | [Error guide](/docs/Standards/lint-errors) | What each lint error means and how to fix it |
|
|
20
|
+
| Prettier | [`prettier.config.mjs`](/docs/Standards/prettier) | Code formatting |
|
|
21
|
+
| Stylelint | [`stylelint.config.mjs`](/docs/Standards/stylelint) | Linting rules for CSS/SCSS/CSS Modules |
|
|
22
|
+
| EditorConfig | [`.editorconfig`](/docs/Standards/editorconfig) | Editor-level whitespace rules |
|
|
23
|
+
| direnv + nvm | [`.envrc` / `.nvmrc`](/docs/Standards/direnv) | Automatic Node version switching on `cd` |
|
|
24
|
+
| AGENTS.md | [`AGENTS.md`](/docs/Standards/agent-specs) | AI agent context and agent skills |
|
|
25
|
+
| CSS Styling | [Styling guide](/docs/Standards/styling) | Tailwind CSS, flexbox-first layout and global colour variables |
|
|
26
|
+
| Tech Stack | [Tech stack](/docs/Standards/tech-stack) | The frameworks, libraries and versions we build on |
|
|
27
|
+
|
|
28
|
+
Project layout is covered under **Structure**: [folder structure](/docs/Structure/folder-structure), [component organization](/docs/Structure/component-organization), [naming conventions](/docs/Structure/naming-conventions), [import organization](/docs/Structure/import-organization) and [API routes](/docs/Structure/api-routes).
|
|
29
29
|
|
|
30
30
|
## Ontology
|
|
31
31
|
|
|
32
|
-
The [Ontology](/ontology) is the shared vocabulary for code: what each code word means. Each project adds its own product words in `docs/product/ontology.md`. Read both first.
|
|
32
|
+
The [Ontology](/docs/ontology) is the shared vocabulary for code: what each code word means. Each project adds its own product words in `docs/product/ontology.md`. Read both first.
|
|
33
33
|
|
|
34
34
|
## Version History
|
|
35
35
|
|
|
36
|
-
The [Version History](/version-history) lists 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`.
|
|
36
|
+
The [Version History](/docs/version-history) lists 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`.
|
|
37
37
|
|
|
38
38
|
## For AI agents: you were pointed here
|
|
39
39
|
|
|
40
|
-
A person has told you to follow the Activatus Code Standards. **Follow [Setup](/Guides/setup) first.** It installs the standards as the `@activatus/code-standards` package, checks which version the project is on, agrees with the person which standards apply, and sets them up. It covers new projects, projects on an older version, and projects that have never followed the standards.
|
|
40
|
+
A person has told you to follow the Activatus Code Standards. **Follow [Setup](/docs/Guides/setup) first.** It installs the standards as the `@activatus/code-standards` package, checks which version the project is on, agrees with the person which standards apply, and sets them up. It covers new projects, projects on an older version, and projects that have never followed the standards.
|
|
41
41
|
|
|
42
|
-
After setup, follow every agreed standard in every change. Read a page when the work reaches its topic: [Styling](/Standards/styling) before writing styles, [Docs](/Standards/documentation) before writing docs, and so on. The ones to read first are the [Ontology](/ontology), [Human-Readable Names](/Standards/human-readable-names), [Readable Code](/Standards/readable-code), [Folder Structure](/Structure/folder-structure) and [Component Organization](/Structure/component-organization).
|
|
42
|
+
After setup, follow every agreed standard in every change. Read a page when the work reaches its topic: [Styling](/docs/Standards/styling) before writing styles, [Docs](/docs/Standards/documentation) before writing docs, and so on. The ones to read first are the [Ontology](/docs/ontology), [Human-Readable Names](/docs/Standards/human-readable-names), [Readable Code](/docs/Standards/readable-code), [Folder Structure](/docs/Structure/folder-structure) and [Component Organization](/docs/Structure/component-organization).
|
|
43
43
|
|
|
44
44
|
**If anything here is unclear, ask the person.** Do not guess, and do not invent a rule.
|
package/docs/ontology.md
CHANGED
|
@@ -7,7 +7,7 @@ sidebar_label: "Ontology"
|
|
|
7
7
|
|
|
8
8
|
> The words these standards use about code, and exactly what each one means.
|
|
9
9
|
|
|
10
|
-
**Status:** Decided · **Updated:** 2026-10-
|
|
10
|
+
**Status:** Decided · **Updated:** 2026-10-18
|
|
11
11
|
|
|
12
12
|
**This page is the source of truth for every word about code.** Every Activatus project uses these terms, with these meanings, in docs, code, prompts and reviews.
|
|
13
13
|
|
|
@@ -50,13 +50,13 @@ The words stay the same everywhere. Only the casing changes, to match where the
|
|
|
50
50
|
|
|
51
51
|
### Docs
|
|
52
52
|
|
|
53
|
-
| Term | Means
|
|
54
|
-
| -------------- |
|
|
55
|
-
| `decision` | A choice made on purpose and written down, never left implied
|
|
56
|
-
| `decision_doc` | One Markdown file that records one decision and why it was made. Every file in a project's `docs/` folder is one. See [Docs](/Standards/documentation) |
|
|
57
|
-
| `docs` | A project's `docs/` folder: its Decision Docs, in the same standard folders in every project
|
|
58
|
-
| `docs_site` | The Docusaurus viewer in `docsSite/` that shows a project's docs at `/docs`. It only runs when `DOCS_URL` is set, which is never in production
|
|
59
|
-
| `ontology` | A shared vocabulary: this page for code words, and the project's own for product words
|
|
53
|
+
| Term | Means |
|
|
54
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `decision` | A choice made on purpose and written down, never left implied |
|
|
56
|
+
| `decision_doc` | One Markdown file that records one decision and why it was made. Every file in a project's `docs/` folder is one. See [Docs](/docs/Standards/documentation) |
|
|
57
|
+
| `docs` | A project's `docs/` folder: its Decision Docs, in the same standard folders in every project |
|
|
58
|
+
| `docs_site` | The Docusaurus viewer in `docsSite/` that shows a project's docs at `/docs`. It only runs when `DOCS_URL` is set, which is never in production |
|
|
59
|
+
| `ontology` | A shared vocabulary: this page for code words, and the project's own for product words |
|
|
60
60
|
|
|
61
61
|
### People and agents
|
|
62
62
|
|
|
@@ -65,7 +65,7 @@ The words stay the same everywhere. Only the casing changes, to match where the
|
|
|
65
65
|
| `human` | A person, as opposed to an agent |
|
|
66
66
|
| `developer` | A human who writes code |
|
|
67
67
|
| `agent` | An AI that writes or checks code, such as Claude Code. It follows every standard a developer does |
|
|
68
|
-
| `agent_spec` | A project's `AGENTS.md` file: the first thing an agent reads, setting out how to work on that project. See [Agent Specs](/Standards/agent-specs)
|
|
68
|
+
| `agent_spec` | A project's `AGENTS.md` file: the first thing an agent reads, setting out how to work on that project. See [Agent Specs](/docs/Standards/agent-specs) |
|
|
69
69
|
| `agent_harness` | Everything around an agent that runs it: the program it runs in (such as Claude Code), its instructions, the tools and permissions it has, and the rules it follows. The ontology says what words mean; the harness says how an agent behaves |
|
|
70
70
|
| `context` | Everything an agent is given to read for its task: the agent spec, the docs and the code it is working on |
|
|
71
71
|
| `tool` | One action an agent is allowed to take, such as editing a file or running the tests. Tools come from the agent harness or an MCP server |
|
|
@@ -74,31 +74,32 @@ The words stay the same everywhere. Only the casing changes, to match where the
|
|
|
74
74
|
|
|
75
75
|
### Code
|
|
76
76
|
|
|
77
|
-
| Term | Means
|
|
78
|
-
| --------------------------------------- |
|
|
79
|
-
| `component` | One piece of the user interface that does one job. Its file is PascalCase (`InvoiceTable.tsx`) inside a camelCase folder (`invoiceTable/`). See [Component Organization](/Structure/component-organization)
|
|
80
|
-
| `design_system_component` | A standard component that every project builds the same way, with the same name, variants and props, such as Button or Card. Each one is listed on the [Design System Components](/design-system-components) page and lives in `components/ui/`. It takes everything through props and imports nothing from the project, so it can be copied into another project unchanged
|
|
81
|
-
| `shared_component` | A component this project uses on more than one page, built from Design System Components. It lives in `components/shared/`
|
|
82
|
-
| `page_component` | A component used by one page, or by a few pages in one section. It lives in a `components/` folder beside that page, or in the section's route group. See [Where components live](/Structure/folder-structure#-where-components-live)
|
|
83
|
-
| `props` | The values a component takes. `props` is a [dictionary word](/Standards/human-readable-names#dictionary). Their type is named after the component and ends in `Props`: `ButtonProps`
|
|
84
|
-
| `type` | A TypeScript type or interface. Its name ends in `Props` or `Type`
|
|
85
|
-
| `dependency` | Something the code relies on but does not define itself: a package it installs, or the functions handed into a function as its `dependencies`. How tickets wait on each other is not a dependency here: each project names that itself, such as Launchpad's `blocked_by`
|
|
86
|
-
| `utils` | Reusable functions that are not components, such as `formatCurrency`. They live in a `utils/` folder: global, for one section, or for one component. Each function has its own folder with its test file and an `index.ts`. `utils` is a [dictionary word](/Standards/human-readable-names#dictionary). Never `helpers` or `utilities`. See [Utils](/Structure/folder-structure#-utils) |
|
|
87
|
-
| `services` | The business logic: what the app does, its rules and operations. Pages, API routes and server actions stay thin and call into `services/`. See [utils, services and lib](/Structure/folder-structure#utils-services-and-lib)
|
|
88
|
-
| `lib` | Code that connects the app to something outside it, such as integration clients in `lib/integrations/stripe/`, and app-wide setup: permissions, middleware, validation, constants, errors and shared types
|
|
89
|
-
| `route` | A web address in the app, such as `/account-settings` or `/api/calendar-events`, and the folder or file that creates it. Route folders are kebab-case, because their names become the URL. In Next.js, routes are the folders under `app/`. See [API Routes](/Structure/api-routes)
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
77
|
+
| Term | Means |
|
|
78
|
+
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `component` | One piece of the user interface that does one job. Its file is PascalCase (`InvoiceTable.tsx`) inside a camelCase folder (`invoiceTable/`). See [Component Organization](/docs/Structure/component-organization) |
|
|
80
|
+
| `design_system_component` | A standard component that every project builds the same way, with the same name, variants and props, such as Button or Card. Each one is listed on the [Design System Components](/docs/design-system-components) page and lives in `components/ui/`. It takes everything through props and imports nothing from the project, so it can be copied into another project unchanged |
|
|
81
|
+
| `shared_component` | A component this project uses on more than one page, built from Design System Components. It lives in `components/shared/` |
|
|
82
|
+
| `page_component` | A component used by one page, or by a few pages in one section. It lives in a `components/` folder beside that page, or in the section's route group. See [Where components live](/docs/Structure/folder-structure#-where-components-live) |
|
|
83
|
+
| `props` | The values a component takes. `props` is a [dictionary word](/docs/Standards/human-readable-names#dictionary). Their type is named after the component and ends in `Props`: `ButtonProps` |
|
|
84
|
+
| `type` | A TypeScript type or interface. Its name ends in `Props` or `Type` |
|
|
85
|
+
| `dependency` | Something the code relies on but does not define itself: a package it installs, or the functions handed into a function as its `dependencies`. How tickets wait on each other is not a dependency here: each project names that itself, such as Launchpad's `blocked_by` |
|
|
86
|
+
| `utils` | Reusable functions that are not components, such as `formatCurrency`. They live in a `utils/` folder: global, for one section, or for one component. Each function has its own folder with its test file and an `index.ts`. `utils` is a [dictionary word](/docs/Standards/human-readable-names#dictionary). Never `helpers` or `utilities`. See [Utils](/docs/Structure/folder-structure#-utils) |
|
|
87
|
+
| `services` | The business logic: what the app does, its rules and operations. Pages, API routes and server actions stay thin and call into `services/`. See [utils, services and lib](/docs/Structure/folder-structure#utils-services-and-lib) |
|
|
88
|
+
| `lib` | Code that connects the app to something outside it, such as integration clients in `lib/integrations/stripe/`, and app-wide setup: permissions, middleware, validation, constants, errors and shared types |
|
|
89
|
+
| `route` | A web address in the app, such as `/account-settings` or `/api/calendar-events`, and the folder or file that creates it. Route folders are kebab-case, because their names become the URL. In Next.js, routes are the folders under `app/`. See [API Routes](/docs/Structure/api-routes) |
|
|
90
|
+
| `no_data` | Stand-in data shaped exactly like a real response, used only in local development when the real source can't be reached. It lives in `lib/constants/noData.ts`, never in production. See [Constants](/docs/Structure/folder-structure#constants) |
|
|
91
|
+
| `server_component` / `client_component` | A component that runs on the server, and one that runs in the browser. They live in separate files, and the server one wraps the client one |
|
|
92
|
+
| `test_file` | The file that tests one function or component, named after it: `formatCurrency.test.ts`. Every function and component has one |
|
|
93
|
+
| `dictionary` | The list of short names that are words, not abbreviations: `id`, `docs`, `props`, `utils`, `url` and the rest. A short name not in the [Dictionary](/docs/Standards/human-readable-names#dictionary) is written out in full. A new word is added to the Dictionary before it is used |
|
|
94
|
+
| `third_party_names` | Names that come from someone else's code — a package, a framework or an outside service — such as React's `ref`, Next.js's `params` or shadcn/ui's `cn`. They are used exactly as they are, because renaming them breaks the code. The naming rule is only for names we write. See [Third-party names](/docs/Standards/human-readable-names#third-party-names) |
|
|
95
|
+
| `third_party_code` | Code we did not write: `node_modules/`, and anything copied into `vendor/`. It is never linted, reformatted or renamed |
|
|
96
|
+
| `global_palette` | The colours defined in `app/globals.css`. Every colour in a project comes from it. See [Styling](/docs/Standards/styling) |
|
|
96
97
|
|
|
97
98
|
### Checks
|
|
98
99
|
|
|
99
|
-
| Term | Means
|
|
100
|
-
| ------------ |
|
|
101
|
-
| `lint_error` | A broken rule the linter reports. Fix the code; never switch the rule off without a comment saying why. See [Lint Errors](/Standards/lint-errors) |
|
|
100
|
+
| Term | Means |
|
|
101
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
102
|
+
| `lint_error` | A broken rule the linter reports. Fix the code; never switch the rule off without a comment saying why. See [Lint Errors](/docs/Standards/lint-errors) |
|
|
102
103
|
|
|
103
104
|
---
|
|
104
105
|
|
package/docs/templates.mdx
CHANGED
|
@@ -67,7 +67,7 @@ Each file is also served as a plain file, so a person or an AI agent can fetch i
|
|
|
67
67
|
|
|
68
68
|
**Copy to:** `AGENTS.md` in the project root
|
|
69
69
|
|
|
70
|
-
Replace every `[placeholder]`. See [AGENTS.md Specifications](/Standards/agent-specs).
|
|
70
|
+
Replace every `[placeholder]`. See [AGENTS.md Specifications](/docs/Standards/agent-specs).
|
|
71
71
|
|
|
72
72
|
<CodeBlock language="markdown" title="AGENTS.md">
|
|
73
73
|
{agents}
|
|
@@ -79,7 +79,7 @@ Replace every `[placeholder]`. See [AGENTS.md Specifications](/Standards/agent-s
|
|
|
79
79
|
|
|
80
80
|
**Copy to:** `eslint.config.mjs` in the project root
|
|
81
81
|
|
|
82
|
-
For TypeScript projects. Install commands are on the [ESLint page](/Standards/eslint#installation).
|
|
82
|
+
For TypeScript projects. Install commands are on the [ESLint page](/docs/Standards/eslint#installation).
|
|
83
83
|
|
|
84
84
|
<CodeBlock language="js" title="eslint.config.mjs">
|
|
85
85
|
{eslintTypescript}
|
|
@@ -127,7 +127,7 @@ For plain JavaScript and Node.js projects.
|
|
|
127
127
|
|
|
128
128
|
**Copy to:** `prettier.config.mjs` in the project root
|
|
129
129
|
|
|
130
|
-
See the [Prettier page](/Standards/prettier).
|
|
130
|
+
See the [Prettier page](/docs/Standards/prettier).
|
|
131
131
|
|
|
132
132
|
<CodeBlock language="js" title="prettier.config.mjs">
|
|
133
133
|
{prettier}
|
|
@@ -139,7 +139,7 @@ See the [Prettier page](/Standards/prettier).
|
|
|
139
139
|
|
|
140
140
|
**Copy to:** `stylelint.config.mjs` in the project root
|
|
141
141
|
|
|
142
|
-
See the [Stylelint page](/Standards/stylelint).
|
|
142
|
+
See the [Stylelint page](/docs/Standards/stylelint).
|
|
143
143
|
|
|
144
144
|
<CodeBlock language="js" title="stylelint.config.mjs">
|
|
145
145
|
{stylelintCss}
|
|
@@ -163,7 +163,7 @@ For projects that use SCSS.
|
|
|
163
163
|
|
|
164
164
|
**Copy to:** `app/globals.css`
|
|
165
165
|
|
|
166
|
-
Replace the example colours with the project's palette. See [CSS Styling](/Standards/styling).
|
|
166
|
+
Replace the example colours with the project's palette. See [CSS Styling](/docs/Standards/styling).
|
|
167
167
|
|
|
168
168
|
<CodeBlock language="css" title="globals.css">
|
|
169
169
|
{globalsCss}
|
|
@@ -175,7 +175,7 @@ Replace the example colours with the project's palette. See [CSS Styling](/Stand
|
|
|
175
175
|
|
|
176
176
|
**Copy to:** `.editorconfig` in the project root
|
|
177
177
|
|
|
178
|
-
See the [EditorConfig page](/Standards/editorconfig).
|
|
178
|
+
See the [EditorConfig page](/docs/Standards/editorconfig).
|
|
179
179
|
|
|
180
180
|
<CodeBlock language="ini" title=".editorconfig">
|
|
181
181
|
{editorconfig}
|
|
@@ -187,7 +187,7 @@ See the [EditorConfig page](/Standards/editorconfig).
|
|
|
187
187
|
|
|
188
188
|
**Copy to:** `.nvmrc` in the project root
|
|
189
189
|
|
|
190
|
-
Set it to the project's Node major version. See [direnv + nvm](/Standards/direnv).
|
|
190
|
+
Set it to the project's Node major version. See [direnv + nvm](/docs/Standards/direnv).
|
|
191
191
|
|
|
192
192
|
<CodeBlock language="text" title=".nvmrc">
|
|
193
193
|
{nvmrc}
|
|
@@ -199,7 +199,7 @@ Set it to the project's Node major version. See [direnv + nvm](/Standards/direnv
|
|
|
199
199
|
|
|
200
200
|
**Copy to:** `.envrc` in the project root
|
|
201
201
|
|
|
202
|
-
Run `direnv allow` after adding it. See [direnv + nvm](/Standards/direnv).
|
|
202
|
+
Run `direnv allow` after adding it. See [direnv + nvm](/docs/Standards/direnv).
|
|
203
203
|
|
|
204
204
|
<CodeBlock language="bash" title=".envrc">
|
|
205
205
|
{envrc}
|
|
@@ -211,7 +211,7 @@ Run `direnv allow` after adding it. See [direnv + nvm](/Standards/direnv).
|
|
|
211
211
|
|
|
212
212
|
**Copy to:** `.agents/skills/` in the project root, and again to `.claude/commands/` so Claude Code picks them up as slash commands.
|
|
213
213
|
|
|
214
|
-
The eight standard skills. Copy all of them into every project. See [Agent Skills](/Standards/agent-skills) for how they are written.
|
|
214
|
+
The eight standard skills. Copy all of them into every project. See [Agent Skills](/docs/Standards/agent-skills) for how they are written.
|
|
215
215
|
|
|
216
216
|
| Skill | Invocation | Plain file |
|
|
217
217
|
| -------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
@@ -294,7 +294,7 @@ Runs the test suite; reports failures grouped by cause, tests that never ran, an
|
|
|
294
294
|
|
|
295
295
|
**Copy to:** a `docsSite/` folder in the project root
|
|
296
296
|
|
|
297
|
-
The Docusaurus viewer that shows the project's `docs/` folder at `/docs`. Copy every file, keeping the folder layout. See [Documentation](/Standards/documentation#-setting-it-up).
|
|
297
|
+
The Docusaurus viewer that shows the project's `docs/` folder at `/docs`. Copy every file, keeping the folder layout. See [Documentation](/docs/Standards/documentation#-setting-it-up).
|
|
298
298
|
|
|
299
299
|
| File | Plain file |
|
|
300
300
|
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -360,7 +360,7 @@ Plain file: [`/templates/next.config.mjs`](pathname:///templates/next.config.mjs
|
|
|
360
360
|
|
|
361
361
|
**Copy to:** the `docs/` folder in the project root, keeping the folder layout
|
|
362
362
|
|
|
363
|
-
The full set of Decision Docs for a new project: every [reusable folder](/Standards/documentation#-the-folders) with every standard file, each marked `Status: Not started`. Copy the whole [`static/templates/docs/`](https://github.com/activatus-life/code-standards/tree/main/static/templates/docs) folder from this repository.
|
|
363
|
+
The full set of Decision Docs for a new project: every [reusable folder](/docs/Standards/documentation#-the-folders) with every standard file, each marked `Status: Not started`. Copy the whole [`static/templates/docs/`](https://github.com/activatus-life/code-standards/tree/main/static/templates/docs) folder from this repository.
|
|
364
364
|
|
|
365
365
|
| Folder | Example file |
|
|
366
366
|
| --------------- | --------------------------------------------------------------------------------------------- |
|
|
@@ -375,7 +375,7 @@ After copying, rename `overview/what-is-it.md` after the project and update its
|
|
|
375
375
|
|
|
376
376
|
**Copy to:** any new doc that has no template file
|
|
377
377
|
|
|
378
|
-
The shape every doc follows. See [The doc format](/Standards/documentation#-the-doc-format). Plain file: [`/templates/decision-doc.md`](pathname:///templates/decision-doc.md)
|
|
378
|
+
The shape every doc follows. See [The doc format](/docs/Standards/documentation#-the-doc-format). Plain file: [`/templates/decision-doc.md`](pathname:///templates/decision-doc.md)
|
|
379
379
|
|
|
380
380
|
<CodeBlock language="markdown" title="decision-doc.md">
|
|
381
381
|
{decisionDoc}
|