@hupan56/wlkj 2.7.5 → 2.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -114,22 +114,80 @@ TOOLS = [
|
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
116
|
"name": "create_story",
|
|
117
|
-
"description": "在禅道创建需求(PRD发布→禅道需求)
|
|
117
|
+
"description": "在禅道创建需求(PRD发布→禅道需求)。权限不足会返回友好提示不报错。例: create_story(product_id=1, title='品质案件催办', spec='需求详情', pri=3, module=104)",
|
|
118
118
|
"inputSchema": {
|
|
119
119
|
"type": "object",
|
|
120
120
|
"properties": {
|
|
121
121
|
"product_id": {"type": "integer", "description": "产品ID"},
|
|
122
122
|
"title": {"type": "string", "description": "需求标题"},
|
|
123
123
|
"spec": {"type": "string", "description": "需求描述"},
|
|
124
|
-
"pri": {"type": "integer", "description": "优先级 1-4(1
|
|
125
|
-
"
|
|
124
|
+
"pri": {"type": "integer", "description": "优先级 1-4(1最高, 默认3)"},
|
|
125
|
+
"module": {"type": "integer", "description": "模块ID(可选)"},
|
|
126
|
+
"category": {"type": "string", "description": "类别(feature/interface/optimization, 默认feature)"},
|
|
126
127
|
},
|
|
127
128
|
"required": ["product_id", "title", "spec"],
|
|
128
129
|
},
|
|
129
130
|
},
|
|
131
|
+
{
|
|
132
|
+
"name": "list_plans",
|
|
133
|
+
"description": "查某产品的计划/迭代列表(让用户选归属)。例: list_plans(product_id=1)",
|
|
134
|
+
"inputSchema": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"properties": {
|
|
137
|
+
"product_id": {"type": "integer", "description": "产品ID"},
|
|
138
|
+
},
|
|
139
|
+
"required": ["product_id"],
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "list_executions",
|
|
144
|
+
"description": "查活跃的执行/迭代(按周划分的后端/前端/移动端)。例: list_executions(limit=5)",
|
|
145
|
+
"inputSchema": {
|
|
146
|
+
"type": "object",
|
|
147
|
+
"properties": {
|
|
148
|
+
"limit": {"type": "integer", "description": "返回数量(默认10)"},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "link_story_to_execution",
|
|
154
|
+
"description": "把需求关联到执行/迭代(让开发能看到)。权限不足返回提示不报错。例: link_story_to_execution(story_id=761, execution_id=73)",
|
|
155
|
+
"inputSchema": {
|
|
156
|
+
"type": "object",
|
|
157
|
+
"properties": {
|
|
158
|
+
"story_id": {"type": "integer", "description": "需求ID"},
|
|
159
|
+
"execution_id": {"type": "integer", "description": "执行ID"},
|
|
160
|
+
},
|
|
161
|
+
"required": ["story_id", "execution_id"],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"name": "assign_story",
|
|
166
|
+
"description": "指派需求给某人(设负责人)。权限不足返回提示不报错。例: assign_story(story_id=761, account='hupan')",
|
|
167
|
+
"inputSchema": {
|
|
168
|
+
"type": "object",
|
|
169
|
+
"properties": {
|
|
170
|
+
"story_id": {"type": "integer", "description": "需求ID"},
|
|
171
|
+
"account": {"type": "string", "description": "禅道账号"},
|
|
172
|
+
},
|
|
173
|
+
"required": ["story_id", "account"],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"name": "change_story_status",
|
|
178
|
+
"description": "变更需求状态(draft→reviewing→active→closed)。权限不足返回提示不报错。例: change_story_status(story_id=761, status='active')",
|
|
179
|
+
"inputSchema": {
|
|
180
|
+
"type": "object",
|
|
181
|
+
"properties": {
|
|
182
|
+
"story_id": {"type": "integer", "description": "需求ID"},
|
|
183
|
+
"status": {"type": "string", "description": "目标状态(draft/reviewing/active/closed)"},
|
|
184
|
+
},
|
|
185
|
+
"required": ["story_id", "status"],
|
|
186
|
+
},
|
|
187
|
+
},
|
|
130
188
|
{
|
|
131
189
|
"name": "list_execution_tasks",
|
|
132
|
-
"description": "
|
|
190
|
+
"description": "查某执行的任务列表(谁在做什么)。例: list_execution_tasks(execution_id=73)",
|
|
133
191
|
"inputSchema": {
|
|
134
192
|
"type": "object",
|
|
135
193
|
"properties": {
|
|
@@ -141,7 +199,7 @@ TOOLS = [
|
|
|
141
199
|
},
|
|
142
200
|
{
|
|
143
201
|
"name": "get_story_detail",
|
|
144
|
-
"description": "查需求详情(
|
|
202
|
+
"description": "查需求详情(完整描述+状态+关联)。例: get_story_detail(story_id=761)",
|
|
145
203
|
"inputSchema": {
|
|
146
204
|
"type": "object",
|
|
147
205
|
"properties": {
|
|
@@ -184,18 +242,89 @@ def _execute_tool(name, args):
|
|
|
184
242
|
|
|
185
243
|
if name == 'create_story':
|
|
186
244
|
pid = args.get('product_id', 1)
|
|
187
|
-
|
|
245
|
+
payload = {
|
|
188
246
|
'title': args.get('title', ''),
|
|
189
247
|
'spec': args.get('spec', ''),
|
|
190
248
|
'category': args.get('category', 'feature'),
|
|
191
249
|
'pri': args.get('pri', 3),
|
|
192
|
-
}
|
|
250
|
+
}
|
|
251
|
+
if args.get('module'):
|
|
252
|
+
payload['module'] = args['module']
|
|
253
|
+
r = _api('POST', '/products/%s/stories' % pid, payload)
|
|
193
254
|
if r.status_code in (200, 201):
|
|
194
255
|
d = r.json()
|
|
195
256
|
sid = d.get('id', '?')
|
|
196
257
|
return '✅ 需求已创建! ID=%s\n禅道地址: %s/story-view-%s.html' % (
|
|
197
258
|
sid, ZENTAO_URL.rstrip('/'), sid)
|
|
198
|
-
|
|
259
|
+
# 权限不足或字段错误, 友好返回不崩
|
|
260
|
+
try:
|
|
261
|
+
err = r.json().get('error', r.text[:100])
|
|
262
|
+
except Exception:
|
|
263
|
+
err = r.text[:100]
|
|
264
|
+
return '⚠️ 需求创建失败: %s\n(可能权限不足或字段缺失, 不影响其它操作)' % err
|
|
265
|
+
|
|
266
|
+
if name == 'list_plans':
|
|
267
|
+
pid = args.get('product_id', 1)
|
|
268
|
+
r = _api('GET', '/products/%s/plans' % pid)
|
|
269
|
+
if r.status_code != 200:
|
|
270
|
+
return '查询计划失败: %s' % r.text[:100]
|
|
271
|
+
plans = r.json().get('plans', [])
|
|
272
|
+
if not plans:
|
|
273
|
+
return '产品 %s 暂无计划。可在禅道里创建计划/迭代。' % pid
|
|
274
|
+
lines = ['产品 %s 的计划 (%d 个):' % (pid, len(plans))]
|
|
275
|
+
for p in plans:
|
|
276
|
+
lines.append(' [%s] %s (%s~%s)' % (
|
|
277
|
+
p.get('id'), str(p.get('title', ''))[:20], p.get('begin', ''), p.get('end', '')))
|
|
278
|
+
return '\n'.join(lines)
|
|
279
|
+
|
|
280
|
+
if name == 'list_executions':
|
|
281
|
+
limit = args.get('limit', 10)
|
|
282
|
+
r = _api('GET', '/executions', {'limit': limit})
|
|
283
|
+
if r.status_code != 200:
|
|
284
|
+
return '查询执行失败: %s' % r.text[:100]
|
|
285
|
+
execs = r.json().get('executions', [])
|
|
286
|
+
lines = ['活跃执行/迭代 (%d 个):' % len(execs)]
|
|
287
|
+
for ex in execs[:limit]:
|
|
288
|
+
lines.append(' [%s] %s (%s~%s project=%s)' % (
|
|
289
|
+
ex.get('id'), str(ex.get('name', ''))[:15],
|
|
290
|
+
ex.get('begin', ''), ex.get('end', ''), ex.get('project', '')))
|
|
291
|
+
return '\n'.join(lines)
|
|
292
|
+
|
|
293
|
+
if name == 'link_story_to_execution':
|
|
294
|
+
sid = args.get('story_id', 0)
|
|
295
|
+
eid = args.get('execution_id', 0)
|
|
296
|
+
r = _api('POST', '/executions/%s/stories' % eid, {'stories': [sid]})
|
|
297
|
+
if r.status_code in (200, 201):
|
|
298
|
+
return '✅ 需求 #%s 已关联到执行 #%s' % (sid, eid)
|
|
299
|
+
try:
|
|
300
|
+
err = r.json().get('error', r.text[:100])
|
|
301
|
+
except Exception:
|
|
302
|
+
err = r.text[:100]
|
|
303
|
+
return '⚠️ 关联失败: %s\n(可能权限不足, 需在禅道手动关联)' % err
|
|
304
|
+
|
|
305
|
+
if name == 'assign_story':
|
|
306
|
+
sid = args.get('story_id', 0)
|
|
307
|
+
account = args.get('account', '')
|
|
308
|
+
r = _api('POST', '/stories/%s/assign' % sid, {'assignedTo': account})
|
|
309
|
+
if r.status_code in (200, 201):
|
|
310
|
+
return '✅ 需求 #%s 已指派给 %s' % (sid, account)
|
|
311
|
+
try:
|
|
312
|
+
err = r.json().get('error', r.text[:100])
|
|
313
|
+
except Exception:
|
|
314
|
+
err = r.text[:100]
|
|
315
|
+
return '⚠️ 指派失败: %s\n(可能权限不足, 需在禅道手动指派)' % err
|
|
316
|
+
|
|
317
|
+
if name == 'change_story_status':
|
|
318
|
+
sid = args.get('story_id', 0)
|
|
319
|
+
status = args.get('status', '')
|
|
320
|
+
r = _api('POST', '/stories/%s/change' % sid, {'status': status})
|
|
321
|
+
if r.status_code in (200, 201):
|
|
322
|
+
return '✅ 需求 #%s 状态变更为 %s' % (sid, status)
|
|
323
|
+
try:
|
|
324
|
+
err = r.json().get('error', r.text[:100])
|
|
325
|
+
except Exception:
|
|
326
|
+
err = r.text[:100]
|
|
327
|
+
return '⚠️ 状态变更失败: %s\n(可能权限不足或状态转换不合法)' % err
|
|
199
328
|
|
|
200
329
|
if name == 'list_execution_tasks':
|
|
201
330
|
eid = args.get('execution_id', 1)
|