sync
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<objective>
Reconcile the codebase state with Linear. Detect mismatches between git history and issue statuses
across 10 gap categories. Consolidate project-level objectives across Linear, GSD, and CLAUDE.md.
Surface gaps and ask the user how to resolve each one. Clean up stale branches, duplicate issues,
and orphaned refs. End by routing to the most impactful next action.
</objective>
<context>
Input: $ARGUMENTS — mode selector
- (empty) or "full" → all gap categories + consolidation + interactive resolution (default)
- "quick" → report only, no interactive resolution or consolidation
- "--consolidate" → only run the objectives alignment step
Requires: git repo, `linear` CLI authenticated
Optional: .planning/ directory (GSD state), CLAUDE.md, .linear-project
Error handling convention for ALL bash commands in this skill:
- IF command exits non-zero → capture stderr, print diagnostic, then retry or fallback:
✗ {command} failed: {stderr summary} → Try: {suggested fix} → Fallback: {what the skill does instead} - IF command returns empty stdout when a result is expected → treat as ⚠ warn, note it, proceed with fallback
- Never stop the entire skill for a single command failure — degrade gracefully and skip the affected section </context>
<objective>
协调代码库状态与Linear的一致性。跨10个差异类别检测git历史与issue状态之间的不匹配情况。整合Linear、GSD和CLAUDE.md中的项目级目标。展示所有差异并询问用户每个差异的解决方式。清理过时分支、重复issue和孤立引用。最后为用户推荐优先级最高的下一步操作。
</objective>
<context>
输入:$ARGUMENTS — 模式选择器
- (空)或 "full" → 全量检测所有差异类别+目标整合+交互解决(默认)
- "quick" → 仅生成报告,不进行交互解决或目标整合
- "--consolidate" → 仅运行目标对齐步骤
依赖:git仓库、已完成身份验证的`linear` CLI
可选:.planning/ 目录(GSD状态)、CLAUDE.md、.linear-project
本技能中所有bash命令的错误处理约定:
- 如果命令退出码非0 → 捕获stderr,打印诊断信息,然后重试或使用降级方案:
✗ {command} failed: {stderr summary} → Try: {suggested fix} → Fallback: {what the skill does instead} - 如果预期有返回结果但命令返回空stdout → 视为⚠警告,记录后使用降级方案继续执行
- 永远不要因为单个命令失败停止整个技能的运行——优雅降级并跳过受影响的部分 </context>
0. Parse Arguments & Validate Environment
0. 解析参数并验证环境
Parse mode from $ARGUMENTS:
- IF empty or "full" → MODE=full
- IF "quick" → MODE=quick
- IF "--consolidate" → MODE=consolidate
- IF unrecognized → show usage and stop: "Usage: /product:sync [quick|full|--consolidate]"
Check git repo:
- Run
git rev-parse --is-inside-work-tree 2>&1 - IF exit code non-zero → stop:
"✗ Not inside a git repo. Run or cd into your project."
git init - Run → store HAS_REMOTE (true if any remote configured)
git remote -v 2>/dev/null
Check Linear CLI:
- Run
linear auth whoami 2>&1 - IF command not found → set LINEAR_AVAILABLE=false, warn:
✗ linear CLI not found → Try: Install from https://github.com/schpet/linear-cli → Fallback: Running git-only sync (Linear checks will be skipped) - ELIF output contains "not authenticated" or "unauthorized" or exit code non-zero → set LINEAR_AVAILABLE=false, warn:
✗ linear CLI not authenticated → Try: Run `linear auth` to log in → Fallback: Running git-only sync (Linear checks will be skipped) - ELSE → LINEAR_AVAILABLE=true
Read project scope:
- IF exists:
.linear-project- Read file and trim whitespace/newlines:
PROJECT=$(cat .linear-project | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') - IF trimmed value is empty → warn: "exists but is empty. Continuing unscoped."
.linear-project - ELIF LINEAR_AVAILABLE:
- Validate project exists:
linear project list 2>&1 | grep -qi "$PROJECT" - IF not found → warn:
Set PROJECT="" (clear it)
⚠ Project '{PROJECT}' not found in Linear. It may have been renamed or archived. → Try: Update `.linear-project` or run `/product:init-project` to relink → Fallback: Continuing unscoped (showing all projects) - ELSE → note: "Scoped to Linear project: {PROJECT}"
- Validate project exists:
- Build PROJECT_FLAG:
${PROJECT:+--project '$PROJECT'}
- Read file and trim whitespace/newlines:
- IF missing → warn: "No
.linear-projectfound — showing issues from all projects. Run.linear-projectto link one."/product:init-project
Print header:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRODUCT ► SYNC [{PROJECT or "All Projects"}] ({MODE})
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━IF MODE=consolidate → skip to Step 3.
从$ARGUMENTS解析运行模式:
- 如果为空或 "full" → MODE=full
- 如果为 "quick" → MODE=quick
- 如果为 "--consolidate" → MODE=consolidate
- 如果无法识别 → 展示用法后退出: "Usage: /product:sync [quick|full|--consolidate]"
检查git仓库:
- 运行
git rev-parse --is-inside-work-tree 2>&1 - 如果退出码非0 → 退出:
"✗ 不在git仓库内。请运行或进入你的项目目录。"
git init - 运行 → 存储HAS_REMOTE(如果配置了任何远程仓库则为true)
git remote -v 2>/dev/null
检查Linear CLI:
- 运行
linear auth whoami 2>&1 - 如果提示命令未找到 → 设置LINEAR_AVAILABLE=false,输出警告:
✗ linear CLI not found → Try: Install from https://github.com/schpet/linear-cli → Fallback: Running git-only sync (Linear checks will be skipped) - 否则如果输出包含 "not authenticated" 或 "unauthorized" 或退出码非0 → 设置LINEAR_AVAILABLE=false,输出警告:
✗ linear CLI not authenticated → Try: Run `linear auth` to log in → Fallback: Running git-only sync (Linear checks will be skipped) - 否则 → LINEAR_AVAILABLE=true
读取项目范围:
- 如果文件存在:
.linear-project- 读取文件并去除空白/换行符:
PROJECT=$(cat .linear-project | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') - 如果处理后的值为空 → 警告:"存在但内容为空。将不限制项目范围继续运行。"
.linear-project - 否则如果LINEAR_AVAILABLE为true:
- 验证项目是否存在:
linear project list 2>&1 | grep -qi "$PROJECT" - 如果未找到 → 警告:
设置PROJECT=""(清空值)
⚠ Project '{PROJECT}' not found in Linear. It may have been renamed or archived. → Try: Update `.linear-project` or run `/product:init-project` to relink → Fallback: Continuing unscoped (showing all projects) - 否则 → 提示:"限定在Linear项目:{PROJECT}"
- 验证项目是否存在:
- 构建PROJECT_FLAG:
${PROJECT:+--project '$PROJECT'}
- 读取文件并去除空白/换行符:
- 如果不存在 → 警告: "未找到
.linear-project— 将展示所有项目的issue。运行.linear-project可关联指定项目。"/product:init-project
打印头部信息:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRODUCT ► SYNC [{PROJECT or "All Projects"}] ({MODE})
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━如果MODE=consolidate → 直接跳转到步骤3。
1. Gather State
1. 收集状态数据
Collect data from all available sources. Run independent commands in parallel where possible.
From Linear (skip entirely if LINEAR_AVAILABLE=false):
- → in-progress issues
linear issue list -s started --limit 20 $PROJECT_FLAG 2>&1- IF fails → warn and set STARTED_ISSUES=empty
- → backlog
linear issue list -s unstarted --limit 20 $PROJECT_FLAG 2>&1- IF fails → warn and set BACKLOG_ISSUES=empty
- → recently completed
linear issue list -s completed --limit 10 $PROJECT_FLAG 2>&1- IF fails → warn and set COMPLETED_ISSUES=empty
- → recently cancelled (for orphan detection)
linear issue list -s cancelled --limit 10 $PROJECT_FLAG 2>&1- IF fails → warn and set CANCELLED_ISSUES=empty
From Git:
- → recent commits
git log --oneline -30 2>&1- IF repo has no commits → note "Empty repo, no commits yet" and skip git-based gap detection
- → commits on default branch only (for squash-merge detection)
git log --oneline --first-parent main -30 2>/dev/null || git log --oneline --first-parent master -30 2>/dev/null- IF fails (no main/master) → skip squash-merge detection, note which default branch was tried
- → local branches
git branch --list 2>&1 - → remote branches merged into default (only if HAS_REMOTE)
git branch -r --merged main 2>/dev/null || git branch -r --merged master 2>/dev/null - → detect force-pushes/rebases
git reflog --since="7 days ago" --no-decorate 2>/dev/null | head -50 - Current branch name:
git branch --show-current 2>&1
From GSD (if .planning/ exists):
- Read for current phase context
.planning/STATE.md - Read for phase list and completion status
.planning/ROADMAP.md - Read for project objectives
.planning/PROJECT.md - IF any file missing → skip silently (GSD is optional)
从所有可用来源收集数据。尽可能并行运行独立命令。
来自Linear(如果LINEAR_AVAILABLE=false则完全跳过):
- → 进行中的issue
linear issue list -s started --limit 20 $PROJECT_FLAG 2>&1- 如果运行失败 → 警告并设置STARTED_ISSUES为空
- → 待办issue
linear issue list -s unstarted --limit 20 $PROJECT_FLAG 2>&1- 如果运行失败 → 警告并设置BACKLOG_ISSUES为空
- → 近期完成的issue
linear issue list -s completed --limit 10 $PROJECT_FLAG 2>&1- 如果运行失败 → 警告并设置COMPLETED_ISSUES为空
- → 近期取消的issue(用于孤立资源检测)
linear issue list -s cancelled --limit 10 $PROJECT_FLAG 2>&1- 如果运行失败 → 警告并设置CANCELLED_ISSUES为空
来自Git:
- → 近期提交记录
git log --oneline -30 2>&1- 如果仓库没有提交 → 提示"空仓库,暂无提交"并跳过基于git的差异检测
- → 仅默认分支的提交记录(用于压缩合并检测)
git log --oneline --first-parent main -30 2>/dev/null || git log --oneline --first-parent master -30 2>/dev/null- 如果运行失败(没有main/master分支) → 跳过压缩合并检测,提示尝试过的默认分支名称
- → 本地分支列表
git branch --list 2>&1 - → 已合并到默认分支的远程分支(仅当HAS_REMOTE为true时运行)
git branch -r --merged main 2>/dev/null || git branch -r --merged master 2>/dev/null - → 检测强制推送/变基操作
git reflog --since="7 days ago" --no-decorate 2>/dev/null | head -50 - 当前分支名称:
git branch --show-current 2>&1
来自GSD(如果.planning/目录存在):
- 读取获取当前阶段上下文
.planning/STATE.md - 读取获取阶段列表和完成状态
.planning/ROADMAP.md - 读取获取项目目标
.planning/PROJECT.md - 如果任意文件缺失 → 静默跳过(GSD为可选依赖)
2. Detect Gaps
2. 检测差异
IF LINEAR_AVAILABLE=false → only detect git-only gaps (working tree, stale branches). Skip all Linear-dependent categories.
Compare sources and classify each finding into exactly one bucket:
| Status | Definition |
|---|---|
| Synced | Linear status matches git state (e.g., in-progress + recent commits on branch) |
| Stale in Linear | Issue is "In Progress" but no commits referencing it in 48h+ |
| Untracked work | Commits reference an issue ID but Linear still shows "Unstarted" |
| Done but open | Branch merged or squash-merged into default branch, but Linear issue not moved to Done |
| Orphan branch | Local branch references a Linear issue that is cancelled, done, or doesn't exist |
| Missing branch | Linear issue is "In Progress" but no matching local branch exists |
| Squash-merged | Issue ID appears in default branch's first-parent commit messages, but Linear status is still "Started" — detected via |
| Rebased/force-pushed | Branch reflog shows rebase or force-push entries for a branch mapped to an active issue — informational, flagged as ⚠ |
| Direct-to-main | Commits on default branch reference an issue ID (e.g., |
| Unassigned in-progress | Linear issue is "In Progress" but has no assignee |
Detection logic:
-
Synced: For each in-progress Linear issue, check if a local branch contains the issue ID (e.g.,in branch name) AND has commits within the last 48h referencing it.
eng-123 -
Stale in Linear: In-progress issues wherereturns empty.
git log --all --oneline --since="48 hours ago" | grep -i "$ISSUE_ID" -
Untracked work:extracts issue IDs from recent commits, cross-reference against Linear unstarted list.
git log --oneline -30 | grep -oiE '[A-Z]+-[0-9]+' -
Done but open: Check(or master) for branches containing issue IDs that are still "Started" in Linear. Also check first-parent log for squash-merge references.
git branch --merged main -
Orphan branch: Extract issue IDs from branch names (), check against cancelled/done issues list.
git branch --list | grep -oiE '[a-z]+-[0-9]+' -
Missing branch: In-progress Linear issues where no local branch contains the issue ID.
-
Squash-merged: Issue IDs found inthat are still "Started" in Linear but have no open feature branch.
git log --first-parent main --oneline -
Rebased/force-pushed: Parsefor lines containing "rebase" or "reset" on branches that match active issue IDs. Flag as informational.
git reflog -
Direct-to-main: Issue IDs in default branch commits that have no corresponding branch in.
git branch --list -
Unassigned in-progress: From Linear data, check started issues for missing assignee field (parseoutput).
linear issue list
如果LINEAR_AVAILABLE=false → 仅检测纯git相关的差异(工作树、过时分支)。跳过所有依赖Linear的类别。
对比多源数据,将每个发现归类到唯一的分类桶中:
| 状态 | 定义 |
|---|---|
| 已同步 | Linear状态与git状态匹配(例如:进行中 + 对应分支有近期提交) |
| Linear中状态过时 | Issue标记为"进行中",但48小时以上没有关联提交 |
| 未跟踪工作 | 提交记录关联了issue ID,但Linear中对应issue仍显示为"未开始" |
| 已完成但未关闭 | 分支已合并或压缩合并到默认分支,但Linear issue未移动到已完成 |
| 孤立分支 | 本地分支关联的Linear issue已取消、已完成或不存在 |
| 分支缺失 | Linear issue标记为"进行中",但不存在对应的本地分支 |
| 已压缩合并 | Issue ID出现在默认分支的首父提交消息中,但Linear状态仍为"进行中"——通过 |
| 已变基/强制推送 | 关联活跃issue的分支的reflog中存在变基或强制推送记录——信息类标记,标注为⚠ |
| 直接提交到主分支 | 默认分支的提交关联了issue ID(例如 |
| 进行中issue未分配 | Linear issue标记为"进行中"但没有经办人 |
检测逻辑:
-
已同步:对于每个进行中的Linear issue,检查是否存在包含对应issue ID(例如分支名含)的本地分支,且该分支近48小时内有相关提交。
eng-123 -
Linear中状态过时:进行中的issue执行返回空结果。
git log --all --oneline --since="48 hours ago" | grep -i "$ISSUE_ID" -
未跟踪工作:从近期提交中提取issue ID,与Linear未开始列表交叉比对。
git log --oneline -30 | grep -oiE '[A-Z]+-[0-9]+' -
已完成但未关闭:检查(或master)中包含issue ID且Linear中仍为"进行中"的分支。同时检查首父提交日志中的压缩合并引用。
git branch --merged main -
孤立分支:从分支名中提取issue ID(),与已取消/已完成issue列表比对。
git branch --list | grep -oiE '[a-z]+-[0-9]+' -
分支缺失:进行中的Linear issue没有对应的含issue ID的本地分支。
-
已压缩合并:中存在的issue ID,Linear中仍为"进行中"且没有未合并的特性分支。
git log --first-parent main --oneline -
已变基/强制推送:解析中关联活跃issue ID的分支对应的含"rebase"或"reset"的记录,标记为信息类提示。
git reflog -
直接提交到主分支:默认分支提交中的issue ID在中没有对应分支。
git branch --list -
进行中issue未分配:从Linear数据中检查进行中issue的经办人字段是否缺失(解析输出)。
linear issue list
3. Consolidate Objectives
3. 整合目标
IF MODE=quick → skip this step.
Compare three sources of truth for project-level alignment:
Source 1 — Linear project (if LINEAR_AVAILABLE and PROJECT is set):
- Run → extract milestones, description, target dates
linear project view "$PROJECT" 2>&1 - IF command fails or project not set → note "Linear project metadata unavailable" and skip this source
Source 2 — GSD planning (if .planning/ exists):
- Read → extract phase names and completion status
.planning/ROADMAP.md - Read → extract stated objectives and timeline
.planning/PROJECT.md - IF files missing → note "GSD planning state unavailable" and skip this source
Source 3 — CLAUDE.md (if exists at repo root):
- Read → extract any goals, objectives, or project description sections
CLAUDE.md - IF missing → skip this source
Cross-reference:
- Does every Linear milestone have a corresponding GSD phase?
- Does CLAUDE.md mention goals not tracked in Linear or GSD?
- Are there GSD phases with no matching Linear milestone (future work is okay)?
Present alignment table:
Objective Alignment:
─────────────────────
✓ "Auth system" — Linear milestone ↔ GSD Phase 3 ↔ CLAUDE.md
⚠ "API redesign" — Linear milestone, no GSD phase planned
⚠ "Performance audit" — In CLAUDE.md goals, not in Linear
○ "Onboarding flow" — GSD Phase 5, no Linear milestone (future work)IF misalignments found AND MODE != quick:
Ask: "How do you want to resolve these misalignments?"
- Create Linear issues for untracked objectives
- Update CLAUDE.md to match current Linear state
- Note them and move on (address later)
- Skip — alignment is fine as-is
IF only one source is available → note: "Only one source of truth available — consolidation needs at least two of: Linear project, GSD planning, CLAUDE.md"
如果MODE=quick → 跳过此步骤。
对比三个项目级对齐的可信数据源:
数据源1 — Linear项目(如果LINEAR_AVAILABLE为true且PROJECT已设置):
- 运行 → 提取里程碑、描述、截止日期
linear project view "$PROJECT" 2>&1 - 如果命令运行失败或未设置项目 → 提示"无法获取Linear项目元数据"并跳过此数据源
数据源2 — GSD规划(如果.planning/目录存在):
- 读取→ 提取阶段名称和完成状态
.planning/ROADMAP.md - 读取→ 提取声明的目标和时间线
.planning/PROJECT.md - 如果文件缺失 → 提示"无法获取GSD规划状态"并跳过此数据源
数据源3 — CLAUDE.md(如果仓库根目录存在):
- 读取→ 提取所有目标、目的或项目描述部分
CLAUDE.md - 如果不存在 → 跳过此数据源
交叉比对:
- 每个Linear里程碑都有对应的GSD阶段吗?
- CLAUDE.md中提到的目标是否没有在Linear或GSD中跟踪?
- 是否存在没有对应Linear里程碑的GSD阶段(未来工作是合理的)?
展示对齐表格:
Objective Alignment:
─────────────────────
✓ "Auth system" — Linear milestone ↔ GSD Phase 3 ↔ CLAUDE.md
⚠ "API redesign" — Linear milestone, no GSD phase planned
⚠ "Performance audit" — In CLAUDE.md goals, not in Linear
○ "Onboarding flow" — GSD Phase 5, no Linear milestone (future work)如果发现对齐偏差且MODE != quick:
询问:"你希望如何解决这些对齐偏差?"
- 为未跟踪的目标创建Linear issue
- 更新CLAUDE.md匹配当前Linear状态
- 记录下来后续处理
- 跳过——当前对齐状态没问题
如果仅存在一个可用数据源 → 提示:"仅一个可信数据源可用——整合至少需要以下两个数据源:Linear项目、GSD规划、CLAUDE.md"
4. Present Summary
4. 展示汇总报告
Print a formatted sync report:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SYNC REPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Synced (N):
✓ ENG-123 — Feature description
Gaps Found (N):
⚠ ENG-456 — Stale: in-progress but no commits in 3 days
⚠ ENG-789 — Untracked: commits exist but Linear shows unstarted
⚠ ENG-012 — Done but open: branch merged, issue still in-progress
⚠ ENG-345 — Squash-merged: appears on main, still marked Started
○ ENG-678 — Direct-to-main: commits on main, no feature branch
○ ENG-901 — Unassigned: in-progress but no assignee
○ eng-999-old-feature — Rebased: force-push detected (informational)
Backlog (N):
○ ENG-234 — Urgent — Unstarted
○ ENG-567 — High — Unstarted
{IF consolidation ran:}
Objective Alignment:
✓ N aligned ⚠ N misaligned ○ N untrackedIF MODE=quick → print summary and skip to Step 6 (route only, no interactive resolution).
打印格式化的同步报告:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SYNC REPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
已同步 (N):
✓ ENG-123 — 特性描述
发现差异 (N):
⚠ ENG-456 — 状态过时:标记为进行中但3天无提交
⚠ ENG-789 — 未跟踪工作:存在提交但Linear显示未开始
⚠ ENG-012 — 已完成但未关闭:分支已合并,issue仍为进行中
⚠ ENG-345 — 已压缩合并:已合入main分支,仍标记为进行中
○ ENG-678 — 直接提交到主分支:main分支有相关提交,无特性分支
○ ENG-901 — 未分配:进行中但无经办人
○ eng-999-old-feature — 已变基:检测到强制推送(信息类提示)
待办 (N):
○ ENG-234 — 紧急 — 未开始
○ ENG-567 — 高优 — 未开始
{如果运行了目标整合:}
目标对齐情况:
✓ N个已对齐 ⚠ N个存在偏差 ○ N个未跟踪如果MODE=quick → 打印汇总后跳转到步骤6(仅提供下一步指引,无交互解决)。
5. Resolve Gaps (Interactive)
5. 解决差异(交互模式)
IF zero gaps found → skip to Step 6.
Walk through each gap and ask what to do:
For "Stale in Linear":
Ask: "ENG-456 has been in-progress for N days with no commits. What happened?"
- Still working on it → keep as-is
- Blocked → add a blocker comment to Linear:
linear issue comment add $ID -b "Blocked: {reason}" 2>&1 - Abandoned → move back to backlog:
linear issue update $ID -s "Triage" 2>&1 - Actually done → move to Done:
linear issue update $ID -s "Done" 2>&1
For "Untracked work":
Ask: "Found commits referencing ENG-789 but it's still Unstarted in Linear. Update it?"
- Yes, move to In Progress:
linear issue update $ID -s "In Progress" 2>&1 - Yes, it's actually Done:
linear issue update $ID -s "Done" 2>&1 - No, those commits were reverted → skip
For "Done but open":
Ask: "ENG-012 looks complete (branch merged). Close it in Linear?"
- Yes, move to Done with auto-generated summary:
linear issue update $ID -s "Done" 2>&1 - No, there's still remaining work → skip
For "Orphan branch":
Ask: "Branch references a cancelled/done issue. Clean up?"
eng-999-old-feature- Delete the branch: (safe delete; if fails, note it may have unmerged work and ask about
git branch -d $BRANCH 2>&1)-D - Keep it → skip
For "Missing branch":
Ask: "ENG-345 is In Progress but has no local branch. What happened?"
- Create one now → (generate slug from issue title)
git checkout -b $BRANCH_NAME 2>&1 - It's on a different machine → skip
- It's done, just not tracked → move to Done
For "Squash-merged":
Ask: "ENG-345 appears squash-merged into main but is still In Progress. Close it?"
- Yes, move to Done with merge reference
- No, there's still remaining work on another branch
For "Direct-to-main":
Ask: "Found commits on main referencing ENG-678 but no feature branch was used. Track this?"
- Move to Done (work is on main)
- Ignore (was a hotfix, already tracked)
For "Unassigned in-progress":
Ask: "ENG-901 is In Progress but has no assignee. Assign to you?"
- Yes, assign to me:
linear issue update $ID --assignee me 2>&1 - Assign to someone else → prompt for name
- Move back to backlog:
linear issue update $ID -s "Triage" 2>&1
For "Rebased/force-pushed": (informational only)
Note: "Branch for ENG-XXX was rebased/force-pushed recently. Commit references in Linear comments may be stale."
- No action needed unless user asks
For ALL Linear update commands: check exit code. If update fails, print:
✗ Failed to update ENG-XXX: {stderr}
→ Try: Run the command manually: linear issue update ...如果未发现差异 → 跳转到步骤6。
遍历每个差异,询问用户处理方式:
针对"Linear中状态过时":
询问:"ENG-456已标记为进行中N天无提交,是什么情况?"
- 仍在开发中 → 保持现状
- 被阻塞 → 在Linear添加阻塞评论:
linear issue comment add $ID -b "Blocked: {reason}" 2>&1 - 已废弃 → 移回待办:
linear issue update $ID -s "Triage" 2>&1 - 实际已完成 → 移动到已完成:
linear issue update $ID -s "Done" 2>&1
针对"未跟踪工作":
询问:"发现关联ENG-789的提交,但Linear中仍为未开始,是否更新?"
- 是,移动到进行中:
linear issue update $ID -s "In Progress" 2>&1 - 是,实际已完成:
linear issue update $ID -s "Done" 2>&1 - 否,这些提交已被回滚 → 跳过
针对"已完成但未关闭":
询问:"ENG-012看起来已完成(分支已合并),是否在Linear中关闭?"
- 是,自动生成摘要移动到已完成:
linear issue update $ID -s "Done" 2>&1 - 否,仍有剩余工作 → 跳过
针对"孤立分支":
询问:"分支关联的issue已取消/完成,是否清理?"
eng-999-old-feature- 删除分支:(安全删除;如果失败,提示可能存在未合并工作并询问是否使用
git branch -d $BRANCH 2>&1强制删除)-D - 保留 → 跳过
针对"分支缺失":
询问:"ENG-345标记为进行中但没有本地分支,是什么情况?"
- 现在创建 → (从issue标题生成分支名)
git checkout -b $BRANCH_NAME 2>&1 - 在其他设备上 → 跳过
- 已完成,只是未跟踪 → 移动到已完成
针对"已压缩合并":
询问:"ENG-345看起来已压缩合并到main分支,但仍为进行中,是否关闭?"
- 是,添加合并引用移动到已完成
- 否,其他分支上仍有剩余工作
针对"直接提交到主分支":
询问:"发现main分支上关联ENG-678的提交,但没有使用特性分支,是否跟踪?"
- 移动到已完成(工作已在主分支)
- 忽略(是热修复,已跟踪)
针对"进行中issue未分配":
询问:"ENG-901标记为进行中但没有经办人,是否分配给你?"
- 是,分配给我:
linear issue update $ID --assignee me 2>&1 - 分配给其他人 → 提示输入姓名
- 移回待办:
linear issue update $ID -s "Triage" 2>&1
针对"已变基/强制推送":(仅信息类提示)
提示:"ENG-XXX对应的分支近期被变基/强制推送。Linear评论中的提交引用可能已失效。"
- 无需操作,除非用户主动要求
针对所有Linear更新命令:检查退出码。如果更新失败,打印:
✗ Failed to update ENG-XXX: {stderr}
→ Try: Run the command manually: linear issue update ...6. Cleanup & Route
6. 清理与下一步指引
Cleanup (ask before each action)
清理(每个操作前询问用户)
Stale branch cleanup:
- List branches from "Orphan branch" gaps that user agreed to delete
- Also check for any local branches already merged into default branch:
git branch --merged main 2>/dev/null | grep -v 'main\|master\|\*' - Ask: "Found N merged/orphan branches. Delete them all, pick which to delete, or skip?"
Suggest issue consolidation:
- From the gathered Linear data, check for issues with very similar titles (compare words, look for near-duplicates)
- IF potential duplicates found → "These issues might be duplicates:"
"Merge them in Linear? (This just flags them — you'll need to merge manually in Linear)"
⚠ ENG-111 "Login page redesign" ↔ ENG-222 "Redesign login page" - IF none → skip silently
Prune remote refs (only if HAS_REMOTE):
- Check for stale remote tracking branches:
git remote prune origin --dry-run 2>&1 - IF stale refs found → ask: "Found N stale remote refs. Prune them?"
- Yes →
git remote prune origin 2>&1 - No → skip
- Yes →
过时分支清理:
- 列出用户确认删除的"孤立分支"差异对应的分支
- 同时检查所有已合并到默认分支的本地分支:
git branch --merged main 2>/dev/null | grep -v 'main\|master\|\*' - 询问:"发现N个已合并/孤立分支,是否全部删除、选择删除或跳过?"
建议issue合并:
- 从收集的Linear数据中,检查标题非常相似的issue(对比关键词,查找接近重复的内容)
- 如果发现潜在重复项 → "以下issue可能是重复项:"
"是否在Linear中合并它们?(仅做标记,你需要在Linear中手动完成合并)"
⚠ ENG-111 "Login page redesign" ↔ ENG-222 "Redesign login page" - 如果没有 → 静默跳过
清理远程引用(仅当HAS_REMOTE为true时):
- 检查过时的远程跟踪分支:
git remote prune origin --dry-run 2>&1 - 如果发现过时引用 → 询问:"发现N个过时远程引用,是否清理?"
- 是 →
git remote prune origin 2>&1 - 否 → 跳过
- 是 →
Route to Next Action
下一步操作指引
Based on the final state after resolving gaps:
- IF consolidation found misalignment → suggest for a full project status review
/product:update - IF there are unstarted high/urgent issues → suggest
/product:start-task - IF there's an active in-progress issue with no branch → suggest creating one
- IF GSD state exists with an incomplete phase → suggest
/gsd:progress - IF many gaps were found and resolved → suggest running again to verify, or
/product:syncfor a deeper health check/product:maintain - IF everything is synced and nothing urgent → "All clear. Pick up the next task when ready."
<success_criteria>
- Environment validated with explicit error messages for every failure mode
- Linear CLI auth checked (not just existence) — graceful fallback if unavailable
- trimmed, validated against Linear, special chars handled
.linear-project - All 10 gap categories detected (or skipped gracefully with reason)
- Squash-merged and direct-to-main work correctly identified
- Objectives consolidated across Linear, GSD, and CLAUDE.md (in full/consolidate mode)
- Every gap surfaced and user made an explicit decision
- All Linear update commands have exit code checking
- Cleanup offered: stale branches, duplicate issues, remote ref pruning
- Clear next action suggested based on final state </success_criteria>
基于解决差异后的最终状态:
- 如果目标整合发现偏差 → 建议运行进行全量项目状态评审
/product:update - 如果存在未开始的高优/紧急issue → 建议运行
/product:start-task - 如果存在进行中但无对应分支的issue → 建议创建分支
- 如果存在GSD状态且有未完成阶段 → 建议运行
/gsd:progress - 如果发现并解决了大量差异 → 建议再次运行验证,或运行
/product:sync进行深度健康检查/product:maintain - 如果所有内容已同步且无紧急事项 → "一切正常。准备就绪后可开始下一个任务。"
<success_criteria>
- 环境已验证,所有失败模式都有明确的错误提示
- 已检查Linear CLI的身份验证状态(不仅是是否存在)——不可用时优雅降级
- 内容已裁剪、与Linear验证、特殊字符已处理
.linear-project - 所有10个差异类别都已检测(或因合理原因优雅跳过)
- 已压缩合并和直接提交到主分支的工作已正确识别
- 已整合Linear、GSD和CLAUDE.md的目标(全量/整合模式下)
- 所有差异已展示,用户已做出明确决策
- 所有Linear更新命令都有退出码检查
- 提供清理选项:过时分支、重复issue、远程引用清理
- 基于最终状态提供清晰的下一步操作建议 </success_criteria>