@vpnsin/devkit 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +318 -0
  2. package/bin/cli.js +431 -0
  3. package/commitlint/index.js +7 -0
  4. package/eslint/base.js +50 -0
  5. package/eslint/next.js +27 -0
  6. package/jest/index.js +20 -0
  7. package/lint-staged/index.js +8 -0
  8. package/package.json +80 -0
  9. package/prettier/index.js +11 -0
  10. package/templates/README.template.md +51 -0
  11. package/templates/app/backend/Dockerfile +24 -0
  12. package/templates/app/backend/dockerignore +7 -0
  13. package/templates/app/backend/env.example +2 -0
  14. package/templates/app/backend/src/app.ts +22 -0
  15. package/templates/app/backend/src/env.ts +8 -0
  16. package/templates/app/backend/src/routes/health.ts +7 -0
  17. package/templates/app/backend/src/server.ts +19 -0
  18. package/templates/app/frontend/app/globals.css +28 -0
  19. package/templates/app/frontend/app/layout.tsx +16 -0
  20. package/templates/app/frontend/app/page.tsx +10 -0
  21. package/templates/app/frontend/env.example +5 -0
  22. package/templates/app/frontend/next.config.mjs +6 -0
  23. package/templates/claude/skills/design-craft/SKILL.md +226 -0
  24. package/templates/cspell.json +30 -0
  25. package/templates/dependabot.yml +18 -0
  26. package/templates/editorconfig +15 -0
  27. package/templates/github/CODEOWNERS +12 -0
  28. package/templates/github/CONTRIBUTING.md +51 -0
  29. package/templates/github/ISSUE_TEMPLATE/bug_report.yml +34 -0
  30. package/templates/github/ISSUE_TEMPLATE/config.yml +5 -0
  31. package/templates/github/ISSUE_TEMPLATE/feature_request.yml +23 -0
  32. package/templates/github/PULL_REQUEST_TEMPLATE.md +27 -0
  33. package/templates/github/SECURITY.md +24 -0
  34. package/templates/github/workflows/ci.yml +55 -0
  35. package/templates/github/workflows/codeql.yml +35 -0
  36. package/templates/github/workflows/dependency-review.yml +23 -0
  37. package/templates/github/workflows/lighthouse.yml +39 -0
  38. package/templates/github/workflows/publish.yml +38 -0
  39. package/templates/github/workflows/release-please-publish.yml +54 -0
  40. package/templates/github/workflows/release-please.yml +22 -0
  41. package/templates/github/workflows/scorecard.yml +41 -0
  42. package/templates/github/workflows/sonarqube.yml +31 -0
  43. package/templates/github/workflows/trivy.yml +43 -0
  44. package/templates/husky/commit-msg +1 -0
  45. package/templates/husky/pre-commit +1 -0
  46. package/templates/lighthouserc.json +23 -0
  47. package/templates/markdownlint-cli2.jsonc +20 -0
  48. package/templates/npmrc +9 -0
  49. package/templates/nvmrc +1 -0
  50. package/templates/release-please-config.json +14 -0
  51. package/templates/sonar-project.properties +13 -0
  52. package/templates/vscode/extensions.json +53 -0
  53. package/templates/vscode/settings.json +70 -0
  54. package/tsconfig/base.json +17 -0
  55. package/tsconfig/next.json +16 -0
  56. package/tsconfig/node.json +14 -0
  57. package/vitest/index.js +22 -0
@@ -0,0 +1,51 @@
1
+ # Project Name
2
+
3
+ > One-line description of what this project does.
4
+
5
+ ## Features
6
+
7
+ - …
8
+ - …
9
+
10
+ ## Getting started
11
+
12
+ ### Prerequisites
13
+
14
+ - Node.js >= 18.18
15
+ - npm
16
+
17
+ ### Install
18
+
19
+ ```bash
20
+ npm install
21
+ ```
22
+
23
+ ### Develop
24
+
25
+ ```bash
26
+ npm run dev
27
+ ```
28
+
29
+ ## Scripts
30
+
31
+ | Script | Description |
32
+ | -------------------- | ---------------------------- |
33
+ | `npm run lint` | Lint with ESLint |
34
+ | `npm run format` | Format with Prettier |
35
+ | `npm run type-check` | Type-check with `tsc` |
36
+ | `npm run lint:md` | Lint Markdown |
37
+ | `npm run build` | Production build (if present)|
38
+
39
+ ## Contributing
40
+
41
+ See [CONTRIBUTING](.github/CONTRIBUTING.md). Commits follow
42
+ [Conventional Commits](https://www.conventionalcommits.org/); releases are
43
+ automated with release-please.
44
+
45
+ ## Security
46
+
47
+ See [SECURITY](.github/SECURITY.md) for how to report vulnerabilities.
48
+
49
+ ## License
50
+
51
+ <!-- e.g. MIT © Year Author -->
@@ -0,0 +1,24 @@
1
+ # syntax=docker/dockerfile:1
2
+
3
+ # ---- build ----
4
+ FROM node:22-alpine AS build
5
+ WORKDIR /app
6
+ COPY package*.json ./
7
+ RUN npm ci
8
+ COPY . .
9
+ RUN npm run build
10
+
11
+ # ---- runtime ----
12
+ FROM node:22-alpine AS runtime
13
+ WORKDIR /app
14
+ ENV NODE_ENV=production
15
+ COPY package*.json ./
16
+ RUN npm ci --omit=dev
17
+ COPY --from=build /app/dist ./dist
18
+ EXPOSE 3000
19
+ USER node
20
+
21
+ # Probe the /health route using Node's built-in fetch (no curl/wget needed).
22
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 CMD node -e "fetch('http://localhost:'+(process.env.PORT||3000)+'/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
23
+
24
+ CMD ["node", "dist/server.js"]
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ dist
3
+ .git
4
+ .github
5
+ .env
6
+ *.log
7
+ npm-debug.log*
@@ -0,0 +1,2 @@
1
+ NODE_ENV=development
2
+ PORT=3000
@@ -0,0 +1,22 @@
1
+ import express, { type Express } from 'express';
2
+ import cors from 'cors';
3
+ import helmet from 'helmet';
4
+ import { healthRouter } from './routes/health.js';
5
+
6
+ // App factory — keep it pure (no listen()) so tests can import and exercise it.
7
+ export function createApp(): Express {
8
+ const app = express();
9
+
10
+ app.use(helmet());
11
+ app.use(cors());
12
+ app.use(express.json());
13
+
14
+ app.use('/health', healthRouter);
15
+
16
+ // Fallback 404.
17
+ app.use((_req, res) => {
18
+ res.status(404).json({ error: 'Not found' });
19
+ });
20
+
21
+ return app;
22
+ }
@@ -0,0 +1,8 @@
1
+ import 'dotenv/config';
2
+
3
+ // Central, typed access to environment config. Extend with validation
4
+ // (e.g. zod) as the surface grows.
5
+ export const env = {
6
+ NODE_ENV: process.env.NODE_ENV ?? 'development',
7
+ PORT: Number(process.env.PORT ?? 3000),
8
+ } as const;
@@ -0,0 +1,7 @@
1
+ import { Router } from 'express';
2
+
3
+ export const healthRouter = Router();
4
+
5
+ healthRouter.get('/', (_req, res) => {
6
+ res.json({ status: 'ok', uptime: process.uptime() });
7
+ });
@@ -0,0 +1,19 @@
1
+ import { createApp } from './app.js';
2
+ import { env } from './env.js';
3
+
4
+ const app = createApp();
5
+
6
+ const server = app.listen(env.PORT, () => {
7
+ // eslint-disable-next-line no-console
8
+ console.log(`API listening on http://localhost:${env.PORT} (${env.NODE_ENV})`);
9
+ });
10
+
11
+ // Graceful shutdown so in-flight requests drain before the process exits.
12
+ function shutdown(signal: string): void {
13
+ // eslint-disable-next-line no-console
14
+ console.log(`${signal} received, shutting down…`);
15
+ server.close(() => process.exit(0));
16
+ }
17
+
18
+ process.on('SIGINT', () => shutdown('SIGINT'));
19
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
@@ -0,0 +1,28 @@
1
+ :root {
2
+ color-scheme: light dark;
3
+ }
4
+
5
+ * {
6
+ box-sizing: border-box;
7
+ }
8
+
9
+ html,
10
+ body {
11
+ margin: 0;
12
+ padding: 0;
13
+ font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
14
+ line-height: 1.5;
15
+ }
16
+
17
+ main {
18
+ max-width: 48rem;
19
+ margin: 0 auto;
20
+ padding: 4rem 1.5rem;
21
+ }
22
+
23
+ code {
24
+ font-family: ui-monospace, 'SFMono-Regular', Menlo, monospace;
25
+ background: rgba(127, 127, 127, 0.15);
26
+ padding: 0.1rem 0.35rem;
27
+ border-radius: 0.25rem;
28
+ }
@@ -0,0 +1,16 @@
1
+ import type { Metadata } from 'next';
2
+ import type { ReactNode } from 'react';
3
+ import './globals.css';
4
+
5
+ export const metadata: Metadata = {
6
+ title: 'App',
7
+ description: 'Bootstrapped with devkit',
8
+ };
9
+
10
+ export default function RootLayout({ children }: { children: ReactNode }) {
11
+ return (
12
+ <html lang="en">
13
+ <body>{children}</body>
14
+ </html>
15
+ );
16
+ }
@@ -0,0 +1,10 @@
1
+ export default function Home() {
2
+ return (
3
+ <main>
4
+ <h1>It works 🎉</h1>
5
+ <p>
6
+ Edit <code>app/page.tsx</code> and save to reload.
7
+ </p>
8
+ </main>
9
+ );
10
+ }
@@ -0,0 +1,5 @@
1
+ # Server-only secrets go here (never exposed to the browser).
2
+ # API_BASE_URL=http://localhost:3000
3
+
4
+ # Public vars MUST be prefixed with NEXT_PUBLIC_ to reach the client.
5
+ NEXT_PUBLIC_APP_NAME=My App
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ };
5
+
6
+ export default nextConfig;
@@ -0,0 +1,226 @@
1
+ ---
2
+ name: design-craft
3
+ description: >-
4
+ Elevate the user experience and visual design of the site. Use when polishing
5
+ UI, redesigning a page or section, adding motion/micro-interactions, tightening
6
+ typography/spacing/color, or auditing design quality. Runs three activity sets —
7
+ Define (taste & design language), Design (layout/type/color/space), Polish
8
+ (motion & micro-interactions) — then a Review gate. Works on Next.js + Tailwind
9
+ sites. Synthesises three skills: emilkowalski/skill, pbakaus/impeccable, and
10
+ Leonxlnx/taste-skill.
11
+ ---
12
+
13
+ # Design Craft
14
+
15
+ A three-phase protocol for making interfaces that feel **considered, premium, and
16
+ alive** — not generic AI "slop". It unifies three sources:
17
+
18
+ - **emilkowalski/skill** (`emil-design-eng`) — motion, micro-interaction, and the
19
+ invisible details that compound. _"All those unseen details combine to produce
20
+ something that's just stunning."_
21
+ - **pbakaus/impeccable** — design quality, consistency, and a concrete anti-pattern
22
+ catalogue. Plan (shape) before you build.
23
+ - **Leonxlnx/taste-skill** — anti-slop framework: infer the brief, tune taste dials,
24
+ map a coherent design system before coding.
25
+
26
+ **Taste is trained, not innate.** Study great work, reverse-engineer why it feels
27
+ right, and apply the concrete rules below rather than defaulting to the obvious.
28
+
29
+ ## How to use this skill
30
+
31
+ - **Full redesign of a page/section** → run Activity Sets 1 → 2 → 3, then Review.
32
+ - **Visual tweak** (spacing/type/color) → Activity Set 2 + Review.
33
+ - **Add/refine motion** → Activity Set 3 + Review.
34
+ - **"Make this feel better" / audit** → Review gate first to find issues, then the
35
+ relevant set to fix them.
36
+
37
+ Always **read the component and match the surrounding conventions** before editing,
38
+ and always finish with the Review gate. On these sites: Tailwind utilities + theme
39
+ tokens, `next/image`, mobile-first; verify at the dev server and keep
40
+ `type-check` / `lint` / `build` green.
41
+
42
+ ---
43
+
44
+ ## Activity Set 1 — Define (taste & design language)
45
+
46
+ _Establish intent before touching code (impeccable: context-first; taste: infer the brief)._
47
+
48
+ 1. **State the context** in one or two lines: audience, brand-vs-product, voice,
49
+ the single feeling the page should evoke. If the repo has a `DESIGN.md` /
50
+ `CLAUDE.md`, read it; otherwise infer from the existing site and say what you
51
+ inferred.
52
+ 2. **Tune three dials (1–10) and write them down** so choices are deliberate:
53
+ - **DESIGN_VARIANCE** — layout experimentation (low = centred/clean; high = asymmetric/editorial).
54
+ - **MOTION_INTENSITY** — animation depth (low = hover/press only; high = scroll-driven/magnetic).
55
+ - **VISUAL_DENSITY** — information per viewport (low = spacious; high = dense dashboard).
56
+ - _Premium eco / marketing brand (e.g. Flora Dine) default:_ variance **4**, motion **4**, density **3** — calm, trustworthy, spacious.
57
+ 3. **Map the design system** so everything is reused, not reinvented: type scale,
58
+ spacing rhythm (8px grid), colour tokens (already in the Tailwind theme),
59
+ radius, shadow, and the existing component inventory. New work must pull from
60
+ these tokens — no hard-coded hex or one-off spacing.
61
+
62
+ **Deliverable:** a 3–5 line direction (context + dials + the tokens you'll use).
63
+
64
+ ---
65
+
66
+ ## Activity Set 2 — Design (layout, type, colour, space)
67
+
68
+ _Shape the composition, then build it (impeccable + taste). Avoid generic patterns._
69
+
70
+ **Shape first.** Describe the layout and visual hierarchy in words before writing
71
+ JSX — what leads, what supports, where the eye goes.
72
+
73
+ **Typography**
74
+
75
+ - Clear scale with real hierarchy (don't size everything the same).
76
+ - Body line-height ≥ 1.5; tighten display headings.
77
+ - Avoid the obvious defaults for display type (Arial, system stack, and plain
78
+ **Inter** as the "AI default"). The brand font should do the talking.
79
+
80
+ **Colour**
81
+
82
+ - **Never pure black or pure gray** — always tint toward the brand (e.g. text is a
83
+ very dark brand-tinted neutral, not `#000`).
84
+ - **No gray text on coloured backgrounds** — it reads muddy; use a tint of the
85
+ background or an on-colour token.
86
+ - Maintain **4.5:1** contrast for text. Drive everything from theme tokens.
87
+
88
+ **Spacing & layout**
89
+
90
+ - 8px rhythm; treat white space as a design element, not leftover.
91
+ - Use the dials: raise variance with an asymmetric hero or offset grid when the
92
+ brand allows; keep density low for a premium feel.
93
+
94
+ **Avoid the "slop" tells** (taste + impeccable anti-patterns)
95
+
96
+ - Purple→blue "AI gradient"; bouncy/elastic easing; everything wrapped in cards;
97
+ **cards nested inside cards**; side-tab coloured borders; skipped heading levels;
98
+ undersized touch targets; centered-everything with no hierarchy.
99
+ - In UI microcopy, vary punctuation — don't lean on the em-dash as a verbal tic
100
+ (a common AI tell). Keep copy specific and human.
101
+
102
+ **Deliverable:** the built/edited section using tokens, with hierarchy that reads
103
+ at a glance and none of the anti-patterns above.
104
+
105
+ ---
106
+
107
+ ## Activity Set 3 — Polish (motion & micro-interactions)
108
+
109
+ _The emil-design-eng layer — where "fine" becomes "loved". This is the most concrete set._
110
+
111
+ ### Decide whether to animate at all
112
+
113
+ | Frequency | Decision |
114
+ | --- | --- |
115
+ | 100+×/day (keyboard, command palette) | **Never animate** |
116
+ | Tens×/day (hover, list nav) | Remove or drastically reduce |
117
+ | Occasional (modals, drawers, toasts) | Standard animation |
118
+ | Rare / first-time (onboarding, celebration) | Can add delight |
119
+
120
+ Every animation must answer **"why does this animate?"** — spatial consistency,
121
+ state indication, feedback, or preventing a jarring change. "Looks cool" + seen
122
+ often = don't.
123
+
124
+ ### Easing — use custom curves, never `ease-in` on UI
125
+
126
+ ```css
127
+ --ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* enter/exit */
128
+ --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* move/morph on screen */
129
+ --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* drawers/sheets */
130
+ ```
131
+
132
+ - Entering/exiting → `ease-out`. Moving/morphing → `ease-in-out`. Hover/colour →
133
+ `ease`. Constant motion → `linear`.
134
+ - **Never `ease-in`** on UI (delays the first frame users watch most). Built-in CSS
135
+ easings are too weak — use the curves above.
136
+
137
+ ### Duration — keep UI under 300ms
138
+
139
+ | Element | Duration |
140
+ | --- | --- |
141
+ | Button press feedback | 100–160ms |
142
+ | Tooltip / small popover | 125–200ms |
143
+ | Dropdown / select | 150–250ms |
144
+ | Modal / drawer | 200–500ms |
145
+
146
+ ### Core rules
147
+
148
+ - **Animate only `transform` and `opacity`** (GPU; skips layout/paint). Never
149
+ animate `width`/`height`/`margin`/`padding`/`top`/`left`.
150
+ - **Press feedback:** `:active { transform: scale(0.97) }` on pressable elements
151
+ (subtle, 0.95–0.98).
152
+ - **Never enter from `scale(0)`** — start `scale(0.95)` + `opacity: 0` (nothing in
153
+ reality appears from nothing).
154
+ - **Origin-aware popovers** scale from their trigger (`transform-origin`), not
155
+ center. **Modals stay centered.**
156
+ - **Asymmetric timing:** slow where the user is deciding (e.g. hold-to-delete 2s
157
+ linear), snappy where the system responds (200ms ease-out). Make exits a touch
158
+ faster than enters.
159
+ - **Stagger** list entries 30–80ms; never block interaction during a stagger.
160
+ - **Springs** for drag/gesture & "alive" elements (they keep velocity when
161
+ interrupted): Apple-style `{ type: 'spring', duration: 0.5, bounce: 0.2 }`; keep
162
+ bounce 0.1–0.3.
163
+ - Prefer **CSS transitions** over keyframes for interruptible UI; use `@starting-style`
164
+ for enter animations; reach for `clip-path` for reveals/wipes/comparison sliders.
165
+ - **Tailwind note:** these sites have `tailwindcss-animate`; for bespoke motion add a
166
+ token-based transition (`transition-transform duration-200 ease-[cubic-bezier(...)]`)
167
+ rather than `transition-all`.
168
+
169
+ ### Accessibility (non-negotiable)
170
+
171
+ - `@media (prefers-reduced-motion: reduce)` → keep opacity/colour, drop movement
172
+ (reduce, don't remove).
173
+ - Gate hover effects behind `@media (hover: hover) and (pointer: fine)` so touch
174
+ taps don't trigger them.
175
+
176
+ ---
177
+
178
+ ## Review gate (run before shipping)
179
+
180
+ Combine all three skills' checks. Produce findings as a **Before → After → Why**
181
+ markdown table (emil's required format), not prose bullets.
182
+
183
+ **Technical audit** (impeccable `audit`)
184
+
185
+ - A11y: 4.5:1 contrast, keyboard reachable + visible focus, real `<label>`s,
186
+ 44×44px targets, `prefers-reduced-motion` respected.
187
+ - Performance: only `transform`/`opacity` animated; no `transition: all`; images via
188
+ `next/image` with correct `sizes`.
189
+ - Responsive: no horizontal overflow and correct reflow at 480 / 768 / 1024 / 1440.
190
+
191
+ **Creative critique** (impeccable `critique` + taste pre-flight)
192
+
193
+ - Hierarchy reads at a glance; one clear focal point per view.
194
+ - Clarity of copy and CTAs; emotional resonance matches the brand feeling.
195
+ - **Cohesion:** easing, duration, and vibe are unified — motion matches mood
196
+ (playful can bounce; a premium brand stays crisp/calm).
197
+ - No "slop" tells from Activity Set 2 remain.
198
+
199
+ **Emil's code checklist** (fix on sight)
200
+
201
+ | Issue | Fix |
202
+ | --- | --- |
203
+ | `transition: all` | name the property: `transition: transform 200ms var(--ease-out)` |
204
+ | `scale(0)` entry | `scale(0.95)` + `opacity: 0` |
205
+ | `ease-in` on UI | `ease-out` / custom curve |
206
+ | `transform-origin: center` on popover | set to trigger (modals exempt) |
207
+ | Animation on a keyboard action | remove |
208
+ | Duration > 300ms on UI | reduce to 150–250ms |
209
+ | Hover without `@media (hover)` | add the media query |
210
+ | Same enter/exit speed | make the exit faster |
211
+ | Everything appears at once | add 30–80ms stagger |
212
+
213
+ **Then verify the build:** `npm run type-check`, `npm run lint`, `npm run build`,
214
+ and look at it on the dev server (responsive widths above).
215
+
216
+ ---
217
+
218
+ ## Set your project's defaults
219
+
220
+ Record the design direction once — in `CLAUDE.md` or a `DESIGN.md` — so every run
221
+ is consistent: the brand's one-line feeling, the three dial values, and the token
222
+ set to reuse. Then Activity Set 1 reads it instead of re-inferring each time.
223
+
224
+ > Example (premium / calm brand): dials variance **4** / motion **4** / density
225
+ > **3**; `ease-out` motion under ~250ms; lean on the existing theme tokens and the
226
+ > 8px grid.
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
3
+ "version": "0.2",
4
+ "language": "en",
5
+ "words": [
6
+ "commitlint",
7
+ "devkit",
8
+ "dotenv",
9
+ "esbenp",
10
+ "lintstagedrc",
11
+ "markdownlint",
12
+ "npmrc",
13
+ "nvmrc",
14
+ "tsup",
15
+ "unconfigured",
16
+ "vitest"
17
+ ],
18
+ "ignorePaths": [
19
+ "node_modules/**",
20
+ "dist/**",
21
+ "build/**",
22
+ "coverage/**",
23
+ ".next/**",
24
+ "*.log",
25
+ "package-lock.json",
26
+ "pnpm-lock.yaml",
27
+ "yarn.lock",
28
+ "CHANGELOG.md"
29
+ ]
30
+ }
@@ -0,0 +1,18 @@
1
+ version: 2
2
+ updates:
3
+ # npm dependencies
4
+ - package-ecosystem: npm
5
+ directory: /
6
+ schedule:
7
+ interval: weekly
8
+ open-pull-requests-limit: 5
9
+ groups:
10
+ # Batch low-risk updates into a single PR to cut noise.
11
+ minor-and-patch:
12
+ update-types: [minor, patch]
13
+
14
+ # GitHub Actions used in workflows
15
+ - package-ecosystem: github-actions
16
+ directory: /
17
+ schedule:
18
+ interval: weekly
@@ -0,0 +1,15 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+ indent_size = 2
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
13
+
14
+ [*.{bat,cmd}]
15
+ end_of_line = crlf
@@ -0,0 +1,12 @@
1
+ # Code owners are automatically requested for review on matching paths.
2
+ # Docs: https://docs.github.com/articles/about-code-owners
3
+ #
4
+ # Replace @OWNER with your username or team (e.g. @your-org/maintainers).
5
+
6
+ # Default owner for everything in the repo
7
+ * @OWNER
8
+
9
+ # Examples — uncomment and adjust:
10
+ # /.github/ @your-org/devops
11
+ # /src/api/ @your-org/backend
12
+ # *.md @your-org/docs
@@ -0,0 +1,51 @@
1
+ # Contributing
2
+
3
+ Thanks for contributing! This repository uses shared tooling from
4
+ [`devkit`](https://github.com/vpnsin/devkit) — ESLint, Prettier,
5
+ commitlint, markdownlint, Husky, and CI/release workflows.
6
+
7
+ ## Getting started
8
+
9
+ - **Node.js** >= 18.18 and **npm**
10
+ - `npm install` (sets up Git hooks via Husky automatically)
11
+
12
+ ## Development workflow
13
+
14
+ 1. Branch off `main` (or `dev`):
15
+ `git checkout -b feat/short-description`
16
+ 2. Make your changes. On commit, the pre-commit hook auto-formats and lints
17
+ staged files.
18
+ 3. Before pushing, verify locally:
19
+
20
+ ```bash
21
+ npm run type-check
22
+ npm run lint
23
+ npm run lint:md
24
+ npm run format:check
25
+ npm run build # if the repo has a build step
26
+ ```
27
+
28
+ ## Commit messages — Conventional Commits (required)
29
+
30
+ The `commit-msg` hook enforces them, and release-please uses them to compute the
31
+ version bump and changelog.
32
+
33
+ | Type | Effect |
34
+ | -------------------------------------------------------------------- | ------------- |
35
+ | `feat:` | minor release |
36
+ | `fix:` | patch release |
37
+ | `docs:` `chore:` `refactor:` `test:` `ci:` `build:` `perf:` `style:` | no release |
38
+ | `feat!:` / `BREAKING CHANGE:` footer | major release |
39
+
40
+ Example: `feat(auth): add password reset flow`
41
+
42
+ ## Pull requests
43
+
44
+ - Keep PRs focused and fill in the PR template.
45
+ - Make sure CI is green.
46
+ - A code owner (see `CODEOWNERS`) will review and merge.
47
+
48
+ ## Releases
49
+
50
+ Merging to `main` opens or updates a **release-please** PR. Merging that PR
51
+ publishes the GitHub release, tag, and changelog.
@@ -0,0 +1,34 @@
1
+ name: Bug report
2
+ description: Report a problem so we can fix it
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened?
9
+ description: A clear description of the bug and what you expected instead.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: repro
14
+ attributes:
15
+ label: Steps to reproduce
16
+ placeholder: |
17
+ 1. Go to '...'
18
+ 2. Run '...'
19
+ 3. See error
20
+ validations:
21
+ required: true
22
+ - type: input
23
+ id: version
24
+ attributes:
25
+ label: Version / environment
26
+ description: Package version, Node version, OS.
27
+ validations:
28
+ required: true
29
+ - type: textarea
30
+ id: logs
31
+ attributes:
32
+ label: Logs / screenshots
33
+ description: Relevant output (will be rendered as code).
34
+ render: shell
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security vulnerability
4
+ url: https://github.com/vpnsin/devkit/security/advisories/new
5
+ about: Please report security issues privately, not as public issues.
@@ -0,0 +1,23 @@
1
+ name: Feature request
2
+ description: Suggest an idea or improvement
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What problem does this solve? What's the use case?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ description: What would you like to happen?
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: Alternatives considered
23
+ description: Other approaches you've thought about.
@@ -0,0 +1,27 @@
1
+ <!-- PR title MUST be a Conventional Commit, e.g. "feat: add X" or "fix: handle Y"
2
+ — release-please reads it to compute the version bump and changelog. -->
3
+
4
+ ## Summary
5
+
6
+ <!-- What does this PR change, and why? Link any issue: Closes #123 -->
7
+
8
+ ## Type of change
9
+
10
+ - [ ] `feat` — new feature (minor bump)
11
+ - [ ] `fix` — bug fix (patch bump)
12
+ - [ ] `refactor` — no behaviour change
13
+ - [ ] `docs` — documentation only
14
+ - [ ] `chore` / `ci` / `build` — tooling, deps, config
15
+ - [ ] `perf` / `style` / `test`
16
+
17
+ ## Checklist
18
+
19
+ - [ ] PR title is a Conventional Commit (`feat:`, `fix:`, `chore:` …)
20
+ - [ ] `npm run type-check` passes
21
+ - [ ] `npm run lint` passes (+ `npm run lint:md` if docs changed)
22
+ - [ ] `npm run build` succeeds (if applicable)
23
+ - [ ] No secrets committed (env values stay in the deploy platform / local `.env`)
24
+
25
+ ## Screenshots / notes
26
+
27
+ <!-- Before/after for UI changes; migration notes; follow-ups -->