@youcloud/metersphere-mcp 0.0.0-stage → 1.0.0

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.
@@ -0,0 +1,117 @@
1
+ # 执行与缺陷引用工具
2
+
3
+ [返回工具目录](../README.md) · 工具组 `execution` · 2 个写入工具。先读取计划用例、完成实际测试,再回填事实;工具不会运行浏览器,也不会独立验证证据 URL 的内容。
4
+
5
+ ## record_case_result
6
+
7
+ **写入。** 先追加可追溯的执行评论,再写计划用例状态和实际结果。接受[写入公共参数](../README.md#写入公共参数),真实写入要求 `case_execution` revision。
8
+
9
+ | 参数 | 类型 | 必填 | 说明 |
10
+ | --- | --- | --- | --- |
11
+ | `project_id` | string | 是 | 目标项目 ID |
12
+ | `plan_id` | string | 是 | 测试计划 ID |
13
+ | `plan_case_id` | string | 是 | 计划内关联 ID,不是用例库 `case_id` |
14
+ | `run_id` | string(UUID) | 是 | 同一执行轮次复用 |
15
+ | `attempt_id` | string(UUID) | 是 | 一次实际执行的 ID,真正复测才使用新值 |
16
+ | `result` | object | 是 | 以下实际执行记录 |
17
+
18
+ ### result 字段
19
+
20
+ | 字段 | 类型 | 必填 | 说明 |
21
+ | --- | --- | --- | --- |
22
+ | `status` | string | 是 | `passed / failed / blocked / skipped` |
23
+ | `environment` | string | 是 | 实际被测环境,非空正文,最多 20000 字符 |
24
+ | `tested_version` | string | 否 | 实际构建或版本,非空正文,最多 20000 字符 |
25
+ | `started_at`、`finished_at` | string | 是 | 带时区的 ISO 8601,结束不早于开始 |
26
+ | `summary`、`observed` | string | 是 | 执行摘要、实际观察,分别为非空正文,最多 20000 字符 |
27
+ | `reason` | string | 条件必填 | `blocked / skipped` 必填真实原因;非空,最多 20000 字符 |
28
+ | `failure_disposition` | object | 否 | `{kind, reason}`;`kind` 为 `not_a_product_defect / deferred`,`reason` 为非空正文,最多 20000 字符 |
29
+ | `step_results` | object[] | STEP 必填 | 最多 100 条,每条结构见下表;须覆盖当前全部步骤 |
30
+ | `evidence` | object[] | 是 | 1–20 项,每项结构见下表 |
31
+
32
+ | 对象 | 字段 | 约束 |
33
+ | --- | --- | --- |
34
+ | `step_results[]` | `step_index` | 正整数,从 1 开始按当前定义依次排列,不缺失、不重复 |
35
+ | `step_results[]` | `status` | `passed / failed / blocked / skipped / not_run` |
36
+ | `step_results[]` | `observed` | 非空实际观察,最多 20000 字符 |
37
+ | `evidence[]` | `kind` | `text / url` |
38
+ | `evidence[]` | `value` | 非空文本,最多 20000 字符;`url` 必须以 `https://` 开头 |
39
+
40
+ **调用示例**(假设当前 STEP 定义恰有一个步骤,实际调用须填写真实执行事实):
41
+
42
+ ```json
43
+ {
44
+ "project_id": "project-1",
45
+ "plan_id": "plan-1",
46
+ "plan_case_id": "plan-case-1",
47
+ "run_id": "00000000-0000-4000-8000-000000000010",
48
+ "attempt_id": "00000000-0000-4000-8000-000000000011",
49
+ "operation_id": "00000000-0000-4000-8000-000000000007",
50
+ "expected_revision": "替换为计划用例上下文的 expected_revision",
51
+ "result": {
52
+ "status": "passed",
53
+ "environment": "验收环境",
54
+ "tested_version": "build-20261111",
55
+ "started_at": "2026-11-11T10:00:00+08:00",
56
+ "finished_at": "2026-11-11T10:02:00+08:00",
57
+ "summary": "空地址无法提交",
58
+ "observed": "页面停留在结算页并提示地址必填",
59
+ "step_results": [
60
+ {"step_index": 1, "status": "passed", "observed": "地址为空时显示必填提示,未创建订单"}
61
+ ],
62
+ "evidence": [{"kind": "text", "value": "此处替换为本次实际执行证据;本示例不是真实测试记录"}]
63
+ }
64
+ }
65
+ ```
66
+
67
+ 另见[失败结果输入示例](../../examples/record-case-result.json)。该文件的 `dry_run=true` 仅表示预览,其中的 ID 和 revision 仍须替换。
68
+
69
+ **返回**:成功时 `result` 包含 `project_id / plan_id / plan_case_id / run_id / attempt_id / comment_id / observed_executor / status / expected_revision`。`status` 是原生值:`passed → Pass`、`failed → Failure`、`blocked → Blocking`、`skipped → Skip`;新 revision 仍为 `case_execution`,可供本次缺陷引用使用。
70
+
71
+ ### STEP、TEXT 与执行边界
72
+
73
+ - STEP 逐步结果须覆盖全部步骤。整体 `passed` 要求每步通过;整体 `failed` 至少有一步失败;存在失败步骤时不能填写其他整体结论。未执行的后续步骤使用 `not_run`,并说明观察。
74
+ - TEXT 不接受非空 `step_results`,实际观察写入 `actualResult`;STEP 写入原生 `results`。STEP 单步观察超过 300 字符时,原生字段写入指向执行评论的提示,完整观察保留在评论中。
75
+ - 整条序列化记录另受 `max_execution_record_chars` 限制(默认 20000),并非每个字段都能同时填满。超限返回 `RECORD_TOO_LARGE`,不会截断证据。证据只保存文本或 URL,不上传附件、不下载或验证链接。
76
+ - 相同目标、轮次和 `attempt_id` 已有执行记录时返回 `DUPLICATE_ATTEMPT`;核查原操作,不能换操作 ID 重复登记同一次执行。真实复测需重新读上下文并生成新 `attempt_id`。
77
+ - 归档计划拒绝回填。评论可能通知关注人;同状态复测可能不改变原生 `executor`,返回真实 `observed_executor`,评论作者体现回填主体。
78
+ - 评论和结果是两个写步骤,可能部分成功;先用原操作 ID 核查,再按恢复指示补做明确可执行的步骤。
79
+
80
+ 执行器、网络或账号阻塞应记为 `blocked` 并说明原因,不能直接当作产品失败。结束计划前,每条失败须有本轮有效 Mantis 引用,或真实的 `failure_disposition`;不得为满足完成条件虚构处置理由。
81
+
82
+ ## link_mantis_issue
83
+
84
+ **写入。** 将已由调用方核对的 Mantis 主单引用保存到对应执行的评论中。接受[写入公共参数](../README.md#写入公共参数),真实写入要求最新 `case_execution` revision。
85
+
86
+ | 参数 | 类型 | 必填 | 说明 |
87
+ | --- | --- | --- | --- |
88
+ | `project_id` | string | 是 | 目标 MeterSphere 项目 ID |
89
+ | `plan_id` | string | 是 | 测试计划 ID |
90
+ | `plan_case_id` | string | 是 | 计划内用例关联 ID |
91
+ | `run_id`、`attempt_id` | string(UUID) | 是 | 对应已登记的本轮实际执行 |
92
+ | `mantis_project_id` | integer | 是 | 正整数,须与工作流配置的项目绑定一致 |
93
+ | `issue_id` | integer | 是 | 已核对的 Mantis 主单编号,正整数 |
94
+ | `relation` | string | 是 | `found_in`(本次发现)或 `verified_in`(本次验证) |
95
+ | `reason` | string | 是 | 关联理由,非空,最多 20000 字符 |
96
+
97
+ **调用示例**:
98
+
99
+ ```json
100
+ {
101
+ "project_id": "project-1",
102
+ "plan_id": "plan-1",
103
+ "plan_case_id": "plan-case-1",
104
+ "run_id": "00000000-0000-4000-8000-000000000010",
105
+ "attempt_id": "00000000-0000-4000-8000-000000000011",
106
+ "mantis_project_id": 123,
107
+ "issue_id": 456,
108
+ "relation": "found_in",
109
+ "reason": "已通过 Mantis 核对,主单对应本次发现的问题",
110
+ "expected_revision": "替换为回填结果或最新计划用例上下文的 expected_revision",
111
+ "operation_id": "00000000-0000-4000-8000-000000000012"
112
+ }
113
+ ```
114
+
115
+ **返回**:除 `record_case_result` 所列公共结果字段外,还包含 `issue_id / url / link_kind: "external_reference" / native_issue_id: null / external_validation: "caller_supplied"`。URL 根据配置的 `mantis_base_url` 与主单编号构造。
116
+
117
+ 必须存在唯一的、由当前账号记录的对应执行,且定义仍匹配,否则返回 `MISSING_CURRENT_ATTEMPT`;项目未绑定或不匹配返回 `MISSING_PROJECT_BINDING`。该工具不请求 Mantis 验证主单,不创建 MeterSphere/Jira 镜像,不更新执行状态或关闭缺陷。引用数与原生缺陷数分别统计,不能互相替代。
@@ -0,0 +1,52 @@
1
+ # 操作核查工具
2
+
3
+ [返回工具目录](../README.md) · 工具组 `operations` · 1 个只读工具。未知写入的核查必须保留原 `operation_id` 和本地状态目录。
4
+
5
+ ## get_workflow_operation
6
+
7
+ **远程只读。** 读取当前主体的操作账本并核对既有写入,不补发远程写请求;核查可能更新本地记录并使用本地锁。
8
+
9
+ | 参数 | 类型 | 必填 | 说明 |
10
+ | --- | --- | --- | --- |
11
+ | `operation_id` | string(UUID) | 是 | 原业务写入操作 ID |
12
+
13
+ **调用示例**:
14
+
15
+ ```json
16
+ {"operation_id": "00000000-0000-4000-8000-000000000007"}
17
+ ```
18
+
19
+ **返回**:通常采用[写入返回结构](../README.md#写入返回结构),`action` 是原工具,保留原 `subject / result / steps / verification / warnings`,不是新的写操作。
20
+
21
+ - 已成功操作返回历史结果并重新检查对象可见性,标记 `verification.historical_result=true`;这不表示重新执行,也不表示所有业务字段仍与当时一致。
22
+ - 未完成操作核查已发送步骤,将原 `in_flight` 视为待确认;能回读确认则更新本地记录,无法确认则保留未知结果。
23
+ - 有进程持锁时返回 `in_progress`;不存在当前主体记录时返回 `RECOVERY_UNAVAILABLE`。读取前置错误可能仅包含 `schema_version / error`,不能要求每个失败都有完整写入结构。
24
+ - 原写工具被禁用时,仍可核查已有结果,但不返回执行恢复建议。
25
+
26
+ ### 按恢复指示处理
27
+
28
+ 仅当返回以下恢复指示时,才能继续调用原写工具:
29
+
30
+ ```json
31
+ {
32
+ "action": "resume_same_operation",
33
+ "automatic_retry": false,
34
+ "tool": "record_case_result",
35
+ "resume": true
36
+ }
37
+ ```
38
+
39
+ 此段展示 `recovery` 字段,不是工具调用参数。恢复时使用原工具、原业务输入、原 `operation_id` 和原 `expected_revision`,只增加 `resume=true`;原记录不存在时禁止当成新操作执行。
40
+
41
+ 恢复仅允许发送尚未开始或明确被拒绝的步骤。已经成功响应或处于未知状态的步骤只继续核查,不能重发。`recovery.action=manual_review` 时需人工核对目标、证据和存储;`none` 表示没有建议的恢复动作,不保证业务成功,仍须检查 `outcome / error`。
42
+
43
+ `unknown / partial_success / conflict` 都不能通过生成新 UUID 来“重试”。修改业务参数前,先确认原操作已无未知副作用,并按实际目标重新开始一项明确的新操作。工作流映射或限制配置变化会阻止未完成操作继续,避免套用新的业务规则恢复旧写入。
44
+
45
+ ### 本地状态异常
46
+
47
+ - `verification.ledger_persisted=false`:账本未能可靠保存,保留业务结果、原输入和操作 ID,先修复存储,再核查。不把本地保存失败当作远程未写入。
48
+ - `verification.locks_released=false`:业务结果仍保留,`lock_release_errors` 为脱敏错误;修复存储并核实持锁进程后处理遗留锁,再核查原操作。
49
+ - `error.system_code` 或核查错误中的 `system_code` 可提供 `EPERM / ENOSPC` 等已知系统码,不返回原始路径和异常正文。
50
+ - 不要删除未核清操作的状态目录。锁不协调其他机器和网页用户;当前主体的本地未结操作列表不代表所有账号、所有机器均已无未结操作。
51
+
52
+ 完整业务顺序和恢复规则见 [Agent 工作流](../agent-workflow.md)。
@@ -0,0 +1,182 @@
1
+ # 测试计划工具
2
+
3
+ [返回工具目录](../README.md) · 工具组 `plans` · 2 个只读工具、3 个写入工具。计划生命周期、用例执行状态和本轮测试结论分别判断。
4
+
5
+ ## list_test_plans
6
+
7
+ **只读。** 按项目、名称、负责人及生命周期发现测试计划。
8
+
9
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
10
+ | --- | --- | --- | --- |
11
+ | `project_id` | string | 是 | 目标项目 ID |
12
+ | `query` | string | 否 | 非空名称关键词,最多 20000 字符;本地复核区分大小写 |
13
+ | `executor` | string | 否 | 计划负责人 ID;`me` 为当前 API Key 对应用户 |
14
+ | `statuses` | string[] | 否 | 可选 `Prepare / Underway / Completed / Finished / Archived`;省略不限制,空数组不匹配任何项 |
15
+ | `limit` | integer | 否 | 默认 20,范围 `1–100` |
16
+ | `cursor` | string | 否 | 同一查询的续读游标 |
17
+
18
+ **调用示例**:
19
+
20
+ ```json
21
+ {
22
+ "project_id": "project-1",
23
+ "executor": "me",
24
+ "statuses": ["Prepare", "Underway"],
25
+ "limit": 20
26
+ }
27
+ ```
28
+
29
+ **返回**:[分页结构](../README.md#分页与完整性)。`items` 含 `id / projectId / name / status / stage / principals` 和上游提供的 `testPlanTestCaseCount / testPlanApiCaseCount / testPlanApiScenarioCount / testPlanLoadCaseCount`。
30
+
31
+ 使用负责人筛选时,返回 `executor_filter_scope: "plan_principal_only"`;未筛选为 `null`。工具会补查负责人列表,不能把该筛选理解为“所有分派给我的计划用例”。列表生命周期不代表本轮结果,需要读取执行汇总。
32
+
33
+ ## get_test_plan_context
34
+
35
+ **只读。** 获取计划完整成员边界,按需展示分页用例、报告和本轮执行汇总。
36
+
37
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
38
+ | --- | --- | --- | --- |
39
+ | `project_id` | string | 是 | 目标项目 ID |
40
+ | `plan_id` | string | 是 | 测试计划 ID |
41
+ | `sections` | string[] | 否 | `["cases"]`;可选 `cases / reports / execution_summary` |
42
+ | `run_id` | string(UUID) | 条件必填 | 包含 `execution_summary` 时必填 |
43
+ | `limit` | integer | 否 | 默认 20,范围 `1–100`;控制 `cases` 展示页 |
44
+ | `cursor` | string | 否 | 同一 `cases` 查询的续读游标 |
45
+
46
+ **调用示例**(读取计划用例与报告):
47
+
48
+ ```json
49
+ {"project_id": "project-1", "plan_id": "plan-1", "sections": ["cases", "reports"], "limit": 50}
50
+ ```
51
+
52
+ **返回**:始终包含 `plan`(`id / projectId / name / status / stage / description / plannedStartTime / plannedEndTime` 等)、`functional_case_count`、`other_case_counts`(`api / scenario / load`)、`expected_revision` 和 `revision_scope: "plan_membership"`。
53
+
54
+ | section | 返回字段 | 内容 |
55
+ | --- | --- | --- |
56
+ | `cases` | `cases` | 嵌套分页结构;每项含 `id / caseId / planId / name / status / priority / executor / versionId / refId` |
57
+ | `reports` | `reports` | 当前计划的报告元数据数组:`id / name / status / createTime / creator` |
58
+ | `execution_summary` | `execution_summary`、`completion_revision` | 指定轮次的完整执行核查及 `plan_completion` revision |
59
+
60
+ **调用示例**(结束计划或生成报告前):
61
+
62
+ ```json
63
+ {
64
+ "project_id": "project-1",
65
+ "plan_id": "plan-1",
66
+ "sections": ["execution_summary"],
67
+ "run_id": "00000000-0000-4000-8000-000000000010"
68
+ }
69
+ ```
70
+
71
+ 执行汇总包含:
72
+
73
+ | 字段 | 含义 |
74
+ | --- | --- |
75
+ | `run_id`、`counts` | 本轮 ID 及 `passed / failed / blocked / skipped / not_run` 数量 |
76
+ | `attempts` | 经核对的执行记录,包含 `plan_case_id / attempt_id / comment_id / actor_id / record_hash` |
77
+ | `external_defect_references`、`external_reference_count` | 本轮有效 Mantis 引用及条数;条数不是去重缺陷数 |
78
+ | `all_passed` | 非空纯功能计划的全部功能用例通过 |
79
+ | `completion_ready` | 执行、失败处置、范围及本地主体待核查操作满足结束条件 |
80
+ | `problems` | 如 `MISSING_CURRENT_ATTEMPT / AMBIGUOUS_ATTEMPT / RESULT_MISMATCH / UNTRIAGED_FAILURE / MIXED_PLAN / EMPTY_PLAN` |
81
+ | `pending_operations` | 当前主体本地账本中该计划未完成操作;非空时 `completion_ready=false` |
82
+ | `snapshot_consistent`、`proof_of_execution` | 均为 `false`,不宣称原子快照或独立执行证明 |
83
+
84
+ 核查逐条补读计划用例详情,并将最新执行评论与当前定义、实际结果和 `run_id` 比对。旧轮次结果或其他新执行覆盖后,不能用早先的同轮记录冒充当前结果。`completion_ready=true` 可以包含有真实原因的阻塞、跳过及已处置失败,**不等于 `all_passed=true`**。
85
+
86
+ `limit` 只控制返回的用例页,不降低完整成员核查范围;完整扫描受配置上限约束。
87
+
88
+ ## create_test_plan
89
+
90
+ **写入。** 在真实项目、工作空间、阶段和负责人下创建功能测试计划。接受[写入公共参数](../README.md#写入公共参数),不要求 revision。
91
+
92
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
93
+ | --- | --- | --- | --- |
94
+ | `project_id` | string | 是 | 目标项目 ID,工作空间由项目上下文取得 |
95
+ | `name` | string | 是 | 非空名称,最多 255 字符 |
96
+ | `stage` | string | 是 | 非空,最多 20000 字符;匹配项目阶段选项的实际字符串、`value` 或 `id` |
97
+ | `principal_ids` | string[] | 是 | 1–50 个项目成员 ID,提交前去重 |
98
+ | `starts_at`、`ends_at` | string | 是 | 带时区的 ISO 8601,结束不早于开始 |
99
+ | `description` | string | 否 | `""`,最多 20000 字符 |
100
+
101
+ **调用示例**(项目实际存在示例阶段值时):
102
+
103
+ ```json
104
+ {
105
+ "project_id": "project-1",
106
+ "name": "结算功能验收",
107
+ "stage": "functional",
108
+ "principal_ids": ["user-1"],
109
+ "starts_at": "2026-11-11T09:00:00+08:00",
110
+ "ends_at": "2026-11-13T18:00:00+08:00",
111
+ "description": "覆盖结算主流程及边界条件",
112
+ "operation_id": "00000000-0000-4000-8000-000000000005"
113
+ }
114
+ ```
115
+
116
+ **返回**:成功时 `result.project_id / plan_id / created: true`,初始状态为 `Prepare`。
117
+
118
+ 同项目下已有同名计划时拒绝创建,不自动复用。说明会转义 HTML 并追加 `MSMCP:<operation_id>` 核查标记;计划可能触发部署配置中的通知。创建不自动关联用例、执行、结束或分享。先用 [get_project_context](projects.md#get_project_context) 获取实际阶段和成员,避免猜测 `stage`。
119
+
120
+ ## add_cases_to_plan
121
+
122
+ **写入。** 按明确版本 ID 增量关联用例。接受[写入公共参数](../README.md#写入公共参数),真实写入要求 `plan_membership` revision。
123
+
124
+ | 参数 | 类型 | 必填 | 说明 |
125
+ | --- | --- | --- | --- |
126
+ | `project_id` | string | 是 | 目标项目 ID |
127
+ | `plan_id` | string | 是 | 测试计划 ID |
128
+ | `case_ids` | string[] | 是 | 1–50 个用例库版本 ID,不可重复,另受 `max_association_items` 限制 |
129
+
130
+ **调用示例**:
131
+
132
+ ```json
133
+ {
134
+ "project_id": "project-1",
135
+ "plan_id": "plan-1",
136
+ "case_ids": ["case-1", "case-2"],
137
+ "expected_revision": "替换为计划上下文的 expected_revision",
138
+ "operation_id": "00000000-0000-4000-8000-000000000006"
139
+ }
140
+ ```
141
+
142
+ **返回示例**(成功时的 `result`):
143
+
144
+ ```json
145
+ {
146
+ "associations": [
147
+ {"case_id": "case-1", "plan_case_id": "plan-case-1", "already_existed": true},
148
+ {"case_id": "case-2", "plan_case_id": "plan-case-2", "already_existed": false}
149
+ ],
150
+ "expected_revision": "新的 plan_membership 标识"
151
+ }
152
+ ```
153
+
154
+ 已有成员不重复创建,不移除其他成员,不使用“全选”关联。归档计划拒绝修改;上游关联可能使 `Prepare / Completed` 变为 `Underway`。逐条关联可能部分成功,恢复会核查本操作已发送的成员,拒绝无关新增、重复、移除及版本变化。后续执行须使用返回的 `plan_case_id`。
155
+
156
+ ## complete_test_plan
157
+
158
+ **写入。** 核对本轮完整范围后登记计划结束。接受[写入公共参数](../README.md#写入公共参数),`expected_revision` 必须填入 **`completion_revision`**。
159
+
160
+ | 参数 | 类型 | 必填 | 说明 |
161
+ | --- | --- | --- | --- |
162
+ | `project_id` | string | 是 | 目标项目 ID |
163
+ | `plan_id` | string | 是 | 测试计划 ID |
164
+ | `run_id` | string(UUID) | 是 | 本轮执行 ID |
165
+ | `summary` | string | 是 | 非空结束摘要,最多 20000 字符;保存于本地操作记录 |
166
+
167
+ **调用示例**:
168
+
169
+ ```json
170
+ {
171
+ "project_id": "project-1",
172
+ "plan_id": "plan-1",
173
+ "run_id": "00000000-0000-4000-8000-000000000010",
174
+ "summary": "本轮执行结束,失败处置和证据已逐条核对",
175
+ "expected_revision": "替换为执行汇总上下文的 completion_revision",
176
+ "operation_id": "00000000-0000-4000-8000-000000000008"
177
+ }
178
+ ```
179
+
180
+ **返回**:成功时 `result` 包含 `plan_id / lifecycle_status / summary / summary_storage: "local_operation" / execution_summary / completion_revision`。新的 `completion_revision` 可供紧接着生成报告使用。
181
+
182
+ 拒绝空计划、混合类型计划、归档计划、缺失本轮执行、未处置失败或存在本地主体未结操作的计划。非终态计划提交 `Completed`;原本已为 `Completed / Finished` 时不重复写状态,但仍核对本轮证据。结束摘要不修改计划描述;生命周期结束不代表全部通过。
@@ -0,0 +1,99 @@
1
+ # 项目与模块工具
2
+
3
+ [返回工具目录](../README.md) · 工具组 `projects` · 1 个只读工具、1 个写入工具。
4
+
5
+ ## get_project_context
6
+
7
+ **只读。** 发现当前账号、工作空间与项目,按需读取项目配置。支持动作不代表当前账号有写权限。
8
+
9
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
10
+ | --- | --- | --- | --- |
11
+ | `workspace_id` | string | 否 | 从工作空间列表取得;用于分页发现该空间的项目 |
12
+ | `project_id` | string | 否 | 读取指定项目;提供后直接进入项目模式 |
13
+ | `sections` | string[] | 否 | `[]`;可选 `nodes`、`members`、`stages`、`issue_platform`、`bindings` |
14
+ | `limit` | integer | 否 | 默认 20,范围 `1–100`;仅项目发现列表使用 |
15
+ | `cursor` | string | 否 | 同一项目发现查询的续读游标 |
16
+
17
+ **调用示例**(先发现工作空间):
18
+
19
+ ```json
20
+ {}
21
+ ```
22
+
23
+ **返回示例**:
24
+
25
+ ```json
26
+ {
27
+ "schema_version": 1,
28
+ "user": {"id": "user-1", "name": "测试人员"},
29
+ "workspaces": [{"id": "workspace-1", "name": "研发工作空间"}],
30
+ "warnings": ["选择 workspace_id 继续发现项目"]
31
+ }
32
+ ```
33
+
34
+ **调用示例**(选择工作空间):
35
+
36
+ ```json
37
+ {"workspace_id": "workspace-1", "limit": 20}
38
+ ```
39
+
40
+ **返回**:`user` 和[分页结构](../README.md#分页与完整性),`items` 每项包含 `id`、`name`、`workspaceId`。
41
+
42
+ **调用示例**(读取已明确的项目):
43
+
44
+ ```json
45
+ {
46
+ "project_id": "project-1",
47
+ "sections": ["nodes", "members", "stages", "issue_platform", "bindings"]
48
+ }
49
+ ```
50
+
51
+ **返回**:始终有 `user`、`project`(`id / name / workspaceId`)、`supported_actions_are_not_permissions: true`;按 `sections` 增加:
52
+
53
+ | section | 返回字段 | 用途 |
54
+ | --- | --- | --- |
55
+ | `nodes` | `nodes` | 模块树,包含 `id / name / level / parentId / children` |
56
+ | `members` | `members` | 项目成员的 `id / name / status`,用于评审人、计划负责人 |
57
+ | `stages` | `stages` | 上游阶段选项,保留实际结构,创建计划使用实际值 |
58
+ | `issue_platform` | `issue_platform` | 项目原生缺陷平台配置,未配置为 `null` |
59
+ | `bindings` | `mantis_binding` | 本地配置中的 Mantis 项目映射,未配置为 `null` |
60
+
61
+ `sections` 仅对项目模式生效。项目模式不分页;同时传 `workspace_id` 时,不以它验证项目归属,归属以返回的 `project.workspaceId` 为准。
62
+
63
+ ## create_case_module
64
+
65
+ **写入。** 创建一级或子级功能用例模块。接受[写入公共参数](../README.md#写入公共参数),不要求 `expected_revision`。
66
+
67
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
68
+ | --- | --- | --- | --- |
69
+ | `project_id` | string | 是 | 目标项目 ID |
70
+ | `name` | string | 是 | 去除首尾空白后 1–100 字符,不含 `/`、`\` 或控制字符 |
71
+ | `parent_id` | string 或 null | 否 | 省略或 `null` 创建一级模块;子模块填写模块树中的真实父 ID |
72
+
73
+ **调用示例**:
74
+
75
+ ```json
76
+ {
77
+ "project_id": "project-1",
78
+ "name": "结算",
79
+ "parent_id": "node-shopping",
80
+ "operation_id": "00000000-0000-4000-8000-000000000001"
81
+ }
82
+ ```
83
+
84
+ **返回示例**(成功时的 `result`):
85
+
86
+ ```json
87
+ {
88
+ "project_id": "project-1",
89
+ "node_id": "node-checkout",
90
+ "parent_id": "node-shopping",
91
+ "level": 2,
92
+ "path": "/购物/结算",
93
+ "created": true
94
+ }
95
+ ```
96
+
97
+ `node_id` 可直接交给 [create_test_case](cases.md#create_test_case)。模块最多 8 层;同一父模块下不允许同名,不会自动复用已有模块,不同父模块下可同名。不要将界面的根节点占位值 `"0"` 当成父 ID。
98
+
99
+ 创建前保存预分配 UUID,未知结果按该 ID 回读;恢复前重新校验父模块位置、名称及层级。`MODULE_ALREADY_EXISTS / MODULE_DEPTH_LIMIT / TARGET_MISMATCH` 分别提示重名、超深或父节点不匹配;未知写入先核查原 `operation_id`。
@@ -0,0 +1,80 @@
1
+ # 测试报告工具
2
+
3
+ [返回工具目录](../README.md) · 工具组 `reports` · 1 个只读工具、1 个写入工具。报告生成会触发上游重算计划生命周期,属于写操作。
4
+
5
+ ## generate_test_report
6
+
7
+ **写入。** 为本轮证据完整且已结束的纯功能计划生成报告,核对报告内容及生成后的计划状态。接受[写入公共参数](../README.md#写入公共参数),`expected_revision` 必须填入最新 **`completion_revision`**。
8
+
9
+ | 参数 | 类型 | 必填 | 说明 |
10
+ | --- | --- | --- | --- |
11
+ | `project_id` | string | 是 | 目标项目 ID |
12
+ | `plan_id` | string | 是 | 测试计划 ID |
13
+ | `run_id` | string(UUID) | 是 | 本轮执行 ID |
14
+
15
+ **调用示例**:
16
+
17
+ ```json
18
+ {
19
+ "project_id": "project-1",
20
+ "plan_id": "plan-1",
21
+ "run_id": "00000000-0000-4000-8000-000000000010",
22
+ "expected_revision": "替换为最新的 completion_revision",
23
+ "operation_id": "00000000-0000-4000-8000-000000000009"
24
+ }
25
+ ```
26
+
27
+ **前置条件**:计划为 `Completed / Finished`;完整执行汇总满足 `completion_ready`;没有当前主体本地未结操作。归档计划、未完成的阶段报告、空计划、混合类型计划和证据不完整计划均不接受。阶段性进展通过 [get_test_plan_context](plans.md#get_test_plan_context) 的 `execution_summary` 查看。
28
+
29
+ **返回**:`result` 包含下方读取工具的 `report / content / functional_cases / native_issue_count`,以及:
30
+
31
+ | 字段 | 含义 |
32
+ | --- | --- |
33
+ | `plan_id`、`lifecycle_status_before`、`lifecycle_status` | 目标计划及生成前后的真实生命周期 |
34
+ | `lifecycle_verified` | 生成后是否仍为 `Completed / Finished` |
35
+ | `execution_summary` | 本操作保存的本轮执行与外部引用汇总 |
36
+ | `stage_report` | 正常成功路径为 `false` |
37
+ | `correlation` | `best_effort`,报告归因只能尽力匹配 |
38
+ | `created_by_this_operation_verified` | `false`,不承诺报告唯一归因 |
39
+ | `content_verification` | `functional_snapshot_matched` 表示保存的功能结果快照一致;`functional_status_matched` 表示范围、状态和文本结果一致,但原生报告缺少逐步 `results`;`partial` 表示未核验通过,保留未知结果 |
40
+ | `unavailable_detail_fields` | 核验通过时返回缺失的明细字段;当前为 `[]` 或 `["results"]` |
41
+
42
+ 上游只返回 `success`,不返回报告 ID。工具按创建人用户 ID 请求列表,再结合新增 ID、目标计划、手动触发、时间窗口和唯一候选核对。列表中的 `creator` 是显示名,不能用于身份比较;同账号并发仍可能歧义,因此即使 `outcome=succeeded`,也不能声称唯一证明报告由本操作创建。
43
+
44
+ 报告始终与生成前持久化的快照比较,不使用当前用例结果回填历史报告。v1.20.23 的报告查询未选择逐步 `results`,允许以 `functional_status_matched` 完成核查并明确列出缺失字段;用例关联、状态、文本 `actualResult` 或已返回的逐步内容不一致仍不通过。完整逐步观察保留在原执行评论中,本地补充摘要提供计数、记录引用和摘要哈希,不代替原生明细。
45
+
46
+ 缺少可靠响应、多个候选、内容无法匹配或计划未保持终态时保留 `unknown`。核查只读取已有报告和状态,不再次生成;保留原操作 ID,不换 UUID 重试,也不自动将被上游改变的状态写回终态。生成后保存 `result.report.id` 和本次 `operation_id`,读取时用于取得本地补充摘要。
47
+
48
+ ## get_test_report
49
+
50
+ **只读。** 核对报告所属项目和计划,读取裁剪后的原生报告;可结合生成操作读取本地补充摘要。
51
+
52
+ | 参数 | 类型 | 必填 | 说明 |
53
+ | --- | --- | --- | --- |
54
+ | `project_id` | string | 是 | 目标项目 ID |
55
+ | `report_id` | string | 是 | 真实报告 ID,可从计划报告列表或生成结果取得 |
56
+ | `operation_id` | string(UUID) | 否 | 对应 `generate_test_report` 操作 ID,用于读取本地摘要;不是新的写入操作 ID |
57
+
58
+ **调用示例**:
59
+
60
+ ```json
61
+ {
62
+ "project_id": "project-1",
63
+ "report_id": "report-1",
64
+ "operation_id": "00000000-0000-4000-8000-000000000009"
65
+ }
66
+ ```
67
+
68
+ **返回**:
69
+
70
+ | 字段 | 内容 |
71
+ | --- | --- |
72
+ | `report` | `id / testPlanId / name / status / creator / createTime / triggerMode` 等元数据 |
73
+ | `content` | `testPlanReportId / name / caseCount / executeCount / passCount / summary / functionResult` 等原生字段 |
74
+ | `functional_cases` | 可用时返回 `id / caseId / name / status / results / actualResult` 数组,缺少原生明细时为 `null` |
75
+ | `native_issue_count` | 原生 `issueList` 长度;未提供列表时为 `null`,不按 0 推断 |
76
+ | `content_verification` | 本读取工具为 `partial`,不重新验证生成时快照 |
77
+ | `supplement` | 对应本地生成操作保存的 `execution_summary`,未提供操作 ID 时为 `null` |
78
+ | `supplement_unavailable` | 没有可用补充摘要时为 `true` |
79
+
80
+ 提供 `operation_id` 时必须属于当前账号、对应生成工具、项目及报告,否则返回 `TARGET_MISMATCH`。该摘要只保存在本地账本,不声称已写入原生报告。原生缺陷数与 `supplement.external_reference_count` 分开解释;不提供文件导出或报告分享。
@@ -0,0 +1,75 @@
1
+ # 用例评审工具
2
+
3
+ [返回工具目录](../README.md) · 工具组 `reviews` · 1 个只读工具、1 个写入工具。发起评审和读取结论,不代替评审人员写入通过或拒绝决定。
4
+
5
+ ## create_case_review
6
+
7
+ **写入。** 创建评审并关联明确的功能用例、评审人。接受[写入公共参数](../README.md#写入公共参数),不要求 revision。
8
+
9
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
10
+ | --- | --- | --- | --- |
11
+ | `project_id` | string | 是 | 目标项目 ID |
12
+ | `name` | string | 是 | 非空名称,最多 255 字符 |
13
+ | `case_ids` | string[] | 是 | 1–50 个用例库版本 ID,不可重复,另受 `max_association_items` 限制 |
14
+ | `reviewer_ids` | string[] | 是 | 1–50 个项目成员 ID,提交前去重 |
15
+ | `description` | string | 否 | `""`,最多 20000 字符 |
16
+ | `ends_at` | string | 否 | 带时区的 ISO 8601;省略时使用首次准备操作时刻的 3 天后 |
17
+
18
+ **调用示例**:
19
+
20
+ ```json
21
+ {
22
+ "project_id": "project-1",
23
+ "name": "结算用例评审",
24
+ "case_ids": ["case-1", "case-2"],
25
+ "reviewer_ids": ["user-1"],
26
+ "description": "请核对边界条件和预期结果",
27
+ "ends_at": "2026-11-13T18:00:00+08:00",
28
+ "operation_id": "00000000-0000-4000-8000-000000000004"
29
+ }
30
+ ```
31
+
32
+ **返回示例**(成功时的 `result`):
33
+
34
+ ```json
35
+ {
36
+ "project_id": "project-1",
37
+ "review_id": "review-1",
38
+ "created": true,
39
+ "case_ids": ["case-1", "case-2"],
40
+ "review_decision_written": false
41
+ }
42
+ ```
43
+
44
+ 同项目下已有同名评审时拒绝创建,不自动复用。说明会转义 HTML 并追加 `MSMCP:<operation_id>` 标记用于核查。评审 ID 以服务端返回为准,不使用客户端猜测值。
45
+
46
+ 这是“创建评审 → 关联用例”的多步骤动作,可能触发部署配置中的通知。中途失败可能已留下评审;先用原操作 ID 核查,只在返回允许恢复时继续原操作,不能另建同名评审。关联前会核对用例版本与内容是否变化。
47
+
48
+ ## get_case_review_context
49
+
50
+ **只读。** 读取评审信息、评审人员和一页逐条结论。
51
+
52
+ | 参数 | 类型 | 必填 | 默认值 / 说明 |
53
+ | --- | --- | --- | --- |
54
+ | `project_id` | string | 是 | 目标项目 ID |
55
+ | `review_id` | string | 是 | 真实评审 ID |
56
+ | `limit` | integer | 否 | 默认 20,范围 `1–100` |
57
+ | `cursor` | string | 否 | 同一查询的续读游标 |
58
+
59
+ **调用示例**:
60
+
61
+ ```json
62
+ {"project_id": "project-1", "review_id": "review-1", "limit": 50}
63
+ ```
64
+
65
+ **返回**:
66
+
67
+ - `review`:`id / name / status / projectId`。
68
+ - `reviewers`:人员的 `id / name`。
69
+ - [分页字段](../README.md#分页与完整性)及 `items`:每项含 `id / caseId / name / reviewStatus / refId / versionId`。
70
+ - `counts_in_page`:本页 `passed / failed / pending`;`Pass` 计通过,`UnPass` 计失败,其他值计待评审。
71
+ - `all_passed`:仅当**无输入游标、一次读到源末尾、结果非空且本次全部为 Pass**时为 `true`。
72
+
73
+ 评审的整体 `Completed` 状态不代表每条通过。分多页读取时,后续页的 `all_passed=false` 也不能直接判定存在失败;应读完所有页后结合逐条结果汇总,并说明跨页不具备快照一致性。
74
+
75
+ v1.20.23 的关联列表可能返回 `projectId=null`,且不按请求的 `projectId` 过滤。读取和创建回读均先核对评审项目,再通过关联 `reviewId / caseId` 与用例详情核验归属;缺失字段不会导致用例被静默丢弃,归属不匹配则明确拒绝。逐条结论使用该评审的关联状态,不使用用例库中的全局评审状态替代。
@@ -0,0 +1,27 @@
1
+ {
2
+ "project_id": "00000000-0000-4000-8000-000000000001",
3
+ "plan_id": "00000000-0000-4000-8000-000000000002",
4
+ "plan_case_id": "00000000-0000-4000-8000-000000000003",
5
+ "run_id": "00000000-0000-4000-8000-000000000004",
6
+ "attempt_id": "00000000-0000-4000-8000-000000000005",
7
+ "operation_id": "00000000-0000-4000-8000-000000000006",
8
+ "expected_revision": "示例占位:调用 get_test_case_context 后使用真实标识",
9
+ "dry_run": true,
10
+ "resume": false,
11
+ "result": {
12
+ "status": "failed",
13
+ "environment": "示例测试环境",
14
+ "tested_version": "example-build-001",
15
+ "started_at": "2026-10-04T14:00:00+08:00",
16
+ "finished_at": "2026-10-04T14:02:00+08:00",
17
+ "summary": "示例:必填项只输入空格时仍可进入下一步",
18
+ "observed": "提交只包含空格的必填值后进入确认页面,预期应保留在当前页面并显示校验错误。",
19
+ "step_results": [
20
+ {"step_index": 1, "status": "passed", "observed": "已进入示例表单页面。"},
21
+ {"step_index": 2, "status": "failed", "observed": "提交空格后进入确认页面,未出现预期的必填校验错误。"}
22
+ ],
23
+ "evidence": [
24
+ {"kind": "text", "value": "这是合成契约示例,不是真实执行证据;实际调用应提供真实观察及可访问的证据引用。"}
25
+ ]
26
+ }
27
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "schema_version": 1,
3
+ "adapter": "metersphere-v1.20",
4
+ "mantis_base_url": "https://mantis.umlife.net",
5
+ "project_bindings": [
6
+ {
7
+ "metersphere_project_id": "替换为实际 MeterSphere 项目 ID",
8
+ "mantis_project_id": 123,
9
+ "description": "此映射为示例;123 不是已验证的目标项目"
10
+ }
11
+ ],
12
+ "limits": {
13
+ "default_page_size": 20,
14
+ "max_page_size": 100,
15
+ "max_scan_items_per_call": 500,
16
+ "max_plan_items_for_completion": 2000,
17
+ "max_association_items": 50,
18
+ "max_execution_record_chars": 20000
19
+ }
20
+ }