ps-css-build
Skill4 starsChanged 13 days agoMITView on GitHub
Sets up a modern CSS build pipeline for a PrestaShop child theme: source partials in _dev/css/, lightningcss bundle+minify to a single generated assets/css/custom.css, pnpm 11 with supply-chain hardening, pre-commit hook with zero-dependency Node fallback, and agent/team documentation. Replaces runtime @import chains and manual ?v= cache-bust versioning. Use when scaffolding CSS architecture for a new PS child theme, when a theme has multiple @import'ed CSS partials loaded at runtime, when the user mentions manual CSS version bumps, CSS cache busting problems, "el CSS no se actualiza", or wants the Milagros-style CSS build on another project.
- Deletes or force-pushes
- Installs packages
In this repository37 other files it gives its agents.
- blast-radiusSkill
- elementflow-kbSkill
- gitlab-changelog-releaseSkill
- gitlab-ci-quality-gatesSkill
- gitlab-project-bootstrapSkill
- gitlab-security-setupSkill
- gitlab-wiki-bootstrapSkill
- lando-checkSkill
- lando-img-placeholderSkill
- lando-mail-smtpSkill
- lando-setupSkill
- mallard-releaseSkill
- mr-flowSkill
- no-commentsSkill
- paginated-report-pdfSkill
- panda-kbSkill
- ploi-prestashop-deploySkill
- prestashop-kbSkill
- ps-consoleSkill
- ps-demo-userSkill
- ps-email-previewSkill
- ps-image-regenSkill
- ps-invoice-previewSkill
- ps-new-projectSkill
- ps-one-page-checkoutSkill
- ps-project-docSkill
- ps-security-auditSkill
- ps-storefront-polishSkill
- ps-theme-cacheSkill
- ps-translateSkill
- ps-view-transitionsSkill
- ps-watchSkill
- reflectSkill
- show-me-your-workSkill
- skill-authorSkill
- task-contextSkill
- verify-ps-projectSkill
The file
Files
PS CSS Build — pipeline para child themes
Montado y probado en milagros-colombia-b2b-v9.1 (PS 9.1, child de Panda).
Sustituye: @import runtime (N requests encadenados) + bumps manuales ?v=N
- hacks tipo
_bust={$smarty.now}(que anulan caché por completo).
Resultado final
themes/{child}/
├── _dev/
│ ├── README.md # doc del sistema (plantilla abajo)
│ └── css/
│ ├── custom.css # entry point: @import de los parciales (SIN ?v=)
│ ├── tokens.css # :root design tokens
│ ├── base.css
│ ├── components.css
│ ├── utilities.css
│ └── pages/*.css
├── scripts/bundle-css.js # fallback cero-deps para el hook
├── scripts/watch.js # rebuild al guardar (lo lanza node --watch-path)
├── assets/css/custom.css # GENERADO — único CSS servido
├── package.json # pnpm + scripts css/watch
├── pnpm-workspace.yaml # supply-chain hardening
├── pnpm-lock.yaml
└── .gitignore # node_modules/
.githooks/pre-commit # raíz del repo
.gitattributes # dist marcado generatedPS core auto-registra assets/css/custom.css como theme-custom — mantener
ese path/nombre exacto = cero cambios PHP, tema padre intacto.
Paso 1 — Mover fuentes
cd themes/{child}
mkdir -p _dev/css
git mv assets/css/*.css _dev/css/ # parciales + custom.css
git mv assets/css/pages _dev/css/pages # si existeLimpiar el entry point _dev/css/custom.css:
- Quitar todos los
?v=Nde los imports:sed -i '' -E "s/\.css\?v=[0-9]+'/.css'/g" _dev/css/custom.css - CRÍTICO: buscar
@importcon URL remota (Google Fonts) en TODOS los parciales:grep -rn "@import url('http" _dev/css/. lightningcss NO bundlea remotas — panic con error crípticoResolverError NotFound. Moverlas como<link rel="preconnect">+<link rel="stylesheet">al overridetemplates/_partials/stylesheets.tpl(mejor perf además: descarga paralela). - Revisar
url()relativos en parciales (grep -rn "url(" _dev/css/ | grep -v @import). Rutas absolutas (/img/...) OK; relativas pueden romper al cambiar de nivel.
Paso 2 — package.json + pnpm hardened
themes/{child}/package.json:
{
"name": "{child}-theme",
"private": true,
"packageManager": "pnpm@11.1.2",
"scripts": {
"css": "lightningcss --bundle --minify --targets 'defaults' _dev/css/custom.css -o assets/css/custom.css",
"watch": "node --watch-path=_dev/css --watch-preserve-output scripts/watch.js"
},
"devDependencies": {
"lightningcss-cli": "^1.30.2"
}
}Pin de versión pnpm exacta (la instalada: pnpm --version), no 11.x.x.
themes/{child}/scripts/watch.js (el watcher, sin dependencias; Node ≥ 18.11):
// Rebuild the CSS bundle on every change under _dev/css (run via `node --watch-path`).
const { execSync } = require('child_process');
execSync('pnpm run --silent css', { stdio: 'inherit' });No uses chokidar-cli: arrastra braces ≤3.0.3 (high, GHSA-vfj7-8cjw-p6xm) sin
versión parcheada publicada, y el job dependency-audit-node de CI falla.
lightningcss-cli no tiene --watch, por eso el watcher es Node nativo.
themes/{child}/pnpm-workspace.yaml (ver skills supply-chain-security y
gitlab-security-setup para el detalle):
allowBuilds:
lightningcss-cli: true # único postinstall permitido
minimumReleaseAge: 4320 # 72h quarantine (estándar Cinetic)
blockExoticSubdeps: true # bloquea transitivas git/tarball (pnpm 10.26+)
overrides:
form-data: ">=4.0.4"
axios: ">=1.15.2"
lodash: ">=4.18.0"
picomatch: ">=4.0.4"
qs: ">=6.14.2"themes/{child}/.gitignore: node_modules/
pnpm install --dir themes/{child}
pnpm --dir themes/{child} run css # genera el distGotcha: pnpm 11 bloqueará el postinstall de lightningcss-cli en el primer
install y escribirá un placeholder allowBuilds: lightningcss-cli: set this to
true or false en pnpm-workspace.yaml — editarlo a true y re-instalar.
Test real: rm -rf node_modules && pnpm install --frozen-lockfile —
la caché caliente NO aplica las políticas.
Flujo de desarrollo diario (documentar al usuario)
Mientras se edita CSS, el watcher debe estar corriendo en una terminal:
pnpm --dir themes/{child} run watch- Guardas un parcial en
_dev/css/→node --watch-pathdispara lightningcss → dist regenerado en ~10ms → recarga del browser y listo. --initialhace un build al arrancar, así que el dist nunca queda stale al empezar la sesión.- Sin watch corriendo, los cambios en
_dev/css/NO se ven en el browser (el browser carga el dist generado, no los fuentes). Síntoma típico: "cambié el CSS y no sale" → watch no estaba corriendo → build puntual:pnpm --dir themes/{child} run css. - Combina con la skill
ps-watch(BrowserSync) para recarga automática del browser además del rebuild: el watcher regenera el dist y BrowserSync detecta el cambio enassets/css/y recarga. Watch + BrowserSync = guardar y ver.
Paso 3 — Limpiar el tpl
Revisar templates/_partials/stylesheets.tpl del child: si tiene hacks de
cache-bust (?_bust={$smarty.now}, timestamps), quitarlos — anulan caché en
cada pageview. Si el override solo existía para eso, dejarlo igual que el
padre + el bloque de fonts:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family={...}&display=swap">
{foreach $stylesheets.external as $stylesheet}
<link rel="stylesheet" href="{$stylesheet.uri}" media="{$stylesheet.media}">
{/foreach}
...resto igual que el padre (Panda añade $sttheme.custom_css al final)...Cache-busting de producción: el dist commiteado cambia de contenido → ETag
nuevo → revalidación. Si nginx sirve .css con expires largo, opciones:
Cache-Control: no-cache para el dir del tema (304s baratos), o activar
CCC "Smart cache CSS" en BO Rendimiento (ahora funciona porque el CSS es
plano — con @imports runtime se rompía).
Paso 4 — Hook pre-commit con fallback cero-deps
.githooks/pre-commit (raíz, ejecutable chmod +x):
#!/bin/sh
# Rebuild theme CSS bundle when staged changes touch _dev/css sources.
# Works for everyone: pnpm if installed, zero-dep Node.js bundler otherwise.
THEME="themes/{child}"
if git diff --cached --quiet -- "$THEME/_dev/css"; then
exit 0
fi
echo "pre-commit: _dev/css changed — rebuilding custom.css..."
if [ -d "$THEME/node_modules" ]; then
pnpm --dir "$THEME" run --silent css || exit 1
echo "pre-commit: rebuilt OK (minified)"
else
node "$THEME/scripts/bundle-css.js" || exit 1
echo "pre-commit: rebuilt OK (unminified — run 'pnpm install --dir $THEME' for minified)"
fi
git add "$THEME/assets/css/custom.css"themes/{child}/scripts/bundle-css.js — bundler Node sin dependencias
(resuelve @imports recursivo, salta remotas). Copiarlo de
milagros-colombia-b2b-v9.1/themes/milagros/scripts/bundle-css.js ajustando
nada (usa rutas relativas a __dirname).
Activación (por clone, git no auto-activa hooks por diseño):
git config core.hooksPath .githooks.gitattributes (raíz):
themes/{child}/assets/css/custom.css linguist-generated=true -diffPaso 5 — Documentación (obligatorio, es la red de seguridad real)
El hook NO se activa solo en clones nuevos. La protección para compañeros/ agentes que no conocen el sistema es documentación:
- CLAUDE.md del proyecto — sección "CSS del tema hijo — REGLA OBLIGATORIA":
dist generado (jamás editarlo), fuentes en
_dev/css/, comando rebuild, activación del hook, sin?v=, remotas como<link>, no tocar hardening pnpm. Copiar la sección demilagros-colombia-b2b-v9.1/CLAUDE.md. themes/{child}/_dev/README.md— doc completa: diagrama del flujo, setup por clone, watch, cómo funciona el hook (2 caminos), supply chain, tabla troubleshooting. Copiar demilagros-colombia-b2b-v9.1/themes/milagros/_dev/README.md.
Paso 6 — Verificar
pnpm --dir themes/{child} run css→ dist generado, comparar tamaño razonable- Cascade:
tail -c 300 assets/css/custom.css— los overrides del entry deben estar al FINAL (lightningcss respeta orden de imports) - Hook ambos caminos: stage un parcial →
.githooks/pre-commit→ exit 0 y dist staged; repetir connode_modulesrenombrado (camino fallback) - En Lando con agent-browser: página renderiza,
<link>custom.css sin query hacks, tokens aplicados (getComputedStylede una variable), fuente OK rm -rf node_modules && pnpm install --frozen-lockfile && pnpm run css
Limitación conocida (aceptada)
Si alguien clona, NO activa el hook y commitea cambios de _dev/css/, el dist
queda desactualizado y "su cambio no sale". Mitigación: documentación (Paso 5)
- el que integre con agente lo detecta por CLAUDE.md. Opciones descartadas en
Milagros por complejidad/deps: Husky, package.json raíz con prepare, build en
deploy, job CI de sincronía (válida si el proyecto ya tiene runners — ver
gitlab-security-setup).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

