@activatus/code-standards 2.0.0 → 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.
Files changed (51) hide show
  1. package/README.md +12 -13
  2. package/docs/Guides/_category_.json +2 -2
  3. package/docs/Guides/migrating.md +33 -16
  4. package/docs/Guides/setup.md +46 -18
  5. package/docs/Standards/_category_.json +2 -2
  6. package/docs/Standards/agent-skills.md +29 -29
  7. package/docs/Standards/agent-specs.md +17 -32
  8. package/docs/Standards/direnv.mdx +8 -8
  9. package/docs/Standards/documentation.md +5 -2
  10. package/docs/Standards/editorconfig.md +23 -21
  11. package/docs/Standards/eslint.md +593 -402
  12. package/docs/Standards/human-readable-names.md +61 -21
  13. package/docs/Standards/lint-errors.md +37 -5
  14. package/docs/Standards/prettier.md +35 -26
  15. package/docs/Standards/readable-code.md +30 -0
  16. package/docs/Standards/stylelint.md +26 -11
  17. package/docs/Standards/styling.md +9 -3
  18. package/docs/Standards/tech-stack.md +3 -1
  19. package/docs/Structure/_category_.json +2 -2
  20. package/docs/Structure/component-organization.md +9 -2
  21. package/docs/Structure/folder-structure.md +26 -13
  22. package/docs/Structure/naming-conventions.md +0 -2
  23. package/docs/intro.md +1 -3
  24. package/docs/ontology.md +21 -26
  25. package/docs/templates.mdx +15 -38
  26. package/docs/version-history.md +133 -6
  27. package/package.json +6 -2
  28. package/scripts/renameSymbol.mjs +188 -0
  29. package/static/templates/.editorconfig +8 -11
  30. package/static/templates/AGENTS.md +16 -13
  31. package/static/templates/docs/development/coding-standards.md +4 -0
  32. package/static/templates/docsSite/docusaurus.config.mjs +144 -0
  33. package/static/templates/docsSite/sidebars.mjs +7 -0
  34. package/static/templates/docsSite/src/css/custom.css +6 -0
  35. package/static/templates/docsSite/tsconfig.json +5 -5
  36. package/static/templates/eslint/base/eslint.config.mjs +95 -70
  37. package/static/templates/eslint/nextjs/eslint.config.mjs +170 -126
  38. package/static/templates/eslint/react/eslint.config.mjs +160 -125
  39. package/static/templates/eslint/typescript/eslint.config.mjs +143 -115
  40. package/static/templates/globals.css +9 -9
  41. package/static/templates/next.config.mjs +13 -10
  42. package/static/templates/prettier.config.mjs +26 -0
  43. package/static/templates/stylelint/css/stylelint.config.mjs +37 -25
  44. package/static/templates/stylelint/scss/stylelint.config.mjs +10 -7
  45. package/docs/Standards/branch-naming.md +0 -66
  46. package/docs/Standards/conventional-commits.md +0 -189
  47. package/static/templates/.commitlintrc.json +0 -3
  48. package/static/templates/docsSite/docusaurus.config.ts +0 -119
  49. package/static/templates/docsSite/sidebars.ts +0 -8
  50. package/static/templates/husky/commit-msg +0 -1
  51. package/static/templates/prettier.config.js +0 -17
package/docs/ontology.md CHANGED
@@ -17,7 +17,7 @@ An ontology is a shared vocabulary. When a person or an agent says "component",
17
17
 
18
18
  This page only holds **code words**: how code is written, named, tested, documented and reviewed.
19
19
 
20
- **Product words live in each project's own ontology**, in `docs/product/ontology.md`: the words for what that project builds and how its team plans the work. Launchpad's Draft Ticket, Pitch and UAT are product words, so they are in Launchpad's ontology, not here.
20
+ **Product words live in each project's own ontology**, in `docs/product/ontology.md`: the words for what that project builds and how its team plans the work. **Project-management words live there too**: project, feature, ticket, branch, commit, Pull Request, release. Every project defines those for itself. Launchpad's Draft Ticket, Pitch and UAT are product words, so they are in Launchpad's ontology, not here.
21
21
 
22
22
  | | Code words | Product words |
23
23
  | ------------ | -------------------------------------------------------- | --------------------------------------------------- |
@@ -48,12 +48,10 @@ The words stay the same everywhere. Only the casing changes, to match where the
48
48
 
49
49
  ## The terms
50
50
 
51
- ### Projects and docs
51
+ ### Docs
52
52
 
53
53
  | Term | Means |
54
54
  | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
55
- | `project` | One product's code and docs. One project is exactly one repository |
56
- | `repository` | The Git repository that holds a project's code and docs |
57
55
  | `decision` | A choice made on purpose and written down, never left implied |
58
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) |
59
57
  | `docs` | A project's `docs/` folder: its Decision Docs, in the same standard folders in every project |
@@ -62,17 +60,17 @@ The words stay the same everywhere. Only the casing changes, to match where the
62
60
 
63
61
  ### People and agents
64
62
 
65
- | Term | Means |
66
- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
67
- | `human` | A person, as opposed to an agent. Only humans commit code, unless the project's `AGENTS.md` says agents may |
68
- | `developer` | A human who writes code |
69
- | `agent` | An AI that writes or checks code, such as Claude Code. It follows every standard a developer does. By default it never commits, pushes or makes branches — see [A project can choose otherwise](/Standards/agent-specs#a-project-can-choose-otherwise) |
70
- | `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) |
71
- | `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 |
72
- | `context` | Everything an agent is given to read for its task: the agent spec, the docs and the code it is working on |
73
- | `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
- | `model` | The AI model an agent thinks with |
75
- | `mcp` | Model Context Protocol: the standard way to connect an agent to outside tools and data, such as Linear or GitHub. An MCP server offers tools, and the agent calls them |
63
+ | Term | Means |
64
+ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65
+ | `human` | A person, as opposed to an agent |
66
+ | `developer` | A human who writes code |
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) |
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
+ | `context` | Everything an agent is given to read for its task: the agent spec, the docs and the code it is working on |
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 |
72
+ | `model` | The AI model an agent thinks with |
73
+ | `mcp` | Model Context Protocol: the standard way to connect an agent to outside tools and data, such as Linear or GitHub. An MCP server offers tools, and the agent calls them |
76
74
 
77
75
  ### Code
78
76
 
@@ -84,7 +82,10 @@ The words stay the same everywhere. Only the casing changes, to match where the
84
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) |
85
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` |
86
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` |
87
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 |
88
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) |
89
90
  | `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 |
90
91
  | `test_file` | The file that tests one function or component, named after it: `formatCurrency.test.ts`. Every function and component has one |
@@ -93,16 +94,11 @@ The words stay the same everywhere. Only the casing changes, to match where the
93
94
  | `third_party_code` | Code we did not write: `node_modules/`, and anything copied into `vendor/`. It is never linted, reformatted or renamed |
94
95
  | `global_palette` | The colours defined in `app/globals.css`. Every colour in a project comes from it. See [Styling](/Standards/styling) |
95
96
 
96
- ### Changes and checks
97
+ ### Checks
97
98
 
98
- | Term | Means |
99
- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
100
- | `branch` | A line of work in Git, named `type/short-description`. Nobody works straight on `main`. See [Branch Naming](/Standards/branch-naming) |
101
- | `commit` | A saved change, with a [Conventional Commits](/Standards/conventional-commits) message. Only humans make commits, unless the project says agents may |
102
- | `pull_request` | A request to merge a branch into `main`, with a description of what changed and why |
103
- | `pull_request_review` | Checking a Pull Request against these standards before it is merged, by a human or an agent |
104
- | `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) |
105
- | `production` | The live app that real users use |
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) |
106
102
 
107
103
  ---
108
104
 
@@ -114,11 +110,10 @@ These are the terms most easily confused. The **Not** column is the word we do n
114
110
  | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
115
111
  | **Decision / Decision Doc** | The choice itself vs the file that records it | |
116
112
  | **Docs / Docs Site** | The Markdown files vs the viewer that shows them | |
117
- | **Human / Agent** | By default only a human commits. An agent makes the change and leaves it for a human to review | |
118
113
  | **Props** | The values a component takes | `properties` |
119
114
  | **Utils** | Reusable functions | `helpers`, `utilities` |
120
115
  | **Dictionary Word / Third-Party Name** | A short name we chose to keep vs a name someone else chose for us | |
121
- | **Design System / Shared / Page Component** | The same in every project (`components/ui/`) vs used on several pages of this project (`components/shared/`) vs used by one page or section (beside it) | feature components |
116
+ | **Design System / Shared / Page Component** | The same in every project (`components/ui/`) vs used on several pages of this project (`components/shared/`) vs used by one page or section (beside it) | |
122
117
 
123
118
  ---
124
119
 
@@ -8,14 +8,13 @@ import eslintTypescript from "!!raw-loader!@site/static/templates/eslint/typescr
8
8
  import eslintReact from "!!raw-loader!@site/static/templates/eslint/react/eslint.config.mjs";
9
9
  import eslintNextjs from "!!raw-loader!@site/static/templates/eslint/nextjs/eslint.config.mjs";
10
10
  import eslintBase from "!!raw-loader!@site/static/templates/eslint/base/eslint.config.mjs";
11
- import prettier from "!!raw-loader!@site/static/templates/prettier.config.js";
11
+ import prettier from "!!raw-loader!@site/static/templates/prettier.config.mjs";
12
12
  import stylelintCss from "!!raw-loader!@site/static/templates/stylelint/css/stylelint.config.mjs";
13
13
  import stylelintScss from "!!raw-loader!@site/static/templates/stylelint/scss/stylelint.config.mjs";
14
14
  import globalsCss from "!!raw-loader!@site/static/templates/globals.css";
15
15
  import editorconfig from "!!raw-loader!@site/static/templates/.editorconfig";
16
16
  import nvmrc from "!!raw-loader!@site/static/templates/.nvmrc";
17
17
  import envrc from "!!raw-loader!@site/static/templates/.envrc";
18
- import commitlint from "!!raw-loader!@site/static/templates/.commitlintrc.json";
19
18
  import skillLint from "!!raw-loader!@site/static/templates/skills/lint.md";
20
19
  import skillLintFix from "!!raw-loader!@site/static/templates/skills/lintFix.md";
21
20
  import skillFormat from "!!raw-loader!@site/static/templates/skills/format.md";
@@ -25,8 +24,8 @@ import skillSecurityAudit from "!!raw-loader!@site/static/templates/skills/secur
25
24
  import skillTypescript from "!!raw-loader!@site/static/templates/skills/typescript.md";
26
25
  import skillTest from "!!raw-loader!@site/static/templates/skills/test.md";
27
26
  import docsSitePackage from "!!raw-loader!@site/static/templates/docsSite/package.json.txt";
28
- import docsSiteConfig from "!!raw-loader!@site/static/templates/docsSite/docusaurus.config.ts";
29
- import docsSiteSidebars from "!!raw-loader!@site/static/templates/docsSite/sidebars.ts";
27
+ import docsSiteConfig from "!!raw-loader!@site/static/templates/docsSite/docusaurus.config.mjs";
28
+ import docsSiteSidebars from "!!raw-loader!@site/static/templates/docsSite/sidebars.mjs";
30
29
  import docsSiteTsconfig from "!!raw-loader!@site/static/templates/docsSite/tsconfig.json";
31
30
  import docsSiteWorkspace from "!!raw-loader!@site/static/templates/docsSite/pnpm-workspace.yaml";
32
31
  import docsSiteCss from "!!raw-loader!@site/static/templates/docsSite/src/css/custom.css";
@@ -34,7 +33,6 @@ import docsSiteGitignore from "!!raw-loader!@site/static/templates/docsSite/giti
34
33
  import decisionDoc from "!!raw-loader!@site/static/templates/decision-doc.md";
35
34
  import docsSiteHome from "!!raw-loader!@site/static/templates/docsSite/src/pages/index.tsx";
36
35
  import nextConfig from "!!raw-loader!@site/static/templates/next.config.mjs";
37
- import huskyHook from "!!raw-loader!@site/static/templates/husky/commit-msg";
38
36
  import huskyPreCommit from "!!raw-loader!@site/static/templates/husky/pre-commit";
39
37
 
40
38
  # Templates
@@ -43,6 +41,8 @@ Ready-made files to copy into a project. Every config on this page is the exact
43
41
 
44
42
  Each file is also served as a plain file, so a person or an AI agent can fetch it directly instead of copying from this page.
45
43
 
44
+ **Every config file is `.mjs`, even in a TypeScript project.** Never convert one to `.ts` or `.mts`. It works in both, so every project looks the same. A tool that cannot read `.mjs` keeps its own format.
45
+
46
46
  | File | Copy to | Plain file |
47
47
  | ------------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
48
48
  | [AGENTS.md](#agents) | `AGENTS.md` in the project root | [`/templates/AGENTS.md`](pathname:///templates/AGENTS.md) |
@@ -50,16 +50,15 @@ Each file is also served as a plain file, so a person or an AI agent can fetch i
50
50
  | [ESLint — React + TypeScript](#eslintreact) | `eslint.config.mjs` in the project root | [`/templates/eslint/react/eslint.config.mjs`](pathname:///templates/eslint/react/eslint.config.mjs) |
51
51
  | [ESLint — Next.js](#eslintnextjs) | `eslint.config.mjs` in the project root | [`/templates/eslint/nextjs/eslint.config.mjs`](pathname:///templates/eslint/nextjs/eslint.config.mjs) |
52
52
  | [ESLint — JavaScript / Node.js](#eslintbase) | `eslint.config.mjs` in the project root | [`/templates/eslint/base/eslint.config.mjs`](pathname:///templates/eslint/base/eslint.config.mjs) |
53
- | [Prettier](#prettier) | `prettier.config.js` in the project root | [`/templates/prettier.config.js`](pathname:///templates/prettier.config.js) |
53
+ | [Prettier](#prettier) | `prettier.config.mjs` in the project root | [`/templates/prettier.config.mjs`](pathname:///templates/prettier.config.mjs) |
54
54
  | [Stylelint — CSS and CSS Modules](#stylelintcss) | `stylelint.config.mjs` in the project root | [`/templates/stylelint/css/stylelint.config.mjs`](pathname:///templates/stylelint/css/stylelint.config.mjs) |
55
55
  | [Stylelint — SCSS](#stylelintscss) | `stylelint.config.mjs` in the project root | [`/templates/stylelint/scss/stylelint.config.mjs`](pathname:///templates/stylelint/scss/stylelint.config.mjs) |
56
56
  | [Global styles and colour palette](#globalscss) | `app/globals.css` | [`/templates/globals.css`](pathname:///templates/globals.css) |
57
57
  | [EditorConfig](#editorconfig) | `.editorconfig` in the project root | [`/templates/.editorconfig`](pathname:///templates/.editorconfig) |
58
58
  | [Node version](#nvmrc) | `.nvmrc` in the project root | [`/templates/.nvmrc`](pathname:///templates/.nvmrc) |
59
59
  | [direnv](#envrc) | `.envrc` in the project root | [`/templates/.envrc`](pathname:///templates/.envrc) |
60
- | [Commitlint](#commitlint) | `.commitlintrc.json` in the project root | [`/templates/.commitlintrc.json`](pathname:///templates/.commitlintrc.json) |
61
60
  | [Agent skills](#skills) | `.agents/skills/` and `.claude/commands/` | Eight files — see [below](#skills) |
62
- | [Husky commit hook](#husky) | `.husky/commit-msg` | [`/templates/husky/commit-msg`](pathname:///templates/husky/commit-msg) |
61
+ | [Lint before commit](#husky-pre-commit) | `.husky/pre-commit` | [`/templates/husky/pre-commit`](pathname:///templates/husky/pre-commit) |
63
62
  | [Docs site](#docs-site) | `docsSite/` in the project root | Several files — see [below](#docs-site) |
64
63
  | [`/docs` route](#docs-route) | `next.config.mjs` | [`/templates/next.config.mjs`](pathname:///templates/next.config.mjs) |
65
64
  | [Document templates](#document-templates) | `docs/` in the project root | Several files — see [below](#document-templates) |
@@ -128,11 +127,11 @@ For plain JavaScript and Node.js projects.
128
127
 
129
128
  ## Prettier {#prettier}
130
129
 
131
- **Copy to:** `prettier.config.js` in the project root
130
+ **Copy to:** `prettier.config.mjs` in the project root
132
131
 
133
132
  See the [Prettier page](/Standards/prettier).
134
133
 
135
- <CodeBlock language="js" title="prettier.config.js">
134
+ <CodeBlock language="js" title="prettier.config.mjs">
136
135
  {prettier}
137
136
  </CodeBlock>
138
137
 
@@ -210,18 +209,6 @@ Run `direnv allow` after adding it. See [direnv + nvm](/Standards/direnv).
210
209
 
211
210
  ---
212
211
 
213
- ## Commitlint {#commitlint}
214
-
215
- **Copy to:** `.commitlintrc.json` in the project root
216
-
217
- See [Conventional Commits](/Standards/conventional-commits).
218
-
219
- <CodeBlock language="json" title=".commitlintrc.json">
220
- {commitlint}
221
- </CodeBlock>
222
-
223
- ---
224
-
225
212
  ## Agent skills {#skills}
226
213
 
227
214
  **Copy to:** `.agents/skills/` in the project root, and again to `.claude/commands/` so Claude Code picks them up as slash commands.
@@ -305,21 +292,11 @@ Runs the test suite; reports failures grouped by cause, tests that never ran, an
305
292
 
306
293
  ---
307
294
 
308
- ## Husky commit hook {#husky}
309
-
310
- **Copy to:** `.husky/commit-msg` in the project root
311
-
312
- Refuses a commit whose message does not follow [Conventional Commits](/Standards/conventional-commits#enforcing-commit-messages). Plain file: [`/templates/husky/commit-msg`](pathname:///templates/husky/commit-msg)
313
-
314
- <CodeBlock language="text" title=".husky/commit-msg">
315
- {huskyHook}
316
- </CodeBlock>
317
-
318
- ### Lint before commit {#husky-pre-commit}
295
+ ## Lint before commit {#husky-pre-commit}
319
296
 
320
297
  **Copy to:** `.husky/pre-commit` in the project root
321
298
 
322
- Refuses a commit while `pnpm lint` reports errors. Plain file: [`/templates/husky/pre-commit`](pathname:///templates/husky/pre-commit)
299
+ Refuses a commit while `pnpm lint` reports errors. See [Lint before every commit](/Standards/lint-errors#lint-before-every-commit). Plain file: [`/templates/husky/pre-commit`](pathname:///templates/husky/pre-commit)
323
300
 
324
301
  <CodeBlock language="text" title=".husky/pre-commit">
325
302
  {huskyPreCommit}
@@ -336,8 +313,8 @@ The Docusaurus viewer that shows the project's `docs/` folder at `/docs`. Copy e
336
313
  | File | Plain file |
337
314
  | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
338
315
  | `package.json` | [`/templates/docsSite/package.json.txt`](pathname:///templates/docsSite/package.json.txt) — rename to `package.json` |
339
- | `docusaurus.config.ts` | [`/templates/docsSite/docusaurus.config.ts`](pathname:///templates/docsSite/docusaurus.config.ts) |
340
- | `sidebars.ts` | [`/templates/docsSite/sidebars.ts`](pathname:///templates/docsSite/sidebars.ts) |
316
+ | `docusaurus.config.mjs` | [`/templates/docsSite/docusaurus.config.mjs`](pathname:///templates/docsSite/docusaurus.config.mjs) |
317
+ | `sidebars.mjs` | [`/templates/docsSite/sidebars.mjs`](pathname:///templates/docsSite/sidebars.mjs) |
341
318
  | `tsconfig.json` | [`/templates/docsSite/tsconfig.json`](pathname:///templates/docsSite/tsconfig.json) |
342
319
  | `pnpm-workspace.yaml` | [`/templates/docsSite/pnpm-workspace.yaml`](pathname:///templates/docsSite/pnpm-workspace.yaml) |
343
320
  | `src/css/custom.css` | [`/templates/docsSite/src/css/custom.css`](pathname:///templates/docsSite/src/css/custom.css) |
@@ -347,7 +324,7 @@ The Docusaurus viewer that shows the project's `docs/` folder at `/docs`. Copy e
347
324
 
348
325
  Set `PROJECT_NAME` at the top of the config:
349
326
 
350
- <CodeBlock language="ts" title="docusaurus.config.ts">
327
+ <CodeBlock language="js" title="docusaurus.config.mjs">
351
328
  {docsSiteConfig}
352
329
  </CodeBlock>
353
330
 
@@ -355,7 +332,7 @@ Set `PROJECT_NAME` at the top of the config:
355
332
  {docsSitePackage}
356
333
  </CodeBlock>
357
334
 
358
- <CodeBlock language="ts" title="sidebars.ts">
335
+ <CodeBlock language="js" title="sidebars.mjs">
359
336
  {docsSiteSidebars}
360
337
  </CodeBlock>
361
338
 
@@ -31,11 +31,134 @@ sidebar_label: "Version History"
31
31
 
32
32
  Anyone changing the standards adds a version, in the same pull request as the change:
33
33
 
34
- - **One version per change that reaches `main`**, numbered one higher than the last. Whole numbers only.
34
+ - **One version per release**, numbered one higher than the last. Whole numbers only. A version can collect several changes before it is released.
35
35
  - **Bump the package's major version to match** in `package.json`: version 3 is `3.0.0`. Then publish it to npm (npmjs.com) with `pnpm publish`. pnpm is the tool; npm is where the package lives, and projects install it from there with `pnpm add`.
36
36
  - **For every change, write:** what changed, why, what to do in a project, and how to check it is done. Write it for an agent that has not read the rest of the standards.
37
37
  - **If a project has nothing to do, say so.**
38
38
  - **Newest version at the top.**
39
+ - **Work in progress goes under `## Version N — not released yet`**, with a line saying projects should not apply it yet. Changes can be added to it over several Pull Requests. To release it: drop "not released yet", add the **Released** date and **Updates from** line, set `package.json` to `N.0.0`, then publish.
40
+
41
+ ---
42
+
43
+ ## Version 3
44
+
45
+ **Released:** 2026-10-17 · **Updates from:** version 2
46
+
47
+ Install it with `pnpm add -D @activatus/code-standards@3.0.0`. Do change 1 first: it says which parts of the project's `AGENTS.md` are now the project's own to write.
48
+
49
+ ### 1. Project workflow is no longer part of the standards
50
+
51
+ **Why:** The standards are a base for code. How a project runs its work — branch names, commit messages, Pull Requests, merging, releases, and whether AI agents may commit — is each project's own decision, and every project makes it differently.
52
+
53
+ **What to do:**
54
+
55
+ - The Branch Naming and Commit Messages standards are gone, along with standards 19, 20 and 22 from the setup list. Keep whatever the project already does, and make sure it is written up in the project's own docs, usually `docs/development/`.
56
+ - In `AGENTS.md`, replace the "Development workflow" section with a **Project workflow** section, copied from the [template](/templates#agents). Fill it in with the project's own rules: who commits, branches, commit messages, Pull Requests, merging and releases. Put the most important rule for agents — whether they may commit — in the line at the very top.
57
+ - Remove the "Never commit code" and "Do not create, switch or delete branches" lines from "Out of scope for AI agents", unless they are the project's own rule. If they are, they belong in Project workflow.
58
+ - Commitlint and the `.husky/commit-msg` hook are no longer templates. Keep them if the project wants its commit messages checked; they are now the project's choice.
59
+ - **Keep `.husky/pre-commit`.** Running `pnpm lint` before every commit is still a standard. See [Lint before every commit](/Standards/lint-errors#lint-before-every-commit).
60
+
61
+ **How to check:** `AGENTS.md` has a Project workflow section, and every rule in it is written up in the project's docs.
62
+
63
+ ### 2. `lib`, `ref` and `repo` are dictionary words, and `library/` is `lib/`
64
+
65
+ **Why:** They are the words developers use. `lib/` is the name Next.js and shadcn/ui use too.
66
+
67
+ **What to do:**
68
+
69
+ - Rename the `library/` folder to `lib/` with `git mv`, and fix the imports: `@/library/` → `@/lib/`.
70
+ - Rename names ending in `Reference` that hold a React ref back to `Ref`: `inputReference` → `inputRef`. Rename `repository` back to `repo` where it is short for a Git repository, such as `repositoryName` → `repoName`. Use the editor's Rename Symbol (F2), or the [rename script](/Guides/migrating#renaming-from-the-command-line).
71
+ - Copy the new [ESLint config](/Standards/eslint). The naming rule now has `replacements: { docs: false, lib: false, props: false, ref: false, repo: false, utils: false }` and `allowList: { params: true, searchParams: true }`.
72
+ - Update the "Dictionary words stay short" line in `AGENTS.md` from the [template](/templates#agents), and remove `lib/` → `library/` and `repo` → `repository` from its Never / Always table.
73
+
74
+ **How to check:** There is no `library/` folder, `grep -rn "@/library" --exclude-dir=node_modules .` finds nothing, and `pnpm lint` passes.
75
+
76
+ ### 3. utils, services and lib are defined
77
+
78
+ **Why:** It wasn't clear which functions go in `utils/`, `services/` or `lib/`. See [utils, services and lib](/Structure/folder-structure#utils-services-and-lib).
79
+
80
+ **What to do:** Check each function in those three folders against the definitions, and move any that are in the wrong one. The common one: a function in `utils/` that calls a database or an API belongs in `services/` or `lib/`. Shared constants and types live in `lib/constants/` and `lib/types/`; a component's own types stay in its `types.ts`. Move any root-level `constants/` or `types/` folder into `lib/`.
81
+
82
+ **How to check:** Nothing in `utils/` imports from `services/`, `lib/integrations/` or a database client, and there is no root-level `constants/` or `types/` folder.
83
+
84
+ ### 4. The Ontology only holds code words
85
+
86
+ **Why:** Project-management words mean different things in different projects. Launchpad's "project" is a product made of several MVPs, and its Pull Requests go through `feature → dev → uat → main`.
87
+
88
+ **What to do:** The code [Ontology](/ontology) no longer defines `project`, `repository`, `branch`, `commit`, `pull_request`, `pull_request_review` or `production`, and `human`, `developer` and `agent` no longer say who may commit. If the project uses those words, define them in its own `docs/product/ontology.md`, the way the project actually works.
89
+
90
+ **How to check:** The project's ontology defines every project-management word it uses.
91
+
92
+ ### 5. Every config file is `.mjs`
93
+
94
+ **Why:** `.mjs` works in TypeScript and JavaScript projects alike, so every project looks the same.
95
+
96
+ **What to do:**
97
+
98
+ - Rename each config file that is `.js`, `.ts` or `.mts` to `.mjs`, even in a TypeScript project, wherever the tool can read `.mjs`: `prettier.config.mjs`, `next.config.mjs`, `eslint.config.mjs`, `docsSite/docusaurus.config.mjs`, `docsSite/sidebars.mjs` and so on. Use `git mv`. Never convert a config to `.ts` or `.mts`.
99
+ - Remove any TypeScript-only syntax as you go. A type annotation becomes a JSDoc comment: `const config: NextConfig = {` becomes `/** @type {import("next").NextConfig} */ const config = {`. Copy the [`docsSite/` templates](/templates#docs-site), which are already `.mjs`.
100
+ - Update anything that names the old file, such as `sidebarPath: './sidebars.mjs'` in the docs site config.
101
+
102
+ **How to check:** `ls *.config.* docsSite/*.config.* docsSite/sidebars.*` shows only `.mjs` files, and `pnpm lint`, `pnpm format:check`, the build and `pnpm docs:build` still run.
103
+
104
+ ### 6. Prettier: 70-character lines and tabs
105
+
106
+ **Why:** A lot of code is read and reviewed on a phone, where short lines fit the screen. Tabs let each person see the indent at the width they like.
107
+
108
+ **What to do:**
109
+
110
+ - Copy the new [`prettier.config.mjs`](/templates#prettier) and [`.editorconfig`](/templates#editorconfig). Prettier now has `printWidth: 70` and `useTabs: true`, and keeps spaces for Markdown and YAML. EditorConfig indents with tabs, except Markdown, YAML and Python.
111
+ - Run `pnpm format` once, on its own, in a Pull Request with nothing else in it. It touches nearly every file, so keep it apart from real changes.
112
+ - If the project shows code on a web page, such as its docs site, add `pre, code { tab-size: 2; }` to its CSS, so tabs are not shown 8 characters wide. The [`docsSite/` template](/templates#docs-site) already has it.
113
+
114
+ **How to check:** `pnpm format:check` passes.
115
+
116
+ ### 7. When a name clashes, rename our own thing first
117
+
118
+ **Why:** A third-party name is the name everyone knows it by, and a clash usually means our own name is too vague. Renaming an import for taste makes the code harder to search and to match against the package's docs.
119
+
120
+ **What to do:** Search for renamed imports: `grep -rn "import {[^}]* as " --include=*.ts --include=*.tsx --exclude-dir=node_modules .`. For each one:
121
+
122
+ - **If nothing in the file clashes with the original name**, undo the rename and use the original name.
123
+ - **If our own thing clashes**, rename ours to a more specific full-word name, with the editor's Rename Symbol or the [rename script](/Guides/migrating#renaming-from-the-command-line). Then undo the import rename. For example, our `createClient` becomes `createProjectDatabaseClient`, and Supabase's `createClient` keeps its name.
124
+ - **If both names are third-party, or ours is fixed by a framework** (such as a Next.js route's `GET`), keep the import renamed, as the owner plus the original name, never shortened: `Link as LucideLinkIcon`.
125
+
126
+ See [When a name clashes](/Standards/human-readable-names#when-a-name-clashes).
127
+
128
+ **How to check:** Every renamed import that is left clashes with another third-party name or a framework-fixed name, and starts with its owner's name.
129
+
130
+ ### 8. Name a type after what it is, not the job it does
131
+
132
+ **Why:** A type named after its role in one function, such as `StartAgentRunDependenciesType`, is a second name for what is really part of that function's props.
133
+
134
+ **What to do:** Find types used for only one field of one `Props` type. Move each one inside that `Props` and delete the separate type. Where the object is built somewhere else, remove its type annotation: TypeScript checks it against the `Props` when it is passed in. See [Name a type after what it is](/Standards/readable-code#name-a-type-after-what-it-is-not-the-job-it-does).
135
+
136
+ **How to check:** No type is used only as the type of one field of one `Props`.
137
+
138
+ ### 9. "go" means carry on
139
+
140
+ **Why:** People often send just "go" to nudge an agent along, for example when their connection drops and the agent looks stuck. An agent must never read it as permission to commit.
141
+
142
+ **What to do:** Copy the line that starts **"go" means carry on** from the top of the [`AGENTS.md` template](/templates#agents) into the top of the project's `AGENTS.md`.
143
+
144
+ **How to check:** The project's `AGENTS.md` has the line near the top.
145
+
146
+ ### 10. Unfinished changes are recorded, not hidden
147
+
148
+ **Why:** A big change, such as switching on the standard ESLint config, may be done later in its own Pull Request. The version number has to stay honest about that.
149
+
150
+ **What to do:** Add an "Unfinished changes" section to `docs/development/coding-standards.md`, from the [template](/templates#document-templates). List any change from any version that is not done yet, with what is left and where it is being done, or write "None". See [Finishing a change later](/Guides/setup#finishing-a-change-later).
151
+
152
+ **How to check:** `docs/development/coding-standards.md` has an "Unfinished changes" section.
153
+
154
+ ### No action needed
155
+
156
+ - The [Ontology](/ontology) defines `dependency`: something the code relies on but does not define itself. Ticket relationships are not dependencies; each project names those itself.
157
+ - The package now ships a rename script for agents working from the command line, using TypeScript's own rename: `node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs <file> <currentName> <newName>`. See [Renaming from the command line](/Guides/migrating#renaming-from-the-command-line).
158
+ - The [Setup](/Guides/setup) guide says the standards are a base for code only, and explains how to get past pnpm's `minimumReleaseAge` when a new version is too fresh to install.
159
+ - [Folder Structure](/Structure/folder-structure) explains each `lib/` folder in one line.
160
+ - The [ESLint page](/Standards/eslint#installation) says the config needs ESLint 10.4 or later, and the React configs explain why they set `settings.react.version`.
161
+ - "Lint before every commit" moved to [Lint Errors](/Standards/lint-errors#lint-before-every-commit).
39
162
 
40
163
  ---
41
164
 
@@ -73,14 +196,17 @@ Anyone changing the standards adds a version, in the same pull request as the ch
73
196
  **What to do:**
74
197
 
75
198
  - Rename the folders with `git mv`: `documentation/` → `docs/`, `documentationSite/` → `docsSite/`.
199
+ - **If both `docsSite/` and `documentationSite/` exist**, merge them into `docsSite/`: move each tracked file from `documentationSite/` with `git mv`, keeping whichever copy is newer, then delete `documentationSite/`. Ask the person before deleting a file that exists in only one of them.
76
200
  - Rename `docs/overview/writing-documentation.md` → `docs/overview/writing-docs.md`, and fix every link to it.
77
201
  - Rename the environment variable `DOCUMENTATION_URL` → `DOCS_URL` in `next.config.mjs`, `.env.local`, `.env.example` and the hosting provider's settings.
78
202
  - Rename the route `/documentation` → `/docs`. Copy the new rewrite from the [`next.config.mjs` template](/templates#docs-route).
79
- - In `docsSite/docusaurus.config.ts`, set `baseUrl: '/docs/'` and `path: '../docs'`. Copy the [`docsSite/` template](/templates#docs-site) if unsure.
203
+ - **Re-copy `docsSite/docusaurus.config.ts`** from the [`docsSite/` template](/templates#docs-site), keeping the project's name and theme. Version 2 changed it: `baseUrl: '/docs/'`, `path: '../docs'`, full-word variable names (`rest` → `remainingArguments`, `doc` → `page`), and `static/img` → `static/images`. Rename the project's `docsSite/static/img/` to `static/images/` to match.
80
204
  - Rename the scripts in `package.json`: `documentation:install` → `docs:install`, `documentation:dev` → `docs:dev`, `documentation:build` → `docs:build`.
205
+ - If the docs site's generated folders were ever committed, stop tracking them: `git rm -r --cached docsSite/.docusaurus docsSite/build`. They are in the [`docsSite/` template's](/templates#docs-site) `.gitignore`.
81
206
  - Update every mention in `AGENTS.md`, `README.md` and the docs themselves.
207
+ - **Update every ignore list** that names the old folders: ESLint, Prettier, `tsconfig.json`, Vitest or Jest, and `.gitignore`. A leftover docs site with its own `node_modules` makes test runners and linters run its files too.
82
208
 
83
- **How to check:** `grep -rn "documentation/\|documentationSite\|DOCUMENTATION_URL\|documentation:" --exclude-dir=node_modules .` finds nothing. Normal sentences that say "documentation" are fine.
209
+ **How to check:** `grep -rn "documentation/\|'../documentation'\|documentationSite\|DOCUMENTATION_URL\|documentation:" --exclude-dir=node_modules .` finds nothing. Normal sentences that say "documentation" are fine.
84
210
 
85
211
  ### 4. `props` is a dictionary word: prop types end in `Props`
86
212
 
@@ -88,11 +214,12 @@ Anyone changing the standards adds a version, in the same pull request as the ch
88
214
 
89
215
  **What to do:**
90
216
 
91
- - Rename every type ending in `Properties` to end in `Props`: `ButtonProperties` → `ButtonProps`. Use the editor's Rename Symbol (F2), not find-and-replace.
217
+ - Rename every type ending in `Properties` to end in `Props`: `ButtonProperties` → `ButtonProps`. Never use find-and-replace. Use the editor's Rename Symbol (F2) or, for an agent working from the command line, the rename script in version 3 and later of the package: `node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs <file> <currentName> <newName>`. Both use TypeScript's own rename, so they change every use and nothing else.
92
218
  - Rename variables and parameters called `properties` to `props`, including spreads: `...buttonProperties` → `...buttonProps`.
93
- - Copy the new [ESLint config](/Standards/eslint). Two things changed in it:
219
+ - **If the project already uses the standard ESLint config**, copy the new [ESLint config](/Standards/eslint). It needs ESLint 10.4 or later. Two things changed in it:
94
220
  - The type-name rule is now `(Props|Type)$`.
95
221
  - `unicorn/name-replacements` now has `replacements: { docs: false, props: false, utils: false }`.
222
+ - **If the project never had the standard ESLint config**, do only the renames in this change. Switching the config on can find hundreds of problems, so do it separately with [Migrating an Existing Project](/Guides/migrating), one stage per Pull Request, and record it as unfinished: see [Finishing a change later](/Guides/setup#finishing-a-change-later).
96
223
 
97
224
  **How to check:** `grep -rn "Properties\b" --include=*.ts --include=*.tsx --exclude-dir=node_modules .` finds nothing of ours, and `pnpm lint` passes.
98
225
 
@@ -179,7 +306,7 @@ Anyone changing the standards adds a version, in the same pull request as the ch
179
306
 
180
307
  **Why:** Strict no commit is right for most projects, but a tool built to ship code with AI, such as Launchpad, needs agents to commit.
181
308
 
182
- **What to do:** This is standard 22 in the list from change 2. If the person kept it, keep the template's "NEVER COMMIT CODE" lines for strict no commit. Otherwise, replace them with the project's own rule, saying exactly which agents may commit, push and open Pull Requests, and when. See [A project can choose otherwise](/Standards/agent-specs#a-project-can-choose-otherwise).
309
+ **What to do:** This is standard 22 in the list from change 2. If the person kept it, keep the template's "NEVER COMMIT CODE" lines for strict no commit. Otherwise, replace them with the project's own rule, saying exactly which agents may commit, push and open Pull Requests, and when. See [A project can choose otherwise](/Standards/agent-specs#project-workflow).
183
310
 
184
311
  **How to check:** The top of `AGENTS.md` states the project's commit rule.
185
312
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@activatus/code-standards",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "The Activatus code standards: the rules as Markdown, and the config files to copy. Install it so an AI agent can read the standards from node_modules.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,6 +9,7 @@
9
9
  "homepage": "https://activatus-code-standards.vercel.app",
10
10
  "files": [
11
11
  "docs",
12
+ "scripts",
12
13
  "static/templates",
13
14
  "README.md"
14
15
  ],
@@ -27,6 +28,7 @@
27
28
  "@mdx-js/react": "^3.0.0",
28
29
  "clsx": "^2.0.0",
29
30
  "pagefind": "^1.3.0",
31
+ "prettier": "^3.9.10",
30
32
  "prism-react-renderer": "^2.3.0",
31
33
  "raw-loader": "^4.0.2",
32
34
  "react": "^18.3.1",
@@ -54,6 +56,8 @@
54
56
  "build": "docusaurus build",
55
57
  "serve": "docusaurus serve",
56
58
  "clear": "docusaurus clear",
57
- "typecheck": "tsc"
59
+ "typecheck": "tsc",
60
+ "format": "prettier --write .",
61
+ "format:check": "prettier --check ."
58
62
  }
59
63
  }