Skip to content

Commit f304f6f

Browse files
XuebinMaclaude
andauthored
fix(og): 社交卡片写着 76 条(实际 82),并补上它缺失的生成源与闸门 (#107)
* fix(og): 社交卡片写着 76 条,实际 82;顺手给它补上生成源与闸门 那张 og-cover.png 从 2026-07-10 起就写着「76 pitfalls」,两个月里书涨到 82, 没人发现——因为**这个数字只存在于像素里,没有任何检查读得到它**。仓库里也 没有生成源,改都无从改起。 所以这次不只是把 76 改成 82: - 新增 scripts/og-cover/og-cover.html —— 卡片的生成源,数字是文本 - 新增 scripts/og-cover/render.sh —— 无头 Chrome 渲染回 2560x1280 PNG (`--headless=new` 是必须的:旧的 `--headless` 在这台机器上会无限挂起) - scripts/check-counts.js 把这个数字纳入受检计数,跟 core-20 / intro / CLAUDE.md 那几处一样,再漂移就会红 这正是本书 07「文档不是防护」那条讲的东西用在自己身上:一个没有检查能读到 的声明,只是散文。 闸门:check:counts(现查 8 处)/ check:mirror / check:mirror-deep / cspell 全过,两 locale 两实例 build 通过。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(check-counts): og-cover 的 label 用 ASCII 引号,修掉 autocorrect 报错 上一个提交在英文 label 外面套了中文直角引号「」,CI 的 autocorrect 报 scripts/check-counts.js:69 一处 Error,#107 因此变红。同文件其他英文 label ("All N entries is a lot" 等)都用 ASCII 双引号,这里改成一致。 这次在推之前本地跑过同一道闸门:CI 用的是 npm 包 autocorrect-node@2.8.4, `npx --yes autocorrect-node@2.8.4 --lint .` 全仓 Error 0。上次红,是因为我以为 autocorrect 本机跑不了、只能等 CI——其实它能跑,只是没有全局命令。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent f401641 commit f304f6f

4 files changed

Lines changed: 149 additions & 0 deletions

File tree

‎scripts/check-counts.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ const CLAIMS = [
5858
expect: docsCount,
5959
label: '「全书 N 条太多」',
6060
},
61+
{
62+
// The social card. It shipped "76 pitfalls" against 82 for two months
63+
// because the number lived only in a PNG, where nothing could read it.
64+
// Now it is text in the render source, so this check can.
65+
// Changed the count? Re-run: bash scripts/og-cover/render.sh
66+
file: 'scripts/og-cover/og-cover.html',
67+
pattern: /<em>(\d+)<\/em> pitfalls/,
68+
expect: docsCount,
69+
label: '"og-cover N pitfalls"',
70+
},
6171
{
6272
file: 'i18n/en/docusaurus-plugin-content-docs/current/intro.md',
6373
pattern: /All (\d+) entries is a lot/,

‎scripts/og-cover/og-cover.html‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<!doctype html>
2+
<!--
3+
Source of truth for static/img/og-cover.png (the social card).
4+
5+
The PNG that shipped from 2026-07-10 to 2026-09-13 said "76 pitfalls" while
6+
the book had 82. Nobody caught it because the image had no source: the number
7+
lived only in pixels, so no check could read it. This file exists so the
8+
number is text, and scripts/check-counts.js can hold it to the real count.
9+
10+
Regenerate: bash scripts/og-cover/render.sh
11+
-->
12+
<meta charset="utf-8" />
13+
<title>AiWiki og:image</title>
14+
<style>
15+
:root {
16+
--ink: #0b0f14;
17+
--green-bright: #3fb950;
18+
--white: #f0f6fc;
19+
--grey: #8b949e;
20+
--pill: #161b22;
21+
--pill-edge: #30363d;
22+
}
23+
* { margin: 0; padding: 0; box-sizing: border-box; }
24+
html, body { width: 2560px; height: 1280px; }
25+
body {
26+
background:
27+
radial-gradient(1100px 700px at 88% 4%, rgba(46, 160, 67, 0.16), transparent 62%),
28+
radial-gradient(900px 600px at 4% 96%, rgba(46, 160, 67, 0.10), transparent 60%),
29+
var(--ink);
30+
color: var(--white);
31+
font-family: -apple-system, "SF Pro Display", "Helvetica Neue", "PingFang SC", sans-serif;
32+
padding: 96px 0 0 196px;
33+
-webkit-font-smoothing: antialiased;
34+
}
35+
.dots { display: flex; gap: 24px; margin-bottom: 76px; }
36+
.dots i { width: 30px; height: 30px; border-radius: 50%; display: block; }
37+
.dots i:nth-child(1) { background: #ff5f57; }
38+
.dots i:nth-child(2) { background: #febc2e; }
39+
.dots i:nth-child(3) { background: #28c840; }
40+
41+
.mono {
42+
font-family: "SF Mono", "JetBrains Mono", Menlo, monospace;
43+
letter-spacing: -0.01em;
44+
}
45+
.prompt { font-size: 46px; color: var(--green-bright); margin-bottom: 34px; }
46+
47+
.wordmark {
48+
font-size: 232px;
49+
font-weight: 800;
50+
letter-spacing: -0.045em;
51+
line-height: 1.02;
52+
margin-bottom: 48px;
53+
}
54+
.wordmark b { color: var(--green-bright); font-weight: 800; }
55+
56+
.tagline { font-size: 66px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 22px; }
57+
.tagline-cjk { font-size: 50px; color: var(--grey); font-weight: 400; margin-bottom: 68px; }
58+
59+
.pills { display: flex; gap: 42px; margin-bottom: 78px; }
60+
.pill {
61+
border: 2px solid var(--pill-edge);
62+
background: var(--pill);
63+
border-radius: 999px;
64+
padding: 26px 52px;
65+
font-size: 48px;
66+
font-weight: 700;
67+
white-space: nowrap;
68+
}
69+
.pill em { color: var(--green-bright); font-style: normal; }
70+
71+
.footer { font-size: 42px; color: var(--grey); }
72+
</style>
73+
74+
<div class="dots"><i></i><i></i><i></i></div>
75+
76+
<div class="mono prompt">~/AiWiki &gt; what you keep getting wrong about working with me</div>
77+
78+
<div class="wordmark">Ai<b>Wiki</b></div>
79+
80+
<div class="tagline">AI-coding pitfalls — written in the AI's own voice.</div>
81+
<div class="tagline-cjk">用 AI 第一人称视角写的「AI 编码避坑」百科</div>
82+
83+
<div class="pills">
84+
<!-- scripts/check-counts.js reads the number below. Keep the wording. -->
85+
<div class="pill"><em>82</em> pitfalls</div>
86+
<div class="pill"><em>5</em> tools</div>
87+
<div class="pill">中文 / English</div>
88+
</div>
89+
90+
<div class="mono footer">xuebinma.github.io/AIWiki · CC BY-SA 4.0</div>

‎scripts/og-cover/render.sh‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env bash
2+
# Regenerate static/img/og-cover.png from og-cover.html.
3+
#
4+
# Headless Chrome rather than an SVG rasteriser: the card uses CJK, a bold
5+
# display face and radial gradients, and Chrome is the one renderer on this
6+
# machine that has all three plus the system fonts the design assumes.
7+
set -euo pipefail
8+
9+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10+
REPO="$(cd "$HERE/../.." && pwd)"
11+
OUT="$REPO/static/img/og-cover.png"
12+
CHROME="${CHROME:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}"
13+
14+
if [ ! -x "$CHROME" ]; then
15+
echo "no Chrome at: $CHROME" >&2
16+
echo "set CHROME=/path/to/chrome and re-run" >&2
17+
exit 1
18+
fi
19+
20+
WORK="$(mktemp -d)"
21+
trap 'rm -rf "$WORK"' EXIT
22+
23+
# --headless=new is required: the legacy --headless path hangs indefinitely
24+
# here. --virtual-time-budget bounds the wait so a font that never resolves
25+
# cannot stall the render, and the first-run/extension flags keep a throwaway
26+
# profile from blocking on setup.
27+
"$CHROME" \
28+
--headless=new \
29+
--disable-gpu \
30+
--no-sandbox \
31+
--no-first-run \
32+
--no-default-browser-check \
33+
--disable-extensions \
34+
--hide-scrollbars \
35+
--force-device-scale-factor=1 \
36+
--virtual-time-budget=4000 \
37+
--window-size=2560,1280 \
38+
--screenshot="$WORK/og-cover.png" \
39+
--user-data-dir="$WORK/profile" \
40+
"file://$HERE/og-cover.html" >/dev/null 2>&1 || true
41+
42+
if [ ! -s "$WORK/og-cover.png" ]; then
43+
echo "Chrome produced no image" >&2
44+
exit 1
45+
fi
46+
47+
mv "$WORK/og-cover.png" "$OUT"
48+
echo "wrote $OUT"
49+
command -v sips >/dev/null && sips -g pixelWidth -g pixelHeight "$OUT" | tail -2

‎static/img/og-cover.png‎

-15.2 KB
Loading

0 commit comments

Comments
 (0)