From claude-skills
Transition a YouTrack issue's workflow state (e.g. 进行中, 自测, 完成) through the pp-youtrack MCP server. Narrow-scope skill focused on state transitions only — no comments, no creation, no search. Other YouTrack operations live in their own pp-youtrack-* skills (e.g. pp-youtrack-comment). Used by obsidian-design and code-execute to auto-advance tasks along the lifecycle.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-skills:pp-youtrack-stateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**仅负责 YouTrack issue 的 workflow 状态流转**(`待办` → `进行中` → `自测` → `完成` 这类)。一件事就干这一件,不管评论、不管创建 issue、不管 assignee、不管搜索。
仅负责 YouTrack issue 的 workflow 状态流转(待办 → 进行中 → 自测 → 完成 这类)。一件事就干这一件,不管评论、不管创建 issue、不管 assignee、不管搜索。
其他 YouTrack 操作属于独立的 skill(例如未来的 pp-youtrack-comment、pp-youtrack-search 等),本 skill 不跨职责。
不适用于 Atlassian Jira 任务(用 common-skills:jira-cli skill)。
mcp__pp-youtrack__* 系列 MCP 工具已加载(通过 /plugin 启用 pp-youtrack MCP)PP-123、SHOWCASE-456,具体格式取决于目标 project)mcp__pp-youtrack__update_issue 没有顶层 state 参数。state 是 YouTrack 的 custom field,必须通过 customFields 对象传入,而且值必须是该 project schema 里的 enum 原文(可能是英文 In Progress,即使你传的目标状态是中文 进行中)。完整流程:
schema = mcp__pp-youtrack__get_issue_fields_schema(project_key)
在 schema 输出里找 $type: StateProjectCustomField(或类似的 state-type custom field),读出两样东西:
State,但个别 project 会用 状态 / Workflow State 之类,不要写死)["Submitted", "Open", "In Progress", "Review", "Self Test", "Done"]把 key 名和 enum 列表缓存到本会话,同一 project 复用,不重复 get schema。
caller 传过来的目标状态很可能是本 skill 已知列表里的本地化名(中文 进行中、自测、完成)。直接这样传进 update_issue 大概率打不中,因为 YouTrack 后台存的是 schema enum 原文(英文 In Progress、Self Test、Done)。
映射步骤:
进行中 → "In Progress 阶段")In Progress)Hotfix Pending)→ 走规则 2.5 的 AskUserQuestion fallback,让用户告诉你 enum 列表里哪一项对应目标生命周期阶段,绝不猜正确写法:
result = mcp__pp-youtrack__update_issue(
issue_id = "<ISSUE-ID>",
customFields = { "<State 的 key 名>": "<映射后的 enum 原文>" }
)
错误写法(会静默失败——这是踩过的坑):
# ❌ MCP 会忽略未知顶层字段 `state` 并返回成功,看起来流转成功但 issue 实际没动
mcp__pp-youtrack__update_issue(
issue_id = "<ISSUE-ID>",
state = "<target-state-name>"
)
硬规则:所有 state 流转一律通过 customFields 传,绝对不要写成顶层 state=。即使你觉得"试试看"也不行——MCP 的成功返回值在这种情况下是假阳性,没有任何报错。
update_issue 的返回值里有一个 failedToUpdateFields 数组。这是唯一可靠的成功判定信号:
failedToUpdateFields 是空数组 [] → 真成功,流转生效failedToUpdateFields 非空(列出了某几个字段) → 失败,对应字段没更新。不要当成功。常见原因:enum 值拼错、key 名拼错、workflow 禁止该 transition、权限不足。按规则 3 的"流转失败"流程走 AskUserQuestion,把 failedToUpdateFields 原文贴给用户绝不仅凭 update_issue "没抛错" 就当真成功——必须读 failedToUpdateFields。这是本 skill 对抗静默假阳性的最后一道闸。
下面是 pp-youtrack 常见的 state 名,以 project 实际 workflow 为准:
| 阶段 | 状态名 | 含义 |
|---|---|---|
| 入口 | Open / 提交 | 新创建,未分配 |
| — | 待办 / Backlog | 在队列里等待处理 |
| — | 进行中 | 正在设计/分析/实施 |
| — | Review / 待评审 | 等待 review |
| — | 自测 | 开发完成,进入自测阶段 |
| — | 测试中 / QA | QA 验证中 |
| 终态 | 完成 / Done | 闭环 |
如果你不确定目标 project 用的是哪个名字,先 mcp__pp-youtrack__get_issue(issue_id) 拿当前 issue 的 state 值,观察命名风格,再决定传什么。
默认不允许把 issue 从后面的状态往前拉(例如 自测 → 进行中)。原因:回退状态通常意味着"发现 bug 重新开工",这是人为决策,不应该由自动流程决定。
流转前检查:先 get_issue 看当前状态,判断目标状态是不是生命周期顺序上的向前移动。
判定方式:用下面这张已知生命周期顺序表(数字越大越靠后,只对已知名字有效):
| 阶段 | 已知 state 名 | 序号 |
|---|---|---|
| 入口 | Open / 提交 / Submitted | 0 |
| — | 待办 / Backlog / To Do | 1 |
| — | 进行中 / In Progress | 2 |
| — | Review / 待评审 / In Review | 3 |
| — | 自测 / Self Test | 4 |
| — | 测试中 / QA / In Testing | 5 |
| 终态 | 完成 / Done / Closed | 6 |
例子:
待办(1) → 目标 进行中(2):✅ 正常前进进行中(2) → 目标 自测(4):✅ 正常前进自测(4) → 目标 进行中(2):❌ 回退,跳过(走规则 2)完成(6) → 目标任意非完成:❌ 跳过,不回退已关闭的 issue如果当前状态已经等于目标状态,或者在生命周期上已经超过目标状态,不报错也不流转,只在对话里输出一行提示:
YouTrack issue <ID> 当前状态 "<current>" 已经在或超过目标状态 "<target>",跳过流转。
这样 caller 能知道"skill 已经识别了,没做多余动作",而不是沉默跳过。
如果从 get_issue 拿到的当前 state 名或 caller 传入的目标 state 名有任意一个不在上面的已知生命周期表内(例如 project 用了自定义 workflow Code Review / UAT / Hotfix Pending / Blocked / Cancelled 等),你没有能力判断它的生命周期序号,绝对不能猜。立即:
AskUserQuestion 把以下信息告诉用户:
进行中 之后、自测 之前"这种)然后基于用户的判断决定推进/跳过/回退这条规则比规则 1 和规则 2 的优先级更高:在跑顺序判断之前必须先确认两端的 state 名都在已知表内。
如果未来这个 project 用一组新的 state 名,正确做法是把它们补进上面的表(改本 skill),而不是在 caller 那边硬编绕过本 skill。
任何 update_issue 调用失败(API 报错、状态名不存在、权限不足、project workflow 禁止该 transition 等)都不能绕过。立即:
AskUserQuestion 问用户选择:
caller 应该以这样的自然语言交代意图:
调用
pp-youtrack-stateskill,把<ISSUE-ID>流转到<target-state>状态。
skill 内部按严格顺序负责(任何一步省略都可能踩假阳性):
get_issue_fields_schema(project_key) 拿到 State 字段的 key 名 + enum 值列表,缓存到本会话get_issue(issue_id) 读当前状态原文update_issue(issue_id, customFields={ "<key>": "<enum 原文>" })——永远走 customFields,不写顶层 state=failedToUpdateFields,空数组才算真成功;非空 → AskUserQuestion 把原文贴给用户obsidian-design command:在开始设计/分析之前把 YouTrack issue 从 待办 流转到 进行中code-execute command:在 Opus review 通过后把 YouTrack issue 从 进行中 流转到 自测jira-close,把 issue 推到最终完成状态common-skills:jira-cli skill)mcp__pp-youtrack__* 对应工具;本 skill 只管状态)Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub sampeng87/skills --plugin claude-skills