网站技能
在 handley-lab.github.io 仓库内工作时使用此技能。它编码了 CLAUDE.md 中的网站约定以及添加食谱和其他内容的工作流程。
何时使用
- 用户想要在网站上添加或编辑内容。
- 用户想要本地预览他们的更改。
- 用户想要发布一个食谱(卡片和可选的长格式配套页面)。
recipe技能(或其他内容技能)将草稿移交以供预览。
Bootstrap
每台机器执行一次:
script/bootstrap # gem install bundler && bundle install
本地预览
script/server # bundle exec jekyll serve, http://127.0.0.1:4000
实时重载会捕获对 *.md、_data/*.yml、_layouts/*.html、_includes/*.html 以及 _recipes/ 中集合文件的编辑。
构建检查
在提交之前:
script/build # bundle exec jekyll build → _site/
如果你修改了任何可能暴露 skills/ 的内容,也要运行泄露检查。该仓库有意同时包含一个公开的 skills.md 页面(发布到 /skills/)和一个私有的 skills/ 源目录(从构建中排除)。这种组合很微妙——这些检查使区分变得明确:
# 公开市场页面必须存在。
test -f _site/skills/index.html
# 原始技能文件绝对不能泄露。
test ! -e _site/skills/website
test ! -e _site/skills/recipe
test ! -e _site/skills/README.md
# _site/skills/ 下除 index.html 和构建资源外的任何其他内容都是泄露。
find _site/skills -mindepth 1 ! -name index.html ! -name '*.css' ! -name '*.js' -print
最后的 find 命令应该什么都不打印。
script/cibuild # 构建,断言 _site/index.html 存在,然后删除 _site
如果 script/cibuild 退出码为 0(打印 "It builds!"),则网站构建成功。
AI Cookbook 内容模型
两个层面:
_data/recipes.yml— 在/cookbook/显示的食谱卡片列表。每个食谱都有一张卡片。_recipes/<id>.md— 在/cookbook/<id>/渲染的可选配套页面。为卡片添加一个“阅读完整食谱”链接。
纯卡片条目是有效的。长度是食谱的一个属性;有些食谱是 3-4 分钟的阅读,没有配套页面,另一些则有值得链接出去的长文。
添加或编辑食谱卡片
食谱卡片只存在于 _data/recipes.yml 中。它们不需要 _recipes/ 中的文件。
- id: <id>
title: "..." # 纯描述性——说明它是什么,而不是它有多巧妙
category: "..." # 例如 上下文工程, 研究传播
timebox: "..." # 例如 10 分钟, 一个下午, 多次会话
status: "Draft" # 存根 | 草稿 | 进行中 | 已完成
proposer: "..." # 可选;用于工作坊署名
summary: "..." # 1-2 句。先说成为可能的事,而不是什么有效率。
outcome: "..." # 必填,必须非空 (存根: ... 可以接受)
evidence: "..." # 必填,必须非空 (存根: ... 可以接受)
demo_url:
repo_url: "..."
在 2026 年 5 月 5 日工作坊及任何后续工作坊期间,倾向于将食谱卡片 YAML 发布到协调问题的编排器批量合并中,而不是针对 _data/recipes.yml 打开多个冲突的 PR——该文件在并行编辑下是一个合并冲突磁铁。
为食谱添加长格式配套页面
一个长格式食谱有两半必须保持同步:
- 卡片 —
_data/recipes.yml中的一个条目。在/cookbook/和首页预览块上渲染。 - 配套页面 —
_recipes/<id>.md中的一个文件。在/cookbook/<id>/渲染。
卡片包含 (_includes/recipe_card.html) 通过集合 slug 发现匹配的配套页面——Jekyll 从文件名自动派生 slug。因此 <id>(卡片字段、配套页面的 frontmatter id 和文件名)必须全部一致。 否则“阅读完整食谱”链接不会出现。
步骤 1 — 选择 <id> 并检查它是否未被使用
- 使用 kebab-case(例如
jaxwavelets、gw-emulator、cosmosis-cobaya-port)。 - 在它必须一致的所有三个位置(文件名、卡片
id、配套 frontmatterid)唯一。
脚本检查(使用你选择的 <id> 运行):
id="<id>"
fail=0
# 1. 卡片 id 不得存在于 _data/recipes.yml
if grep -nE "^- id: ${id}\$" _data/recipes.yml; then
echo "错误: _data/recipes.yml 中已存在 id: ${id}"; fail=1
fi
# 2. 配套文件名不得存在
if test -e "_recipes/${id}.md"; then
echo "错误: _recipes/${id}.md 已存在"; fail=1
fi
# 3. 配套 frontmatter id 不得以其他文件名存在
if grep -RsnE "^id: ${id}\$" _recipes; then
echo "错误: 另一个 _recipes/*.md 已包含 id: ${id}"; fail=1
fi
[ "$fail" = 0 ] && echo "OK: ${id} 可用"
如果任何检查失败,请选择不同的 id。不要覆盖。
步骤 2 — 创建功能分支
git checkout -b recipe/<id>
先创建分支,再写入——未提交的更改会迁移过去,但一开始就将编辑限制在分支内更清晰。永远不要直接推送到 main。
步骤 3 — 编写 _recipes/<id>.md
Frontmatter 必须包含完整的卡片模式(以便页面自文档化且布局拥有所需数据):
---
id: <id>
title: "..."
category: "..."
timebox: "..."
status: "Draft" # 存根 | 草稿 | 进行中 | 已完成
summary: "..."
outcome: "..."
evidence: "..."
demo_url: # 可选;保留字段为空或完全省略
repo_url: "..." # 可选
author: "..."
date: YYYY-MM-DD
---
status 接受 "Stub"、"Draft"、"In progress" 或 "Complete"。outcome 和 evidence 必须非空(对于存根,用 Stub: ... 开头,而不是留空)。
然后是长格式正文。不要写前导正文 H1——_layouts/recipe.html 将 {{ page.title }} 渲染为 H1。从 ## Section 开始正文。
使用 _recipes/jaxwavelets.md 作为参考模板(需要注意的是,在 2026 年 5 月 5 日工作坊中,其执行被批评为过长和过于密集——倾向于 3-4 分钟的阅读,并在 Methods 注释中提供详细信息)。
步骤 4 — 将匹配的卡片追加到 _data/recipes.yml
- id: <id> # 必须与 _recipes/<id>.md 匹配
title: "..."
category: "..."
timebox: "..."
status: "..."
summary: "..."
outcome: "..." # 必填,必须非空
evidence: "..." # 必填,必须非空
demo_url:
repo_url: "..."
不要提交空的 outcome 或 evidence。如果你无法编写它们,则食谱尚未准备好发布。
步骤 5 — 预览
运行 script/server(或刷新运行中的服务器)。访问:
/cookbook/<id>/— 配套页面渲染,frontmatter 标题作为 H1,如果需要则加载 MathJax。/cookbook/— 新卡片出现,带有可用的“阅读完整食谱”链接。/— 如果<id>在前三张卡片中,首页预览块会反映更改。
步骤 6 — 构建检查 + 提交
script/cibuild # 如果一切正常则退出码为 0
git add _recipes/<id>.md _data/recipes.yml
git commit -m "添加 <id> 食谱"
git push -u origin recipe/<id>
gh pr create # 如果 gh 未认证,则在 GitHub Web UI 中打开 PR
未经用户明确同意,此技能不得修改的文件
_posts/— 当前正在审计;新文章通过 PR 审核(请参阅下面的 Papers)。assets/group/group.yaml— 通过script/calculate管理。_config.yml— 网站范围配置;需要用户明确同意。script/*— 构建脚本;需要用户明确同意。
Papers (_posts/)
_posts/ 目录历史上包含来自 script/posts/arxiv.py 的自动生成 arXiv 摘要。截至 2026 年 5 月 5 日,这些正在被审计:_posts/ 中的任何内容都不应假定为经过人工审查,并且 /papers/ 页面正在重建,仅显示经 PR 审查的条目。如有疑问,不要直接添加到 _posts/——打开一个 PR 并请求人工审查。
常见故障模式
- 缺少“阅读完整食谱”链接:文件名 slug 与卡片的
id不匹配。验证_recipes/<id>.md存在且卡片具有id: <id>。 - 页面上出现重复 H1:正文以
# ...开头。去掉它;布局从{{ page.title }}添加 H1。 - “结果:” / “证据:”标签为空:卡片字段是
""。填充它们;没有它们,食谱就不准备好发布。 - 编辑
_config.yml后构建失败:集合或默认作用域语法错误。当前集合是recipes(小写),带有permalink: /cookbook/:path/。