cursor-hook-authoring

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cursor Hook 設計

Cursor Hook 设计

発火タイミング

触发时机

  1. Cursor Cloud Agent 環境で Git hook を追加・変更する
  2. Co-authored-by:
    の自動付与と除去の連鎖を設計する
  3. lefthook 等の既存 hook と Cursor 管理 hook の共存を整理する
  1. 在 Cursor Cloud Agent 环境中添加或修改 Git hook
  2. 设计
    Co-authored-by:
    自动添加和移除的链
  3. 整理 lefthook 等现有 hook 与 Cursor 管理的 hook 之间的共存关系

Git hook と Cursor Cloud の commit-msg 連鎖

Git hook 与 Cursor Cloud 的 commit-msg 链

実行順

执行顺序

Cursor Cloud Agent は
.git/hooks/<hook-name>
を
.dispatcher
経由で差し替える。
commit-msg
の実行順は次のとおり:
  1. ユーザー hook —
    .cursor-original-hooks-path
    が指すパス(通常
    .git/hooks
    )に同名 hook があれば先に実行
  2. Cursor 管理 hook —
    $HOOKS_DIR/$HOOK_NAME.cursor*
    をファイル名の辞書順で順次実行
commit-msg
の典型例:
順序ファイル名役割
1
commit-msg.cursor
シークレットスキャン(commit ブロック)
2
commit-msg.cursor.co-author
Co-authored-by:
を自動付与
3
commit-msg.cursor.co-author-strip
Co-authored-by:
行を除去(プロジェクト strip hook)
MUST: strip hook のベース名は
commit-msg.cursor.co-author-strip
とし、
commit-msg.cursor.co-author
より辞書順で後になる命名にする。NEVER:
commit-msg.cursor.strip-co-author
等、co-author より前に実行される名前を使用する。
Cursor Cloud Agent 通过
.dispatcher
替换
.git/hooks/<hook-name>
。
commit-msg
的执行顺序如下:
  1. 用户 hook — 如果
    .cursor-original-hooks-path
    指向的路径(通常为
    .git/hooks
    )中存在同名 hook,则先执行
  2. Cursor 管理的 hook — 按照文件名的字典序,依次执行
    $HOOKS_DIR/$HOOK_NAME.cursor*
commit-msg
的典型示例:
顺序文件名作用
1
commit-msg.cursor
secret 扫描(commit 内容块)
2
commit-msg.cursor.co-author
自动添加
Co-authored-by:
3
commit-msg.cursor.co-author-strip
移除
Co-authored-by:
行(项目 strip hook)
必须:strip hook 的 basename 必须设为
commit-msg.cursor.co-author-strip
,并确保其命名在字典序上位于
commit-msg.cursor.co-author
之后。绝不能:使用
commit-msg.cursor.strip-co-author
等会在 co-author 之前执行的名称。

strip hook 実装

strip hook 实现

  1. MUST: 除去ロジックは
    .cursor/hooks/strip-co-authored-by.sh
    に置く
  2. MUST:
    commit-msg.cursor.co-author-strip
    は当該スクリプトを呼び出す薄いラッパーとする
  3. MUST: strip 対象は
    Co-authored-by:
    /
    Co-Authored-By:
    行(大文字小文字不問)および直前の空行
  4. NEVER: コミットメッセージ本体(件名・説明)を削除しない
参考実装(
.cursor/hooks/strip-co-authored-by.sh
):
bash
#!/usr/bin/env bash
set -euo pipefail

COMMIT_MSG_FILE="${1:?commit message file required}"

if [ ! -f "$COMMIT_MSG_FILE" ]; then
  exit 0
fi

tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

awk '
  BEGIN { skip_blank = 0 }
  /^[Cc]o-[Aa]uthored-[Bb]y:/ { skip_blank = 1; next }
  skip_blank && /^[[:space:]]*$/ { next }
  { skip_blank = 0; print }
' "$COMMIT_MSG_FILE" > "$tmp"

mv "$tmp" "$COMMIT_MSG_FILE"
trap - EXIT
  1. 必须:将移除逻辑放在
    .cursor/hooks/strip-co-authored-by.sh
    中
  2. 必须:
    commit-msg.cursor.co-author-strip
    必须仅作为调用该脚本的轻量 wrapper
  3. 必须:移除目标包括
    Co-authored-by:
    /
    Co-Authored-By:
    行(不区分大小写)以及紧邻的空行
  4. 绝不能:删除 commit message 主体(主题和详细说明)
参考实现(
.cursor/hooks/strip-co-authored-by.sh
):
bash
#!/usr/bin/env bash
set -euo pipefail

COMMIT_MSG_FILE="${1:?commit message file required}"

if [ ! -f "$COMMIT_MSG_FILE" ]; then
  exit 0
fi

tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

awk '
  BEGIN { skip_blank = 0 }
  /^[Cc]o-[Aa]uthored-[Bb]y:/ { skip_blank = 1; next }
  skip_blank && /^[[:space:]]*$/ { next }
  { skip_blank = 0; print }
' "$COMMIT_MSG_FILE" > "$tmp"

mv "$tmp" "$COMMIT_MSG_FILE"
trap - EXIT

install スクリプト

安装脚本

  1. MUST:
    scripts/install-cursor-agent-hooks.sh
    で strip 連鎖を Cursor hook ディレクトリへ配置する
  2. MUST: install 先は Cursor が
    .git/hooks
    を差し替えている実ディレクトリ(
    readlink -f .git/hooks
    で解決したパスの親、または
    .git/hooks/.cursor-original-hooks-path
    と併用)
  3. MUST:
    commit-msg.cursor.co-author-strip
    に実行権限を付与する
  4. IF: install 先が特定できない; THEN MUST: 手動で
    $CURSOR_AGENT_HOOKS_DIR
    を指定して実行する
  1. 必须:使用
    scripts/install-cursor-agent-hooks.sh
    将 strip 链部署到 Cursor hook 目录
  2. 必须:安装目标必须是 Cursor 用来替换
    .git/hooks
    的实际目录(通过
    readlink -f .git/hooks
    解析出的路径的父目录,或与
    .git/hooks/.cursor-original-hooks-path
    结合使用)
  3. 必须:为
    commit-msg.cursor.co-author-strip
    添加执行权限
  4. 如果:无法确定安装目标;那么必须:手动指定
    $CURSOR_AGENT_HOOKS_DIR
    并执行

lefthook 多層防御

lefthook 多层防御

  1. IF: リポジトリが lefthook を使用する; THEN SHOULD:
    commit-msg
    ジョブに strip スクリプトを追加し、Cursor hook 連鎖と二重に
    Co-authored-by:
    を除去する
  2. IF:
    git-guard.sh
    等で
    git commit --no-verify
    を deny する; THEN MUST: strip 連鎖で
    --no-verify
    なしに
    Co-Authored-By
    禁止を満たす
  3. IF: force push を git-guard で制限する; THEN MUST: 履歴修正が必要な場合は
    GIT_GUARD_ALLOW_FORCE_PUSH=1
    を一時設定し、作業後に元に戻す
  1. 如果:仓库使用 lefthook;那么应该:将 strip 脚本添加到
    commit-msg
    job 中,通过 Cursor hook 链和 lefthook 双重移除
    Co-authored-by:
  2. 如果:使用
    git-guard.sh
    等机制拒绝执行
    git commit --no-verify
    ;那么必须:确保 strip 链在不依赖
    --no-verify
    的情况下仍满足
    Co-Authored-By
    禁止规则
  3. 如果:使用 git-guard 限制 force push;那么必须:在需要修正历史时临时设置
    GIT_GUARD_ALLOW_FORCE_PUSH=1
    ,并在操作完成后恢复原值

テスト手順

测试步骤

  1. MUST:
    scripts/install-cursor-agent-hooks.sh
    を実行する
  2. MUST: テストコミットを作成し、
    git log -1 --format=%B
    で
    Co-authored-by:
    /
    Co-Authored-By:
    が含まれないことを確認する
  3. MUST:
    github
    スキルの
    Co-Authored-By
    禁止ルールと矛盾しないことを確認する
  4. IF: lefthook を使用する; THEN MUST:
    lefthook run commit-msg --commit-msg-file /tmp/test-msg
    で strip を単体検証する
  1. 必须:执行
    scripts/install-cursor-agent-hooks.sh
  2. 必须:创建测试 commit,并通过
    git log -1 --format=%B
    确认其中不包含
    Co-authored-by:
    /
    Co-Authored-By:
  3. 必须:确认测试结果与
    github
    skill 的
    Co-Authored-By
    禁止规则不冲突
  4. 如果:使用 lefthook;那么必须:执行
    lefthook run commit-msg --commit-msg-file /tmp/test-msg
    ,对 strip 进行独立验证

関連スキル

相关 skill

  • github
    : コミット author 指定、
    Co-Authored-By
    禁止、Hook 迂回禁止
  • skill-escalation
    : スキル改変の上流提案
  • refresh-skills
    : スキル追加時の整合性検査
  • github
    :commit author 指定、
    Co-Authored-By
    禁止、禁止绕过 Hook
  • skill-escalation
    :对 skill 变更提出上游建议
  • refresh-skills
    :添加 skill 时进行一致性检查