diff --git a/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/completion-summary.md b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/completion-summary.md new file mode 100644 index 0000000..2d9c59d --- /dev/null +++ b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/completion-summary.md @@ -0,0 +1,95 @@ +# blog-5m:热力图定稿萤火(4 只)落地正式开源页 - 完成总结 + +## 交付结论 +- 结果:完成 +- 完成时间:2026-11-05 11:21 + +## 假设回顾 +### 已验证假设 +- 月柱在无「点亮联动」后仍有信息价值(静态高度=哪个月最忙),保留不删 +- 萤火引擎的 offsetLeft/offsetTop 定位对官方组件的 11px/10px 双档网格同样成立(布局实测,零手算节距) + +### 仍未完全验证的假设 +- 无 + +## 交付范围 +### 已交付 +- task_0001 萤火落地与预览退役 +- task_0002 生产核验(manual: 部署后人工核验) + +### 未交付 +- 无 + +### 偏差说明 +- 无 + +## 简化决策 +### 保持简单的关键选择 +- 最简可行:Heatmap.astro 三处手术(浮层标记换 4 只 hm-fly、script 换萤火引擎、style 换 hm-fly/hm-lit+月柱静态)+ 删三类一次性资产 + E2E 一条断言 +- 暂不引入: 虫数可配置化 +- 不做的抽象: 「动效引擎注册表」(只有一种引擎,抽象无收益) +- 范围级别:package +- 变更对象:开源页热力图组件与一次性预览资产 +- 快速检查:`pnpm astro build` + `python3 scripts/build-perf/config-check.py .` +- 集成检查:E2E(含萤火新断言)+ content-lint 0/0/0 + grep 断言产物(无 heatmap-preview、无 hm-head、4 只 hm-fly) +- 全项目检查:生产部署后人工核验 /opensource/ 萤火在跑、/heatmap-preview/ 404;**升级条件**——仅当改动触及 BaseLayout 或构建链时才升级全站回归,本包不涉及 +- 升级触发:开源页独立区块,升级为「该区块人工核验」即可 + +### 本轮明确不做的内容 +- 萤火参数再调(数量/速度/半径——用户未提,不为未发生的需求加工) + +## 变更边界 +### 本轮主要改动模块 +- 见 tasks.md 的 boundary 记录 + +### 明确未触碰的区域 +- 萤火参数再调(数量/速度/半径——用户未提,不为未发生的需求加工) + +## 验证证据 +### 备注 +- 机器证据:runs.jsonl(见验证范围的机器验证率) + +## 验证范围 +- 级别:package +- 机器验证率:1/1;manual 任务 1 项不计入分母 +- 规则:check 与 done 复用该范围;只有记录升级触发时才执行全项目检查 + +## 哲学生效证据 +### 行为成效回填 +- Development Record 行为门禁通过 + +### 一致性门禁回顾 +- 验收面(checklist 或成功标准)已通过 + +## Git 记录 +- 日期时间:2026-11-05 11:21 +- 范围:blog-5m:热力图定稿萤火(4 只)落地正式开源页 +- 功能:task_0001 萤火落地与预览退役;task_0002 生产核验(manual: 部署后人工核验) +- 操作:提交 / 推送 +- 成效:Development Record 行为门禁通过 +- 提交:pending local commit +- 提交区间:44cd62e9a2a5fc0f400de2862a3a07c5686bf25e..44cd62e9a2a5fc0f400de2862a3a07c5686bf25e +- 推送:not-run (push stage follows commit) + +## AGENTS.md 增量提议 +```diff +热力图 v5 选型闭环:用户在五案预览页选定萤火并指定虫数 4——引擎落进正式开源页(贪吃蛇与月柱点亮联动退役,月柱转静态),预览路由/五候选组件/lint 白名单全部退役,E2E 补萤火断言(61/61)。 +``` + +## 被拒绝的扩展提议 +- 无 + +## 门禁证据 +- check_spec_package.py exit 0 + +## 遗留事项 +- 无;问题处置见下方结构化区块 + +## 问题处置 + +```json +{ + "issues": [], + "version": 1 +} +``` diff --git a/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/evidence/verify_t1.sh b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/evidence/verify_t1.sh new file mode 100644 index 0000000..a443b22 --- /dev/null +++ b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/evidence/verify_t1.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# task_0001 萤火落地与预览退役:构建 + 产物断言 + lint + E2E +set -euo pipefail +cd "$(git rev-parse --show-toplevel)" +export PATH="$HOME/.local/node/bin:$PATH" +pnpm astro build >/dev/null 2>&1 +[ ! -f src/pages/heatmap-preview.astro ] +[ ! -d src/components/geek/hm ] +! grep -q heatmap-preview scripts/build-perf/content-lint.mjs +! grep -q hm-head src/components/geek/Heatmap.astro +[ "$(grep -o 'class="hm-fly"' dist/opensource/index.html | wc -l)" -eq 4 ] +node scripts/build-perf/content-lint.mjs dist 2>&1 | grep -q "通过" +nohup python3 scripts/build-perf/gz-server.py 18925 "$PWD/dist" >/tmp/gz-5m.log 2>&1 & +SRV=$! +sleep 2 +trap 'kill $SRV 2>/dev/null || true' EXIT +E2E_BASE=http://127.0.0.1:18925 node tests/e2e.mjs 2>&1 | grep -qE "汇总: 61/61 PASS" +echo "verify_t1 OK" diff --git a/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/runs.jsonl b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/runs.jsonl new file mode 100644 index 0000000..75055cf --- /dev/null +++ b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/runs.jsonl @@ -0,0 +1,2 @@ +{"task": "task_0001", "cmd": "bash .spec/specs/2026-11-05_blog-5m-heatmap-fireflies/evidence/verify_t1.sh", "exit": 0, "duration_s": 44.525, "stdout_tail_sha256": "cced3c08cf1601b8177b7728e48c6add6982099d0785fa9fa4dd470b1f4900a5", "tree_fp": "e364e39e9d06d1dcfe55ea481995d132f94854ed078cb251c9fa4fa9a6af1202", "at": "2026-11-05T03:21:15+00:00"} +{"task": "task_0001", "cmd": "bash .spec/specs/2026-11-05_blog-5m-heatmap-fireflies/evidence/verify_t1.sh", "exit": 0, "duration_s": 43.513, "stdout_tail_sha256": "cced3c08cf1601b8177b7728e48c6add6982099d0785fa9fa4dd470b1f4900a5", "tree_fp": "e364e39e9d06d1dcfe55ea481995d132f94854ed078cb251c9fa4fa9a6af1202", "at": "2026-11-05T03:21:58+00:00"} diff --git a/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/spec.md b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/spec.md new file mode 100644 index 0000000..c5b37c8 --- /dev/null +++ b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/spec.md @@ -0,0 +1,68 @@ + +# blog-5m:热力图定稿萤火(4 只)落地正式开源页 + +- **slug**: 2026-11-05_blog-5m-heatmap-fireflies +- **日期**: 2026-11-05 +- **状态**: 进行中 +- Git integration branch:`spec/2026-11-05_blog-5m-heatmap-fireflies` +- 证据协议:evidence: runs +- **提案**: 用户在 /heatmap-preview/ 五案中选定方案五「萤火」并要求虫数 5→4。把萤火引擎落进正式 Heatmap.astro(换下 P1 贪吃蛇),删预览路由/五候选组件/lint 白名单,E2E 补萤火断言。 + +## 1. 问题定义 +- **项目目标**: 开源页热力图动效从贪吃蛇切换为萤火(4 只,暖色游走、落格点亮),保持数据语义(ink 档位=密度)与无障碍兜底(reduced-motion 静态、无 JS 可读)不变;一次性预览资产全部退役。 +- **目标用户**: 读者(更安静文气的动效);站长(选定方案的落地闭环) +- **核心价值**: 选型闭环——预览页五案并陈→用户点选→落地删预览的工作流第三次跑通,站点只留定稿资产 + +## 2. 假设与待确认 + +### 2.1 已确认事实 +- 萤火引擎已在预览页跑通(/heatmap-preview/ 方案五),视觉复核判词无硬伤、色向已转暖 +- 官方 Heatmap.astro 现役结构:streak 行 + 蛇引擎(hm-head/hm-trail/eaten + 月柱 .on 联动)+ 月柱 + 图例 + 横滚锚定 +- E2E 无蛇头断言(仅注释),补萤火断言无旧断言要改 + +### 2.2 关键假设 +- 月柱在无「点亮联动」后仍有信息价值(静态高度=哪个月最忙),保留不删 +- 萤火引擎的 offsetLeft/offsetTop 定位对官方组件的 11px/10px 双档网格同样成立(布局实测,零手算节距) + +### 2.3 待确认问题 +- [x] 虫数 4(用户明确:5→4) +- [x] 贪吃蛇整体退役(用户选新方案即换下,git 历史留档) + +### 2.4 可选解释与取舍 +- 五个候选组件目录整体删除而非保留:git 历史即档案,工作树不留死代码 +- 月柱保留静态形态:删掉会丢「月度粗粒度」信息,联动点亮属蛇的语义,随蛇退役 + +### 2.5 已证伪路径 +- 无(本包是纯落地,无新设计探索) + +## 3. 功能范围 + +### 3.1 核心功能(MVP) +- [x] T1 萤火落地:Heatmap.astro 换引擎(4 虫、data-hm-fire 锚、hm-lit 样式、月柱转静态)、删预览路由+五候选组件+lint 白名单两处、E2E 补萤火断言 + +### 3.2 扩展功能 +- 无 + +### 3.3 不在范围内 +- 萤火参数再调(数量/速度/半径——用户未提,不为未发生的需求加工) + +## 4. 最小实现路径 +- 最简可行:Heatmap.astro 三处手术(浮层标记换 4 只 hm-fly、script 换萤火引擎、style 换 hm-fly/hm-lit+月柱静态)+ 删三类一次性资产 + E2E 一条断言 +- 暂不引入: 虫数可配置化 +- 不做的抽象: 「动效引擎注册表」(只有一种引擎,抽象无收益) + +### 5.1 验证策略 +- 范围级别:package +- 变更对象:开源页热力图组件与一次性预览资产 +- 快速检查:`pnpm astro build` + `python3 scripts/build-perf/config-check.py .` +- 集成检查:E2E(含萤火新断言)+ content-lint 0/0/0 + grep 断言产物(无 heatmap-preview、无 hm-head、4 只 hm-fly) +- 全项目检查:生产部署后人工核验 /opensource/ 萤火在跑、/heatmap-preview/ 404;**升级条件**——仅当改动触及 BaseLayout 或构建链时才升级全站回归,本包不涉及 +- 升级触发:开源页独立区块,升级为「该区块人工核验」即可 + +## 6. 成功标准与验证方式 +- [x] 正式开源页萤火 4 只在跑、预览资产全退役 -> verify: task_0001 +- [x] 生产 /opensource/ 人工核验 + /heatmap-preview/ 404 -> verify: task_0002(manual: 部署后人工核验) + +## 7. 关联与风险 +- 前序:v4 路径优化(P1 蛇)、v5 五案预览(44cd62e) +- 风险:萤火引擎在官方组件的 11px 移动档网格上包围盒内缩 6px 后可用幅度变小——若视觉过挤,回退方案是内缩降为 3px(本包不预设,部署后看) diff --git a/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/tasks.md b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/tasks.md new file mode 100644 index 0000000..f94a2c1 --- /dev/null +++ b/.spec/specs/archive/2026-11-05_blog-5m-heatmap-fireflies/tasks.md @@ -0,0 +1,16 @@ +# Phase 5m:热力图萤火落地 - 任务拆解 + +## 使用规则 +- E2E 口径:`pnpm astro build → gz-server.py 18925 → E2E_BASE=http://127.0.0.1:18925 node tests/e2e.mjs` + +## 阶段一:实现 + +- [x] task_0001 萤火落地与预览退役 + - claim: orchestrator + - boundary: src/components/geek/Heatmap.astro(换引擎)、tests/e2e.mjs(断言)、删除 src/pages/heatmap-preview.astro、删除 src/components/geek/hm/、scripts/build-perf/content-lint.mjs(白名单两处退役) + - verify: `bash .spec/specs/2026-11-05_blog-5m-heatmap-fireflies/evidence/verify_t1.sh` + +- [x] task_0002 生产核验(manual: 部署后人工核验) + - claim: orchestrator + - boundary: 无代码改动;生产 /opensource/ 萤火 4 只在跑 + /heatmap-preview/ 404 + - verify: manual: 部署后人工核验 diff --git a/scripts/build-perf/content-lint.mjs b/scripts/build-perf/content-lint.mjs index 54d1fdb..18ca567 100644 --- a/scripts/build-perf/content-lint.mjs +++ b/scripts/build-perf/content-lint.mjs @@ -14,13 +14,7 @@ if (MODE === 'skip') { } const SKIP_PREFIX = ['/admin/', '/photos-originals/']; // admin=CMS 路由;photos-originals=部署期 rsync 叠加层(不在 dist,另有部署链保障) -// 已知不存在的 en 孪生目标(见 targetExists 内注释) -const KNOWN_MISSING_TWIN = new Set(['/en/heatmap-preview/']); -const SKIP_FILE = new Set([ - '/404.html', // Astro 404 页不参与配对 - // 一次性预览路由(预览-选型-落地模式):只有 zh 版,配对检查豁免;选定后随路由一起删 - '/heatmap-preview/index.html', -]); +const SKIP_FILE = new Set(['/404.html']); // Astro 404 页不参与配对 @@ -45,9 +39,6 @@ function decodePath(p) { /** /x/ → dist/x/index.html;/a.svg → dist/a.svg;找不到即 null */ function targetExists(url) { if (SKIP_PREFIX.some((s) => url.startsWith(s))) return true; - // 一次性预览路由的 en 孪生:语言切换器会给预览页生成 /en/… 链接,而预览只有 zh 版 - // (页面本体已在 SKIP_FILE 豁免配对检查;此处豁免切换器链接,选定后随路由一起删) - if (KNOWN_MISSING_TWIN.has(url.split('#')[0].split('?')[0])) return true; const p = decodePath(url.split('#')[0].split('?')[0]); if (!p || p === '/') return existsSync(join(DIST, 'index.html')); if (p.endsWith('/')) return existsSync(join(DIST, p, 'index.html')); diff --git a/src/components/geek/Heatmap.astro b/src/components/geek/Heatmap.astro index 777804a..de0ddcd 100644 --- a/src/components/geek/Heatmap.astro +++ b/src/components/geek/Heatmap.astro @@ -51,9 +51,8 @@ const maxMonth = Math.max(...months.map(([, v]) => v), 1); {streak.total}{locale === 'en' ? 'total' : '总贡献'} 数据更新于 {updatedOn}

-
- - +
+ {[0, 1, 2, 3].map(() =>