docs: add .agents workspace and the Astro refactor plan

Adds the agent-facing workspace and a 20-task plan for migrating the site
to Astro. Nothing here implements the refactor; these are briefs, rules and
templates that the task agents read.

- .agents/ holds context, rules, checklists, skills, specialist agents,
  component/page/config templates and gate scripts. It is vendor-neutral so
  MiniMax, Gemini and Codex can all read it; CLAUDE.md just points at
  AGENTS.md.
- .husky/ plus .lintstagedrc.json wire the three gate tiers. gate.sh locks on
  the shared git-common-dir so parallel worktrees serialise, and guards the
  assertion count in scripts/verify.mjs against a coverage drop.
- plans/astro-refactor/ carries the phase graph, per-task briefs and the
  model-routing recommendation.

These files must be tracked before fanning out: a worktree only checks out
tracked files, so an untracked plan is invisible to every agent working in one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Marcos Paulo
2026-09-05 01:18:27 +00:00
parent aa85c1d0b7
commit aae4d42229
79 changed files with 3805 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
dist
node_modules
public/hands-on
submitted-skills
skill-reviews
vote-service
.agents/snapshots
+11
View File
@@ -0,0 +1,11 @@
{
"printWidth": 100,
"singleQuote": true,
"semi": true,
"trailingComma": "all",
"plugins": ["prettier-plugin-astro"],
"overrides": [
{ "files": "*.astro", "options": { "parser": "astro" } },
{ "files": "*.md", "options": { "proseWrap": "always", "printWidth": 80 } }
]
}
@@ -0,0 +1,22 @@
{
"extends": ["stylelint-config-standard"],
"ignoreFiles": [
"dist/**",
"public/hands-on/**",
"submitted-skills/**"
],
"rules": {
"custom-property-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"declaration-property-value-disallowed-list": {
"/^transition/": ["/width/", "/height/", "/^top/", "/^left/", "/margin/"],
"/^animation/": ["/width/", "/height/"]
},
"media-feature-name-no-unknown": true,
"no-descending-specificity": null,
"selector-class-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$"
},
"_comments": {
"declaration-property-value-disallowed-list": "Animating layout properties forces reflow every frame and fails the 200ms INP budget. transform and opacity only — see .agents/rules/animation.md",
"ignoreFiles": "hands-on/ is a lab fixture and submitted-skills/ is other people's work; neither is ours to restyle"
}
}
+26
View File
@@ -0,0 +1,26 @@
// Flat config (ESLint 9+). Copy to the repository root in task 01.
import js from '@eslint/js';
import astro from 'eslint-plugin-astro';
export default [
js.configs.recommended,
...astro.configs.recommended,
{
ignores: [
'dist/**',
'public/hands-on/**', // lab fixtures ship verbatim — linting them would
// invite "fixes" that break the exercise
'submitted-skills/**', // other people's work, reproduced as submitted
'skill-reviews/**', // generated from skills-review/catalog.js
'vote-service/**', // Go service, separate lifecycle
],
},
{
rules: {
'no-console': ['warn', { allow: ['warn', 'error'] }],
eqeqeq: ['error', 'always'],
'no-var': 'error',
'prefer-const': 'error',
},
},
];
+39
View File
@@ -0,0 +1,39 @@
# Tier 3 gate. Copy to .gitea/workflows/verify.yml in task 01.
#
# Known trap: this Gitea's act-runner registration lives in an emptyDir, so a
# pod restart silently kills CI. If the site stops updating, check the runner
# BEFORE debugging the workflow.
name: verify
on:
push:
branches: [main]
pull_request:
jobs:
gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # gate.sh compares assertion counts against origin/main
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci --prefer-offline
- run: npm run lint
- run: ./.agents/scripts/gate.sh
# Tier 3 only: too slow for pre-push, essential before publishing.
- name: visual regression
run: |
npx playwright install --with-deps chromium
node .agents/scripts/visual-regression.mjs
- uses: actions/upload-artifact@v4
if: failure()
with:
name: screenshots
path: .agents/snapshots/diff/
@@ -0,0 +1,27 @@
{
"_note": "Merge these into package.json in task 01. `prepare` is what installs husky; without it every hook is inert.",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"check": "astro check",
"lint": "eslint . --max-warnings=0 && stylelint '**/*.css' --max-warnings=0",
"format": "prettier --write .",
"verify": "node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs",
"gate": "./.agents/scripts/gate.sh",
"snapshot": "node .agents/scripts/snapshot-route.mjs",
"prepare": "husky"
},
"devDependencies": {
"astro": "^5",
"@eslint/js": "^9",
"eslint": "^9",
"eslint-plugin-astro": "^1",
"husky": "^9",
"lint-staged": "^16",
"prettier": "^3",
"prettier-plugin-astro": "^0.14",
"stylelint": "^16",
"stylelint-config-standard": "^39"
}
}