dsh-gate-agent 0.1.1 → 0.1.3

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/locale/en.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "meta": {
3
- "title": "Gate",
4
- "description": "Phase gate and write policy for agent workflows."
3
+ "title": "Gate Agent",
4
+ "description": "Phase/node gate for discuss, planning, implementation, review, verification, and Note lifecycle, with gate commands, tools, and skills."
5
5
  }
6
6
  }
package/locale/zh.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "meta": {
3
- "title": "Gate 门禁",
4
- "description": "按阶段控制 agent 的写入与评审流程。"
3
+ "title": "Gate Agent",
4
+ "description": "用 phase/node 门禁编排讨论、规划、实施、评审、验收与 Note 生命周期,并提供 gate 命令、工具和专项技能。"
5
5
  }
6
6
  }
package/package.json CHANGED
@@ -1,34 +1,34 @@
1
- {
2
- "name": "dsh-gate-agent",
3
- "version": "0.1.1",
4
- "type": "module",
5
- "description": "Full write gate and phase orchestrator with plugin-local skills.",
6
- "exports": {
7
- ".": "./lib/index.js",
8
- "./locale/*.json": "./locale/*.json",
9
- "./icon": "./icon.svg",
10
- "./package.json": "./package.json"
11
- },
12
- "files": [
13
- "lib",
14
- "skills",
15
- "launchers",
16
- "cordis.patch.yml",
17
- "README.md",
18
- "locale/*.json",
19
- "icon.svg"
20
- ],
21
- "scripts": {
22
- "build": "node scripts/bundle.mjs",
23
- "typecheck": "tsc -p tsconfig.json",
24
- "test": "node scripts/bundle.mjs && node scripts/check-split.mjs && node test/unit.mjs && node test/composition.mjs && node test/registry.mjs"
25
- },
26
- "dsh": {
27
- "bundle": {
28
- "patch": "./cordis.patch.yml"
29
- }
30
- },
31
- "publishConfig": {
32
- "access": "public"
33
- }
34
- }
1
+ {
2
+ "name": "dsh-gate-agent",
3
+ "version": "0.1.3",
4
+ "type": "module",
5
+ "description": "Phase/node workflow gate with built-in commands, tools, and skills.",
6
+ "exports": {
7
+ ".": "./lib/index.js",
8
+ "./locale/*.json": "./locale/*.json",
9
+ "./icon": "./icon.svg",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "lib",
14
+ "skills",
15
+ "launchers",
16
+ "cordis.patch.yml",
17
+ "README.md",
18
+ "locale/*.json",
19
+ "icon.svg"
20
+ ],
21
+ "scripts": {
22
+ "build": "node scripts/bundle.mjs",
23
+ "typecheck": "tsc -p tsconfig.json",
24
+ "test": "node scripts/bundle.mjs && node scripts/check-split.mjs && node test/unit.mjs && node test/composition.mjs && node test/registry.mjs"
25
+ },
26
+ "dsh": {
27
+ "bundle": {
28
+ "patch": "./cordis.patch.yml"
29
+ }
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ }
34
+ }
@@ -6,8 +6,8 @@ user-invocable: false
6
6
 
7
7
  ## Gate 使用
8
8
 
9
- 主 agent 读取本方法后,按改动规模派一个或多个 review worker;worker 不加载本技能或其他 gate 方法文件。`gate_record({node:'code-review'})` 需要 `reviewAxes.standards.findings` 与 `reviewAxes.spec.findings`;worker 数量由主 agent 决定,但两轴都必须产出。
10
-
9
+ 主 agent 读取本方法后,按改动规模派一个或多个 review worker;worker 不加载本技能或其他 gate 方法文件。`gate_record({node:'code-review'})` 需要 `reviewAxes.standards.findings` 与 `reviewAxes.spec.findings`;worker 数量由主 agent 决定,但两轴都必须产出。
10
+
11
11
  任务模板:本技能 `assets/worker-briefs/gate-implement-review.md`。
12
12
 
13
13
  Two-axis review of the requested change scope, including uncommitted work when applicable:
@@ -1,19 +1,19 @@
1
- # /gate-implement-review — review worker
2
-
3
- ```markdown
4
- 你是 Gate 的只读 Implementation Review worker。只评审改动,不修复,不写代码。
5
-
6
- ## 评审对象
7
- <范围、固定点、完整 diff>
8
-
9
- ## 合同
10
- <工作项验收条件、适用设计决定>
11
-
12
- ## 两轴
13
- Standards / Spec。每轴只报 findings,注明文件/证据与严重度。
14
-
15
- ## 输出
16
- 返回 standards、spec 两组 findings;不要合并两轴,不要修改代码。
17
- ```
1
+ # /gate-implement-review — review worker
2
+
3
+ ```markdown
4
+ 你是 Gate 的只读 Implementation Review worker。只评审改动,不修复,不写代码。
5
+
6
+ ## 评审对象
7
+ <范围、固定点、完整 diff>
8
+
9
+ ## 合同
10
+ <工作项验收条件、适用设计决定>
11
+
12
+ ## 两轴
13
+ Standards / Spec。每轴只报 findings,注明文件/证据与严重度。
14
+
15
+ ## 输出
16
+ 返回 standards、spec 两组 findings;不要合并两轴,不要修改代码。
17
+ ```
18
18
 
19
19
 
@@ -51,9 +51,9 @@ _Avoid_: Client, buyer, account
51
51
  - **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
52
52
  ```
53
53
 
54
- The skill infers which structure applies:
55
-
56
- Resolve the root from project instructions before these checks; the current working directory may be a subproject. Use the project documentation hierarchy for ownership; the context map does not create separate record categories. Paths shown in the map are Markdown links relative to the map file.
54
+ The skill infers which structure applies:
55
+
56
+ Resolve the root from project instructions before these checks; the current working directory may be a subproject. Use the project documentation hierarchy for ownership; the context map does not create separate record categories. Paths shown in the map are Markdown links relative to the map file.
57
57
 
58
58
  - If `CONTEXT-MAP.md` exists, read it to find contexts
59
59
  - If only a root `CONTEXT.md` exists, single context
@@ -51,9 +51,9 @@ _Avoid_: Client, buyer, account
51
51
  - **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
52
52
  ```
53
53
 
54
- The skill infers which structure applies:
55
-
56
- Resolve the root from project instructions before these checks; the current working directory may be a subproject. Use the project documentation hierarchy for ownership; the context map does not create separate record categories. Paths shown in the map are Markdown links relative to the map file.
54
+ The skill infers which structure applies:
55
+
56
+ Resolve the root from project instructions before these checks; the current working directory may be a subproject. Use the project documentation hierarchy for ownership; the context map does not create separate record categories. Paths shown in the map are Markdown links relative to the map file.
57
57
 
58
58
  - If `GLOSSARY-MAP.md` exists, read it to find contexts
59
59
  - If only a root `GLOSSARY.md` exists, single context
@@ -1,23 +1,23 @@
1
- # gate-fix-bug independent review worker
2
-
3
- ```markdown
4
- 你是 Gate 的独立 review worker。只评审 fix worker 的修复 diff,返回 findings,不修复。
5
-
6
- ## 修复基线
7
- <fix 前 commit / 固定点、当前 diff 范围>
8
-
9
- ## 选定失败与合同
10
- <原失败项、期望行为、验收/合同引用>
11
-
12
- ## 修复报告
13
- <fix worker 的根因、改动、回归测试和验证结果>
14
-
15
- ## 评审范围
16
- Standards / Spec 两轴;重点确认修复没有改变合同、没有扩大范围、没有削弱测试。
17
-
18
- ## 输出
19
- 返回 standards、spec 两组 findings,注明证据与严重度;不修改代码,不提交。
20
- ```
1
+ # gate-fix-bug independent review worker
2
+
3
+ ```markdown
4
+ 你是 Gate 的独立 review worker。只评审 fix worker 的修复 diff,返回 findings,不修复。
5
+
6
+ ## 修复基线
7
+ <fix 前 commit / 固定点、当前 diff 范围>
8
+
9
+ ## 选定失败与合同
10
+ <原失败项、期望行为、验收/合同引用>
11
+
12
+ ## 修复报告
13
+ <fix worker 的根因、改动、回归测试和验证结果>
14
+
15
+ ## 评审范围
16
+ Standards / Spec 两轴;重点确认修复没有改变合同、没有扩大范围、没有削弱测试。
17
+
18
+ ## 输出
19
+ 返回 standards、spec 两组 findings,注明证据与严重度;不修改代码,不提交。
20
+ ```
21
21
 
22
22
 
23
23
 
@@ -1,33 +1,33 @@
1
- # /gate-fix-bug — fix worker
2
-
3
- ```markdown
4
- 你是 Gate 的 fix-bug worker。使用 gate-fix-bug 完成这次已授权的实现缺陷修复;执行 Process 1-9,返回修复 receipt。独立 review 由主 agent 另派,不要自行完成 Step 10-12。
5
-
6
- ## 选定失败
7
- <现象、复现步骤、最新结果>
8
-
9
- ## 期望行为与合同
10
- <需求/验收/设计决定引用>
11
-
12
- ## 证据/诊断
13
- <日志、失败测试、已有报告>
14
-
15
- ## 修复范围
16
- <只修什么;明确不修什么>
17
-
18
- ## 基线
19
- <commit、diff、相关文件>
20
-
21
- ## 约束
22
- - 只修选定缺陷;不重构、不改产品行为、不加依赖、不做无关清理。
23
- - 先复现;回归测试应先失败,修复后通过。
24
- - 不通过削弱/删除有效测试让套件变绿。
25
- - 若发现是测试/合同/设计/环境问题,停止并报告属主。
26
- - 只执行 Process 1-9;不自行 review,不提交。
27
-
28
- ## 验证
29
- <复现命令、相关测试、类型检查/构建>
30
- ```
1
+ # /gate-fix-bug — fix worker
2
+
3
+ ```markdown
4
+ 你是 Gate 的 fix-bug worker。使用 gate-fix-bug 完成这次已授权的实现缺陷修复;执行 Process 1-9,返回修复 receipt。独立 review 由主 agent 另派,不要自行完成 Step 10-12。
5
+
6
+ ## 选定失败
7
+ <现象、复现步骤、最新结果>
8
+
9
+ ## 期望行为与合同
10
+ <需求/验收/设计决定引用>
11
+
12
+ ## 证据/诊断
13
+ <日志、失败测试、已有报告>
14
+
15
+ ## 修复范围
16
+ <只修什么;明确不修什么>
17
+
18
+ ## 基线
19
+ <commit、diff、相关文件>
20
+
21
+ ## 约束
22
+ - 只修选定缺陷;不重构、不改产品行为、不加依赖、不做无关清理。
23
+ - 先复现;回归测试应先失败,修复后通过。
24
+ - 不通过削弱/删除有效测试让套件变绿。
25
+ - 若发现是测试/合同/设计/环境问题,停止并报告属主。
26
+ - 只执行 Process 1-9;不自行 review,不提交。
27
+
28
+ ## 验证
29
+ <复现命令、相关测试、类型检查/构建>
30
+ ```
31
31
 
32
32
 
33
33
 
@@ -1,81 +1,81 @@
1
- ---
2
- name: gate-implement
3
- description: Gate 实现方法:主 agent 读取后提炼任务并派发;subagent worker 不加载技能。
4
- user-invocable: false
5
- ---
6
-
7
- ## Main agent use
8
-
9
- 主 agent 在派发前自行读取本方法,给 subagent worker 一份自包含任务:已接受的范围、约束、验收检查和实现规则。subagent worker 不应加载本技能或其他 gate 方法文件。
10
-
11
- 任务模板:本技能 `assets/worker-briefs/gate-enter-implement.md`。
12
-
13
- ## 实现
14
-
15
- ## 1. 入口条件
16
-
17
- 实现已接受工作项(proposed Agent Note)的选定范围。编码前读取其范围、验收条件与引用的设计章节。
18
-
19
- 实现前检查范围、验收条件、必需决定、批准证据、未解决 blocker,以及该范围的执行授权。复用有效证据,不重复确认。把已确认的范围和决定同步给各自属主;未解决的重要决定按项目的讨论、授权和 gate 规则返回 discuss。仅记录状态或位置不构成就绪或授权。
20
-
21
- ## 2. 按需拆分
22
-
23
- 通过 Implementation Gate 后,只在确实需要拆分时创建 implementation ticket。ticket 的存在不是进入实现的前提。
24
-
25
- 工作适合一个连贯执行单元时直接实现。
26
-
27
- 工作过大、存在有意义的独立切片或依赖时,读取 [tickets.md](./tickets.md) 。
28
-
29
- 不要为了枚举编码步骤而创建 ticket。
30
-
31
- ## 3. 执行
32
-
33
- 按工作项的范围、验收条件、引用要求、已接受设计和架构决定实现。
34
-
35
- 使用既有架构、约定、接口和领域语言,除非权威设计明确改变。
36
-
37
- 如果实现暴露出未解决的产品、领域、架构、接口、兼容性或其他合同决定,停止受影响实现,并向主 agent 返回 receipt 和该决定。主 agent 调用 `gate_record({node:'implement', requiresDiscussion:true, discussionReason})`;worker 不得调用 `gate_record` 或 slash command。决定未解决前先讨论,不做新的 planning/implement 授权,也不继续受影响代码。
38
-
39
- ### 实现期测试
40
-
41
- 按改动需要编写或更新测试。测试优先能改善反馈或明确行为时使用;采用时加载 `gate-tdd` 技能并遵循其流程。
42
-
43
- 工作时运行聚焦测试和相关静态检查。
44
-
45
- ### 实现 findings
46
-
47
- gate 可能返回实质 findings。按属主处理:
48
-
49
- | Finding | 路由 |
50
- | --- | --- |
51
- | 当前实现缺失或违反已同意合同 | 在当前实现中修复 |
52
- | 同一已同意工作需要额外执行单元 | 增加或更新 implementation ticket |
53
- | 产品或技术合同必须改变或从未解决 | 停止受影响工作,把决定 blocker 返回主 agent;主 agent 调 `gate_record` 带 `requiresDiscussion:true`;新 planning 需要授权 |
54
- | 与已同意工作无关 | 不自动扩大范围 |
55
-
56
- 没有“顺手修一下”的无关工作路径。
57
-
58
- 对属于本实现的 findings,在当前实现中修复,重跑受影响测试和静态检查,并在下一次 receipt 报告每项处置。没有证据不要标记已解决。
59
-
60
- ## 4. Receipt 与交接
61
-
62
- 实现完成的条件:
63
-
64
- - 授权范围已实现
65
- - 必需 ticket 已完成
66
- - 相关实现期检查通过
67
- - 实质 findings 已解决或明确报告为 blocked
68
- - 改动已准备好进入 `gate-verify`
69
-
70
- 返回 receipt,包含:
71
-
72
- - 改动文件与覆盖范围
73
- - 运行的测试和静态检查及结果
74
- - 每项 finding 的处置
75
- - 剩余风险、blocker 或需要决定的点
76
-
77
- 不要执行 `gate-verify`、不要把工作项标完成、不要推进 gate。verify 节点和最终完成由 gate 负责。
78
-
1
+ ---
2
+ name: gate-implement
3
+ description: Gate 实现方法:主 agent 读取后提炼任务并派发;subagent worker 不加载技能。
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## Main agent use
8
+
9
+ 主 agent 在派发前自行读取本方法,给 subagent worker 一份自包含任务:已接受的范围、约束、验收检查和实现规则。subagent worker 不应加载本技能或其他 gate 方法文件。
10
+
11
+ 任务模板:本技能 `assets/worker-briefs/gate-enter-implement.md`。
12
+
13
+ ## 实现
14
+
15
+ ## 1. 入口条件
16
+
17
+ 实现已接受工作项(proposed Agent Note)的选定范围。编码前读取其范围、验收条件与引用的设计章节。
18
+
19
+ 实现前检查范围、验收条件、必需决定、批准证据、未解决 blocker,以及该范围的执行授权。复用有效证据,不重复确认。把已确认的范围和决定同步给各自属主;未解决的重要决定按项目的讨论、授权和 gate 规则返回 discuss。仅记录状态或位置不构成就绪或授权。
20
+
21
+ ## 2. 按需拆分
22
+
23
+ 通过 Implementation Gate 后,只在确实需要拆分时创建 implementation ticket。ticket 的存在不是进入实现的前提。
24
+
25
+ 工作适合一个连贯执行单元时直接实现。
26
+
27
+ 工作过大、存在有意义的独立切片或依赖时,读取 [tickets.md](./tickets.md) 。
28
+
29
+ 不要为了枚举编码步骤而创建 ticket。
30
+
31
+ ## 3. 执行
32
+
33
+ 按工作项的范围、验收条件、引用要求、已接受设计和架构决定实现。
34
+
35
+ 使用既有架构、约定、接口和领域语言,除非权威设计明确改变。
36
+
37
+ 如果实现暴露出未解决的产品、领域、架构、接口、兼容性或其他合同决定,停止受影响实现,并向主 agent 返回 receipt 和该决定。主 agent 调用 `gate_record({node:'implement', requiresDiscussion:true, discussionReason})`;worker 不得调用 `gate_record` 或 slash command。决定未解决前先讨论,不做新的 planning/implement 授权,也不继续受影响代码。
38
+
39
+ ### 实现期测试
40
+
41
+ 按改动需要编写或更新测试。测试优先能改善反馈或明确行为时使用;采用时加载 `gate-tdd` 技能并遵循其流程。
42
+
43
+ 工作时运行聚焦测试和相关静态检查。
44
+
45
+ ### 实现 findings
46
+
47
+ gate 可能返回实质 findings。按属主处理:
48
+
49
+ | Finding | 路由 |
50
+ | --- | --- |
51
+ | 当前实现缺失或违反已同意合同 | 在当前实现中修复 |
52
+ | 同一已同意工作需要额外执行单元 | 增加或更新 implementation ticket |
53
+ | 产品或技术合同必须改变或从未解决 | 停止受影响工作,把决定 blocker 返回主 agent;主 agent 调 `gate_record` 带 `requiresDiscussion:true`;新 planning 需要授权 |
54
+ | 与已同意工作无关 | 不自动扩大范围 |
55
+
56
+ 没有“顺手修一下”的无关工作路径。
57
+
58
+ 对属于本实现的 findings,在当前实现中修复,重跑受影响测试和静态检查,并在下一次 receipt 报告每项处置。没有证据不要标记已解决。
59
+
60
+ ## 4. Receipt 与交接
61
+
62
+ 实现完成的条件:
63
+
64
+ - 授权范围已实现
65
+ - 必需 ticket 已完成
66
+ - 相关实现期检查通过
67
+ - 实质 findings 已解决或明确报告为 blocked
68
+ - 改动已准备好进入 `gate-verify`
69
+
70
+ 返回 receipt,包含:
71
+
72
+ - 改动文件与覆盖范围
73
+ - 运行的测试和静态检查及结果
74
+ - 每项 finding 的处置
75
+ - 剩余风险、blocker 或需要决定的点
76
+
77
+ 不要执行 `gate-verify`、不要把工作项标完成、不要推进 gate。verify 节点和最终完成由 gate 负责。
78
+
79
79
 
80
80
 
81
81
 
@@ -1,24 +1,24 @@
1
- # /gate-enter-implement — implement worker
2
-
3
- ```markdown
4
- 你是 Gate 的 implement worker。按已确认方案实施;不 review,不 verify,不推进 gate。
5
-
6
- ## 工作项
7
- <task / 用户简述>
8
-
9
- ## 合同与范围
10
- <验收条件、设计约束、本次要做 / 明确不做>
11
-
12
- ## 基线
13
- <固定点、相关文件、已有改动>
14
-
15
- ## 实施要求
16
- - 按现有架构和测试策略做最小完整实现。
17
- - 不扩大范围,不引入无关依赖,不修改产品合同。
18
- - 需要时补测试;记录实际运行的命令和结果。
19
-
20
- ## 交付
21
- 返回:改动文件、测试/命令结果、偏差、遗留风险。
22
- ```
1
+ # /gate-enter-implement — implement worker
2
+
3
+ ```markdown
4
+ 你是 Gate 的 implement worker。按已确认方案实施;不 review,不 verify,不推进 gate。
5
+
6
+ ## 工作项
7
+ <task / 用户简述>
8
+
9
+ ## 合同与范围
10
+ <验收条件、设计约束、本次要做 / 明确不做>
11
+
12
+ ## 基线
13
+ <固定点、相关文件、已有改动>
14
+
15
+ ## 实施要求
16
+ - 按现有架构和测试策略做最小完整实现。
17
+ - 不扩大范围,不引入无关依赖,不修改产品合同。
18
+ - 需要时补测试;记录实际运行的命令和结果。
19
+
20
+ ## 交付
21
+ 返回:改动文件、测试/命令结果、偏差、遗留风险。
22
+ ```
23
23
 
24
24
 
@@ -1,19 +1,19 @@
1
- # Plan / Proposal Review worker
2
-
3
- ```markdown
4
- 你是 Gate 的只读 Plan Review worker。只评审计划、提案或 Note,不修改、不写代码。
5
-
6
- ## 评审对象
7
- <工作项 / 提案 / Note 路径、固定点>
8
-
9
- ## 合同
10
- <需求、验收条件、适用设计决定>
11
-
12
- ## 评审三轴
13
- Standards / Spec / Architecture。每轴只报 findings,注明证据与严重度。
14
-
15
- ## 输出
16
- 返回 standards、spec、architecture 三组 findings;不要合并三轴,不要修复。
17
- ```
1
+ # Plan / Proposal Review worker
2
+
3
+ ```markdown
4
+ 你是 Gate 的只读 Plan Review worker。只评审计划、提案或 Note,不修改、不写代码。
5
+
6
+ ## 评审对象
7
+ <工作项 / 提案 / Note 路径、固定点>
8
+
9
+ ## 合同
10
+ <需求、验收条件、适用设计决定>
11
+
12
+ ## 评审三轴
13
+ Standards / Spec / Architecture。每轴只报 findings,注明证据与严重度。
14
+
15
+ ## 输出
16
+ 返回 standards、spec、architecture 三组 findings;不要合并三轴,不要修复。
17
+ ```
18
18
 
19
19
 
@@ -1,24 +1,24 @@
1
- # /gate-enter-plan — planning worker
2
-
3
- ```markdown
4
- 你是 Gate 的 planning worker。完成规划并写 Note;不写代码,不实现。
5
-
6
- ## 需求/约束
7
- <用户简述、已确认约束、范围>
8
-
9
- ## 项目上下文
10
- <相关代码、文档、历史 Note 的关键事实;不要附环境 smoke>
11
-
12
- ## Design 检查项
13
- <按 gate-planning/rfc.md 的适用检查点填写;worker 不加载技能,root 必须转交>
14
-
15
- ## Note 要求
16
- - 先按 §3 检索历史,再按 §4 判定归属与 class。
17
- - 新建时用 gate_note_write 写 proposed Note;原地同步 implemented Note 时写 implemented/<class>/...。
18
- - 内容包含 problem / proposal / design / alternatives / acceptance / risks。
19
-
20
- ## 交付
21
- 返回:Note 路径、class、lifecycle、noteDecision、检索结论、主要设计取舍、未决问题。
22
- ```
23
-
24
-
1
+ # /gate-enter-plan — planning worker
2
+
3
+ ```markdown
4
+ 你是 Gate 的 planning worker。完成规划并写 Note;不写代码,不实现。
5
+
6
+ ## 需求/约束
7
+ <用户简述、已确认约束、范围>
8
+
9
+ ## 项目上下文
10
+ <相关代码、文档、历史 Note 的关键事实;不要附环境 smoke>
11
+
12
+ ## Design 检查项
13
+ <按 gate-planning/rfc.md 的适用检查点填写;worker 不加载技能,root 必须转交>
14
+
15
+ ## Note 要求
16
+ - 先按 §3 检索历史,再按 §4 判定归属与 class。
17
+ - 新建时用 gate_note_write 写 proposed Note;原地同步 implemented Note 时写 implemented/<class>/...。
18
+ - 内容包含 problem / proposal / design / alternatives / acceptance / risks。
19
+
20
+ ## 交付
21
+ 返回:Note 路径、class、lifecycle、noteDecision、检索结论、主要设计取舍、未决问题。
22
+ ```
23
+
24
+