Communitygithub.com

handley-lab/handley-lab.github.io 网站技能

用于管理 handley-lab.github.io Jekyll 网站:启动、预览、构建、编辑数据文件、添加 AI Cookbook 食谱(卡片及可选配套页面)、在功能分支上提交并创建 PR。

handley-lab.github.io 网站技能 是什么?

此技能专为在 handley-lab.github.io Jekyll 网站仓库中工作的 AI 代理设计。它封装了网站的全部约定和工作流程,使用户能够高效地添加或编辑内容,特别是 AI Cookbook 的食谱。技能涵盖了从初始 Bootstrap 和本地预览 (`script/server`) 到构建检查 (`script/cibuild`) 的完整开发周期。核心功能是管理“AI Cookbook”内容模型,该模型包含两个部分:`_data/recipes.yml` 中的纯卡片条目和 `_recipes/` 目录下可选的配套长文页面。技能提供了详细的逐步说明,用于创建唯一 ID、建立功能分支、同步卡片与页面数据、预览更改并提交 PR,同时严格防止技能文件泄露和未授权的文件修改。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/handley-lab/handley-lab.github.io/tree/HEAD/skills/website

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

网站技能

在 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——该文件在并行编辑下是一个合并冲突磁铁。

为食谱添加长格式配套页面

一个长格式食谱有两半必须保持同步:

  1. 卡片 — _data/recipes.yml 中的一个条目。在 /cookbook/ 和首页预览块上渲染。
  2. 配套页面 — _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、配套 frontmatter id)唯一。

脚本检查(使用你选择的 <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/。

相关技能