@codepassion/skills 1.0.2 → 1.1.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 +13 -912
- package/SKILLS.md +4 -4
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,918 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# C9N Agent Skills
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
1. [Development Workflow](#1-development-workflow)
|
|
5
|
-
2. [Git Branching Strategy](#2-git-branching-strategy)
|
|
6
|
-
3. [Commit Message Convention](#3-commit-message-convention)
|
|
7
|
-
4. [Pull Request (PR) Guidelines](#4-pull-request-pr-guidelines)
|
|
8
|
-
5. [Code Review (Conventional Comments)](#5-code-review-conventional-comments)
|
|
9
|
-
6. [Clean Code (TypeScript)](#6-clean-code-typescript)
|
|
10
|
-
7. [TypeScript Rules (ESLint)](#7-typescript-rules-eslint)
|
|
11
|
-
8. [Code Formatting](#8-code-formatting)
|
|
12
|
-
9. [JSON:API Overview](#9-jsonapi-overview)
|
|
13
|
-
10. [Go/No Go Release Step](#10-gono-go-release-step)
|
|
14
|
-
11. [Deployment Guide (Semantic Versioning 2.0.0)](#11-deployment-guide-semantic-versioning-200)
|
|
3
|
+
Agent skills (SKILL.md) based on the CodePassion (C9N) conventions.
|
|
15
4
|
|
|
16
|
-
|
|
5
|
+
## Install
|
|
17
6
|
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
npx @codepassion/skills install claude # ~/.claude/skills
|
|
8
|
+
npx @codepassion/skills install codex # ~/.codex/skills
|
|
9
|
+
npx @codepassion/skills install project # ./.agents/skills
|
|
10
|
+
npx @codepassion/skills install combined # one combined skill
|
|
20
11
|
|
|
21
|
-
|
|
12
|
+
Or: ./install.sh {claude|codex|project|combined}
|
|
22
13
|
|
|
23
|
-
|
|
24
|
-
sequenceDiagram
|
|
25
|
-
participant Dev as Developer
|
|
26
|
-
participant Jira as Jira Board
|
|
27
|
-
participant Repo as Repository
|
|
28
|
-
participant CI as CI/CD Pipeline
|
|
29
|
-
participant Env as Alpha Environment
|
|
30
|
-
participant QA as QA Team
|
|
14
|
+
## Edit
|
|
31
15
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Dev->>Jira: Add size, start/end date & duration estimates
|
|
37
|
-
Dev->>Jira: Move to "Ready for Dev"
|
|
38
|
-
Dev->>Jira: Move to "Dev in Progress"
|
|
39
|
-
Dev->>Repo: Push working branch & create draft PR
|
|
40
|
-
Dev->>Jira: Update working status
|
|
41
|
-
Dev->>Repo: Write & run tests (unit, e2e, automation)
|
|
42
|
-
Dev->>Jira: Move to "Ready for Code Review"
|
|
43
|
-
Dev->>Repo: Update PR & request review
|
|
44
|
-
|
|
45
|
-
alt PR Approved
|
|
46
|
-
Dev->>Repo: Merge PR
|
|
47
|
-
else Changes Requested
|
|
48
|
-
Dev->>Repo: Resolve comments & update PR
|
|
49
|
-
Dev->>Repo: Request re-review
|
|
50
|
-
Dev->>Repo: Merge PR after approval
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
Dev->>Jira: Move to "Ready to Deploy"
|
|
54
|
-
Dev->>Repo: Pull latest develop & tag (vX.Y.Z-alpha)
|
|
55
|
-
Dev->>CI: Push tag to trigger deployment
|
|
56
|
-
CI->>Env: Deploy to Alpha
|
|
57
|
-
Dev->>Env: Validate changes in Alpha
|
|
58
|
-
Dev->>Jira: Move to "Ready for QA" & assign to QA
|
|
59
|
-
|
|
60
|
-
alt QA Passed
|
|
61
|
-
QA->>Jira: Close ticket as "Done"
|
|
62
|
-
else Issues Found
|
|
63
|
-
QA->>Jira: Move to "Reopened" & assign back to Dev
|
|
64
|
-
Dev->>Jira: Pick up ticket & repeat from clarification
|
|
65
|
-
end
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Steps of Work
|
|
69
|
-
|
|
70
|
-
1. **Pick up your ticket** — Review your assigned tickets in Jira (For You page or Active Sprint).
|
|
71
|
-
2. **Clarify requirements** — Before starting, confirm the requirements, acceptance criteria, steps to reproduce (for bugs), test cases, and definition of done with the reporter or your manager.
|
|
72
|
-
3. **Analyze the ticket** — Move the ticket to **"To Analyze"**. Evaluate solutions, draw diagrams, identify dependencies, and complete any necessary POCs.
|
|
73
|
-
4. **Provide estimates** — Add ticket size, start date, end date, and duration estimates (days/hours).
|
|
74
|
-
5. **Mark ready for development** — Move the ticket to **"Ready for Dev"** once analysis is complete.
|
|
75
|
-
6. **Start development** — Move the ticket to **"Dev in Progress"**. Push your working branch and create a draft pull request.
|
|
76
|
-
7. **Keep status updated** — Regularly update your working status in the Jira ticket.
|
|
77
|
-
8. **Write tests** — Add unit tests, e2e tests, and automation tests to cover all changes. Ensure no existing tests are broken.
|
|
78
|
-
9. **Request code review** — Move the ticket to **"Ready for Code Review"**. Update your PR and assign another developer to review.
|
|
79
|
-
10. **Address review feedback** — If changes are requested, resolve or fix all comments. Once approved, merge the PR.
|
|
80
|
-
11. **Prepare for deployment** — Move the ticket to **"Ready to Deploy"**. Pull the latest changes from the develop branch, create a new tag (`vX.Y.Z`), and push it.
|
|
81
|
-
12. **Validate in Alpha** — After the CI/CD pipeline completes, verify your changes in the Alpha environment.
|
|
82
|
-
13. **Hand off to QA** — Move the ticket to **"Ready for QA"** and assign it to a QA team member.
|
|
83
|
-
14. **QA verification** — If QA tests pass, the ticket is closed as **"Done"**. If issues are found, the ticket is moved to **"Reopened"** and assigned back to you with test results. Repeat from step 2.
|
|
84
|
-
|
|
85
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
86
|
-
|
|
87
|
-
## 2. Git Branching Strategy
|
|
88
|
-
We follow the **Conventional Branch** specification to ensure branch names are human and machine-readable.
|
|
89
|
-
|
|
90
|
-
### Format
|
|
91
|
-
```
|
|
92
|
-
<type>/<description>
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Branch Types
|
|
96
|
-
|
|
97
|
-
| Type | Purpose | Example |
|
|
98
|
-
|------|---------|---------|
|
|
99
|
-
| `main` | Main development branch | `main`, `master`, `develop` |
|
|
100
|
-
| `feature/` or `feat/` | New features | `feature/add-login-page` |
|
|
101
|
-
| `bugfix/` or `fix/` | Bug fixes | `bugfix/fix-header-bug` |
|
|
102
|
-
| `hotfix/` | Urgent fixes | `hotfix/security-patch` |
|
|
103
|
-
| `release/` | Release preparation | `release/v1.2.0` |
|
|
104
|
-
| `chore/` | Non-code tasks (dependencies, docs) | `chore/update-readme` |
|
|
105
|
-
|
|
106
|
-
### Naming Rules
|
|
107
|
-
|
|
108
|
-
| ✅ Do | ❌ Don't |
|
|
109
|
-
|------|---------|
|
|
110
|
-
| `feature/user-profile` | `Feature/User-Profile` (use lowercase) |
|
|
111
|
-
| `feature/user-login-page` | `feature/user_login_page` (use hyphens) |
|
|
112
|
-
| `feature/add-payment` | `feature/add-payment!` (avoid special chars) |
|
|
113
|
-
| `feature/new-feature` | `feature/new--feature` (no consecutive separators) |
|
|
114
|
-
| `feature/login-page` | `feature/-login-page` (no leading/trailing separators) |
|
|
115
|
-
| `release/v1.2.0` | `feature/v1.2.0` (dots only in release branches) |
|
|
116
|
-
| `feature/issue-123-add-login` | `feature/add-login` (include ticket number if exists) |
|
|
117
|
-
| `feature/add-user-authentication` | `feature/updates` (be specific, not vague) |
|
|
118
|
-
| `fix/resolve-memory-leak` | `fix/john-fixes` (no personal names) |
|
|
119
|
-
| `hotfix/security-vulnerability-patch` | `feature/this-is-a-very-long-branch-name-that-exceeds-fifty-characters` (keep under 50 chars) |
|
|
120
|
-
|
|
121
|
-
Reference: [Conventional Branch](https://conventional-branch.github.io)
|
|
122
|
-
|
|
123
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
124
|
-
|
|
125
|
-
## 3. Commit Message Convention
|
|
126
|
-
We adhere to **Conventional Commits** to create an explicit commit history that supports automated Semantic Versioning.
|
|
127
|
-
|
|
128
|
-
### Format
|
|
129
|
-
```
|
|
130
|
-
<type>[optional scope]: <description>
|
|
131
|
-
|
|
132
|
-
[optional body]
|
|
133
|
-
|
|
134
|
-
[optional footer(s)]
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Commit Types
|
|
138
|
-
|
|
139
|
-
| Type | Purpose | SemVer Impact | Example |
|
|
140
|
-
|------|---------|---------------|---------|
|
|
141
|
-
| `feat:` | New feature | MINOR | `feat: add user authentication` |
|
|
142
|
-
| `fix:` | Bug fix | PATCH | `fix: resolve login error` |
|
|
143
|
-
| `docs:` | Documentation changes | - | `docs: update API documentation` |
|
|
144
|
-
| `style:` | Code style changes (formatting) | - | `style: fix indentation` |
|
|
145
|
-
| `refactor:` | Code refactoring | - | `refactor: simplify validation logic` |
|
|
146
|
-
| `test:` | Add or update tests | - | `test: add unit tests for parser` |
|
|
147
|
-
| `chore:` | Maintenance tasks | - | `chore: update dependencies` |
|
|
148
|
-
| `ci:` | CI/CD changes | - | `ci: update build pipeline` |
|
|
149
|
-
| `perf:` | Performance improvements | PATCH | `perf: optimize database queries` |
|
|
150
|
-
|
|
151
|
-
### Breaking Changes
|
|
152
|
-
A commit introducing a **breaking API change** (correlates with MAJOR version) must be indicated by:
|
|
153
|
-
- Appending a `!` after the type/scope: `feat!: ...` or `fix(api)!: ...`
|
|
154
|
-
- Or including a footer: `BREAKING CHANGE: <description>`
|
|
155
|
-
|
|
156
|
-
### Writing Good Commit Messages
|
|
157
|
-
|
|
158
|
-
| ✅ Do | ❌ Don't |
|
|
159
|
-
|------|---------|
|
|
160
|
-
| `feat: add user authentication` | `feat: added stuff` (be specific) |
|
|
161
|
-
| `feat: add new feature` | `feat: Add new feature` (lowercase after colon) |
|
|
162
|
-
| `docs: update README` | `docs: update README.` (no ending punctuation) |
|
|
163
|
-
| `refactor: simplify logic` | `refactor: simplified logic` (use imperative mood) |
|
|
164
|
-
| `feat: add password reset` | `feat: add a complete password reset functionality with email verification` (keep under 50 chars) |
|
|
165
|
-
| `fix(api): handle null response` | `fix(api, auth, db): multiple fixes` (one scope only) |
|
|
166
|
-
| ```feat: add password reset functionality<br><br>Allow users to reset their password via email.<br><br>Closes #123``` | ```feat: stuff<br><br>Updated some files.``` (provide clear description) |
|
|
167
|
-
|
|
168
|
-
Reference: [Conventional Commits](https://www.conventionalcommits.org)
|
|
169
|
-
|
|
170
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
171
|
-
|
|
172
|
-
## 4. Pull Request (PR) Guidelines
|
|
173
|
-
A consistent naming convention for PRs helps reviewers identify the context immediately.
|
|
174
|
-
|
|
175
|
-
### Subject Format
|
|
176
|
-
```
|
|
177
|
-
#[Ticket_ID] PR description
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Pull Request Guidelines
|
|
181
|
-
|
|
182
|
-
| ✅ Do | ❌ Don't |
|
|
183
|
-
|------|---------|
|
|
184
|
-
| `#CLS-23 Add user dashboard` | `Add user dashboard` (include ticket ID) |
|
|
185
|
-
| `#CLS-23 Add feature` | `#CLS-23 Added feature` (use imperative mood) |
|
|
186
|
-
| `#CLS-23 Add login page` | `#CLS-23 add login page` (capitalize first word) |
|
|
187
|
-
| `#CLS-23 Add search feature` | `#CLS-23 Add search feature.` (no ending punctuation) |
|
|
188
|
-
| `#CLS-23 Add OAuth authentication` | `#CLS-23 Add stuff` (be specific) |
|
|
189
|
-
| ```#CLS-23 Add Edit on Github button to all pages<br><br>This change adds an "Edit on Github" button to improve<br>contributor experience. The button appears on every<br>documentation page and links to the source file.<br><br>- Added button component<br>- Integrated with page layout<br>- Tested on mobile and desktop<br><br>Closes #CLS-23``` | ```#cls-23 added edit button.``` (follow all conventions) |
|
|
190
|
-
|
|
191
|
-
Reference: [Naming Convention (Pull Request)](https://namingconvention.org/git/pull-request-naming.html)
|
|
192
|
-
|
|
193
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
194
|
-
|
|
195
|
-
## 5. Code Review (Conventional Comments)
|
|
196
|
-
To prevent misunderstandings and make feedback actionable, use **labels** to prefix comments.
|
|
197
|
-
|
|
198
|
-
### Format
|
|
199
|
-
```
|
|
200
|
-
<label> [decorations]: <subject>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Labels
|
|
204
|
-
|
|
205
|
-
| Label | Purpose | When to Use | Example |
|
|
206
|
-
|-------|---------|-------------|---------|
|
|
207
|
-
| `praise:` | Highlight positive aspects | Something is well done | `praise: Great error handling here!` |
|
|
208
|
-
| `nitpick:` | Trivial preferences | Minor style/formatting | `nitpick: Consider using single quotes` |
|
|
209
|
-
| `suggestion:` | Propose improvements | Better approach exists | `suggestion: Use map() instead of forEach()` |
|
|
210
|
-
| `issue:` | Highlight problems | Bug or technical issue | `issue: This will cause a memory leak` |
|
|
211
|
-
| `question:` | Ask for clarification | Need more information | `question: Why is this timeout set to 5000ms?` |
|
|
212
|
-
| `todo:` | Small necessary changes | Must be addressed | `todo: Add error handling for null case` |
|
|
213
|
-
| `chore:` | Process/documentation tasks | Non-code updates needed | `chore: Update API docs before merging` |
|
|
214
|
-
|
|
215
|
-
### Decorations
|
|
216
|
-
|
|
217
|
-
Use decorations in parentheses to provide additional context:
|
|
218
|
-
|
|
219
|
-
| Decoration | Meaning | Impact |
|
|
220
|
-
|------------|---------|--------|
|
|
221
|
-
| `(non-blocking)` | Optional feedback | Does not prevent approval |
|
|
222
|
-
| `(blocking)` | Required change | Must be resolved before merge |
|
|
223
|
-
| `(if-minor)` | Conditional | Resolve only if changes are small |
|
|
224
|
-
|
|
225
|
-
### Review Comment Guidelines
|
|
226
|
-
|
|
227
|
-
| Scenario | ✅ Do | ❌ Don't |
|
|
228
|
-
|----------|------|---------|
|
|
229
|
-
| **Suggesting improvements** | `suggestion: Extract this logic into a separate function for better readability` | `This code is bad` |
|
|
230
|
-
| **Asking questions** | `question (non-blocking): Why did we choose setTimeout instead of setInterval here?` | `Why setTimeout??` |
|
|
231
|
-
| **Reporting issues** | `issue (blocking): This will cause a null pointer exception when user is undefined` | `This will crash` |
|
|
232
|
-
| **Style preferences** | `nitpick (non-blocking): Consider using single quotes for consistency with the rest of the codebase` | `Use single quotes` |
|
|
233
|
-
| **Praising code** | `praise: Excellent test coverage and edge case handling!` | `Good job` |
|
|
234
|
-
| **Requesting changes** | `todo: Add JSDoc comment for this public API method` | `Add comment` |
|
|
235
|
-
|
|
236
|
-
Reference: [Conventional Comments](https://conventionalcomments.org)
|
|
237
|
-
|
|
238
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
239
|
-
|
|
240
|
-
## 6. Clean Code (TypeScript)
|
|
241
|
-
We follow **Clean Code** principles adapted for TypeScript to produce readable, reusable, and refactorable software.
|
|
242
|
-
|
|
243
|
-
### Variables
|
|
244
|
-
|
|
245
|
-
| ✅ Do | ❌ Don't |
|
|
246
|
-
|------|---------|
|
|
247
|
-
| Use meaningful and pronounceable names | Use cryptic abbreviations |
|
|
248
|
-
| Use searchable named constants | Use magic numbers or strings |
|
|
249
|
-
| Use explanatory variables | Use mental mapping |
|
|
250
|
-
| Use default arguments | Use short circuiting for defaults |
|
|
251
|
-
| Use the same vocabulary for the same type | Use different names for the same concept |
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
// ❌ Bad
|
|
255
|
-
const d = 86400000;
|
|
256
|
-
function between<T>(a1: T, a2: T, a3: T): boolean {
|
|
257
|
-
return a2 <= a1 && a1 <= a3;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// ✅ Good
|
|
261
|
-
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
262
|
-
function between<T>(value: T, left: T, right: T): boolean {
|
|
263
|
-
return left <= value && value <= right;
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Functions
|
|
268
|
-
|
|
269
|
-
| ✅ Do | ❌ Don't |
|
|
270
|
-
|------|---------|
|
|
271
|
-
| Keep arguments to 2 or fewer (use objects for more) | Pass many individual arguments |
|
|
272
|
-
| Make functions do one thing | Make functions handle multiple responsibilities |
|
|
273
|
-
| Use descriptive names that say what they do | Use vague or misleading names |
|
|
274
|
-
| Keep one level of abstraction per function | Mix levels of abstraction |
|
|
275
|
-
| Remove duplicate code | Copy-paste similar logic |
|
|
276
|
-
|
|
277
|
-
```typescript
|
|
278
|
-
// ❌ Bad
|
|
279
|
-
function createMenu(title: string, body: string, buttonText: string, cancellable: boolean) {
|
|
280
|
-
// ...
|
|
281
|
-
}
|
|
282
|
-
createMenu('Foo', 'Bar', 'Baz', true);
|
|
283
|
-
|
|
284
|
-
// ✅ Good
|
|
285
|
-
type MenuOptions = {
|
|
286
|
-
title: string;
|
|
287
|
-
body: string;
|
|
288
|
-
buttonText: string;
|
|
289
|
-
cancellable: boolean;
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
function createMenu(options: MenuOptions) {
|
|
293
|
-
// ...
|
|
294
|
-
}
|
|
295
|
-
createMenu({ title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: true });
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Objects and Data Structures
|
|
299
|
-
|
|
300
|
-
| ✅ Do | ❌ Don't |
|
|
301
|
-
|------|---------|
|
|
302
|
-
| Use getters and setters with encapsulation | Access properties directly without control |
|
|
303
|
-
| Use `readonly` for properties that should not change | Leave immutable properties mutable |
|
|
304
|
-
| Use type aliases and interfaces for clarity | Use inline complex types repeatedly |
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
// ❌ Bad
|
|
308
|
-
type Car = {
|
|
309
|
-
carMake: string;
|
|
310
|
-
carModel: string;
|
|
311
|
-
carColor: string;
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
// ✅ Good
|
|
315
|
-
type Car = {
|
|
316
|
-
make: string;
|
|
317
|
-
model: string;
|
|
318
|
-
color: string;
|
|
319
|
-
};
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
### Classes
|
|
323
|
-
|
|
324
|
-
| ✅ Do | ❌ Don't |
|
|
325
|
-
|------|---------|
|
|
326
|
-
| Prefer composition over inheritance | Overuse inheritance hierarchies |
|
|
327
|
-
| Use method chaining when appropriate | Ignore fluent interfaces for builder-like classes |
|
|
328
|
-
| Use `readonly` and access modifiers (`private`, `protected`) | Leave all class members public by default |
|
|
329
|
-
|
|
330
|
-
```typescript
|
|
331
|
-
// ❌ Bad
|
|
332
|
-
class Dashboard {
|
|
333
|
-
getData() { /* ... */ }
|
|
334
|
-
renderChart() { /* ... */ }
|
|
335
|
-
handleClick() { /* ... */ }
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// ✅ Good (Single Responsibility)
|
|
339
|
-
class DashboardData {
|
|
340
|
-
getData() { /* ... */ }
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
class DashboardRenderer {
|
|
344
|
-
renderChart(data: DashboardData) { /* ... */ }
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### SOLID
|
|
349
|
-
|
|
350
|
-
| Principle | Description |
|
|
351
|
-
|-----------|-------------|
|
|
352
|
-
| **S**ingle Responsibility | A class should have only one reason to change |
|
|
353
|
-
| **O**pen/Closed | Open for extension, closed for modification |
|
|
354
|
-
| **L**iskov Substitution | Subtypes must be substitutable for their base types |
|
|
355
|
-
| **I**nterface Segregation | No client should depend on methods it does not use |
|
|
356
|
-
| **D**ependency Inversion | Depend on abstractions, not concretions |
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
// ❌ Bad (violates Interface Segregation)
|
|
360
|
-
interface Worker {
|
|
361
|
-
work(): void;
|
|
362
|
-
eat(): void;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// ✅ Good
|
|
366
|
-
interface Workable {
|
|
367
|
-
work(): void;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
interface Feedable {
|
|
371
|
-
eat(): void;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
class HumanWorker implements Workable, Feedable {
|
|
375
|
-
work() { /* ... */ }
|
|
376
|
-
eat() { /* ... */ }
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
class RobotWorker implements Workable {
|
|
380
|
-
work() { /* ... */ }
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### Error Handling
|
|
385
|
-
|
|
386
|
-
| ✅ Do | ❌ Don't |
|
|
387
|
-
|------|---------|
|
|
388
|
-
| Use typed exceptions or error classes | Throw plain strings |
|
|
389
|
-
| Always handle caught errors | Leave empty catch blocks |
|
|
390
|
-
| Use `Error` types for thrown values | Throw non-Error values |
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
// ❌ Bad
|
|
394
|
-
throw 'Something went wrong';
|
|
395
|
-
|
|
396
|
-
// ✅ Good
|
|
397
|
-
class HttpError extends Error {
|
|
398
|
-
constructor(public statusCode: number, message: string) {
|
|
399
|
-
super(message);
|
|
400
|
-
this.name = 'HttpError';
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
throw new HttpError(404, 'User not found');
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Testing
|
|
408
|
-
|
|
409
|
-
| ✅ Do | ❌ Don't |
|
|
410
|
-
|------|---------|
|
|
411
|
-
| Test one concept per test | Test multiple concepts in one test |
|
|
412
|
-
| Use descriptive test names | Use vague test names |
|
|
413
|
-
| Follow Arrange-Act-Assert (AAA) pattern | Mix setup, action, and verification |
|
|
414
|
-
|
|
415
|
-
```typescript
|
|
416
|
-
// ❌ Bad
|
|
417
|
-
describe('User', () => {
|
|
418
|
-
it('should work', () => {
|
|
419
|
-
// tests multiple things at once
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
// ✅ Good
|
|
424
|
-
describe('User', () => {
|
|
425
|
-
it('should throw when name is empty', () => {
|
|
426
|
-
expect(() => new User('')).toThrow(ValidationError);
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
it('should set the name correctly', () => {
|
|
430
|
-
const user = new User('John');
|
|
431
|
-
expect(user.name).toBe('John');
|
|
432
|
-
});
|
|
433
|
-
});
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
Reference: [Clean Code TypeScript](https://github.com/labs42io/clean-code-typescript)
|
|
437
|
-
|
|
438
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
439
|
-
|
|
440
|
-
## 7. TypeScript Rules (ESLint)
|
|
441
|
-
We use **ESLint** with **typescript-eslint** to enforce code quality and catch common mistakes at compile time.
|
|
442
|
-
|
|
443
|
-
### Recommended Rules
|
|
444
|
-
|
|
445
|
-
| Rule | Description | Why |
|
|
446
|
-
|------|-------------|-----|
|
|
447
|
-
| `@typescript-eslint/no-explicit-any` | Disallow the `any` type | Encourages proper typing over escape hatches |
|
|
448
|
-
| `@typescript-eslint/explicit-function-return-type` | Require return types on functions | Improves readability and prevents unintended return types |
|
|
449
|
-
| `@typescript-eslint/no-unused-vars` | Disallow unused variables | Keeps code clean and avoids dead code |
|
|
450
|
-
| `@typescript-eslint/consistent-type-imports` | Enforce `import type` for type-only imports | Ensures types are erased at compile time |
|
|
451
|
-
| `@typescript-eslint/no-floating-promises` | Require promises to be handled | Prevents silently ignored async errors |
|
|
452
|
-
| `@typescript-eslint/strict-boolean-expressions` | Disallow implicit boolean coercions | Avoids truthy/falsy bugs with strings, numbers, and nulls |
|
|
453
|
-
| `@typescript-eslint/naming-convention` | Enforce naming conventions | Ensures consistent casing across the codebase |
|
|
454
|
-
| `@typescript-eslint/no-non-null-assertion` | Disallow non-null assertions (`!`) | Encourages proper null checks instead of overrides |
|
|
455
|
-
| `@typescript-eslint/no-misused-promises` | Disallow passing promises where not expected | Prevents async bugs in callbacks and conditionals |
|
|
456
|
-
| `@typescript-eslint/prefer-nullish-coalescing` | Prefer `??` over logical OR for nullish values | Avoids unintended falsy coercion with `0`, `""`, or `false` |
|
|
457
|
-
|
|
458
|
-
### Example ESLint Configuration
|
|
459
|
-
|
|
460
|
-
```javascript
|
|
461
|
-
// eslint.config.mjs
|
|
462
|
-
import eslint from '@eslint/js';
|
|
463
|
-
import tseslint from 'typescript-eslint';
|
|
464
|
-
|
|
465
|
-
export default tseslint.config(
|
|
466
|
-
eslint.configs.recommended,
|
|
467
|
-
...tseslint.configs.strictTypeChecked,
|
|
468
|
-
...tseslint.configs.stylisticTypeChecked,
|
|
469
|
-
{
|
|
470
|
-
languageOptions: {
|
|
471
|
-
parserOptions: {
|
|
472
|
-
projectService: true,
|
|
473
|
-
tsconfigRootDir: import.meta.dirname,
|
|
474
|
-
},
|
|
475
|
-
},
|
|
476
|
-
rules: {
|
|
477
|
-
'@typescript-eslint/no-explicit-any': 'error',
|
|
478
|
-
'@typescript-eslint/explicit-function-return-type': 'warn',
|
|
479
|
-
'@typescript-eslint/no-unused-vars': [
|
|
480
|
-
'error',
|
|
481
|
-
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
|
482
|
-
],
|
|
483
|
-
'@typescript-eslint/consistent-type-imports': [
|
|
484
|
-
'error',
|
|
485
|
-
{ prefer: 'type-imports' },
|
|
486
|
-
],
|
|
487
|
-
'@typescript-eslint/no-floating-promises': 'error',
|
|
488
|
-
'@typescript-eslint/strict-boolean-expressions': 'warn',
|
|
489
|
-
'@typescript-eslint/naming-convention': [
|
|
490
|
-
'error',
|
|
491
|
-
{ selector: 'variable', format: ['camelCase', 'UPPER_CASE', 'PascalCase'] },
|
|
492
|
-
{ selector: 'function', format: ['camelCase', 'PascalCase'] },
|
|
493
|
-
{ selector: 'typeLike', format: ['PascalCase'] },
|
|
494
|
-
],
|
|
495
|
-
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
496
|
-
'@typescript-eslint/no-misused-promises': 'error',
|
|
497
|
-
'@typescript-eslint/prefer-nullish-coalescing': 'warn',
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
);
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
### TypeScript Compiler Options
|
|
504
|
-
|
|
505
|
-
Pair ESLint rules with strict TypeScript compiler settings for maximum safety:
|
|
506
|
-
|
|
507
|
-
```jsonc
|
|
508
|
-
// tsconfig.json
|
|
509
|
-
{
|
|
510
|
-
"compilerOptions": {
|
|
511
|
-
"strict": true,
|
|
512
|
-
"noUncheckedIndexedAccess": true,
|
|
513
|
-
"noImplicitOverride": true,
|
|
514
|
-
"noPropertyAccessFromIndexSignature": true,
|
|
515
|
-
"forceConsistentCasingInFileNames": true,
|
|
516
|
-
"verbatimModuleSyntax": true,
|
|
517
|
-
"exactOptionalPropertyTypes": true
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
Reference: [typescript-eslint](https://typescript-eslint.io) · [TSConfig Reference](https://www.typescriptlang.org/tsconfig)
|
|
523
|
-
|
|
524
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
525
|
-
|
|
526
|
-
## 8. Code Formatting
|
|
527
|
-
We use **Prettier** for automatic code formatting and **EditorConfig** for consistent editor settings across IDEs.
|
|
528
|
-
|
|
529
|
-
### Prettier Configuration
|
|
530
|
-
|
|
531
|
-
```jsonc
|
|
532
|
-
// .prettierrc
|
|
533
|
-
{
|
|
534
|
-
"semi": false,
|
|
535
|
-
"singleQuote": true,
|
|
536
|
-
"trailingComma": "none",
|
|
537
|
-
"printWidth": 100,
|
|
538
|
-
"tabWidth": 2,
|
|
539
|
-
"useTabs": false,
|
|
540
|
-
"bracketSpacing": true,
|
|
541
|
-
"arrowParens": "always",
|
|
542
|
-
"endOfLine": "lf"
|
|
543
|
-
}
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
### EditorConfig
|
|
547
|
-
|
|
548
|
-
```ini
|
|
549
|
-
# .editorconfig
|
|
550
|
-
root = true
|
|
551
|
-
|
|
552
|
-
[*]
|
|
553
|
-
charset = utf-8
|
|
554
|
-
indent_style = space
|
|
555
|
-
indent_size = 2
|
|
556
|
-
end_of_line = lf
|
|
557
|
-
trim_trailing_whitespace = true
|
|
558
|
-
insert_final_newline = true
|
|
559
|
-
|
|
560
|
-
[*.md]
|
|
561
|
-
trim_trailing_whitespace = false
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
### Formatting Guidelines
|
|
565
|
-
|
|
566
|
-
| ✅ Do | ❌ Don't |
|
|
567
|
-
|------|---------|
|
|
568
|
-
| Use Prettier to format all TypeScript/JavaScript files | Format code manually or inconsistently |
|
|
569
|
-
| Run formatting on save or as a pre-commit hook | Commit unformatted code |
|
|
570
|
-
| Use `.prettierignore` to skip generated files | Format auto-generated or third-party code |
|
|
571
|
-
| Keep Prettier and ESLint configs compatible | Use ESLint for formatting rules (use Prettier instead) |
|
|
572
|
-
| Share `.editorconfig` in the repository | Rely on individual IDE settings |
|
|
573
|
-
|
|
574
|
-
### Pre-commit Hook (lint-staged)
|
|
575
|
-
|
|
576
|
-
Automate formatting and linting before each commit:
|
|
577
|
-
|
|
578
|
-
```jsonc
|
|
579
|
-
// package.json
|
|
580
|
-
{
|
|
581
|
-
"lint-staged": {
|
|
582
|
-
"*.{ts,tsx}": ["prettier --write", "eslint --fix"],
|
|
583
|
-
"*.{json,md,yaml}": ["prettier --write"]
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
Reference: [Prettier](https://prettier.io) · [EditorConfig](https://editorconfig.org) · [lint-staged](https://github.com/lint-staged/lint-staged)
|
|
589
|
-
|
|
590
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
591
|
-
|
|
592
|
-
## 9. JSON:API Overview
|
|
593
|
-
We follow the **JSON:API** specification to build consistent, efficient, and predictable RESTful APIs.
|
|
594
|
-
|
|
595
|
-
### Document Structure
|
|
596
|
-
A JSON:API response uses a standardized top-level structure:
|
|
597
|
-
|
|
598
|
-
```json
|
|
599
|
-
{
|
|
600
|
-
"data": {},
|
|
601
|
-
"included": [],
|
|
602
|
-
"meta": {},
|
|
603
|
-
"links": {},
|
|
604
|
-
"errors": [],
|
|
605
|
-
"jsonapi": {}
|
|
606
|
-
}
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
| Member | Purpose | Required |
|
|
610
|
-
|--------|---------|----------|
|
|
611
|
-
| `data` | Primary resource or collection | Yes (for successful responses) |
|
|
612
|
-
| `errors` | Array of error objects | Yes (for error responses) |
|
|
613
|
-
| `meta` | Non-standard meta-information | No |
|
|
614
|
-
| `links` | URLs for pagination and navigation | No |
|
|
615
|
-
| `included` | Related resources (compound documents) | No |
|
|
616
|
-
| `jsonapi` | Server implementation info | No |
|
|
617
|
-
|
|
618
|
-
### Resource Objects
|
|
619
|
-
Every resource must have a `type` and `id`. Attributes and relationships are placed in their respective members.
|
|
620
|
-
|
|
621
|
-
```json
|
|
622
|
-
{
|
|
623
|
-
"data": {
|
|
624
|
-
"type": "articles",
|
|
625
|
-
"id": "1",
|
|
626
|
-
"attributes": {
|
|
627
|
-
"title": "JSON:API Overview",
|
|
628
|
-
"body": "A guide to the JSON:API specification."
|
|
629
|
-
},
|
|
630
|
-
"relationships": {
|
|
631
|
-
"author": {
|
|
632
|
-
"data": { "type": "people", "id": "9" }
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
"links": {
|
|
636
|
-
"self": "https://example.com/articles/1"
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
### Relationships
|
|
643
|
-
Use the `relationships` member to express connections between resources.
|
|
644
|
-
|
|
645
|
-
| Type | Description | Example |
|
|
646
|
-
|------|-------------|---------|
|
|
647
|
-
| To-one | Links to a single related resource | `"author": { "data": { "type": "people", "id": "9" } }` |
|
|
648
|
-
| To-many | Links to multiple related resources | `"comments": { "data": [{ "type": "comments", "id": "5" }, { "type": "comments", "id": "12" }] }` |
|
|
649
|
-
|
|
650
|
-
Include related resources in the same response using the `included` array to reduce round-trips:
|
|
651
|
-
|
|
652
|
-
```json
|
|
653
|
-
{
|
|
654
|
-
"data": {
|
|
655
|
-
"type": "articles",
|
|
656
|
-
"id": "1",
|
|
657
|
-
"relationships": {
|
|
658
|
-
"author": {
|
|
659
|
-
"data": { "type": "people", "id": "9" }
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
},
|
|
663
|
-
"included": [
|
|
664
|
-
{
|
|
665
|
-
"type": "people",
|
|
666
|
-
"id": "9",
|
|
667
|
-
"attributes": {
|
|
668
|
-
"name": "John Doe"
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
]
|
|
672
|
-
}
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
### Links
|
|
676
|
-
Use `links` for discoverability and navigation. They can appear at the top level, per resource, or per relationship.
|
|
677
|
-
|
|
678
|
-
| Link | Purpose | Example |
|
|
679
|
-
|------|---------|---------|
|
|
680
|
-
| `self` | URL of the current resource or relationship | `"self": "https://example.com/articles/1"` |
|
|
681
|
-
| `related` | URL of a related resource | `"related": "https://example.com/articles/1/author"` |
|
|
682
|
-
| `first` | First page of a collection | `"first": "https://example.com/articles?page[number]=1"` |
|
|
683
|
-
| `last` | Last page of a collection | `"last": "https://example.com/articles?page[number]=10"` |
|
|
684
|
-
| `prev` | Previous page | `"prev": "https://example.com/articles?page[number]=3"` |
|
|
685
|
-
| `next` | Next page | `"next": "https://example.com/articles?page[number]=5"` |
|
|
686
|
-
|
|
687
|
-
### Error Objects
|
|
688
|
-
Error responses must use the `errors` array instead of `data`:
|
|
689
|
-
|
|
690
|
-
```json
|
|
691
|
-
{
|
|
692
|
-
"errors": [
|
|
693
|
-
{
|
|
694
|
-
"status": "404",
|
|
695
|
-
"title": "Resource Not Found",
|
|
696
|
-
"detail": "The article with id '99' does not exist.",
|
|
697
|
-
"source": {
|
|
698
|
-
"pointer": "/data/attributes/article"
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
]
|
|
702
|
-
}
|
|
703
|
-
```
|
|
704
|
-
|
|
705
|
-
### API Design Guidelines
|
|
706
|
-
|
|
707
|
-
| ✅ Do | ❌ Don't |
|
|
708
|
-
|------|---------|
|
|
709
|
-
| Use plural resource type names (`articles`, `users`) | Use singular names (`article`, `user`) |
|
|
710
|
-
| Use `attributes` for resource data | Place attributes at the root of the resource object |
|
|
711
|
-
| Use `relationships` to express connections | Nest related resources directly inside `attributes` |
|
|
712
|
-
| Return compound documents with `included` to reduce requests | Require separate requests for every related resource |
|
|
713
|
-
| Use `links` for pagination and discoverability | Hardcode URLs on the client side |
|
|
714
|
-
| Return errors in the `errors` array with `status`, `title`, and `detail` | Return plain text error messages |
|
|
715
|
-
| Use `meta` for non-standard information (e.g., total count) | Add custom top-level members outside the spec |
|
|
716
|
-
| Use sparse fieldsets (`?fields[articles]=title,body`) to limit response size | Always return all fields for every resource |
|
|
717
|
-
| Use `type` and `id` to uniquely identify every resource | Omit `type` or `id` from resource objects |
|
|
718
|
-
|
|
719
|
-
Reference: [JSON:API](https://jsonapi.org)
|
|
720
|
-
|
|
721
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
722
|
-
|
|
723
|
-
## 10. Go/No Go Release Step
|
|
724
|
-
A structured decision checkpoint that determines whether a release is ready to proceed to the production environment.
|
|
725
|
-
|
|
726
|
-
### Overview
|
|
727
|
-
The Go/No Go Release Step is a formal decision gate held after QA sign-off and before every production deployment. All required participants must align before the release proceeds.
|
|
728
|
-
|
|
729
|
-
### Decision Diagram
|
|
730
|
-
|
|
731
|
-
```mermaid
|
|
732
|
-
flowchart TD
|
|
733
|
-
A([QA Sign-off Complete]) --> B[Go/No Go Meeting]
|
|
734
|
-
B --> C{All Criteria Met?}
|
|
735
|
-
C -- Yes --> D[✅ GO — Proceed to Release]
|
|
736
|
-
C -- No --> E[🚫 NO GO — Block Release]
|
|
737
|
-
D --> F[Deploy to Production]
|
|
738
|
-
F --> G[Monitor & Verify in Production]
|
|
739
|
-
E --> H[Log Blocking Issues]
|
|
740
|
-
H --> I[Assign & Resolve Issues]
|
|
741
|
-
I --> B
|
|
742
|
-
```
|
|
743
|
-
|
|
744
|
-
### Participants
|
|
745
|
-
|
|
746
|
-
| Role | Responsibility |
|
|
747
|
-
|------|---------------|
|
|
748
|
-
| **Tech Lead** | Final decision authority; ensures technical readiness |
|
|
749
|
-
| **Developer** | Confirms implementation completeness and deployment steps |
|
|
750
|
-
| **QA Engineer** | Confirms all test cases passed and no critical defects remain |
|
|
751
|
-
| **Product Manager / Owner** | Confirms business requirements and stakeholder readiness |
|
|
752
|
-
|
|
753
|
-
### Go/No Go Checklist
|
|
754
|
-
|
|
755
|
-
All items must be **✅ Go** for the release to proceed. A single **🚫 No Go** item blocks the release.
|
|
756
|
-
|
|
757
|
-
#### Code & Build
|
|
758
|
-
| Criteria | Status |
|
|
759
|
-
|----------|--------|
|
|
760
|
-
| All PRs merged to the release branch | ✅ / 🚫 |
|
|
761
|
-
| CI/CD pipeline passes (build, lint, tests) | ✅ / 🚫 |
|
|
762
|
-
| No known critical or high-severity bugs | ✅ / 🚫 |
|
|
763
|
-
|
|
764
|
-
#### Testing
|
|
765
|
-
| Criteria | Status |
|
|
766
|
-
|----------|--------|
|
|
767
|
-
| All acceptance criteria verified by QA | ✅ / 🚫 |
|
|
768
|
-
| Regression tests passed | ✅ / 🚫 |
|
|
769
|
-
| Performance benchmarks within acceptable thresholds | ✅ / 🚫 |
|
|
770
|
-
|
|
771
|
-
#### Deployment Readiness
|
|
772
|
-
| Criteria | Status |
|
|
773
|
-
|----------|--------|
|
|
774
|
-
| Release notes drafted and reviewed | ✅ / 🚫 |
|
|
775
|
-
| Database migrations tested and ready | ✅ / 🚫 |
|
|
776
|
-
| Rollback plan documented and validated | ✅ / 🚫 |
|
|
777
|
-
| Environment configurations verified (env vars, secrets) | ✅ / 🚫 |
|
|
778
|
-
|
|
779
|
-
#### Stakeholder Alignment
|
|
780
|
-
| Criteria | Status |
|
|
781
|
-
|----------|--------|
|
|
782
|
-
| Product Owner has approved the release scope | ✅ / 🚫 |
|
|
783
|
-
| Support team has been briefed on changes | ✅ / 🚫 |
|
|
784
|
-
| Release window agreed upon by all participants | ✅ / 🚫 |
|
|
785
|
-
|
|
786
|
-
### Go — Proceed to Release
|
|
787
|
-
When all checklist items are ✅ Go:
|
|
788
|
-
1. Tech Lead officially declares **Go**.
|
|
789
|
-
2. Tag the release branch: `vX.Y.Z`.
|
|
790
|
-
3. Trigger the production deployment pipeline.
|
|
791
|
-
4. Monitor error rates, logs, and alerts post-deployment.
|
|
792
|
-
5. Confirm successful deployment and close the release ticket.
|
|
793
|
-
|
|
794
|
-
### No Go — Block Release
|
|
795
|
-
When any checklist item is 🚫 No Go:
|
|
796
|
-
1. Tech Lead officially declares **No Go** and states the blocking reason(s).
|
|
797
|
-
2. Blocking issues are logged with owner and target resolution date.
|
|
798
|
-
3. A follow-up Go/No Go meeting is scheduled once issues are resolved.
|
|
799
|
-
4. The release tag is **not** created until all items are ✅ Go.
|
|
800
|
-
|
|
801
|
-
### Decision Guidelines
|
|
802
|
-
|
|
803
|
-
| ✅ Go | 🚫 No Go |
|
|
804
|
-
|------|---------|
|
|
805
|
-
| All tests pass with no critical failures | Any critical or high-severity bug unresolved |
|
|
806
|
-
| Deployment steps are documented and rehearsed | Rollback plan is missing or untested |
|
|
807
|
-
| All participants confirmed their readiness | A required participant is unavailable or has not confirmed |
|
|
808
|
-
| Release window is a low-risk period | Release window conflicts with high-traffic or business-critical events |
|
|
809
|
-
| Feature flags in place for incomplete features | Incomplete features are exposed without a feature flag |
|
|
810
|
-
|
|
811
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
812
|
-
|
|
813
|
-
## 11. Deployment Guide (Semantic Versioning 2.0.0)
|
|
814
|
-
We follow **Semantic Versioning 2.0.0** (SemVer) to communicate the impact of every release clearly and predictably.
|
|
815
|
-
|
|
816
|
-
> **Company standard:** Prefix every semantic version with a lowercase `v` (e.g., `v1.2.3`) to indicate it is a version number. This is the conventional way to express a version in English and aligns with Git tagging practices.
|
|
817
|
-
|
|
818
|
-
### Version Format
|
|
819
|
-
|
|
820
|
-
```
|
|
821
|
-
vMAJOR.MINOR.PATCH
|
|
822
|
-
```
|
|
823
|
-
|
|
824
|
-
| Segment | Meaning | Example change |
|
|
825
|
-
|---------|---------|----------------|
|
|
826
|
-
| `MAJOR` | Incompatible API change | `v1.4.2` → `v2.0.0` |
|
|
827
|
-
| `MINOR` | Backwards-compatible new feature | `v1.4.2` → `v1.5.0` |
|
|
828
|
-
| `PATCH` | Backwards-compatible bug fix | `v1.4.2` → `v1.4.3` |
|
|
829
|
-
|
|
830
|
-
### Version Increment Rules
|
|
831
|
-
|
|
832
|
-
| Scenario | Increment | Example |
|
|
833
|
-
|----------|-----------|---------|
|
|
834
|
-
| Removing or renaming a public API, changing existing behaviour in a breaking way | MAJOR | `v2.0.0` |
|
|
835
|
-
| Adding a new feature without breaking existing functionality | MINOR | `v1.5.0` |
|
|
836
|
-
| Fixing a bug, applying a security patch, or making a performance improvement | PATCH | `v1.4.3` |
|
|
837
|
-
| Starting development of the next version after a release | Reset MINOR and PATCH to `0` when MAJOR bumps; reset PATCH to `0` when MINOR bumps | — |
|
|
838
|
-
|
|
839
|
-
### Pre-release Versions
|
|
840
|
-
|
|
841
|
-
Append a hyphen and a dot-separated identifier after the version core:
|
|
842
|
-
|
|
843
|
-
```
|
|
844
|
-
vMAJOR.MINOR.PATCH-<pre-release>
|
|
845
|
-
```
|
|
846
|
-
|
|
847
|
-
| Identifier | Purpose | Example |
|
|
848
|
-
|------------|---------|---------|
|
|
849
|
-
| `alpha` | Internal, early-stage testing | `v1.5.0` |
|
|
850
|
-
| `beta` | Feature-complete, wider testing | `v1.5.0-beta` |
|
|
851
|
-
| `rc.1`, `rc.2`, … | Release candidate, final verification | `v1.5.0-rc.1` |
|
|
852
|
-
|
|
853
|
-
Pre-release versions have **lower** precedence than the associated normal version:
|
|
854
|
-
`v1.5.0` < `v1.5.0-beta` < `v1.5.0-rc.1`
|
|
855
|
-
|
|
856
|
-
### Build Metadata
|
|
857
|
-
|
|
858
|
-
Append a plus sign and a dot-separated identifier for build information (ignored in precedence comparisons):
|
|
859
|
-
|
|
860
|
-
```
|
|
861
|
-
v1.5.0+20250401.sha.abc1234
|
|
862
|
-
```
|
|
863
|
-
|
|
864
|
-
Build metadata is informational only and is **not** used to determine version precedence.
|
|
865
|
-
|
|
866
|
-
### Tagging Convention
|
|
867
|
-
|
|
868
|
-
| ✅ Do | ❌ Don't |
|
|
869
|
-
|------|---------|
|
|
870
|
-
| Use `v` prefix on every tag: `v1.2.3` | Omit the prefix: `1.2.3` |
|
|
871
|
-
| Use all-lowercase identifiers: `v1.5.0` | Use mixed case: `v1.5.0` |
|
|
872
|
-
| Reset lower segments on increment: `v2.0.0` after a breaking change | Carry over old MINOR/PATCH: `v2.4.3` |
|
|
873
|
-
| Tag only verified, deployable commits | Tag commits that have not passed CI/CD |
|
|
874
|
-
| Use annotated tags with a release message | Use lightweight tags for production releases |
|
|
875
|
-
|
|
876
|
-
### Deployment Steps
|
|
877
|
-
|
|
878
|
-
#### Alpha Environment
|
|
879
|
-
1. Ensure all PRs for the sprint are merged into the `develop` branch.
|
|
880
|
-
2. Pull the latest `develop` branch.
|
|
881
|
-
3. Create and push an annotated pre-release tag:
|
|
882
|
-
```bash
|
|
883
|
-
git tag -a v1.5.0 -m "Release v1.5.0"
|
|
884
|
-
git push origin v1.5.0
|
|
885
|
-
```
|
|
886
|
-
4. The CI/CD pipeline deploys to the Alpha environment automatically.
|
|
887
|
-
5. Validate changes in Alpha and move tickets to **"Ready for QA"**.
|
|
888
|
-
|
|
889
|
-
#### Production Environment (after Go decision)
|
|
890
|
-
1. Confirm a **Go** decision from the [Go/No Go Release Step](#10-gono-go-release-step).
|
|
891
|
-
2. Pull the latest release branch.
|
|
892
|
-
3. Create a release on the project's repository.
|
|
893
|
-
4. The CI/CD pipeline deploys to the Production environment automatically.
|
|
894
|
-
5. Monitor error rates, logs, and alerts post-deployment.
|
|
895
|
-
6. Confirm successful deployment and close the release ticket.
|
|
896
|
-
|
|
897
|
-
### Version Precedence Examples
|
|
898
|
-
|
|
899
|
-
```
|
|
900
|
-
v1.0.0 < v1.0.0.1 < v1.0.0-beta < v1.0.0-rc.1 < v1.0.0
|
|
901
|
-
v1.0.0 < v1.0.1 < v1.1.0 < v2.0.0
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
Reference: [Semantic Versioning 2.0.0](https://semver.org)
|
|
905
|
-
|
|
906
|
-
[⬆ Back to Top](#codepassion-c9n)
|
|
907
|
-
|
|
908
|
-
---
|
|
909
|
-
|
|
910
|
-
Copyright: https://c9n.co
|
|
911
|
-
|
|
912
|
-
---
|
|
913
|
-
|
|
914
|
-
> **C9N** is a [numeronym](https://en.wikipedia.org/wiki/Numeronym) for **CodePassion**:
|
|
915
|
-
> **C** – o[1] – d[2] – e[3] – P[4] – a[5] – s[6] – s[7] – i[8] – o[9] – **N**
|
|
916
|
-
> (the 9 stands for the nine letters between the first letter **C** and the last letter **N**)
|
|
917
|
-
|
|
918
|
-
*The guidelines and conventions in this document are provided for informational purposes only. They represent the recommended practices of the CodePassion team and are subject to change. No warranty, expressed or implied, is made regarding the accuracy, completeness, or suitability of these guidelines for any particular purpose.*
|
|
16
|
+
Per-topic SKILL.md files in skills/c9n-* are the source of truth.
|
|
17
|
+
skills/c9n/SKILL.md is auto-generated — run npm run build.
|
|
18
|
+
npm test validates frontmatter against schemas/skill.schema.json.
|
|
19
|
+
CI runs the same on every push and PR.
|
package/SKILLS.md
CHANGED
|
@@ -4,10 +4,10 @@ Agent skills (SKILL.md) based on the CodePassion (C9N) conventions.
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
npx @codepassion/
|
|
8
|
-
npx @codepassion/
|
|
9
|
-
npx @codepassion/
|
|
10
|
-
npx @codepassion/
|
|
7
|
+
npx @codepassion/skills install claude # ~/.claude/skills
|
|
8
|
+
npx @codepassion/skills install codex # ~/.codex/skills
|
|
9
|
+
npx @codepassion/skills install project # ./.agents/skills
|
|
10
|
+
npx @codepassion/skills install combined # one combined skill
|
|
11
11
|
|
|
12
12
|
Or: ./install.sh {claude|codex|project|combined}
|
|
13
13
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codepassion/skills",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Agent skills (SKILL.md) for CodePassion (C9N) engineering conventions.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"c9n-skills": "bin/c9n-skills.js"
|
|
9
|
-
"skills": "bin/c9n-skills.js"
|
|
8
|
+
"c9n-skills": "./bin/c9n-skills.js"
|
|
10
9
|
},
|
|
11
10
|
"files": [
|
|
12
11
|
"bin",
|
|
@@ -15,13 +14,14 @@
|
|
|
15
14
|
"skills",
|
|
16
15
|
"install.sh",
|
|
17
16
|
"LICENSE",
|
|
18
|
-
"SKILLS.md"
|
|
17
|
+
"SKILLS.md",
|
|
18
|
+
"README.md"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "node scripts/build-combined.mjs",
|
|
22
22
|
"lint": "node scripts/lint-skills.mjs",
|
|
23
23
|
"test": "npm run build && npm run lint",
|
|
24
|
-
"prepack": "npm run build && npm run lint",
|
|
24
|
+
"prepack": "cp SKILLS.md README.md && npm run build && npm run lint",
|
|
25
25
|
"prepare": "husky || true"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
],
|
|
48
48
|
"repository": {
|
|
49
49
|
"type": "git",
|
|
50
|
-
"url": "
|
|
50
|
+
"url": "https://github.com/codepassion-team/c9n.git"
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://github.com/codepassion-team/c9n#readme",
|
|
53
53
|
"bugs": {
|