@activatus/code-standards 3.0.0 → 3.0.1

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 CHANGED
@@ -144,8 +144,7 @@ static/templates/
144
144
  ├── prettier.config.mjs # ✨ Formatting
145
145
  ├── globals.css # 🎨 Tailwind + starter colour palette
146
146
  ├── .editorconfig # ⌨️ Editor whitespace rules
147
- ├── .nvmrc / .envrc # 🟢 Node version switching
148
- └── husky/pre-commit # 🚦 Lint before every commit
147
+ └── .nvmrc / .envrc # 🟢 Node version switching
149
148
  ```
150
149
 
151
150
  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.
@@ -4,7 +4,7 @@ sidebar_position: 3
4
4
 
5
5
  # Migrating an Existing Project
6
6
 
7
- Migrating an established codebase to the shared standards is best done in stages to keep PRs reviewable.
7
+ Migrating an established codebase to the shared standards is best done in stages, so each change stays small enough to check properly.
8
8
 
9
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
10
 
@@ -19,7 +19,7 @@ The standards apply to **code we write**, not to packages we pull in. Do not lin
19
19
 
20
20
  ## Stage 1 — Prettier (formatting only)
21
21
 
22
- Formatting changes are safe to land in one big PR because they don't change behaviour.
22
+ Formatting changes are safe to make all at once because they don't change behaviour.
23
23
 
24
24
  ```bash
25
25
  pnpm add -D prettier prettier-plugin-tailwindcss
@@ -33,7 +33,7 @@ Format everything at once:
33
33
  pnpm prettier --write .
34
34
  ```
35
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.
36
+ Keep the reformat apart from any other change, so the formatting is easy to tell apart from real changes later.
37
37
 
38
38
  Add a `.prettierignore` if you have generated files you don't want touched:
39
39
 
@@ -68,7 +68,7 @@ export default [
68
68
  ];
69
69
  ```
70
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.
71
+ Run `pnpm lint` and triage the output. Fix them one kind at a time (for example, all `any` removals together). Once clean, remove the overrides.
72
72
 
73
73
  ## Stage 4 — Names
74
74
 
@@ -101,9 +101,9 @@ These come up in nearly every project:
101
101
 
102
102
  `docs/`, `docsSite/`, `DOCS_URL` and `pnpm docs:dev` already follow the standard. Leave them.
103
103
 
104
- ### 3. Rename in this order, one pull request each
104
+ ### 3. Rename in this order
105
105
 
106
- 1. **Folders**, with `git mv` so the history follows the files. Fix the imports in the same pull request.
106
+ 1. **Folders**, with `git mv` so the history follows the files. Fix the imports at the same time.
107
107
  2. **Types**, so the `@typescript-eslint/naming-convention` errors clear.
108
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
109
  4. **Everything the linter can't see** — form fields, union values, routes, scripts, environment variables. Search for each one by hand.
@@ -117,7 +117,7 @@ Some names are used outside the code. Renaming them needs more than a code chang
117
117
  - **API routes and request fields** used by another app need both names to work until that app is updated.
118
118
  - **Routes people have bookmarked** need a redirect from the old path.
119
119
 
120
- Write each of these up in the pull request so nobody gets caught out.
120
+ Tell the person about each of these, so nobody gets caught out.
121
121
 
122
122
  ### Renaming from the command line
123
123
 
@@ -132,6 +132,18 @@ node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs <file> <cur
132
132
  node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs components/ui/button/types.ts ButtonProperties ButtonProps
133
133
  ```
134
134
 
135
+ **Many renames at once:** list them in a text file, one per line, and pass it with `--list`. Blank lines and lines starting with `#` are skipped, and the renames run in order:
136
+
137
+ ```text title="renames.txt"
138
+ # Version 3 renames
139
+ components/ui/button/types.ts ButtonProperties ButtonProps
140
+ lib/terminal/tabs.ts surfaceReference surfaceRef
141
+ ```
142
+
143
+ ```bash
144
+ node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs --list renames.txt
145
+ ```
146
+
135
147
  - **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
148
  - **Shorthand stays correct.** `{ properties }` becomes `{ properties: props }`, so objects keep their shape.
137
149
  - **It only renames TypeScript and JavaScript names.** Folders, files, form fields, routes and environment variables still need renaming by hand.
@@ -150,12 +162,8 @@ Copy the eight [standard skill files](/templates#skills) into `.agents/skills/`,
150
162
 
151
163
  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
164
 
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
165
  ## Tips
158
166
 
159
- - **Don't mix formatting and logic changes** in the same PR.
167
+ - **Don't mix formatting and logic changes.** Reformat on its own, then change the code.
160
168
  - **Exclude generated files** from ESLint with `// eslint-disable-file` or `.eslintignore`-equivalent glob ignores in the config.
161
169
  - **Fix new-file compliance first**: agree that all _new_ files must pass the full ruleset even before the migration is complete.
@@ -70,13 +70,21 @@ Tell me the numbers to skip or change, or say "all good".
70
70
  16. Imports: no circular imports, import from folders not files
71
71
  17. API routes: one folder per route, kebab-case
72
72
  18. Docs: every file in docs/ is a Decision Doc, shown at /docs by the docs site
73
- 19. Lint before every commit: a Husky hook runs pnpm lint
74
- 20. AGENTS.md and the eight agent skills
75
- 21. The Ontology: the shared words for code
73
+ 19. Removed in version 3: commit messages are the project's own workflow
74
+ 20. Removed in version 3: branch names are the project's own workflow
75
+ 21. AGENTS.md and the eight agent skills
76
+ 22. Removed in version 3: whether agents commit is the project's own workflow
77
+ 23. The Ontology: the shared words for code
76
78
  ```
77
79
 
78
80
  Then wait for the answer.
79
81
 
82
+ **The numbers never change.** A project records its choices by number, so the numbers stay put:
83
+
84
+ - **A number is never reused.** A removed standard keeps its number in the list, marked "Removed in version N", so a project's old choices still point at the right thing.
85
+ - **A new standard takes the number of the standard it sits closest to, plus a decimal:** a new styling standard after 11 is 11.1, then 11.2, up to 11.9. The list stays short, and nothing after it moves.
86
+ - **Skip the removed ones** when applying the standards. There is nothing to do for them.
87
+
80
88
  | The person says | Do |
81
89
  | --------------------------------------- | ----------------------------- |
82
90
  | "All good" | Apply every standard |
@@ -94,7 +102,7 @@ Do only the standards the person agreed to. Copy every file from `node_modules/@
94
102
 
95
103
  **Every config file is `.mjs`, even in a TypeScript project.** Never convert one to `.ts` or `.mts`. `.mjs` works in both, so every project looks the same. If the project has a config as `.js`, `.ts` or `.mts`, such as `next.config.ts` from `create-next-app` or `vitest.config.mts`, rename it to `.mjs`, removing any TypeScript-only syntax: a type annotation becomes a JSDoc comment, for example `/** @type {import("next").NextConfig} */`. A tool that cannot read `.mjs` keeps its own format.
96
104
 
97
- **An existing project with code already in it** also needs its code brought up to the standards. Do that with [Migrating an Existing Project](/Guides/migrating), one stage per pull request, after the config files below are in place.
105
+ **An existing project with code already in it** also needs its code brought up to the standards. Do that with [Migrating an Existing Project](/Guides/migrating), one stage at a time, after the config files below are in place.
98
106
 
99
107
  | Standard | What to set up |
100
108
  | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -105,8 +113,7 @@ Do only the standards the person agreed to. Copy every file from `node_modules/@
105
113
  | 10. Node version | Copy `static/templates/.nvmrc` and `static/templates/.envrc`. See [direnv + nvm](/Standards/direnv) |
106
114
  | 11. Styling | Copy `static/templates/globals.css` to `app/globals.css`. Ask the person for the project's colours, and replace the example palette |
107
115
  | 18. Docs | Copy `static/templates/docs/` to `docs/` and `static/templates/docsSite/` to `docsSite/`. Add the `/docs` route from `static/templates/next.config.mjs`. See [Setting it up](/Standards/documentation#-setting-it-up) |
108
- | 19. Lint before commit | Copy `static/templates/husky/pre-commit` to `.husky/pre-commit`, once `pnpm lint` passes. See [Lint before every commit](/Standards/lint-errors#lint-before-every-commit) |
109
- | 20. AGENTS.md and skills | Copy `static/templates/AGENTS.md` to the project root and fill in every `[placeholder]`. If the framework wrote its own `AGENTS.md` (Next.js does), keep any instruction it gives about reading the framework's own docs. Copy `static/templates/skills/` into `.agents/skills/`, and again into `.claude/commands/` |
116
+ | 21. AGENTS.md and skills | Copy `static/templates/AGENTS.md` to the project root and fill in every `[placeholder]`. If the framework wrote its own `AGENTS.md` (Next.js does), keep any instruction it gives about reading the framework's own docs. Copy `static/templates/skills/` into `.agents/skills/`, and again into `.claude/commands/` |
110
117
 
111
118
  The other standards are rules for how code is written. There is nothing to install for them: follow them in every change.
112
119
 
@@ -133,7 +140,7 @@ The project already follows the standards, and a newer version is out.
133
140
 
134
141
  3. **Read `node_modules/@activatus/code-standards/docs/version-history.md`**, but only the versions newer than the project's. Do not re-read the rest of the standards.
135
142
  4. **Skip any change to a standard the project opted out of.** The opt-outs are listed in `docs/development/coding-standards.md`.
136
- 5. **Do every other change** as its "What to do" says, and run its "How to check" search. One pull request per kind of change.
143
+ 5. **Do every other change** as its "What to do" says, and run its "How to check" search.
137
144
  6. **Set `**Code standards version:**`** in `AGENTS.md` to the new version, and tell the person what changed. If a change is being finished later, record it first: see [Finishing a change later](#finishing-a-change-later).
138
145
 
139
146
  See the [Version History](/version-history) for the full update rules.
@@ -142,10 +149,10 @@ See the [Version History](/version-history) for the full update rules.
142
149
 
143
150
  ## Finishing a change later
144
151
 
145
- Sometimes a change is too big for the update, such as switching on the standard ESLint config in a project that never had it. It can be done later in its own Pull Request, but **the version number must stay honest**.
152
+ Sometimes a change is too big for the update, such as switching on the standard ESLint config in a project that never had it. It can be finished later, but **the version number must stay honest**.
146
153
 
147
154
  1. Set the project's version to the new version anyway.
148
- 2. In `docs/development/coding-standards.md`, under **Unfinished changes**, list each change that is not done yet: its version and number, what is left, and where it is being done (a ticket or a Pull Request).
155
+ 2. In `docs/development/coding-standards.md`, under **Unfinished changes**, list each change that is not done yet: its version and number, what is left, and where it is being done, if the project tracks that.
149
156
 
150
157
  ```md
151
158
  ## Unfinished changes
@@ -131,7 +131,7 @@ Some short names are not abbreviations. They are the word people actually say, a
131
131
  | `docs` | A project's documentation | `docs/`, `docsSite/`, `DOCS_URL`, `pnpm docs:dev` |
132
132
  | `lib` | The folder for outside connections and app-wide setup. Next.js and shadcn/ui use the same name | `lib/`, `lib/integrations/` |
133
133
  | `props` | The values a component takes | `props`, `ButtonProps` |
134
- | `ref` | A React ref: a handle on an element or a value kept between renders | `inputRef`, `useRef`, `scrollContainerRef` |
134
+ | `ref` | A reference or handle to something: a React ref, or any other handle, such as a terminal tab's ref | `inputRef`, `useRef`, `surfaceRef` |
135
135
  | `repo` | A repository: in GitHub's words, it "contains all of your project's files and each file's revision history" | `repoName`, `repoUrl` |
136
136
  | `utils` | Reusable functions that are not components | `utils/`, `utils/formatCurrency/` |
137
137
  | `app` | The application | `app/`, `appName` |
@@ -150,7 +150,7 @@ Some short names are not abbreviations. They are the word people actually say, a
150
150
  When a short name feels like a dictionary word, don't just use it — add it here first:
151
151
 
152
152
  1. **Ask:** is this the word people actually say, so the long form would only be harder to read? `docs`, `repo`: yes. `env`, `btn`, `msg`: no.
153
- 2. **Add a row** to the table above, in the same pull request as the code that uses it.
153
+ 2. **Add a row** to the table above, before or alongside the code that uses it.
154
154
  3. **If ESLint flags the word**, add it to `replacements` in the `unicorn/name-replacements` rule of the [ESLint config](/Standards/eslint), so the linter agrees: `replacements: { docs: false, lib: false, props: false, ref: false, repo: false, utils: false }`.
155
155
 
156
156
  The list is the record. If a word is not on it, it is not a dictionary word yet.
@@ -128,44 +128,8 @@ Nothing else is switched off. If another rule seems impossible to satisfy, the c
128
128
 
129
129
  ---
130
130
 
131
- ## How errors are caught
131
+ ## When lint must pass
132
132
 
133
- Lint runs in three places, so a broken standard is caught before it reaches `main`:
133
+ **Work is not finished until `pnpm lint` passes.** That goes for people and AI agents alike: an agent fixes every lint error before it says a task is done.
134
134
 
135
- | Where | When | What happens on an error |
136
- | --------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------ |
137
- | **AI agents** | Before finishing any task | The agent fixes the error. Its work is not done until `pnpm lint` passes |
138
- | **Git hook** ([`.husky/pre-commit`](#lint-before-every-commit)) | On every commit | The commit is refused until the errors are fixed |
139
- | **CI** | On every change pushed | The change cannot be merged |
140
-
141
- ## Lint before every commit
142
-
143
- A [Husky](https://typicode.github.io/husky/) git hook runs `pnpm lint` before every commit, so code that breaks the standards cannot be committed.
144
-
145
- 1. Install Husky:
146
-
147
- ```bash
148
- pnpm add -D husky
149
- ```
150
-
151
- 2. Add the `prepare` script to `package.json`, so the hook is installed whenever someone runs `pnpm install`:
152
-
153
- ```json
154
- {
155
- "scripts": {
156
- "prepare": "husky"
157
- }
158
- }
159
- ```
160
-
161
- 3. Copy the hook file [`.husky/pre-commit`](/templates#husky-pre-commit):
162
-
163
- ```text title=".husky/pre-commit"
164
- pnpm lint
165
- ```
166
-
167
- 4. Run `pnpm install` once to switch it on.
168
-
169
- **Add the hook last**, once the project already passes `pnpm lint`. Otherwise every commit is refused until the whole codebase is fixed.
170
-
171
- How the project names commits and branches, and who may commit, is up to the project. See [Project workflow](/Standards/agent-specs#project-workflow).
135
+ How a project makes sure of it, such as a git hook or a check that runs on every change, is the project's own choice. See [Project workflow](/Standards/agent-specs#project-workflow).
@@ -136,7 +136,6 @@ See `package.json` for specific version requirements. Key dependencies:
136
136
 
137
137
  - **Linting**: ESLint 9+
138
138
  - **Formatting**: Prettier
139
- - **Git Hooks**: Husky
140
139
  - **Monorepo**: Turborepo
141
140
  - **Documentation**: Docusaurus
142
141
 
@@ -189,7 +189,7 @@ Three folders hold functions that are not components. Each function belongs in e
189
189
  - **Pages, API routes and server actions stay thin.** They take the request, call a function in `services/`, and return the result. Business logic never lives in them.
190
190
  - **`services/` uses `lib/` to reach the outside world.** A service that charges a card calls the Stripe client in `lib/integrations/stripe/`, never the Stripe package directly.
191
191
  - **`utils/` uses nothing outside itself.** If a function needs a database, an API or the environment, it is not a util: it belongs in `services/` or `lib/`.
192
- - **Group `services/` by the [Ontology](/ontology) word it works on**, one folder per function: `services/invoice/createInvoice/`.
192
+ - **Group `services/` by the project's own ontology word it works on**, one folder per function: `services/invoice/createInvoice/`. The project's ontology is usually in `docs/product/ontology.md`, but it can be in another file. If you can't find it, ask.
193
193
 
194
194
  ## 🧰 Utils
195
195
 
@@ -33,7 +33,6 @@ import docsSiteGitignore from "!!raw-loader!@site/static/templates/docsSite/giti
33
33
  import decisionDoc from "!!raw-loader!@site/static/templates/decision-doc.md";
34
34
  import docsSiteHome from "!!raw-loader!@site/static/templates/docsSite/src/pages/index.tsx";
35
35
  import nextConfig from "!!raw-loader!@site/static/templates/next.config.mjs";
36
- import huskyPreCommit from "!!raw-loader!@site/static/templates/husky/pre-commit";
37
36
 
38
37
  # Templates
39
38
 
@@ -58,7 +57,6 @@ Each file is also served as a plain file, so a person or an AI agent can fetch i
58
57
  | [Node version](#nvmrc) | `.nvmrc` in the project root | [`/templates/.nvmrc`](pathname:///templates/.nvmrc) |
59
58
  | [direnv](#envrc) | `.envrc` in the project root | [`/templates/.envrc`](pathname:///templates/.envrc) |
60
59
  | [Agent skills](#skills) | `.agents/skills/` and `.claude/commands/` | Eight files — see [below](#skills) |
61
- | [Lint before commit](#husky-pre-commit) | `.husky/pre-commit` | [`/templates/husky/pre-commit`](pathname:///templates/husky/pre-commit) |
62
60
  | [Docs site](#docs-site) | `docsSite/` in the project root | Several files — see [below](#docs-site) |
63
61
  | [`/docs` route](#docs-route) | `next.config.mjs` | [`/templates/next.config.mjs`](pathname:///templates/next.config.mjs) |
64
62
  | [Document templates](#document-templates) | `docs/` in the project root | Several files — see [below](#document-templates) |
@@ -292,18 +290,6 @@ Runs the test suite; reports failures grouped by cause, tests that never ran, an
292
290
 
293
291
  ---
294
292
 
295
- ## Lint before commit {#husky-pre-commit}
296
-
297
- **Copy to:** `.husky/pre-commit` in the project root
298
-
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)
300
-
301
- <CodeBlock language="text" title=".husky/pre-commit">
302
- {huskyPreCommit}
303
- </CodeBlock>
304
-
305
- ---
306
-
307
293
  ## Docs site {#docs-site}
308
294
 
309
295
  **Copy to:** a `docsSite/` folder in the project root
@@ -21,30 +21,37 @@ sidebar_label: "Version History"
21
21
  2. **Update the package:** `pnpm update @activatus/code-standards --latest`. Then read this page from `node_modules/@activatus/code-standards/docs/version-history.md`.
22
22
  3. **Read each version newer than the project's**, oldest first. Skip any change to a standard the project opted out of: they are listed in `docs/development/coding-standards.md`.
23
23
  4. **For each change, do the "What to do" steps**, then run the "How to check" searches. A search that still finds something means the change is not finished.
24
- 5. **One pull request per kind of change** (for example, all the folder renames together), so each one stays easy to review. Follow the project's commit rule in `AGENTS.md`.
25
- 6. **Run `pnpm lint`, `pnpm test` and the build** after each change.
26
- 7. **Update the version number** in `AGENTS.md` once every change is done.
24
+ 5. **Run `pnpm lint`, `pnpm test` and the build** after each change.
25
+ 6. **Update the version number** in `AGENTS.md` once every change is done.
27
26
 
28
27
  **When a change does not fit the project**, for example it renames a folder the project does not have, skip it. If you are not sure, ask; do not guess.
29
28
 
30
29
  ## Adding a version
31
30
 
32
- Anyone changing the standards adds a version, in the same pull request as the change:
31
+ Anyone changing the standards adds a version, alongside the change:
33
32
 
34
33
  - **One version per release**, numbered one higher than the last. Whole numbers only. A version can collect several changes before it is released.
35
34
  - **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
35
  - **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
36
  - **If a project has nothing to do, say so.**
38
37
  - **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.
38
+ - **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 time. To release it: drop "not released yet", add the **Released** date and **Updates from** line, set `package.json` to `N.0.0`, then publish.
39
+ - **Fixing a released version** bumps only the last number: `3.0.0` → `3.0.1`. Update the version's changes in place, and list what was fixed under its **Fixes**. Projects keep the same version number in `AGENTS.md`.
40
40
 
41
41
  ---
42
42
 
43
43
  ## Version 3
44
44
 
45
- **Released:** 2026-10-17 · **Updates from:** version 2
45
+ **Released:** 2026-10-17 · **Updates from:** version 2 · **Latest fix:** 3.0.1
46
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.
47
+ Install it with `pnpm add -D @activatus/code-standards@3.0.1`. Do change 1 first: it says which parts of the project's `AGENTS.md` are now the project's own to write.
48
+
49
+ **Fixes in 3.0.1.** If the project already applied 3.0.0, check these:
50
+
51
+ - Setup list numbers are permanent again: 19, 20 and 22 are marked removed, and AGENTS.md and the Ontology are back to 21 and 23. Choices recorded under the version 2 numbers are still right.
52
+ - The Husky lint hook is no longer a standard. Lint must pass before work is finished; how that is enforced is the project's choice.
53
+ - Every name ending in `Reference` uses `Ref`, not only React refs.
54
+ - The rename script takes a list of renames with `--list`.
48
55
 
49
56
  ### 1. Project workflow is no longer part of the standards
50
57
 
@@ -53,10 +60,10 @@ Install it with `pnpm add -D @activatus/code-standards@3.0.0`. Do change 1 first
53
60
  **What to do:**
54
61
 
55
62
  - 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.
63
+ - **Standards 19, 20 and 22 keep their numbers, marked as removed.** No other number changes. If `docs/development/coding-standards.md` records a choice for 19, 20 or 22, move that rule into Project workflow and take it off the list.
64
+ - 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, usually whether they may commit, at the very top: one line, or a short section if it needs more.
57
65
  - 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).
66
+ - Commitlint and the Husky hooks (`.husky/commit-msg` and `.husky/pre-commit`) are no longer templates. Keep them if the project wants them: they are now the project's choice. The standard is only that `pnpm lint` passes before work is finished. See [When lint must pass](/Standards/lint-errors#when-lint-must-pass).
60
67
 
61
68
  **How to check:** `AGENTS.md` has a Project workflow section, and every rule in it is written up in the project's docs.
62
69
 
@@ -67,7 +74,7 @@ Install it with `pnpm add -D @activatus/code-standards@3.0.0`. Do change 1 first
67
74
  **What to do:**
68
75
 
69
76
  - 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).
77
+ - Rename every name ending in `Reference` to end in `Ref`, whatever it refers to: `inputReference` → `inputRef`, `surfaceReference` → `surfaceRef`. 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
78
  - 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
79
  - 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
80
 
@@ -108,7 +115,7 @@ Install it with `pnpm add -D @activatus/code-standards@3.0.0`. Do change 1 first
108
115
  **What to do:**
109
116
 
110
117
  - 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.
118
+ - Run `pnpm format` once, on its own, with no other changes mixed in. It touches nearly every file, so keep it apart from real changes.
112
119
  - 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
120
 
114
121
  **How to check:** `pnpm format:check` passes.
@@ -145,7 +152,7 @@ See [When a name clashes](/Standards/human-readable-names#when-a-name-clashes).
145
152
 
146
153
  ### 10. Unfinished changes are recorded, not hidden
147
154
 
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.
155
+ **Why:** A big change, such as switching on the standard ESLint config, may be finished later. The version number has to stay honest about that.
149
156
 
150
157
  **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
158
 
@@ -154,11 +161,10 @@ See [When a name clashes](/Standards/human-readable-names#when-a-name-clashes).
154
161
  ### No action needed
155
162
 
156
163
  - 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).
164
+ - 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>`. Pass `--list renames.txt` to do many renames in one run, one per line. It can't reach keys in untyped object literals, such as the expected value in a test's `toEqual({ … })`: search the tests for old names and fix those by hand. See [Renaming from the command line](/Guides/migrating#renaming-from-the-command-line).
158
165
  - 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
166
  - [Folder Structure](/Structure/folder-structure) explains each `lib/` folder in one line.
160
167
  - 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).
162
168
 
163
169
  ---
164
170
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@activatus/code-standards",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
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",
@@ -6,14 +6,23 @@
6
6
  // node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs <file> <currentName> <newName>
7
7
  // For example:
8
8
  // node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs components/ui/button/types.ts ButtonProperties ButtonProps
9
+ //
10
+ // To do many renames in one run, list them in a text file, one per line: <file> <currentName> <newName>.
11
+ // Blank lines and lines starting with # are skipped. The renames run in order.
12
+ // node node_modules/@activatus/code-standards/scripts/renameSymbol.mjs --list renames.txt
9
13
  import { readFileSync, writeFileSync } from "node:fs";
10
14
  import { createRequire } from "node:module";
11
15
  import path from "node:path";
12
16
 
13
17
  // process.argv starts with the node binary and this script's path.
14
18
  const FIRST_ARGUMENT_INDEX = 2;
15
- const USAGE =
16
- "Usage: node renameSymbol.mjs <file> <currentName> <newName>";
19
+ const LIST_FLAG = "--list";
20
+ // A rename line has three parts: file, current name, new name.
21
+ const RENAME_PARTS = 3;
22
+ const USAGE = [
23
+ "Usage: node renameSymbol.mjs <file> <currentName> <newName>",
24
+ " or: node renameSymbol.mjs --list <file of renames>",
25
+ ].join("\n");
17
26
 
18
27
  // Uses the project's own TypeScript, so the rename matches the project's compiler exactly.
19
28
  const requireFromProject = createRequire(
@@ -176,12 +185,45 @@ const renameSymbol = ({ filePath, currentName, newName }) => {
176
185
  return `Renamed ${currentName} to ${newName}: ${renameLocations.length} places in ${fileCount} ${fileWord}.`;
177
186
  };
178
187
 
179
- const [filePath, currentName, newName] = process.argv.slice(
180
- FIRST_ARGUMENT_INDEX,
181
- );
188
+ // Each line of a list file is one rename: <file> <currentName> <newName>.
189
+ const readRenameList = (listPath) =>
190
+ readFileSync(listPath, "utf8")
191
+ .split("\n")
192
+ .map((line) => line.trim())
193
+ .filter((line) => line !== "" && !line.startsWith("#"))
194
+ .map((line) => {
195
+ const [filePath, currentName, newName] = line.split(
196
+ /\s+/u,
197
+ RENAME_PARTS,
198
+ );
199
+
200
+ return { filePath, currentName, newName };
201
+ });
182
202
 
183
- if (filePath && currentName && newName) {
184
- console.log(renameSymbol({ filePath, currentName, newName }));
203
+ const isCompleteRename = ({ filePath, currentName, newName }) =>
204
+ Boolean(filePath && currentName && newName);
205
+
206
+ const commandArguments = process.argv.slice(FIRST_ARGUMENT_INDEX);
207
+ const [firstArgument, secondArgument] = commandArguments;
208
+ const renames =
209
+ firstArgument === LIST_FLAG && secondArgument
210
+ ? readRenameList(secondArgument)
211
+ : [
212
+ {
213
+ filePath: commandArguments[0],
214
+ currentName: commandArguments[1],
215
+ newName: commandArguments[2],
216
+ },
217
+ ];
218
+
219
+ if (
220
+ renames.length > 0 &&
221
+ renames.every((rename) => isCompleteRename(rename))
222
+ ) {
223
+ // Each rename reloads the project, so it sees the renames before it.
224
+ for (const rename of renames) {
225
+ console.log(renameSymbol(rename));
226
+ }
185
227
  } else {
186
228
  console.error(USAGE);
187
229
  process.exitCode = 1;
@@ -1,6 +1,6 @@
1
1
  # [Project Name]
2
2
 
3
- > [The project's most important workflow rule for agents, stated first so every agent sees it: whether an agent may commit, push or make branches. See "Project workflow" below.]
3
+ > [The project's most important rule for agents, stated first so every agent sees it. Usually whether an agent may commit, push or make branches. One line, or a short section if it needs more, such as which agents may commit, when, and how the others ask. See "Project workflow" below.]
4
4
 
5
5
  > **"go" means carry on.** When the person sends only "go", carry on with the current task. It is never permission to commit, push or open a Pull Request, and it needs no reply asking what they meant.
6
6
 
@@ -1 +0,0 @@
1
- pnpm lint