start-vibing-stacks 2.15.0 → 2.17.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "start-vibing-stacks",
3
- "version": "2.15.0",
3
+ "version": "2.17.0",
4
4
  "description": "AI-powered multi-stack dev workflow for Claude Code. Supports PHP, Node.js, Python and more.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,52 +1,205 @@
1
1
  ---
2
2
  name: docker-patterns
3
- version: 1.0.0
3
+ version: 2.0.0
4
+ description: "Docker patterns for 2026: BuildKit + Buildx Bake (default builder for Docker Compose since June 2025), multi-stage builds, distroless / chiseled bases (90% size reduction, no shell), non-root users, .dockerignore, healthchecks, additional_contexts for service deps, secrets via build mounts (not COPY), reproducible builds. Stack examples: Node 22, Python 3.13 (uv), PHP 8.4 (FPM + Nginx)."
4
5
  ---
5
6
 
6
- # Docker Patterns
7
+ # Docker Patterns (2026)
7
8
 
8
- ## PHP (PHP-FPM + Nginx)
9
+ **Invoke when writing or modifying any `Dockerfile`, `docker-compose.yml`, `docker-bake.hcl`, or container build config.**
9
10
 
10
- ```dockerfile
11
- FROM php:8.3-fpm-alpine
11
+ > 2026 reality: BuildKit is the only builder; Bake is the default for Compose multi-image projects (since June 2025); distroless / chiseled bases are the default for production runtime; non-root + readonly rootfs is the default. **Anything else needs justification.**
12
12
 
13
- RUN apk add --no-cache \
14
- libzip-dev \
15
- && docker-php-ext-install pdo_mysql zip opcache
13
+ ## 1. The four non-negotiables
16
14
 
17
- COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
18
- COPY . /var/www/html
19
- WORKDIR /var/www/html
15
+ 1. **Multi-stage build** — separate build deps from runtime deps. No exceptions.
16
+ 2. **Distroless or chiseled runtime** — no shell, no package manager, no curl. ~2 MB instead of ~120 MB.
17
+ 3. **Non-root user** — `USER 10001:10001` in the runtime stage. Never `root`.
18
+ 4. **`.dockerignore`** — at minimum: `node_modules`, `vendor`, `.git`, `.env*`, `*.log`, `dist`, `build`, `coverage`, `__pycache__`, `.venv`.
20
19
 
21
- RUN composer install --no-dev --optimize-autoloader
22
- RUN chown -R www-data:www-data /var/www/html
20
+ ## 2. Node.js 22 — production-grade Dockerfile
23
21
 
24
- EXPOSE 9000
25
- CMD ["php-fpm"]
22
+ ```dockerfile
23
+ # syntax=docker/dockerfile:1.7
24
+ ARG NODE_VERSION=22.11.0
25
+
26
+ # ---------- builder ----------
27
+ FROM node:${NODE_VERSION}-alpine AS builder
28
+ WORKDIR /app
29
+ COPY package*.json ./
30
+ RUN --mount=type=cache,target=/root/.npm \
31
+ npm ci --ignore-scripts
32
+ COPY . .
33
+ RUN npm run build && npm prune --omit=dev
34
+
35
+ # ---------- runtime: distroless, no shell ----------
36
+ FROM gcr.io/distroless/nodejs22-debian12:nonroot AS runtime
37
+ WORKDIR /app
38
+ COPY --from=builder --chown=nonroot:nonroot /app/node_modules ./node_modules
39
+ COPY --from=builder --chown=nonroot:nonroot /app/dist ./dist
40
+ COPY --from=builder --chown=nonroot:nonroot /app/package.json ./
41
+ USER nonroot
42
+ EXPOSE 3000
43
+ ENV NODE_ENV=production
44
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
45
+ CMD ["/nodejs/bin/node", "-e", "fetch('http://127.0.0.1:3000/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
46
+ CMD ["dist/server.js"]
26
47
  ```
27
48
 
28
- ## Node.js (Multi-stage)
49
+ Key 2026 patterns: `--mount=type=cache` for npm, `--ignore-scripts` (supply-chain hardening — see `secrets-management` §2025-A03), distroless `nonroot` tag, `--chown` on COPY, healthcheck against `/healthz`.
50
+
51
+ ## 3. Python 3.13 + `uv` — production-grade Dockerfile
29
52
 
30
53
  ```dockerfile
31
- FROM node:20-alpine AS builder
54
+ # syntax=docker/dockerfile:1.7
55
+ FROM python:3.13-slim-bookworm AS builder
56
+ COPY --from=ghcr.io/astral-sh/uv:0.5 /uv /usr/local/bin/uv
32
57
  WORKDIR /app
33
- COPY package*.json ./
34
- RUN npm ci
58
+ COPY pyproject.toml uv.lock ./
59
+ RUN --mount=type=cache,target=/root/.cache/uv \
60
+ uv sync --frozen --no-dev --no-install-project
35
61
  COPY . .
36
- RUN npm run build
62
+ RUN --mount=type=cache,target=/root/.cache/uv \
63
+ uv sync --frozen --no-dev
37
64
 
38
- FROM node:20-alpine
65
+ FROM gcr.io/distroless/python3-debian12:nonroot AS runtime
39
66
  WORKDIR /app
40
- COPY --from=builder /app/dist ./dist
41
- COPY --from=builder /app/node_modules ./node_modules
42
- EXPOSE 3000
43
- CMD ["node", "dist/index.js"]
67
+ COPY --from=builder --chown=nonroot:nonroot /app /app
68
+ USER nonroot
69
+ EXPOSE 8000
70
+ ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
71
+ CMD ["/app/.venv/bin/uvicorn", "myapp.main:app", "--host", "0.0.0.0", "--port", "8000"]
72
+ ```
73
+
74
+ ## 4. PHP 8.4 (FPM + Nginx) with Composer install in builder
75
+
76
+ ```dockerfile
77
+ # syntax=docker/dockerfile:1.7
78
+ FROM composer:2 AS vendor
79
+ WORKDIR /app
80
+ COPY composer.json composer.lock ./
81
+ RUN composer install --no-dev --no-interaction --no-scripts --prefer-dist --optimize-autoloader
82
+
83
+ FROM php:8.4-fpm-alpine AS runtime
84
+ RUN apk add --no-cache libzip-dev oniguruma-dev icu-dev \
85
+ && docker-php-ext-install pdo_mysql zip opcache intl bcmath \
86
+ && rm -rf /var/cache/apk/*
87
+ WORKDIR /var/www/html
88
+ COPY --from=vendor /app/vendor ./vendor
89
+ COPY --chown=www-data:www-data . .
90
+ USER www-data
91
+ EXPOSE 9000
92
+ HEALTHCHECK --interval=30s --timeout=3s CMD php-fpm-healthcheck || exit 1
93
+ CMD ["php-fpm"]
94
+ ```
95
+
96
+ ## 5. Compose with `additional_contexts` — service deps without sequential builds
97
+
98
+ For a project where service B depends on service A's image, **don't** rely on `depends_on` for build order — declare a build-time dependency:
99
+
100
+ ```yaml
101
+ # docker-compose.yml
102
+ services:
103
+ api:
104
+ build:
105
+ context: ./api
106
+ dockerfile: Dockerfile
107
+
108
+ worker:
109
+ build:
110
+ context: ./worker
111
+ dockerfile: Dockerfile
112
+ additional_contexts:
113
+ api: "service:api" # build worker AFTER api, with api's image as a context
114
+ ```
115
+
116
+ ## 6. Bake — the default Compose builder (since Jun 2025)
117
+
118
+ Compose v2 now invokes Buildx Bake by default for multi-service projects. Opt out with `COMPOSE_BAKE=false` only if you need a feature Bake doesn't support (rare).
119
+
120
+ ```hcl
121
+ # docker-bake.hcl — explicit form for CI / multi-arch
122
+ variable "TAG" { default = "latest" }
123
+
124
+ group "default" {
125
+ targets = ["api", "worker"]
126
+ }
127
+
128
+ target "api" {
129
+ context = "./api"
130
+ dockerfile = "Dockerfile"
131
+ platforms = ["linux/amd64", "linux/arm64"]
132
+ tags = ["myorg/api:${TAG}"]
133
+ cache-from = ["type=gha"]
134
+ cache-to = ["type=gha,mode=max"]
135
+ }
136
+
137
+ target "worker" {
138
+ inherits = ["api"]
139
+ context = "./worker"
140
+ tags = ["myorg/worker:${TAG}"]
141
+ }
142
+ ```
143
+
144
+ ```bash
145
+ # Build everything in parallel, push to registry, with cache shared via GitHub Actions
146
+ TAG=v1.2.3 docker buildx bake --push
44
147
  ```
45
148
 
46
- ## Rules
149
+ ## 7. Build-time secrets — `--mount=type=secret`, never `COPY .env`
150
+
151
+ ```dockerfile
152
+ # syntax=docker/dockerfile:1.7
153
+ RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
154
+ npm ci
155
+ ```
156
+
157
+ ```bash
158
+ docker buildx build --secret id=npmrc,src=$HOME/.npmrc .
159
+ ```
160
+
161
+ The secret never lands in any image layer. **Never** `COPY .env` or `ENV API_KEY=...`. See `secrets-management`.
162
+
163
+ ## 8. Healthchecks — match the orchestrator's expectation
164
+
165
+ ```dockerfile
166
+ # Application-level check; fast; idempotent.
167
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
168
+ CMD wget -qO- http://127.0.0.1:3000/healthz || exit 1
169
+ ```
170
+
171
+ For Kubernetes the Dockerfile HEALTHCHECK is informational only — the cluster uses `livenessProbe` / `readinessProbe`. See `observability` §7.
172
+
173
+ ## 9. Image hardening checklist
174
+
175
+ - [ ] Multi-stage build present
176
+ - [ ] Runtime stage is distroless / chiseled / scratch (no shell, no package manager)
177
+ - [ ] `USER` directive set to non-root before `CMD`
178
+ - [ ] `.dockerignore` excludes `.env*`, `node_modules`, `.git`, build outputs
179
+ - [ ] No secrets baked into layers (`docker history --no-trunc IMAGE` clean)
180
+ - [ ] `HEALTHCHECK` directive present
181
+ - [ ] Image pinned by digest in production manifests (`image@sha256:...`)
182
+ - [ ] `docker scout cves IMAGE` (or `trivy image IMAGE`) clean of HIGH/CRITICAL
183
+ - [ ] Build is reproducible — same input → same digest
184
+
185
+ ## FORBIDDEN
186
+
187
+ | Pattern | Why |
188
+ |---|---|
189
+ | `FROM ubuntu:latest` (or any `latest`) | Unpinned, unreproducible |
190
+ | `RUN apt-get install ...` without `--no-install-recommends` and `rm -rf /var/lib/apt/lists/*` | Bloated layers, stale package cache |
191
+ | `COPY .env .` | Secrets in image layer forever |
192
+ | `ENV API_KEY=...` in Dockerfile | Same |
193
+ | `USER root` in runtime stage | Container escape blast radius |
194
+ | `chmod 777` on app dirs | Privilege escalation in shared envs |
195
+ | `--privileged` containers without explicit security review | Almost always wrong |
196
+ | `curl ... | sh` in RUN | Unverifiable supply chain |
197
+ | Single-stage build with dev deps in final image | Bloated, exposes build tools |
198
+ | `HEALTHCHECK NONE` | Orchestrator can't tell if app is wedged |
199
+
200
+ ## See Also
47
201
 
48
- 1. **Multi-stage builds** smaller images
49
- 2. **Alpine base**minimal attack surface
50
- 3. **.dockerignore**exclude node_modules, .git
51
- 4. **Non-root user** security
52
- 5. **Health checks** — always include
202
+ - `secrets-management`build-time secret mounts, OIDC for registry push
203
+ - `security-baseline` (2025-A03)supply chain: pin actions by SHA, sign images (Sigstore/cosign)
204
+ - `observability``/healthz` + `/readyz` semantics
205
+ - `ci-pipelines`building & pushing in CI
@@ -1,40 +1,163 @@
1
1
  ---
2
2
  name: git-workflow
3
- version: 1.0.0
3
+ version: 2.0.0
4
+ description: "Git workflow conventions used by commit-manager v2.0.0+: Conventional Commits (no AI-attribution footers), branch naming, direct-to-main vs feature-branch flow, end-on-main rule, push policy, never force-push main, signed commits encouraged. Invoke when starting a feature, creating commits, pushing, or wiring git-related hooks."
4
5
  ---
5
6
 
6
7
  # Git Workflow
7
8
 
8
- ## Branch Naming
9
+ **ALWAYS invoke when starting work, creating commits, pushing, or wiring `pre-commit` / `Stop` hooks that touch git.**
10
+
11
+ > The git history is documentation. A reader six months from now should understand *why*, not just *what*. The commit-manager agent enforces the message format below; this skill defines what counts as compliant.
12
+
13
+ ## 1. Branch naming
9
14
 
10
15
  ```
11
- feature/short-description
12
- fix/bug-description
13
- refactor/what-changed
14
- chore/maintenance-task
16
+ feature/<short-kebab-description>
17
+ fix/<bug-id-or-description>
18
+ refactor/<area-changed>
19
+ chore/<maintenance-task>
20
+ docs/<scope>
21
+ ci/<workflow-area>
15
22
  ```
16
23
 
17
- ## Commit Format (Conventional)
24
+ Rules:
25
+ - Always kebab-case, never spaces or underscores.
26
+ - ≤ 50 chars; longer goes in the PR description.
27
+ - One feature per branch.
28
+
29
+ ## 2. Conventional Commits — required format
30
+
31
+ ```
32
+ <type>(<scope>): <subject>
33
+
34
+ <body — wrapped at ~72 cols; bullets when ≥ 3 files affected>
35
+ ```
36
+
37
+ | Type | When |
38
+ |---|---|
39
+ | `feat` | New user-visible capability |
40
+ | `fix` | Bug fix |
41
+ | `refactor` | Internal change, no behavior change |
42
+ | `perf` | Performance improvement |
43
+ | `test` | Tests added/changed only |
44
+ | `docs` | Documentation only |
45
+ | `chore` | Build, deps, tooling — nothing user-visible |
46
+ | `ci` | CI/CD config |
47
+ | `style` | Formatting only |
48
+ | `revert` | Reverts a prior commit |
49
+ | `build` | Build system / bundler config |
50
+
51
+ Subject:
52
+ - ≤ 50 chars
53
+ - imperative ("add login retry", not "added", not "adds")
54
+ - no trailing period
55
+ - lowercase first word (after the type/scope prefix)
56
+
57
+ Body (only when ≥ 3 files or non-obvious *why*):
58
+ - explain motivation, trade-offs, links to issues
59
+ - bullet list when summarizing multiple changes
60
+
61
+ ### Example
18
62
 
19
63
  ```
20
- type(scope): description
64
+ feat(auth): add session refresh with rotating cookies
21
65
 
22
- Body explaining what and why.
66
+ - Issue rotated session id on each login + every 7 days
67
+ - Persist previous id for 30s grace window to avoid races
68
+ - Drop legacy cookie name `sid` from response set; honor on read
69
+ ```
23
70
 
71
+ ### **No AI-attribution footers** *(commit-manager v2.0.0+ rule)*
72
+
73
+ Do **not** append:
74
+ ```
24
75
  Generated with Claude Code
25
76
  Co-Authored-By: Claude <noreply@anthropic.com>
26
77
  ```
27
78
 
28
- ## Flow
79
+ The commit message describes the change. Tooling provenance lives in CI artifacts, signed commits, or release metadata — not in every commit body.
80
+
81
+ ## 3. Two valid flows
82
+
83
+ The repo's CLAUDE.md (or `git-workflow` overlay) declares which is in effect.
84
+
85
+ ### Flow A — direct-to-main (small repos, single contributor, fast iteration)
86
+
87
+ ```
88
+ 1. Pull main, ensure clean tree
89
+ 2. Make changes
90
+ 3. Quality gate green
91
+ 4. Commit → push to main
92
+ ```
93
+
94
+ ### Flow B — feature branch + merge (multi-contributor, CI gates required)
29
95
 
30
- 1. Create branch from main: `git checkout -b feature/name`
96
+ ```
97
+ 1. From clean main, create branch: git checkout -b feature/<name>
31
98
  2. Work, commit incrementally
32
- 3. When done: merge to main, delete branch
33
- 4. Push main to remote
99
+ 3. Quality gate green
100
+ 4. Push branch: git push -u origin HEAD
101
+ 5. Open PR; CI must pass
102
+ 6. Merge (squash or rebase — never merge commit on main)
103
+ 7. Delete branch local + remote
104
+ 8. Checkout main, pull
105
+ ```
106
+
107
+ End state in **both flows**: clean tree, on `main`, in sync with `origin/main`. The Stop validator enforces this.
108
+
109
+ ## 4. Push policy
110
+
111
+ | Operation | Allowed | Notes |
112
+ |---|---|---|
113
+ | `git push` to feature branch | ✅ Always | Force-push only if branch is yours and not yet reviewed |
114
+ | `git push` to main | ✅ When tree clean and CI green locally | Branch protection should reject otherwise |
115
+ | `git push --force-with-lease` to feature branch | ✅ Preferred over `--force` | Refuses if remote moved since your last fetch |
116
+ | `git push --force` to main | ❌ Never | Re-writes shared history |
117
+ | `git push --no-verify` | ❌ Never | Bypasses hooks intentionally configured to gate |
118
+
119
+ ## 5. Pre-flight checklist (commit-manager runs this internally)
120
+
121
+ - [ ] Working tree status reviewed (`git status -sb`)
122
+ - [ ] Diff reviewed (`git diff --stat HEAD` then `git diff` if needed)
123
+ - [ ] Quality gate passed (typecheck / lint / tests / build)
124
+ - [ ] Security gate passed (`security-auditor` clean)
125
+ - [ ] No secrets in diff (gitleaks)
126
+ - [ ] CLAUDE.md `Last Change` updated when scope warrants it
127
+ - [ ] Conventional commit message drafted
128
+ - [ ] Push target confirmed (`origin main` vs `origin feature/*`)
129
+
130
+ ## 6. Tags & releases
131
+
132
+ ```bash
133
+ # Annotated tags only — lightweight tags are stripped by some hosts
134
+ git tag -a v1.2.3 -m "Release v1.2.3"
135
+ git push origin v1.2.3
136
+ ```
137
+
138
+ Semver: bump `MAJOR.MINOR.PATCH` per breaking/feature/fix.
139
+
140
+ ## 7. Recovering from mistakes
141
+
142
+ | Situation | Fix |
143
+ |---|---|
144
+ | Bad commit not pushed | `git reset --soft HEAD~1`, fix, re-commit |
145
+ | Bad commit pushed to feature branch | `git commit --amend` then `git push --force-with-lease` |
146
+ | Bad commit pushed to main | `git revert <sha>` and push the revert (NEVER force-push main) |
147
+ | Pushed a secret | Revoke at provider FIRST, then `git filter-repo` + force-push (one-time, document it) |
148
+ | Wrong branch | `git stash`, `git checkout <correct>`, `git stash pop` |
34
149
 
35
150
  ## Rules
36
151
 
37
- - NEVER force push main
38
- - ALWAYS conventional commits
39
- - ALWAYS end on main branch
40
- - ONE feature per branch
152
+ - **NEVER** force-push `main` / `master`
153
+ - **NEVER** `--no-verify` to bypass hooks
154
+ - **ALWAYS** Conventional Commits, no AI-attribution footers
155
+ - **ALWAYS** end on `main` with a clean tree (Stop validator enforces)
156
+ - **ONE** feature per branch (or per direct-to-main commit batch)
157
+
158
+ ## See Also
159
+
160
+ - `commit-manager` agent — drives the message + push pipeline
161
+ - `quality-gate` — the gate the commit-manager waits for
162
+ - `secrets-management` — gitleaks 3-layer (pre-commit, CI, push protection)
163
+ - `ci-pipelines` — branch-protection rules that mirror this skill