[feat] Add zentao plugin (Claude Code + Codex dual scaffold)
新增禅道项目管理系统插件,含项目集/产品/项目/执行、需求 (story/epic/requirement)、Bug、任务、测试、计划与发布、反馈工单 八个工作流技能,自动配置 MCP 连接(禅道「个人中心 → 获取凭证」 自助生成 14 天 Token)。 MCP Server 是团队自建的 zentao-mcp 网桥(部署在 pm.ops.yixiong-tech.com/mcp),基于开源 openapi-mcp-server 二次开发。 Claude 侧走 userConfig 钥匙链 + 自定义 token 头;Codex 侧受限于官方 插件格式只支持 bearer_token_env_var,走 Authorization: Bearer——网桥 那边已经加了 preferred_header/bearer_mode 配置项统一归一化处理,两条 路径都验证过连通。 三轮审查(静态字段对照 openapi.json、跨文件一致性、真实端点实测) 修正过程中发现的问题,技能文档里引用的工具名全部跟服务器真实注册 的 118 个工具核对过。 同步更新:.claude-plugin/marketplace.json、.agents/plugins/marketplace.json、 README.md、CLAUDE.md 的插件索引与说明;README 补充「获取凭证」操作 截图(已脱敏)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016pFx6jnym6kRWRQ5JyDUNv
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
1606d73c41
commit
9d9e31c98e
@@ -0,0 +1,129 @@
|
||||
---
|
||||
name: zentao-story
|
||||
description: "禅道需求管理:用户故事(story)、业务需求(epic)、用户需求(requirement)三条需求线的创建、变更、关闭、激活。当用户说「提个需求」「这个需求变更一下」「需求关闭了」「史诗需求」时使用。"
|
||||
---
|
||||
|
||||
# 禅道需求管理(story / epic / requirement)
|
||||
|
||||
**前置:先读 `zentao-shared`(尤其"路径参数不出现在 inputSchema 里"一节——本技能的
|
||||
`get_epics_storyID`/`get_requirements_storyID` 就是那条规则里点名的例外命名)。**
|
||||
|
||||
---
|
||||
|
||||
## 三条需求线是什么关系
|
||||
|
||||
禅道把"需求"拆成三种独立实体,**不是同一张表的三个状态**,是三套平行的 API:
|
||||
|
||||
| | 中文 | 路径前缀 | 典型用途 |
|
||||
|---|---|---|---|
|
||||
| story | 用户故事 | `/stories` | 敏捷开发里最常用的最小需求单元 |
|
||||
| epic | 业务需求 | `/epics` | 更粗粒度、跨多个 story 的业务目标 |
|
||||
| requirement | 用户需求 | `/requirements` | 来自用户侧的原始需求,未必等于最终交付的 story |
|
||||
|
||||
三者创建字段结构完全一样(`productID`/`title` 必填,`pri`/`module`/`parent`/`estimate`/
|
||||
`spec`/`category`/`source`/`verify`/`assignedTo`/`reviewer` 可选),管理动作也对称
|
||||
(改 / 变更 change / 关闭 close / 激活 activate / 删除),**用户说"需求"时先确认是要
|
||||
哪一种**,不要默认都当 story 处理——三者互不包含,建错类型对方看不到。
|
||||
|
||||
---
|
||||
|
||||
## 详情接口的路径参数命名例外(必读)
|
||||
|
||||
```
|
||||
get_stories_storyID(storyID) 需求详情
|
||||
get_epics_storyID(storyID) 业务需求详情 —— 参数字面叫 storyID,不是 epicID
|
||||
get_requirements_storyID(storyID) 用户需求详情 —— 参数字面叫 storyID,不是 requirementID
|
||||
```
|
||||
|
||||
这是禅道官方 API 本身的命名(不是这个 MCP 网桥引入的),照抄传 `storyID` 就行,别自己
|
||||
"纠正"成语义上更合理的名字,传错名字会静默返回空结果(见 `zentao-shared`)。
|
||||
|
||||
---
|
||||
|
||||
## 查
|
||||
|
||||
```
|
||||
get_products_productID_stories(productID, browseType?, orderBy?, recPerPage?, pageID?)
|
||||
get_projects_projectID_stories(projectID, ...)
|
||||
get_executions_executionID_stories(executionID, ...)
|
||||
get_products_productID_epics(productID, ...)
|
||||
get_products_productID_requirements(productID, ...)
|
||||
```
|
||||
|
||||
`browseType` 常见取值:`allstory` 全部 | `assignedtome` 指派给我 | `openedbyme` 我创建 |
|
||||
`reviewbyme` 待我评审 | `draftstory` 草稿——不传默认是 `unclosed`(未关闭的)。
|
||||
|
||||
---
|
||||
|
||||
## 建
|
||||
|
||||
```
|
||||
post_stories({ payload: { productID, title, pri?, module?, parent?, estimate?, spec?,
|
||||
category?, source?, verify?, assignedTo?, reviewer?,
|
||||
project?, execution? } })
|
||||
post_epics({ payload: { productID, title, ... 同上(无 project/execution) } })
|
||||
post_requirements({ payload: { productID, title, ... 同上(无 project/execution) } })
|
||||
```
|
||||
|
||||
`productID`/`title` 必填,其余可选。`reviewer` 一旦设置,**该需求就必须经过评审**——
|
||||
问清楚用户是否真的需要评审流程再决定填不填。`category`/`source` 是受限枚举(类别/来源),
|
||||
取值以工具 description 为准,写错直接报错。
|
||||
|
||||
只有 story 能挂 `project`/`execution`(关联具体项目或迭代),epic/requirement 没有这两个字段。
|
||||
|
||||
---
|
||||
|
||||
## 变更(change)
|
||||
|
||||
```
|
||||
put_stories_storyID_change({ storyID, payload: { reviewer, title?, spec?, verify? } })
|
||||
put_epics_epicID_change({ epicID, payload: { reviewer, title?, spec?, verify? } })
|
||||
put_requirements_requirementID_change({ requirementID, payload: { title?, spec?, verify? } })
|
||||
```
|
||||
|
||||
**`reviewer` 必填这条规则只对 story 和 epic 成立**——变更这两类需求必须指定评审人,
|
||||
不能跳过评审直接改。**requirement 的变更接口没有 `reviewer` 这个参数,也没有任何必填
|
||||
字段**,三者看起来对称,实际上 requirement 少一层评审约束,不要照搬 story/epic 的调用
|
||||
方式给 requirement 传 `reviewer`(传了会被当成多余字段,不生效)。
|
||||
|
||||
注意这里改的路径参数名恢复正常(`epicID`/`requirementID`),跟上面"详情接口"那个
|
||||
`storyID` 例外命名不是一回事,两套接口的路径参数名不一样,调用前对照工具名确认。
|
||||
|
||||
---
|
||||
|
||||
## 关闭(close)
|
||||
|
||||
```
|
||||
put_stories_storyID_close({ storyID, payload: { closedReason, comment? } })
|
||||
```
|
||||
|
||||
`closedReason` 必填,受限枚举:`done` 已完成 | `subdivided` 已拆分 | `duplicate` 重复 |
|
||||
`postponed` 延期 | `willnotdo` 不做 | `cancel` 已取消 | `bydesign` 设计如此。
|
||||
|
||||
**关闭前必须先跟用户确认关闭原因**(`zentao-shared` 的全局约定:状态流转类操作先确认),
|
||||
不要因为用户说"这个需求做完了"就自动挑一个理由关掉——`done` 和用户实际想表达的可能
|
||||
不是一回事(比如其实是想选 `subdivided` 已拆成子需求)。
|
||||
|
||||
---
|
||||
|
||||
## 激活(activate)
|
||||
|
||||
```
|
||||
put_stories_storyID_activate({ storyID, payload: { assignedTo?, comment? } })
|
||||
put_epics_epicID_activate({ epicID, payload: { assignedTo?, comment? } })
|
||||
put_requirements_requirementID_activate({ requirementID, payload: { assignedTo?, comment? } })
|
||||
```
|
||||
|
||||
三者字段结构一样,都没有必填字段,用于把已关闭/已拆分的需求重新打开。
|
||||
|
||||
---
|
||||
|
||||
## 删
|
||||
|
||||
```
|
||||
delete_stories_storyID({ storyID })
|
||||
delete_epics_epicID({ epicID })
|
||||
delete_requirements_requirementID({ requirementID })
|
||||
```
|
||||
|
||||
不可逆,删除前必须确认(`zentao-shared` 全局约定)。
|
||||
Reference in New Issue
Block a user