@regardio/dev 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin/ship/hotfix.bin.mjs +4 -4
- package/dist/bin/ship/production.bin.mjs +3 -3
- package/dist/bin/ship/staging.bin.mjs +1 -1
- package/dist/bin/ship/{utils-BPxpSgv6.mjs → utils-sL-BT4MX.mjs} +3 -2
- package/docs/en/README.md +11 -3
- package/docs/en/documentation.md +170 -0
- package/docs/en/principles.md +83 -0
- package/docs/en/tools/releases.md +26 -29
- package/docs/en/writing.md +118 -0
- package/package.json +2 -2
- package/templates/actions/forgejo-release.yml +116 -0
- package/templates/actions/github-release.yml +93 -0
- package/templates/agents/CLAUDE.md +37 -0
- package/templates/versionrc/.versionrc.json +42 -11
- package/templates/github/release.yml +0 -68
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Extend the shared configs:
|
|
|
47
47
|
|
|
48
48
|
## Documentation
|
|
49
49
|
|
|
50
|
-
Documentation sits alongside the code
|
|
50
|
+
Documentation sits alongside the code in `docs/en/`, organised by topic. It covers cross-project principles and writing standards as well as code-level standards and toolchain configuration.
|
|
51
51
|
|
|
52
52
|
### Code standards
|
|
53
53
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as git, c as runQualityChecks, i as getWorkspacePackages, n as chooseForEach, o as gitRead, s as runPackageRelease, t as branchExists } from "./utils-
|
|
2
|
+
import { a as git, c as runQualityChecks, i as getWorkspacePackages, n as chooseForEach, o as gitRead, s as runPackageRelease, t as branchExists } from "./utils-sL-BT4MX.mjs";
|
|
3
3
|
//#region src/bin/ship/hotfix.ts
|
|
4
4
|
/**
|
|
5
5
|
* ship-hotfix: Manage hotfix branches based on production code.
|
|
@@ -77,7 +77,7 @@ function runShipHotfix(subcommand, subArgs, cwd = process.cwd()) {
|
|
|
77
77
|
} catch {
|
|
78
78
|
console.log(`No versioning configured for ${pkg.name} — skipping.`);
|
|
79
79
|
}
|
|
80
|
-
} else console.log("No
|
|
80
|
+
} else console.log("No packages configured for versioning — skipping.");
|
|
81
81
|
console.log("\nMerging hotfix into production...");
|
|
82
82
|
git("checkout", "production");
|
|
83
83
|
git("pull", "--ff-only", "origin", "production");
|
|
@@ -99,8 +99,8 @@ function runShipHotfix(subcommand, subArgs, cwd = process.cwd()) {
|
|
|
99
99
|
} catch {}
|
|
100
100
|
if (bumps.length > 0) {
|
|
101
101
|
const shipped = bumps.map((b) => b.package.name).join(", ");
|
|
102
|
-
console.log(`\n✅ Hotfix ${shipped} shipped to production → staging → main
|
|
103
|
-
console.log("CI will
|
|
102
|
+
console.log(`\n✅ Hotfix ${shipped} shipped to production → staging → main.`);
|
|
103
|
+
console.log("CI will handle the rest.");
|
|
104
104
|
} else console.log("\n✅ Hotfix shipped to production → staging → main.");
|
|
105
105
|
console.log("You are on main and ready to keep working.");
|
|
106
106
|
process.exit(0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as git, c as runQualityChecks, i as getWorkspacePackages, n as chooseForEach, o as gitRead, r as confirm, s as runPackageRelease, t as branchExists } from "./utils-
|
|
2
|
+
import { a as git, c as runQualityChecks, i as getWorkspacePackages, n as chooseForEach, o as gitRead, r as confirm, s as runPackageRelease, t as branchExists } from "./utils-sL-BT4MX.mjs";
|
|
3
3
|
//#region src/bin/ship/production.ts
|
|
4
4
|
/**
|
|
5
5
|
* ship-production: Promote main to production following the GitLab workflow.
|
|
@@ -69,7 +69,7 @@ function runShipProduction(cwd = process.cwd()) {
|
|
|
69
69
|
} catch {
|
|
70
70
|
console.log(`No versioning configured for ${pkg.name} — skipping.`);
|
|
71
71
|
}
|
|
72
|
-
} else if (!confirm("\nNo
|
|
72
|
+
} else if (!confirm("\nNo packages configured for versioning — ship commits to production?\n")) process.exit(0);
|
|
73
73
|
console.log("\nMerging main into production...");
|
|
74
74
|
git("checkout", "production");
|
|
75
75
|
git("pull", "--ff-only", "origin", "production");
|
|
@@ -84,7 +84,7 @@ function runShipProduction(cwd = process.cwd()) {
|
|
|
84
84
|
git("push", "--follow-tags", "origin", "main");
|
|
85
85
|
if (bumps.length > 0) {
|
|
86
86
|
const shipped = bumps.map((b) => b.package.name).join(", ");
|
|
87
|
-
console.log(`\n✅ Shipped ${shipped} to production. CI will
|
|
87
|
+
console.log(`\n✅ Shipped ${shipped} to production. CI will handle the rest.`);
|
|
88
88
|
} else console.log("\n✅ Commits shipped to production.");
|
|
89
89
|
console.log("You are on main and ready to keep working.");
|
|
90
90
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as git, c as runQualityChecks, o as gitRead, t as branchExists } from "./utils-
|
|
2
|
+
import { a as git, c as runQualityChecks, o as gitRead, t as branchExists } from "./utils-sL-BT4MX.mjs";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
//#region src/bin/ship/staging.ts
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFileSync, execSync } from "node:child_process";
|
|
3
|
-
import { closeSync, openSync, readSync } from "node:fs";
|
|
3
|
+
import { closeSync, existsSync, openSync, readSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
4
5
|
//#region src/bin/ship/utils.ts
|
|
5
6
|
/**
|
|
6
7
|
* Shared utilities for ship-staging, ship-production, and ship-hotfix.
|
|
@@ -42,7 +43,7 @@ const getWorkspacePackages = (cwd = process.cwd()) => {
|
|
|
42
43
|
cwd,
|
|
43
44
|
encoding: "utf-8"
|
|
44
45
|
});
|
|
45
|
-
return JSON.parse(raw).filter((p) => p.
|
|
46
|
+
return JSON.parse(raw).filter((p) => p.name !== void 0 && existsSync(join(p.path, ".versionrc.json"))).map(({ name, path }) => ({
|
|
46
47
|
name,
|
|
47
48
|
path
|
|
48
49
|
}));
|
package/docs/en/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
3
|
title: "@regardio/dev Documentation"
|
|
4
|
-
description: "Index for the @regardio/dev toolchain — code-level standards and the tools that enforce them."
|
|
4
|
+
description: "Index for the @regardio/dev toolchain — principles, code-level standards, and the tools that enforce them."
|
|
5
5
|
publishedAt: 2026-04-17
|
|
6
6
|
language: "en"
|
|
7
7
|
status: "published"
|
|
@@ -9,9 +9,17 @@ status: "published"
|
|
|
9
9
|
|
|
10
10
|
# Documentation
|
|
11
11
|
|
|
12
|
-
Index for the `@regardio/dev` toolchain.
|
|
12
|
+
Index for the `@regardio/dev` toolchain. All Regardio standards ship with this package and are available at `node_modules/@regardio/dev/docs/en/` after install.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Principles & writing
|
|
15
|
+
|
|
16
|
+
Cross-project standards that carry across every Regardio codebase, regardless of language or framework:
|
|
17
|
+
|
|
18
|
+
| Document | Description |
|
|
19
|
+
|----------|-------------|
|
|
20
|
+
| [Principles](./principles.md) | Code quality, architecture, security, maintainability, collaboration, implementation workflow |
|
|
21
|
+
| [Writing](./writing.md) | Voice, tone, and language — English and German |
|
|
22
|
+
| [Documentation](./documentation.md) | Shape of documents, frontmatter, cross-references, tense and stance |
|
|
15
23
|
|
|
16
24
|
## Code standards
|
|
17
25
|
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: "Documentation"
|
|
4
|
+
description: "How Regardio shapes its documents — a thin shared surface with room for each document to take the form its content asks for."
|
|
5
|
+
publishedAt: 2026-04-17
|
|
6
|
+
order: 1
|
|
7
|
+
language: "en"
|
|
8
|
+
status: "published"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
A Regardio document is read for answers about the system, for judgement about what the project does and why, and as the specification its tests are measured against. These readings do not all need the same shape on every page. An architectural decision reads best as a short chain of reasoning — context, alternatives, what was chosen and why. A naming reference reads best as a catalogue. A quick introduction to a tool reads best as a few paragraphs and a short example. Forcing every document into one template serves the template rather than the content, and what the reader comes away with is ceremony instead of understanding.
|
|
14
|
+
|
|
15
|
+
What the documentation needs is enough predictability for tooling to rely on — a consistent frontmatter, a recognisable title, a place to find related reading — and enough freedom for each document to take the shape its content asks for.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Every Regardio document carries a small shared surface. Underneath, it takes whichever of a few shapes fits the content it carries.
|
|
20
|
+
|
|
21
|
+
### Shared surface
|
|
22
|
+
|
|
23
|
+
Every document has the same top:
|
|
24
|
+
|
|
25
|
+
- **Frontmatter** that identifies the document and lets tooling index it
|
|
26
|
+
- **A title** as a heading or implicit from frontmatter
|
|
27
|
+
- **An opening that names what the document is for** — one or two sentences, before any sub-headings, so that a reader landing cold knows where they are
|
|
28
|
+
|
|
29
|
+
Every document has the same bottom:
|
|
30
|
+
|
|
31
|
+
- **Cross-references** to documents the reader is likely to want next, either inline in the prose or collected under `## Related` at the end
|
|
32
|
+
|
|
33
|
+
Between the top and the bottom, the document takes the shape its content asks for.
|
|
34
|
+
|
|
35
|
+
### Shapes the body takes
|
|
36
|
+
|
|
37
|
+
A few shapes recur. Pick the one the content fits; do not pad the content into a shape it resists.
|
|
38
|
+
|
|
39
|
+
**Decision record.** When the document captures a choice with real trade-offs, the ADR shape carries the reasoning well: *Status → Context → Decision → Alternatives Considered → Operational Rules → Consequences*. Operational Rules are the part tests bind to. The shape is an option for decision-heavy documents, not a requirement for every document.
|
|
40
|
+
|
|
41
|
+
**Reference catalogue.** When the content is a set of rules, names, or mappings that readers look up rather than read end-to-end, a catalogue of short sections with examples is the honest form. Naming conventions, file-layout rules, linter settings, and configuration tables read this way.
|
|
42
|
+
|
|
43
|
+
**Concept or entity note.** When the document describes a thing in the domain — a Channel, a Piece, a Plan — a short run of paragraphs that names the thing, its role, and its relations is usually enough. Two or three headings if the thing has parts worth naming separately.
|
|
44
|
+
|
|
45
|
+
**Quick introduction.** When the document introduces a tool or a workflow, a few paragraphs and a small example are enough. The reader needs to know what the thing is, when to reach for it, and where to go next. No ADR skeleton is required for a tool page.
|
|
46
|
+
|
|
47
|
+
**Warm reasoning.** When the document is working something out — a use case, a walkthrough, an explanation of why a piece of the domain behaves the way it does — prose that follows the thought is the right form. Headings appear where they help the reader keep their place, not because structure is owed.
|
|
48
|
+
|
|
49
|
+
A document can borrow from more than one shape. An architectural document might open with warm reasoning and close with Operational Rules. An entity note might include a short alternatives paragraph when the entity's shape had genuine contenders. The shapes are orientation, not slots.
|
|
50
|
+
|
|
51
|
+
### Frontmatter
|
|
52
|
+
|
|
53
|
+
Frontmatter is the part tooling reads. Keep it stable.
|
|
54
|
+
|
|
55
|
+
| Field | Required | Notes |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `title` | yes | Noun phrase naming the document. Decision records may prefix `"ADR: "`. |
|
|
58
|
+
| `description` | yes | One sentence. What this document is for, without hedging. |
|
|
59
|
+
| `publishedAt` | yes | ISO date (`YYYY-MM-DD`) the document was first accepted. |
|
|
60
|
+
| `status` | yes | `"draft"`, `"published"`, `"superseded"`. |
|
|
61
|
+
| `language` | yes | `"en"`, `"de"`. |
|
|
62
|
+
| `order` | no | Integer, when a sibling set has a meaningful reading order. |
|
|
63
|
+
| `kind` | no | `"adr"`, `"entity"`, `"concept"`, `"architecture"`, `"guide"`, `"use-case"`, `"reference"`. Lets renderers pick the right treatment. |
|
|
64
|
+
| `area` | no | Names the implementation the document belongs to. |
|
|
65
|
+
| `supersedes` | no | Filename (without extension) of the document this one replaces. |
|
|
66
|
+
| `supersededBy` | no | Filename of the document that replaced this one. |
|
|
67
|
+
|
|
68
|
+
### Tense and stance
|
|
69
|
+
|
|
70
|
+
Documents describe what the system does, in the present tense, observed rather than advertised. "The publication function returns pieces ordered by `sort_order`." Not "The publication function will return…" and not "We should implement…". The tense holds whether the behaviour is currently built or still being specified; the `status` frontmatter carries the difference.
|
|
71
|
+
|
|
72
|
+
The stance is observational. A Regardio document is not a pitch. It notices how the system fits together and what follows from that. Reliability, safety, transparency, usefulness, and care for the people the software serves show up through how the reasoning is laid out, not by being claimed. A reader who finishes a document should be able to make their own judgement about whether the system is sound — that is what the prose is for.
|
|
73
|
+
|
|
74
|
+
### What shows up where
|
|
75
|
+
|
|
76
|
+
- **Code snippets** appear where they clarify a contract, a data shape, or a naming pattern. Reference catalogues quite properly carry several; decision records rarely need any. A snippet never stands in for the reasoning around it.
|
|
77
|
+
- **Names** (files, functions, columns, handles) appear where they are contracts readers rely on. They do not appear as a substitute for describing what something does.
|
|
78
|
+
- **Procedural steps** belong in runbooks and READMEs. A domain spec does not read like a cookbook.
|
|
79
|
+
|
|
80
|
+
### Cross-references
|
|
81
|
+
|
|
82
|
+
Links carry a short descriptor of what the link leads to, not just a filename:
|
|
83
|
+
|
|
84
|
+
```markdown
|
|
85
|
+
The [Channel](../entities/channel.md) is the publication destination;
|
|
86
|
+
the [Publishing Architecture](../architecture/publishing-architecture.md)
|
|
87
|
+
describes how callers reach it.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`## Related` at the end of a document lists the next pages a reader is likely to want.
|
|
91
|
+
|
|
92
|
+
### Voice
|
|
93
|
+
|
|
94
|
+
The [Writing](./writing.md) standard covers voice, tone, and language. This document relies on it rather than repeating it.
|
|
95
|
+
|
|
96
|
+
## Alternatives Considered
|
|
97
|
+
|
|
98
|
+
### A single ADR skeleton for every document
|
|
99
|
+
|
|
100
|
+
**Dismissed because** it presses reference catalogues and tool introductions into a shape that does not suit them. The skeleton adds ceremony where the content is already clear, and readers learn to skim past sections that carry no weight. The skeleton remains available for documents whose content earns it.
|
|
101
|
+
|
|
102
|
+
### No shared shape at all
|
|
103
|
+
|
|
104
|
+
**Dismissed because** indexing and cross-referencing need something predictable to bind to, and readers benefit from landing on any document and knowing roughly where to look. A thin shared surface — frontmatter, opening line, closing references — is enough.
|
|
105
|
+
|
|
106
|
+
### Separate templates per document kind
|
|
107
|
+
|
|
108
|
+
**Dismissed because** the kinds blur at the edges. An entity note sometimes carries a decision; a use case sometimes carries a catalogue. A small set of recognisable shapes that documents can borrow from works better than a closed list of templates.
|
|
109
|
+
|
|
110
|
+
## Operational Rules
|
|
111
|
+
|
|
112
|
+
### Frontmatter is complete
|
|
113
|
+
|
|
114
|
+
Every document carries `title`, `description`, `publishedAt`, `status`, and `language`. Tooling that indexes or lists documents relies on these five.
|
|
115
|
+
|
|
116
|
+
### Opening names the subject
|
|
117
|
+
|
|
118
|
+
Before the first sub-heading, a reader can tell what the document is for. If the opening does not make this clear, the document is not ready.
|
|
119
|
+
|
|
120
|
+
### Shape follows content
|
|
121
|
+
|
|
122
|
+
The body takes the shape the content asks for. A decision record uses the ADR skeleton if that skeleton helps the reasoning; a reference uses a catalogue; an introduction stays short. Where a document borrows from more than one shape, it does so in service of the reader, not in service of the template.
|
|
123
|
+
|
|
124
|
+
### Tense is present, stance is observational
|
|
125
|
+
|
|
126
|
+
Documents describe the system as it is, in the present tense. Not-yet-built behaviour is flagged through `status`, not through hedged tense. The prose observes rather than promotes.
|
|
127
|
+
|
|
128
|
+
### Reasoning is preserved, not rewritten
|
|
129
|
+
|
|
130
|
+
When a decision is revisited, the existing document is superseded. The old reasoning stays readable so that future readers can see what was known at the time. An in-place rewrite that changes direction without supersession loses the history.
|
|
131
|
+
|
|
132
|
+
### Code and names earn their place
|
|
133
|
+
|
|
134
|
+
A snippet appears because it clarifies a contract the prose cannot carry alone. A specific name appears because callers rely on it. Both are tools for the reader, not decoration.
|
|
135
|
+
|
|
136
|
+
### Tests can point at a document
|
|
137
|
+
|
|
138
|
+
A behaviour worth testing has a place in a document that names it. The document does not need a section labelled "Operational Rules" for this — it needs prose clear enough that a test can quote it and both the test author and the reviewer know what is being verified.
|
|
139
|
+
|
|
140
|
+
### One subject per document
|
|
141
|
+
|
|
142
|
+
A document names one entity, one concept, one decision, one scenario. When a draft sprawls across several, the move is to split it.
|
|
143
|
+
|
|
144
|
+
## Consequences
|
|
145
|
+
|
|
146
|
+
### Positive
|
|
147
|
+
|
|
148
|
+
- Documents read naturally for their content. ADRs feel like ADRs; reference catalogues feel like reference catalogues; introductions stay short.
|
|
149
|
+
- Readers find a predictable frontmatter and opening, and the body of each document carries its reasoning in the form that fits.
|
|
150
|
+
- The docs stay honest. Observational prose about what the system does leaves room for the reader to form a judgement, rather than prescribing one.
|
|
151
|
+
- Tests bind to the prose that describes behaviour, wherever in the document that prose lives.
|
|
152
|
+
|
|
153
|
+
### Negative
|
|
154
|
+
|
|
155
|
+
- "Shape follows content" asks for judgement. Contributors unsure of the right shape need a reference document to look at; the existing documents serve that role.
|
|
156
|
+
- Without a single template, reviewers sometimes have to say "this would read better as a catalogue" or "this would read better as an ADR". That conversation is part of the standard, not a cost around it.
|
|
157
|
+
|
|
158
|
+
### Mitigations
|
|
159
|
+
|
|
160
|
+
- New documents are often patterned on a nearby existing one. A contributor writing a new entity note copies the shape of an adjacent entity note; a contributor writing an ADR copies an adjacent ADR.
|
|
161
|
+
- Reviewers point at this document when a draft has picked a shape that resists its content, and help the author find the form the content already has.
|
|
162
|
+
|
|
163
|
+
## Related
|
|
164
|
+
|
|
165
|
+
- [Writing](./writing.md) — Voice, tone, language
|
|
166
|
+
- [Principles](./principles.md) — Shared principles
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
**License**: [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) © Regardio
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: "Principles"
|
|
4
|
+
description: "The shared ground Regardio projects stand on — clusters of principles that carry across languages and repos."
|
|
5
|
+
publishedAt: 2026-04-17
|
|
6
|
+
order: 3
|
|
7
|
+
language: "en"
|
|
8
|
+
status: "published"
|
|
9
|
+
kind: "reference"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Regardio spans several codebases and several languages. What keeps them legible to each other is a short list of principles held in common — enough shared ground that a contributor moving between projects finds the same habits in force, and enough room left for each codebase to speak its own idiom.
|
|
13
|
+
|
|
14
|
+
Seven clusters, a handful of items each.
|
|
15
|
+
|
|
16
|
+
## Code quality
|
|
17
|
+
|
|
18
|
+
- Readable code over clever code
|
|
19
|
+
- Consistent naming within each language — `camelCase` in TypeScript, `snake_case` in SQL
|
|
20
|
+
- Small functions with a single responsibility
|
|
21
|
+
- Explicit choices over implicit defaults
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
- Modules decouple from each other; dependencies are deliberate
|
|
26
|
+
- Duplication resolves into an abstraction only when the pattern is clear
|
|
27
|
+
- Interfaces describe what a module does, not how it does it
|
|
28
|
+
- Concerns separate along the seams the domain suggests
|
|
29
|
+
|
|
30
|
+
## Error handling
|
|
31
|
+
|
|
32
|
+
- Input is validated early; failures surface with a clear message
|
|
33
|
+
- Validation covers correctness and security in the same pass
|
|
34
|
+
- Logic stays separated from side effects so it remains testable
|
|
35
|
+
- Dependencies can fail; the code degrades gracefully when they do
|
|
36
|
+
|
|
37
|
+
## Performance
|
|
38
|
+
|
|
39
|
+
- Data structures match the shape of the work
|
|
40
|
+
- Measurement comes before optimisation
|
|
41
|
+
- Memory, connections, and file handles are released on the path that acquired them
|
|
42
|
+
- Scale is considered at design time, not retrofitted
|
|
43
|
+
|
|
44
|
+
## Security
|
|
45
|
+
|
|
46
|
+
- Client data is untrusted by default; server-side validation is the line
|
|
47
|
+
- Privileges stay narrow; access is opened deliberately
|
|
48
|
+
- Defence is layered; a single check never stands alone
|
|
49
|
+
- Openness is an opt-in, not the default posture
|
|
50
|
+
|
|
51
|
+
## Maintainability
|
|
52
|
+
|
|
53
|
+
- Patterns repeat across the codebase so that reading one teaches reading the rest
|
|
54
|
+
- Commits are atomic and speak to one change at a time
|
|
55
|
+
- Refactoring is continuous; debt is paid down rather than accumulated
|
|
56
|
+
|
|
57
|
+
## Collaboration
|
|
58
|
+
|
|
59
|
+
- Every change passes through review
|
|
60
|
+
- Code quality is shared, not owned
|
|
61
|
+
- Decisions that involve a real trade-off leave a trace in the project's `docs/en` tree
|
|
62
|
+
|
|
63
|
+
## Implementation workflow
|
|
64
|
+
|
|
65
|
+
Non-trivial work tends to follow this sequence — not as a ritual, but because skipping a step usually costs more later than it saves now:
|
|
66
|
+
|
|
67
|
+
1. **Understand the business logic first.** The deepest defects come from misunderstood requirements. Read the relevant domain document; know what is needed now rather than what might be needed later.
|
|
68
|
+
2. **Look for existing solutions.** Well-maintained libraries are evaluated before custom code is written. Dependencies are vetted for design quality, test coverage, and recent activity.
|
|
69
|
+
3. **Write the tests as specification.** The behaviour a change produces is described as tests before the change is written. Tests are the contract; the code is measured against them.
|
|
70
|
+
4. **Implement with reusability in mind, not reusability as the goal.** Duplicate until the pattern is clear, then extract. Wrong abstractions cost more than duplication.
|
|
71
|
+
5. **Stop and reconsider when complexity grows.** Difficulty that keeps growing despite good preparation is a signal. Back out, simplify, or question the approach.
|
|
72
|
+
6. **Document intent, not mechanics.** Comments explain *why*; the code explains *what*. Existing context is checked before new prose is added.
|
|
73
|
+
|
|
74
|
+
## Related
|
|
75
|
+
|
|
76
|
+
- [Writing](./writing.md) — Voice, tone, language
|
|
77
|
+
- [Documentation](./documentation.md) — How documents are shaped
|
|
78
|
+
- [Coding](./standards/coding.md) — TypeScript and general patterns
|
|
79
|
+
- [Testing](./standards/testing.md) — Testing philosophy
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
**License**: [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) © Regardio
|
|
@@ -56,7 +56,7 @@ production ──► hotfix/<name> (fix here with conventional commits)
|
|
|
56
56
|
|
|
57
57
|
## Versioning — Per-Package, at Ship Time
|
|
58
58
|
|
|
59
|
-
`ship:production` and `ship:hotfix finish` discover all
|
|
59
|
+
`ship:production` and `ship:hotfix finish` discover all workspace packages that have a `.versionrc.json` and ask you to assign a bump type to each:
|
|
60
60
|
|
|
61
61
|
- `0` — skip (no version change)
|
|
62
62
|
- `1` — patch
|
|
@@ -65,32 +65,32 @@ production ──► hotfix/<name> (fix here with conventional commits)
|
|
|
65
65
|
|
|
66
66
|
For each selected package, `commit-and-tag-version` runs from within that package's directory, reading the package's own `.versionrc.json`. It bumps the `version` field in `package.json`, rewrites `CHANGELOG.md` to include only commits that touched files under that package's directory (`gitRawCommitsOpts.path: "."`), commits the bump, and creates a scoped tag (e.g. `@regardio/dev@v1.2.0`).
|
|
67
67
|
|
|
68
|
-
If
|
|
68
|
+
If no packages have a `.versionrc.json`, the versioning UI is skipped and `ship:production` proceeds directly to the git merge.
|
|
69
69
|
|
|
70
70
|
## CI — What Happens on Each Branch
|
|
71
71
|
|
|
72
72
|
CI behaviour differs by what the repo produces.
|
|
73
73
|
|
|
74
|
-
### Publishing monorepos
|
|
74
|
+
### Publishing monorepos
|
|
75
75
|
|
|
76
76
|
- **staging**: Run typecheck and tests. Nothing is published.
|
|
77
77
|
- **production**: Run typecheck, tests, then `pnpm -r publish --access public --no-git-checks`. Only packages whose current version is not yet on npm are published — packages with `"private": true` are skipped automatically.
|
|
78
78
|
|
|
79
|
-
### Server-deployed apps with Docker
|
|
79
|
+
### Server-deployed apps with Docker
|
|
80
80
|
|
|
81
81
|
- **staging**: Run tests, build the Docker image, push to the container registry, trigger a staging deploy (e.g. Coolify webhook).
|
|
82
82
|
- **production**: Run typecheck + tests, build and push the Docker image, trigger a production deploy.
|
|
83
83
|
|
|
84
|
-
### Cloudflare Workers apps
|
|
84
|
+
### Cloudflare Workers apps
|
|
85
85
|
|
|
86
86
|
- **staging**: Run tests, then `wrangler versions upload --preview-alias preview`.
|
|
87
87
|
- **production**: Run typecheck + tests, then `wrangler deploy`.
|
|
88
88
|
|
|
89
|
-
### Documentation / vocabulary repos
|
|
89
|
+
### Documentation / vocabulary repos
|
|
90
90
|
|
|
91
91
|
- **staging** and **production**: Verify the repo is well-formed (build, typecheck, test). No publishing or deployment — the repo is distributed via git clone, not npm.
|
|
92
92
|
|
|
93
|
-
### Static sites without a configured deployment
|
|
93
|
+
### Static sites without a configured deployment
|
|
94
94
|
|
|
95
95
|
- **staging** and **production**: Run tests, typecheck (production only), and build. A deployment step is left as a TODO until the hosting platform is chosen.
|
|
96
96
|
|
|
@@ -122,8 +122,8 @@ pnpm ship:production
|
|
|
122
122
|
2. Fetch and verify `staging` and `production` branches exist.
|
|
123
123
|
3. Show commits to be shipped.
|
|
124
124
|
4. Run full quality suite — aborts on failure.
|
|
125
|
-
5. If
|
|
126
|
-
6. If no
|
|
125
|
+
5. If packages have `.versionrc.json`: assign a bump type to each; confirm the planned bumps.
|
|
126
|
+
6. If no packages have `.versionrc.json`: confirm whether to ship (versioning is skipped).
|
|
127
127
|
7. For each selected package: run `commit-and-tag-version --release-as <type>` from within the package directory.
|
|
128
128
|
8. Fast-forward merge `main` → `production`, push.
|
|
129
129
|
9. Sync `staging` with `production`, push.
|
|
@@ -139,7 +139,7 @@ git add . && git commit -m "fix: ..."
|
|
|
139
139
|
pnpm ship:hotfix finish
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
`finish` fetches origin, runs quality checks, assigns bump types (
|
|
142
|
+
`finish` fetches origin, runs quality checks, assigns bump types (for packages with `.versionrc.json`), versions the fix, then merges `hotfix → production → staging → main` and deletes the hotfix branch.
|
|
143
143
|
|
|
144
144
|
## Adoption
|
|
145
145
|
|
|
@@ -155,25 +155,22 @@ pnpm ship:hotfix finish
|
|
|
155
155
|
}
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
### 2. Add `.versionrc.json` to each package you want versioned
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
cp node_modules/@regardio/dev/templates/versionrc/.versionrc.json packages/my-pkg/.versionrc.json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Then replace both `@my-scope/my-pkg` placeholders in that file with your actual package name:
|
|
159
165
|
|
|
160
166
|
```json
|
|
161
167
|
{
|
|
162
|
-
"
|
|
163
|
-
|
|
164
|
-
"release:major": "commit-and-tag-version --release-as major",
|
|
165
|
-
"release:minor": "commit-and-tag-version --release-as minor",
|
|
166
|
-
"release:patch": "commit-and-tag-version --release-as patch"
|
|
167
|
-
}
|
|
168
|
+
"tagPrefix": "@my-scope/my-pkg@v",
|
|
169
|
+
"releaseCommitMessageFormat": "chore(release): @my-scope/my-pkg@v{{currentTag}}"
|
|
168
170
|
}
|
|
169
171
|
```
|
|
170
172
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
cp node_modules/@regardio/dev/templates/versionrc/.versionrc.json packages/my-pkg/.versionrc.json
|
|
175
|
-
# then set "tagPrefix": "@my-scope/my-pkg@v" inside that file
|
|
176
|
-
```
|
|
173
|
+
`tagPrefix` scopes the git tag to the package. `releaseCommitMessageFormat` puts the full package identifier in the release commit subject, so the monorepo history reads `chore(release): @my-scope/my-pkg@v1.2.0` rather than a bare version number.
|
|
177
174
|
|
|
178
175
|
Every `.versionrc.json` must include `"gitRawCommitsOpts": { "path": "." }` to filter the git log to commits that actually touched files under that package's directory. Without this, the changelog accumulates noise from unrelated packages.
|
|
179
176
|
|
|
@@ -192,14 +189,14 @@ git checkout main
|
|
|
192
189
|
```bash
|
|
193
190
|
# Forgejo / Codeberg
|
|
194
191
|
mkdir -p .forgejo/workflows
|
|
195
|
-
cp node_modules/@regardio/dev/templates/
|
|
192
|
+
cp node_modules/@regardio/dev/templates/actions/forgejo-release.yml .forgejo/workflows/release.yml
|
|
196
193
|
|
|
197
194
|
# GitHub
|
|
198
195
|
mkdir -p .github/workflows
|
|
199
|
-
cp node_modules/@regardio/dev/templates/github
|
|
196
|
+
cp node_modules/@regardio/dev/templates/actions/github-release.yml .github/workflows/release.yml
|
|
200
197
|
```
|
|
201
198
|
|
|
202
|
-
|
|
199
|
+
Both templates cover the npm-publishing case. Adapt the publish job for Docker / Cloudflare deployments as described in the CI section above.
|
|
203
200
|
|
|
204
201
|
### 5. First publish of any new package must be done locally
|
|
205
202
|
|
|
@@ -219,11 +216,11 @@ pnpm typecheck # Must succeed
|
|
|
219
216
|
pnpm test # Must succeed
|
|
220
217
|
```
|
|
221
218
|
|
|
222
|
-
##
|
|
219
|
+
## Publishing vs Non-Publishing Repos
|
|
223
220
|
|
|
224
|
-
Packages with `"private": true` are skipped by `pnpm -r publish` automatically.
|
|
221
|
+
Packages with `"private": true` are skipped by `pnpm -r publish` automatically — CI only publishes public packages to npm.
|
|
225
222
|
|
|
226
|
-
|
|
223
|
+
Whether a package is published to npm is independent of whether it gets versioned. The ship tooling uses `.versionrc.json` presence as the signal for versioning, not the `private` flag. A private channel app or a vocabulary repo can run `ship:production`, get a version bump, a CHANGELOG entry, and a scoped git tag, without ever touching npm.
|
|
227
224
|
|
|
228
225
|
## Related
|
|
229
226
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: "Writing"
|
|
4
|
+
description: "Voice, tone, and language Regardio content carries, in English and German."
|
|
5
|
+
publishedAt: 2026-04-17
|
|
6
|
+
order: 2
|
|
7
|
+
language: "en"
|
|
8
|
+
status: "published"
|
|
9
|
+
kind: "concept"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
The voice in which Regardio writes about itself and its tools.
|
|
13
|
+
|
|
14
|
+
## What you are doing
|
|
15
|
+
|
|
16
|
+
You write *from within* the System, not *about* it. Your aim is to trigger recognition. The reader you are writing for should be able to think *Yes, that's how it is.*
|
|
17
|
+
|
|
18
|
+
Two trains of thought carry everything the System does — and everything you write about it.
|
|
19
|
+
|
|
20
|
+
**Any one object can be observed from two sides.** Front and back, inside and outside, past and future, still and moving, question and answer, start and finish. A thing that looks complete from one angle shows something new from the other. Writing that only shows one side flattens what it describes. Writing that acknowledges both gives the reader room to stand where they already stand.
|
|
21
|
+
|
|
22
|
+
**A whole becomes graspable when it is cut into a few distinct parts.** Six is the number to return to: enough variety to cover what matters, few enough to hold in the head at once, clear enough to name and locate each piece. A pie cut into six slices is something anyone can picture. When a subject resists clarity, the move is not more words — it is better cuts.
|
|
23
|
+
|
|
24
|
+
These two habits are the grammar underneath the System. Carry them quietly. You rarely name them. They are just the shape of the thinking.
|
|
25
|
+
|
|
26
|
+
## How to meet the reader
|
|
27
|
+
|
|
28
|
+
Every reader comes with their own life and their own pursuit. Assume they notice things for themselves. Trust them to do their own connecting. Address them directly, without talking up or down.
|
|
29
|
+
|
|
30
|
+
The ground under the writing is careful observation of how people actually feel, think, and act — not advice about how they should. When an idea becomes personally recognizable while staying broadly true, it has landed. When it only flatters or only instructs, it hasn't.
|
|
31
|
+
|
|
32
|
+
## Stance
|
|
33
|
+
|
|
34
|
+
Six movements carry every piece.
|
|
35
|
+
|
|
36
|
+
1. **Derive, don't declare.** One thought leads to the next. "The System recognizes…" speaks from above. Better: the observation that leads to the structure. Readers follow a line of thought, not an instruction.
|
|
37
|
+
2. **Observe, don't instruct.** Write like someone who has listened carefully and is sharing an observation, not like someone explaining a method.
|
|
38
|
+
3. **Structure offers freedom, not rules.** The cuts exist to widen a view that has become too narrow, not to discipline one that is already broad.
|
|
39
|
+
4. **Suggest possibilities to choose from.** Offer angles, not answers. Let the reader decide what fits. Suggest questions that people have, not riddles to solve.
|
|
40
|
+
5. **Turned toward what could be, without promises.** Warm, attentive, spacious. Curious about people rather than diagnostic. No salvation talk, no coaching register.
|
|
41
|
+
6. **Good humor makes the deepest thought approachable.** Lightness when it fits. Not forced, not absent. When the moment is right, a small wink can carry weight without claiming it.
|
|
42
|
+
|
|
43
|
+
## Before and after
|
|
44
|
+
|
|
45
|
+
**Instead of:** *"Apply this framework to align your team."*
|
|
46
|
+
**Try:** *"What does the decision we made last week have to do with what's slowing us down now?"*
|
|
47
|
+
|
|
48
|
+
**Instead of:** *"The System helps you gain clarity."*
|
|
49
|
+
**Try:** *"A few angles worth looking at, whatever the pursuit."*
|
|
50
|
+
|
|
51
|
+
**Instead of:** *"Pursuits flourish with a clear core."*
|
|
52
|
+
**Try:** *"How will we know when we've arrived?"*
|
|
53
|
+
|
|
54
|
+
The System's questions are not headers. They are real questions, worth sitting with.
|
|
55
|
+
|
|
56
|
+
## Language
|
|
57
|
+
|
|
58
|
+
Language that leaves room lets readers think. Language that pushes does the thinking for them. Given the choice, choose room.
|
|
59
|
+
|
|
60
|
+
**Favor:** notice, explore, find, might, could, pattern, rhythm, carry, hold — words that leave room.
|
|
61
|
+
|
|
62
|
+
**Avoid:** must, potential, resources, values, purpose, sustainability, growth, leverage, empower, ownership, good, bad. These either push or have been worn down to noise.
|
|
63
|
+
|
|
64
|
+
**No method jargon.** Not from business, not from coaching, not from therapy, not from spirituality. If a term has a clear everyday word behind it, use the everyday word.
|
|
65
|
+
|
|
66
|
+
**People are not categories.** Describe what people do and bring about, not what they are. This is also how gendered forms are handled — name actions, not groups.
|
|
67
|
+
|
|
68
|
+
**The System is humane.** Equal, free cooperation is built in. Avoid connotations of hierarchy, ownership, dominance, control, or force. Reflect that without announcing it.
|
|
69
|
+
|
|
70
|
+
**Complexity earns its place or goes.** Make hard ideas reachable without flattening them. If a sentence has to be read twice, shorten it. If an idea has been reduced past recognition, let it breathe again.
|
|
71
|
+
|
|
72
|
+
## System terms
|
|
73
|
+
|
|
74
|
+
System terms carry precisely defined concepts. Use them as they are; don't swap in synonyms for variety. When tempted to reach for a buzzword, reach for a System term instead — if it fits. If no System term fits, the buzzword probably isn't earning its place either.
|
|
75
|
+
|
|
76
|
+
In every language the System is written in, the terms are chosen to capture the spirit of each concept in that language — not to translate literally from another. Don't import words from other languages into the prose. Let each language stand on its own.
|
|
77
|
+
|
|
78
|
+
## Roots, kept in the background
|
|
79
|
+
|
|
80
|
+
The System draws from many traditions of thought. Reference intents and ideas, not names or schools. The sources show themselves in the structure, not in citation. This is working craft carried by collective intelligence, not an elaborate treatise.
|
|
81
|
+
|
|
82
|
+
## Format and craft
|
|
83
|
+
|
|
84
|
+
**Headers** for orientation. **Prose** for connected thought. **Bold** for System terms at first introduction. *Italics* for genuine emphasis. No emojis. Lists only when the content is genuinely a list — bullets never replace a thought.
|
|
85
|
+
|
|
86
|
+
## Language-specific caveats
|
|
87
|
+
|
|
88
|
+
### German
|
|
89
|
+
|
|
90
|
+
- Address the reader with *du* unless the context clearly calls for *Sie* (formal contracts, legal notices). Keep it direct, without affectation.
|
|
91
|
+
- No gendering artifacts: no *:innen*, no asterisks, no *(m/w/d)*. Prefer action-based descriptions over group labels: *wer etwas vorhat*, *ein Mensch, der …*, *die Person, die …*, *Mitwirkende*, *Beteiligte*.
|
|
92
|
+
- Quotation marks: German low-high („…") in body text.
|
|
93
|
+
|
|
94
|
+
### English
|
|
95
|
+
|
|
96
|
+
- American English: *organize*, *color*, *toward*, *behavior*, *center*. Periods and commas inside quotation marks.
|
|
97
|
+
- No gendered forms. Name actions: *the person pursuing this*, *contributors*, *those involved*. Singular *they* is fine where a pronoun is unavoidable.
|
|
98
|
+
- Quotation marks: straight double quotes (") in Markdown source; typographic quotes ("…") in rendered prose.
|
|
99
|
+
|
|
100
|
+
## Check before publishing
|
|
101
|
+
|
|
102
|
+
- Does it sound like a conversation the reader would want to be in?
|
|
103
|
+
- Does the text derive rather than declare?
|
|
104
|
+
- Are abstract thoughts grounded in concrete examples?
|
|
105
|
+
- Are System terms used consistently, in their precise meaning?
|
|
106
|
+
- Is it free of coaching register, pigeonholing, and tired buzzwords?
|
|
107
|
+
- Could the honest response be *"Yes, that's how it is"*?
|
|
108
|
+
|
|
109
|
+
*This guide is itself a living text. When in doubt: would you enjoy reading this?*
|
|
110
|
+
|
|
111
|
+
## Related
|
|
112
|
+
|
|
113
|
+
- [Documentation](./documentation.md) — How Regardio shapes its documents
|
|
114
|
+
- [Principles](./principles.md) — Shared principles
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
**License**: [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) © Regardio
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.schemastore.org/package.json",
|
|
3
3
|
"name": "@regardio/dev",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.6.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Regardio development presets: biome, typescript, commitlint, markdownlint, vitest, playwright, sqlfluff, husky, and GitLab-flow ship tooling",
|
|
7
7
|
"keywords": [
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
],
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@total-typescript/ts-reset": "0.6.1",
|
|
77
|
-
"@types/node": "25.6.
|
|
77
|
+
"@types/node": "25.6.2",
|
|
78
78
|
"@vitest/coverage-v8": "4.1.5",
|
|
79
79
|
"tsdown": "0.22.0",
|
|
80
80
|
"vitest": "4.1.5"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Regardio npm-publishing workflow — Forgejo Actions
|
|
2
|
+
#
|
|
3
|
+
# Pushes to staging and production are driven by ship tooling, not by hand:
|
|
4
|
+
# pnpm ship:staging — fast-forward main → staging (no version bump)
|
|
5
|
+
# pnpm ship:production — version bump + main → production + sync staging
|
|
6
|
+
# pnpm ship:hotfix finish — version bump + hotfix → production → staging → main
|
|
7
|
+
#
|
|
8
|
+
# Full documentation: node_modules/@regardio/dev/docs/en/tools/releases.md
|
|
9
|
+
#
|
|
10
|
+
# This template covers the npm-publishing case.
|
|
11
|
+
# Adapt the publish job for Docker / Coolify deployments as needed.
|
|
12
|
+
#
|
|
13
|
+
# Required setup:
|
|
14
|
+
# 1. Ship scripts in package.json (ship:hotfix, ship:production, ship:staging)
|
|
15
|
+
# 2. .versionrc.json in each publishable package directory
|
|
16
|
+
# (template: node_modules/@regardio/dev/templates/versionrc/.versionrc.json)
|
|
17
|
+
# 3. staging and production branches created and pushed
|
|
18
|
+
# 4. NPM_TOKEN repo secret; first publish of any new package done locally
|
|
19
|
+
#
|
|
20
|
+
# NOTE: npm provenance is not supported on Forgejo. If Forgejo is added to
|
|
21
|
+
# npm's trusted-publisher list in the future, add --provenance to the publish step.
|
|
22
|
+
|
|
23
|
+
name: Release
|
|
24
|
+
|
|
25
|
+
on:
|
|
26
|
+
push:
|
|
27
|
+
branches: [staging, production]
|
|
28
|
+
|
|
29
|
+
concurrency:
|
|
30
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
31
|
+
cancel-in-progress: ${{ github.ref_name == 'staging' }}
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
typecheck:
|
|
35
|
+
name: ʦ TypeScript
|
|
36
|
+
# Husky enforces typecheck pre-commit; only re-run on production to guard against hotfixes.
|
|
37
|
+
if: github.ref_name == 'production'
|
|
38
|
+
runs-on: codeberg-small
|
|
39
|
+
timeout-minutes: 8
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v5
|
|
42
|
+
with:
|
|
43
|
+
fetch-depth: 1
|
|
44
|
+
- uses: actions/setup-node@v4
|
|
45
|
+
with:
|
|
46
|
+
node-version: '24'
|
|
47
|
+
- run: corepack enable
|
|
48
|
+
- name: Get pnpm store path
|
|
49
|
+
id: pnpm-store
|
|
50
|
+
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
|
51
|
+
- uses: actions/cache@v4
|
|
52
|
+
with:
|
|
53
|
+
path: ${{ steps.pnpm-store.outputs.path }}
|
|
54
|
+
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
55
|
+
restore-keys: pnpm-${{ runner.os }}-
|
|
56
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
|
|
57
|
+
- run: pnpm typecheck
|
|
58
|
+
|
|
59
|
+
test:
|
|
60
|
+
name: ⚫️ Test
|
|
61
|
+
runs-on: codeberg-small
|
|
62
|
+
timeout-minutes: 10
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v5
|
|
65
|
+
with:
|
|
66
|
+
fetch-depth: 1
|
|
67
|
+
- uses: actions/setup-node@v4
|
|
68
|
+
with:
|
|
69
|
+
node-version: '24'
|
|
70
|
+
- run: corepack enable
|
|
71
|
+
- name: Get pnpm store path
|
|
72
|
+
id: pnpm-store
|
|
73
|
+
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
|
74
|
+
- uses: actions/cache@v4
|
|
75
|
+
with:
|
|
76
|
+
path: ${{ steps.pnpm-store.outputs.path }}
|
|
77
|
+
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
78
|
+
restore-keys: pnpm-${{ runner.os }}-
|
|
79
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
|
|
80
|
+
- run: pnpm test
|
|
81
|
+
|
|
82
|
+
publish:
|
|
83
|
+
name: 📦 Publish
|
|
84
|
+
needs: [typecheck, test]
|
|
85
|
+
if: |
|
|
86
|
+
always() &&
|
|
87
|
+
github.ref_name == 'production' &&
|
|
88
|
+
needs.typecheck.result == 'success' &&
|
|
89
|
+
needs.test.result == 'success'
|
|
90
|
+
runs-on: codeberg-small
|
|
91
|
+
timeout-minutes: 10
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v5
|
|
94
|
+
with:
|
|
95
|
+
fetch-depth: 0
|
|
96
|
+
- uses: actions/setup-node@v4
|
|
97
|
+
with:
|
|
98
|
+
node-version: '24'
|
|
99
|
+
- run: corepack enable
|
|
100
|
+
- name: Get pnpm store path
|
|
101
|
+
id: pnpm-store
|
|
102
|
+
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
|
103
|
+
- uses: actions/cache@v4
|
|
104
|
+
with:
|
|
105
|
+
path: ${{ steps.pnpm-store.outputs.path }}
|
|
106
|
+
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
107
|
+
restore-keys: pnpm-${{ runner.os }}-
|
|
108
|
+
- name: Configure npm auth
|
|
109
|
+
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
|
110
|
+
env:
|
|
111
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
112
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
|
|
113
|
+
- run: pnpm -r build
|
|
114
|
+
- run: pnpm -r publish --access public --no-git-checks
|
|
115
|
+
env:
|
|
116
|
+
NPM_CONFIG_USERCONFIG: /root/.npmrc
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Regardio npm-publishing workflow — GitHub Actions
|
|
2
|
+
#
|
|
3
|
+
# Pushes to staging and production are driven by ship tooling, not by hand:
|
|
4
|
+
# pnpm ship:staging — fast-forward main → staging (no version bump)
|
|
5
|
+
# pnpm ship:production — version bump + main → production + sync staging
|
|
6
|
+
# pnpm ship:hotfix finish — version bump + hotfix → production → staging → main
|
|
7
|
+
#
|
|
8
|
+
# Full documentation: node_modules/@regardio/dev/docs/en/tools/releases.md
|
|
9
|
+
#
|
|
10
|
+
# This template covers the npm-publishing case.
|
|
11
|
+
# Adapt the publish job for Docker / Cloudflare deployments as needed.
|
|
12
|
+
#
|
|
13
|
+
# Required setup:
|
|
14
|
+
# 1. Ship scripts in package.json (ship:hotfix, ship:production, ship:staging)
|
|
15
|
+
# 2. .versionrc.json in each publishable package directory
|
|
16
|
+
# (template: node_modules/@regardio/dev/templates/versionrc/.versionrc.json)
|
|
17
|
+
# 3. staging and production branches created and pushed
|
|
18
|
+
# 4. NPM_TOKEN repo secret; first publish of any new package done locally
|
|
19
|
+
|
|
20
|
+
name: Release
|
|
21
|
+
|
|
22
|
+
on:
|
|
23
|
+
push:
|
|
24
|
+
branches: [staging, production]
|
|
25
|
+
|
|
26
|
+
concurrency:
|
|
27
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
28
|
+
cancel-in-progress: ${{ github.ref_name == 'staging' }}
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
typecheck:
|
|
32
|
+
name: ʦ TypeScript
|
|
33
|
+
# Husky enforces typecheck pre-commit; only re-run on production to guard against hotfixes.
|
|
34
|
+
if: github.ref_name == 'production'
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
timeout-minutes: 8
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v6
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 1
|
|
41
|
+
- uses: pnpm/action-setup@v5
|
|
42
|
+
- uses: actions/setup-node@v6
|
|
43
|
+
with:
|
|
44
|
+
node-version: 24
|
|
45
|
+
cache: pnpm
|
|
46
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
|
|
47
|
+
- run: pnpm typecheck
|
|
48
|
+
|
|
49
|
+
test:
|
|
50
|
+
name: ⚫️ Test
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
timeout-minutes: 10
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v6
|
|
55
|
+
with:
|
|
56
|
+
fetch-depth: 1
|
|
57
|
+
- uses: pnpm/action-setup@v5
|
|
58
|
+
- uses: actions/setup-node@v6
|
|
59
|
+
with:
|
|
60
|
+
node-version: 24
|
|
61
|
+
cache: pnpm
|
|
62
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
|
|
63
|
+
- run: pnpm test
|
|
64
|
+
|
|
65
|
+
publish:
|
|
66
|
+
name: 📦 Publish
|
|
67
|
+
needs: [typecheck, test]
|
|
68
|
+
if: |
|
|
69
|
+
always() &&
|
|
70
|
+
github.ref_name == 'production' &&
|
|
71
|
+
needs.typecheck.result == 'success' &&
|
|
72
|
+
needs.test.result == 'success'
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
timeout-minutes: 10
|
|
75
|
+
permissions:
|
|
76
|
+
contents: read
|
|
77
|
+
id-token: write
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v6
|
|
80
|
+
with:
|
|
81
|
+
fetch-depth: 0
|
|
82
|
+
- uses: pnpm/action-setup@v5
|
|
83
|
+
- uses: actions/setup-node@v6
|
|
84
|
+
with:
|
|
85
|
+
node-version: 24
|
|
86
|
+
cache: pnpm
|
|
87
|
+
registry-url: https://registry.npmjs.org
|
|
88
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
|
|
89
|
+
- run: pnpm -r build
|
|
90
|
+
- run: pnpm -r publish --access public --no-git-checks
|
|
91
|
+
env:
|
|
92
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
93
|
+
NPM_CONFIG_PROVENANCE: "true"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# [Project Name] — Agent Context
|
|
2
|
+
|
|
3
|
+
[One sentence: what this project is and its role.]
|
|
4
|
+
|
|
5
|
+
## Standards
|
|
6
|
+
|
|
7
|
+
This project uses `@regardio/dev`. After `pnpm install`, all Regardio standards are available locally:
|
|
8
|
+
|
|
9
|
+
| What | Path |
|
|
10
|
+
|------|------|
|
|
11
|
+
| Full index | `node_modules/@regardio/dev/docs/en/README.md` |
|
|
12
|
+
| Principles | `node_modules/@regardio/dev/docs/en/principles.md` |
|
|
13
|
+
| Writing & language | `node_modules/@regardio/dev/docs/en/writing.md` |
|
|
14
|
+
| Documentation shape | `node_modules/@regardio/dev/docs/en/documentation.md` |
|
|
15
|
+
| Code standards | `node_modules/@regardio/dev/docs/en/standards/` |
|
|
16
|
+
| Toolchain | `node_modules/@regardio/dev/docs/en/tools/` |
|
|
17
|
+
|
|
18
|
+
Read the full index first. It lists every standard and toolchain doc in one place.
|
|
19
|
+
|
|
20
|
+
## Structure
|
|
21
|
+
|
|
22
|
+
[Describe the project's key directories and what lives where.]
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm build # Build
|
|
28
|
+
pnpm test # Run tests
|
|
29
|
+
pnpm typecheck # Type check
|
|
30
|
+
pnpm lint # Lint
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Run `typecheck` and `lint` before calling a task done.
|
|
34
|
+
|
|
35
|
+
## Working here
|
|
36
|
+
|
|
37
|
+
[Anything project-specific an agent needs to know: domain context, conventions that differ from the standards, areas to be careful about.]
|
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"commitAll": false,
|
|
3
|
-
"gitRawCommitsOpts": {
|
|
3
|
+
"gitRawCommitsOpts": {
|
|
4
|
+
"path": "."
|
|
5
|
+
},
|
|
6
|
+
"releaseCommitMessageFormat": "chore(release): @my-scope/my-pkg@v{{currentTag}}",
|
|
4
7
|
"sign": false,
|
|
5
|
-
"tagPrefix": "v",
|
|
8
|
+
"tagPrefix": "@my-scope/my-pkg@v",
|
|
6
9
|
"types": [
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
{
|
|
10
|
+
{
|
|
11
|
+
"section": "Features",
|
|
12
|
+
"type": "feat"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"section": "Bug Fixes",
|
|
16
|
+
"type": "fix"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"section": "Performance",
|
|
20
|
+
"type": "perf"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"section": "Refactoring",
|
|
24
|
+
"type": "refactor"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"hidden": false,
|
|
28
|
+
"section": "Chores",
|
|
29
|
+
"type": "chore"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"hidden": true,
|
|
33
|
+
"type": "docs"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"hidden": true,
|
|
37
|
+
"type": "style"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"hidden": true,
|
|
41
|
+
"type": "test"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"hidden": true,
|
|
45
|
+
"type": "ci"
|
|
46
|
+
}
|
|
16
47
|
]
|
|
17
48
|
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Regardio Release Workflow (GitHub Actions)
|
|
2
|
-
# Copy this file to .github/workflows/release.yml
|
|
3
|
-
#
|
|
4
|
-
# Required setup:
|
|
5
|
-
# 1. Add these scripts to package.json:
|
|
6
|
-
# "release": "commit-and-tag-version",
|
|
7
|
-
# "release:major": "commit-and-tag-version --release-as major",
|
|
8
|
-
# "release:minor": "commit-and-tag-version --release-as minor",
|
|
9
|
-
# "release:patch": "commit-and-tag-version --release-as patch",
|
|
10
|
-
# "ship:staging": "ship-staging",
|
|
11
|
-
# "ship:production": "ship-production",
|
|
12
|
-
# "ship:hotfix": "ship-hotfix"
|
|
13
|
-
# 2. Copy .versionrc.json from node_modules/@regardio/dev/templates/versionrc/.versionrc.json
|
|
14
|
-
# 3. Create the branches:
|
|
15
|
-
# git checkout -b staging && git push -u origin staging
|
|
16
|
-
# git checkout -b production && git push -u origin production
|
|
17
|
-
# 4. Add `NPM_TOKEN` to repo secrets. First npm publish of any new package
|
|
18
|
-
# must be done locally (`npm publish --access public`).
|
|
19
|
-
#
|
|
20
|
-
# Usage:
|
|
21
|
-
# - `pnpm ship:staging` deploys to staging for validation (optional)
|
|
22
|
-
# - `pnpm ship:production` runs commit-and-tag-version locally, bumps the version,
|
|
23
|
-
# merges to production. This workflow then publishes to npm.
|
|
24
|
-
|
|
25
|
-
name: Release
|
|
26
|
-
|
|
27
|
-
on:
|
|
28
|
-
push:
|
|
29
|
-
branches:
|
|
30
|
-
- production
|
|
31
|
-
|
|
32
|
-
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
33
|
-
|
|
34
|
-
jobs:
|
|
35
|
-
release:
|
|
36
|
-
name: Release
|
|
37
|
-
runs-on: ubuntu-latest
|
|
38
|
-
permissions:
|
|
39
|
-
contents: write
|
|
40
|
-
id-token: write
|
|
41
|
-
steps:
|
|
42
|
-
- name: Checkout
|
|
43
|
-
uses: actions/checkout@v6
|
|
44
|
-
with:
|
|
45
|
-
fetch-depth: 0
|
|
46
|
-
|
|
47
|
-
- name: Setup pnpm
|
|
48
|
-
uses: pnpm/action-setup@v5
|
|
49
|
-
with:
|
|
50
|
-
version: 10
|
|
51
|
-
|
|
52
|
-
- name: Setup Node.js
|
|
53
|
-
uses: actions/setup-node@v6
|
|
54
|
-
with:
|
|
55
|
-
node-version: 24
|
|
56
|
-
registry-url: https://registry.npmjs.org
|
|
57
|
-
|
|
58
|
-
- name: Install dependencies
|
|
59
|
-
run: pnpm install --frozen-lockfile
|
|
60
|
-
|
|
61
|
-
- name: Build
|
|
62
|
-
run: pnpm -r build
|
|
63
|
-
|
|
64
|
-
- name: Publish changed public packages
|
|
65
|
-
run: pnpm -r publish --access public --no-git-checks
|
|
66
|
-
env:
|
|
67
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
68
|
-
NPM_CONFIG_PROVENANCE: "true"
|