mcpField
R
recall

recall

github.com/berserkdisruptorsAgent 工作流155281 次安装25 周前更新
代码仓库

关于 recall

面向编码 Agent 的 Git 历史回顾技能,可根据提交记录和工作区差异整理开发脉络。支持分支简报、范围查询及按行动类型检索,突出决策、约束和已否决方案。

主要功能

  1. 01汇总分支提交与未提交差异
  2. 02按范围检索上下文行动记录
  3. 03按行动类型筛选历史信息
  4. 04整理意图、决策、约束和否决项

适用场景

  1. 01开始分支工作前了解已有上下文
  2. 02继续开发时查看当前进展与改动
  3. 03决策前检索特定领域的否决记录
  4. 04整理主分支近期开发活动

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/berserkdisruptors/contextual-commits --skill recall

安装后在 Claude Code 中输入/recall确认已加载。

详细介绍

上下文回顾

根据上下文提交历史还原开发历程,并以自然的简报形式呈现。

参数检测

检查 recall 的调用方式:

  • 无参数 — 运行默认模式(下方的完整分支/会话简报)。
  • 单独的词(例如 recall auth)— 将其视为范围查询。跳转到范围查询。
  • word(word) 模式(例如 recall rejected(auth))— 将其视为操作+范围查询。跳转到操作+范围查询。

默认模式(无参数)

第 1 步:检测分支状态

确定工作状态:

CURRENT_BRANCH=$(git branch --show-current)
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")

# Find the actual parent branch, not just the repo default.
# Try upstream tracking branch first (fast path).
BASE_BRANCH=$(git rev-parse --abbrev-ref @{upstream} 2>/dev/null | sed 's|^origin/||')

# If no upstream, find the nearest local branch by commit distance.
if [ -z "$BASE_BRANCH" ]; then
    BASE_BRANCH=$(git for-each-ref --format='%(refname:short)' refs/heads/ | while read branch; do
        [ "$branch" = "$CURRENT_BRANCH" ] && continue
        echo "$(git log --oneline "$branch..$CURRENT_BRANCH" 2>/dev/null | wc -l | tr -d ' ') $branch"
    done | sort -n | head -1 | awk '{print $2}')
fi

# Final fallback to default branch.
BASE_BRANCH=${BASE_BRANCH:-$DEFAULT_BRANCH}

UNSTAGED=$(git diff --stat)
STAGED=$(git diff --cached --stat)
BRANCH_COMMITS=$(git log ${BASE_BRANCH}..HEAD --oneline 2>/dev/null | wc -l | tr -d ' ')

DEFAULT_BRANCH 用于识别仓库的主分支(检测场景 C/D)。BASE_BRANCH 用于识别最近的祖先分支——当功能分支从非默认分支创建时(例如,从 develop 创建功能分支),两者可能不同。所有相对于分支的查询都使用 BASE_BRANCH。

第 2 步:收集原始材料
场景 A — 位于有提交的功能分支

这是信息最丰富的场景。收集:

# Contextual action lines from all branch commits
git log ${BASE_BRANCH}..HEAD --format="%H%n%s%n%b%n---COMMIT_END---"

# Unstaged changes (what's in progress right now)
git diff --stat
git diff  # read the actual diff for key changes

# Staged changes
git diff --cached --stat
场景 B — 位于尚无提交的功能分支
# Unstaged and staged changes only
git diff --stat
git diff --cached --stat

# Last few commits on the parent branch for project context
git log ${BASE_BRANCH} -10 --format="%H%n%s%n%b%n---COMMIT_END---"
场景 C — 位于默认分支
# Recent commit history with contextual action lines
git log -20 --format="%H%n%s%n%b%n---COMMIT_END---"
场景 D — 位于有未提交更改的默认分支
# Same as C plus uncommitted changes
git log -20 --format="%H%n%s%n%b%n---COMMIT_END---"
git diff --stat
git diff --cached --stat
第 3 步:提取操作行

从收集到的提交正文中,提取符合以下条件的行:

^(intent|decision|rejected|constraint|learned)\(

按提交分组(保留时间顺序),并按类型分组(用于综合整理)。

第 4 步:综合整理输出

优先保证信息密度,而非叙述流畅度。 输出应简洁、易于浏览,并完全基于提交和差异所展示的内容。每一行都应包含可采取行动的信息。不要添加空话或对话式铺垫。

场景 A(有提交的分支):

先输出分支状态,然后将上下文操作行综合整理成简明简报,并按对后续工作的重要性组织内容。

示例输出:

Branch: feat/google-oauth (4 commits ahead of main, unstaged changes in tests/)

Active intent: Add Google as first social login provider. GitHub and Apple to follow.
Approach: passport.js with /api/auth/callback/:provider convention.
Rejected: auth0-sdk — session model incompatible with redis store.
Constraints:
  - Redis session TTL 24h, tokens must refresh within window
  - Callback routes must follow existing :provider pattern
Learned: passport-google needs explicit offline_access scope for refresh tokens.
In progress: Integration tests for callback handler (unstaged).

从非默认分支创建时:

Branch: feat/oauth-refresh (2 commits ahead of develop, no uncommitted changes)

Active intent: Implement token refresh for OAuth providers.
Constraint: Must stay compatible with the session store changes on develop.

优先级顺序:

  1. 当前意图(我们正在构建什么,以及原因)
  2. 当前方案(已做出的决策)
  3. 已否决的方案(不应再次探索的方向——至关重要)
  4. 约束(不可逾越的边界)
  5. 经验(可节省时间的信息)
  6. 进行中的工作(未暂存/已暂存的更改)

如果分支期间意图发生变化(方向转变),应同时展示原始意图和当前意图,让这一变化清晰可见。

场景 B(没有提交的分支):
Branch: feat/new-feature (0 commits ahead of develop)

No contextual history on this branch yet.
Staged: 2 files (src/auth/provider.ts, src/auth/types.ts)
Unstaged: none

Recent project activity (from develop):
  - Auth: OAuth provider framework merged, Google working
  - Payments: Multi-currency support shipped (EUR, GBP alongside USD)
场景 C(默认分支,无更改):

综合整理最近 20 个提交中的已合并工作。按活动领域分组,并突出显示适用于更广范围的当前约束或经验。

Recent project activity:

Auth: OAuth provider framework merged. Google working, GitHub and Apple planned.
  - Rejected auth0-sdk (session model incompatible with redis store)
  - Constraint: redis session TTL 24h, tokens must refresh within window

Payments: Multi-currency support shipped (USD, EUR, GBP).
  - Per-transaction currency, not account-level
  - Constraint: Stripe locks currency at PaymentIntent creation
  - Learned: presentment ≠ settlement currency in Stripe

What do you want to work on?
场景 D(有未提交更改的默认分支):

与场景 C 相同,但在最上方注明未提交的更改。

完全没有上下文提交时

如果历史记录中有规范提交,却没有上下文操作行,仍应根据现有内容提供有用的输出:

Branch: main (no contextual commits found in recent history)

Recent activity (from commit subjects):
  - auth: 6 commits (OAuth implementation, middleware updates) — 2 days ago
  - payments: 4 commits (currency handling, Stripe integration) — last week
  - tests: 3 commits — last week
  - config: 2 commits

Most recent: feat(auth): implement Google OAuth provider

No explicit intent, decisions, or constraints are captured in commit history.
Using the contextual-commit skill on future commits will surface
the reasoning behind changes that commit subjects alone cannot show.

这样既能如实说明信号质量,也能提供有用的方向指引。建议采用此技能是自然的下一步,而不是推销。

指南
  • 简洁明了,不要对话式表达。 每一行都应承载信息。不要写“以下是目前的进展”或“让我来介绍一下”。
  • 以数据为依据。 只报告操作行、提交主题和差异实际展示的内容。不要推断、猜测或填补空白。
  • 突出已否决的方案。 这是价值最高的信号,可以避免重复探索。
  • 存在多个范围时按范围分组。 在历史记录较广的默认分支上,应按领域而非时间顺序组织内容。
  • 以提问收尾。 用“你想开展什么工作?”或类似的话结束。保持简短。
  • 根据数据量调整篇幅。 如果有 2 个上下文提交,输出 3–4 行;如果有 20 个,就写成几个分组段落。不要把稀疏数据扩写成冗长内容。

范围查询(recall <scope>)

针对给定范围查询整个仓库历史记录。前缀匹配:auth 可匹配 auth、auth-tokens、auth-library 等。

步骤 1:查询
git log --all --grep="(${SCOPE}" --format="%H%n%s%n%b%n---COMMIT_END---"
步骤 2:提取

从收集到的提交正文中,提取匹配以下内容的行:

grep -E "^(intent|decision|rejected|constraint|learned)\(${SCOPE}"

这会提取所有范围以查询词开头的操作行。

步骤 3:输出

按操作类型分组,每组内按时间顺序排列。注明找到的子范围。

示例(recall auth):

Scope: auth (also found: auth-tokens, auth-library)

intent:
  - social login starting with Google, then GitHub and Apple
  - original session approach incompatible with redis cluster setup

decision:
  - passport.js over auth0-sdk for multi-provider flexibility
  - JWT with short expiry + refresh token pattern

rejected:
  - auth0-sdk — locks into their session model, incompatible with redis store
  - auth-sessions — redis cluster doesn't support session stickiness needed by passport sessions

constraint:
  - callback routes must follow /api/auth/callback/:provider pattern per existing convention
  - redis 24h TTL means tokens must refresh within that window

learned:
  - passport-google needs explicit offline_access scope for refresh tokens
  - redis-cluster session affinity requires sticky sessions at load balancer level — too invasive

如果未找到匹配项,请明确说明,并建议检查范围名称。


操作+范围查询(recall <action>(<scope>))

针对给定范围查询整个仓库历史记录中的特定操作类型。

步骤 1:查询
git log --all --grep="${ACTION}(${SCOPE}" --format="%H%n%s%n%b%n---COMMIT_END---"
步骤 2:提取
grep "^${ACTION}(${SCOPE}"
步骤 3:输出

按时间顺序排列的列表,并附上提交主题以标明来源。

示例(recall rejected(auth)):

rejected(auth) across history:

  - auth0-sdk — locks into their session model, incompatible with redis store
    from: feat(auth): implement Google OAuth provider

  - auth-sessions — redis cluster doesn't support session stickiness needed by passport sessions
    from: refactor(auth): switch from session-based to JWT tokens

如果未找到匹配项,请明确说明。


主动使用

在任何范围内做出重要决策之前,先检查该范围的 rejected 和 constraint 行:

git log --all --grep="rejected(${SCOPE}" --format="%b" | grep "^rejected(${SCOPE}"
git log --all --grep="constraint(${SCOPE}" --format="%b" | grep "^constraint(${SCOPE}"

如果之前的提交针对你即将提出的方法记录了 rejected 行,请在再次提出之前,先向用户说明拒绝原因。拒绝意见可能仍然有效,也可能情况已经变化;但用户应在掌握完整背景的情况下做出判断,而不是再次走进同一个死胡同。

同样,在提出可能违反已知边界的方法之前,也要检查 constraint 行。

这项检查很轻量,对于你正在处理的任何范围,都应养成习惯。

评论

支持 Markdown