@sokeai/cli 1.0.75 → 1.0.76

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sokeai/cli",
3
- "version": "1.0.75",
3
+ "version": "1.0.76",
4
4
  "description": "授客AI官方CLI工具 - 支持AI Agent Skills",
5
5
  "bin": {
6
6
  "soke-cli": "scripts/run.js"
@@ -81,6 +81,7 @@ soke-cli course +list-course-users --course-id "COURSE-UUID"
81
81
  | `+list-categories` | 查询课程分类(获取 category-id) |
82
82
  | `+create` | 创建课程基本信息 |
83
83
  | `+update` | 更新课程信息 |
84
+ | `+advanced` | 更新课程高级设置 |
84
85
  | `+publish` | 发布课程 |
85
86
  | `+get-course` | 查询课程详情 |
86
87
  | `+list-courses` | 查询课程列表 |
@@ -142,6 +143,11 @@ done
142
143
 
143
144
  # 5. 发布课程
144
145
  soke-cli course +publish --course-id "$course_id"
146
+
147
+ # 或定时发布课程,输入北京时间
148
+ soke-cli course +publish \
149
+ --course-id "$course_id" \
150
+ --publish-time "2026-07-14 17:24:42"
145
151
  ```
146
152
 
147
153
  ### 场景2: 管理现有课程
@@ -214,13 +214,14 @@ Gate 2→3: ✅ 课件 ≥ 1
214
214
  #### Phase 3: 课程设置
215
215
 
216
216
  → read references/subs/settings/SOP.md 执行
217
- 基础: title/description(course +update)
217
+ 基础: title/credit/description/image(course +update)
218
218
 
219
219
  → read references/subs/template/SOP.md Step 3 执行
220
220
  将当前所有设置项以表格形式展示(仅「设置项」+「当前值」两列)
221
221
  告知用户: "想修改哪项?直接告诉我就行。"
222
222
  用户指令处理:
223
- - 标题/描述 → exec: course +update(✅ CLI 支持) → 刷新表格
223
+ - 标题/学分/描述/封面 → exec: course +update(✅ CLI 支持) → 刷新表格
224
+ - 学习模式/倍速/人脸/提醒/评价/拖动/评论/文档防挂机/交流群二维码 → exec: course +advanced(✅ CLI 支持;交流群二维码本地图片用 --image-file,命令内部只上传 OSS,不进入图片库) → 刷新表格
224
225
  - 其他设置 → "已记录: {项} → {新值}(需在后台操作: {路径})" → 刷新表格
225
226
  - "可以了"/"继续" → 退出 Phase 3
226
227
  循环直到用户确认
@@ -231,8 +232,9 @@ Gate 3→4: 无硬阻塞
231
232
 
232
233
  → read references/subs/publish/SOP.md 执行
233
234
  Gate Check: 标题/分类/课件数量/转码状态
234
- 通过 → course +publish
235
- 定时/审批/批量⚠️ CLI 不支持
235
+ 直接发布 → course +publish --course-id <uuid>
236
+ 定时发布course +publish --course-id <uuid> --publish-time "<北京时间>"
237
+ 审批/批量 → ⚠️ CLI 不支持
236
238
 
237
239
  Gate 4→5: ✅ status=1
238
240
 
@@ -378,10 +380,10 @@ Gate 4→5: ✅ status=1
378
380
  |------|------|
379
381
  | 课件类型 | image/article/link/quiz/homework |
380
382
  | 分类 | 新增分类 |
381
- | 课程设置 | credit/point/lector_id/tags/cover上传/简介插图 |
382
- | 高级设置 | 学习模式/倍速/人脸/提醒/评价/证书/签名/钉钉群 |
383
+ | 课程设置 | point/lector_id/tags/简介插图 |
384
+ | 高级设置 | 证书/签名 |
383
385
  | 收费 | 价格/试看 |
384
- | 发布 | 定时/审批/批量 |
386
+ | 发布 | 审批/批量 |
385
387
  | 维护 | 关闭/删除/复制 |
386
388
 
387
389
  ### 中断恢复
@@ -30,14 +30,14 @@
30
30
  | 14 | "换个封面" | cover | Phase 3(⚠️ CLI 不支持) |
31
31
  | 15 | "加几个标签" | tags | Phase 3(⚠️ CLI 不支持) |
32
32
 
33
- ## advanced_settings(高级设置)
33
+ ## advanced(高级设置)
34
34
 
35
35
  | # | 用户输入 | 提取 | 路由 |
36
36
  |---|---------|------|------|
37
- | 16 | "开启倍速" | speed | Phase 3(⚠️ 不支持) |
38
- | 17 | "改成解锁式学习" | study_type=2 | Phase 3(⚠️ 不支持) |
39
- | 18 | "开启人脸识别" | face_recognition | Phase 3(⚠️ 不支持) |
40
- | 19 | "设置未学提醒,每周推送" | remind_cycle=7 | Phase 3(⚠️ 不支持) |
37
+ | 16 | "开启倍速" | is_accelerate=1 | Phase 3(course +advanced) |
38
+ | 17 | "改成解锁式学习" | study_type=2 | Phase 3(course +advanced) |
39
+ | 18 | "开启人脸识别" | open_face_recognition=1 | Phase 3(course +advanced) |
40
+ | 19 | "设置未学提醒,每周推送" | is_remind=1, remind_days=7 | Phase 3(course +advanced) |
41
41
  | 20 | "关联证书" | certificate | Phase 3(⚠️ 不支持) |
42
42
 
43
43
  ## charge(收费)
@@ -53,7 +53,7 @@
53
53
  |---|---------|------|------|
54
54
  | 23 | "发布课程" | publish | Phase 4 |
55
55
  | 24 | "上线吧" | publish | Phase 4 |
56
- | 25 | "定时发布,下周一早上9点" | scheduled | Phase 4(⚠️ 不支持) |
56
+ | 25 | "定时发布,下周一早上9点" | scheduled, publish_time | Phase 4 |
57
57
  | 26 | "提交审批" | approval | Phase 4(⚠️ 不支持) |
58
58
 
59
59
  ## assign(指派)
@@ -92,8 +92,10 @@ Gate 2→3: ✅ lesson_ids 长度 ≥ 1
92
92
 
93
93
  ### Step 3.2: 高级设置
94
94
  调度: soke-course-settings
95
- 全部 ⚠️ CLI 不支持,统一告知:
96
- "高级设置(学习模式/倍速/人脸/提醒/评价/证书/签名/钉钉群)需在后台→课程编辑→高级设置中手动配置。"
95
+ 操作: course +advanced --course-id <uuid> ...
96
+ 支持: 学习模式/待办推送/截止后学习/人脸识别/学习中人脸识别/未学提醒/倍速/拖动/评价/交流群二维码/文档防挂机/评论
97
+ 交流群二维码: 用户给本地图片时,使用 course +advanced --image-file <path>,命令内部只上传 OSS 并生成 imageOssUrl,不进入图片库
98
+ 证书/签名仍需后台操作。
97
99
 
98
100
  ### Step 3.3: 收费设置(可选)
99
101
  读取: subs/charge/SOP.md 执行
@@ -120,12 +122,13 @@ Gate 3→4: 无硬阻塞(设置可跳过)
120
122
  仅警告 → 询问是否忽略
121
123
 
122
124
  ### Step 4.2: 执行发布
123
- 自身: course +publish --course-id <uuid>
125
+ 直接发布: course +publish --course-id <uuid>
126
+ 定时发布: course +publish --course-id <uuid> --publish-time "<北京时间>"
124
127
  提取: 发布状态 → 存上下文
125
128
  失败: 检查 Gate Check 结果
126
129
 
127
130
  ### Step 4.3: 后续(可选)
128
- 定时发布/审批/批量 → ⚠️ CLI 不支持 → 告知后台路径
131
+ 审批/批量 → ⚠️ CLI 不支持 → 告知后台路径
129
132
 
130
133
  Gate 4→5: ✅ status=1
131
134
 
@@ -52,8 +52,10 @@
52
52
  - 审批人为空 → 默认通过
53
53
  - 多级审批: 一级不可删除,默认主管理员和或签
54
54
 
55
- ## 定时发布(⚠️ CLI 暂不支持)
55
+ ## 定时发布
56
56
 
57
+ - 执行: `course +publish --course-id <uuid> --publish-time "<北京时间>"`
58
+ - 输入北京时间,会在规定时间发布课程
57
59
  - 到时间点自动发布并推送消息
58
60
  - 未到点时学员收不到消息、前端看不到
59
61
 
@@ -53,13 +53,26 @@ tags: [soke, publish, gate-check, status, approval]
53
53
 
54
54
  ### 第二步:执行发布 `course +publish`
55
55
 
56
+ 直接发布:
57
+
56
58
  ```bash
57
59
  soke course +publish --course-id <courseId>
58
60
  ```
59
61
 
62
+ 定时发布:
63
+
64
+ ```bash
65
+ soke course +publish \
66
+ --course-id <courseId> \
67
+ --publish-time "2026-07-14 17:24:42"
68
+ ```
69
+
60
70
  | 参数 | 必填 | 说明 |
61
71
  |------|------|------|
62
72
  | `--course-id` | 是 | 课程 ID |
73
+ | `--publish-time` | 否 | 定时发布时间,输入北京时间;不传则直接发布 |
74
+
75
+ > 实现口径:传入非零 `--publish-time` 时开启定时发布;未传或传 `0000-00-00 00:00:00` 时不开启定时发布。
63
76
 
64
77
  发布成功后课程状态由 `0` → `1`。
65
78
 
@@ -67,7 +80,6 @@ soke course +publish --course-id <courseId>
67
80
 
68
81
  | 操作 | 说明 | 替代路径 |
69
82
  |------|------|---------|
70
- | **定时发布** | 设置未来时间自动发布 | 后台 → 课程管理 → 发布设置 → 定时发布 |
71
83
  | **审批流** | 发布需经过审批流程 | 后台 → 系统设置 → 审批设置 |
72
84
  | **批量发布** | 一次发布多门课程 | 后台 → 课程管理 → 批量操作 |
73
85
  | **关闭课程** | 将已发布课程下线 | 后台 → 课程管理 → 课程操作 → 关闭 |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: soke-course-settings
3
3
  version: 1.0.0
4
- description: 课程设置 — 基础信息编辑及高级设置项说明,高级设置需后台操作
4
+ description: 课程设置 — 基础信息编辑及高级设置项说明,支持通过 CLI 更新课程高级设置
5
5
  tags: [soke, course, settings, configuration, advanced]
6
6
  ---
7
7
 
@@ -9,7 +9,7 @@ tags: [soke, course, settings, configuration, advanced]
9
9
 
10
10
  ## 触发描述
11
11
 
12
- 课程创建后需要对课程标题、描述等基础信息进行修改,或需要了解高级设置项(学习模式、人脸识别、证书等)的配置方式时触发本技能。
12
+ 课程创建后需要对课程标题、描述等基础信息进行修改,或需要更新高级设置项(学习模式、人脸识别、提醒、倍速等)时触发本技能。
13
13
 
14
14
  ## CLI 支持的操作
15
15
 
@@ -19,33 +19,88 @@ tags: [soke, course, settings, configuration, advanced]
19
19
  soke course +update \
20
20
  --course-id <courseId> \
21
21
  --title "<新标题>" \
22
- --description "<新描述>"
22
+ --credit 10 \
23
+ --description "<新描述>" \
24
+ --image "<图片库 photoUri>"
23
25
  ```
24
26
 
25
27
  | 参数 | 必填 | 说明 |
26
28
  |------|------|------|
27
29
  | `--course-id` | 是 | 课程 ID |
28
30
  | `--title` | 否 | 课程标题 |
31
+ | `--credit` | 否 | 学分 |
29
32
  | `--description` | 否 | 课程描述/简介 |
33
+ | `--image` | 否 | 课程封面图片地址,使用图片库列表接口返回的 `photoUri` |
34
+ | `--image-x` | 否 | 封面裁剪 x 坐标,默认 0 |
35
+ | `--image-y` | 否 | 封面裁剪 y 坐标,默认 0 |
36
+ | `--image-w` | 否 | 封面裁剪宽度,默认 0 |
37
+ | `--image-h` | 否 | 封面裁剪高度,默认 0 |
30
38
 
31
- > `title` `description` 至少传一个,可同时更新。
39
+ > 至少传一个可更新字段,可同时更新。`--description ""` 会清空课程描述。
32
40
 
33
- ## ⚠️ CLI 不支持的高级设置
41
+ ### 高级设置更新 `course +advanced`
34
42
 
35
- 以下 9 项高级设置均需通过管理后台操作,CLI 暂不支持:
43
+ ```bash
44
+ soke course +advanced \
45
+ --course-id <courseId> \
46
+ --study-type 2 \
47
+ --is-accelerate 1 \
48
+ --is-drag 0 \
49
+ --evaluate-required 1
50
+ ```
51
+
52
+ | 参数 | 默认 | 说明 |
53
+ |------|------|------|
54
+ | `--course-id` | 必填 | 课程 ID |
55
+ | `--open-workrecord` | 0 | 待办推送,1 开启,0 不开启 |
56
+ | `--allow-after-expiration` | 1 | 截止后继续学习,1 允许,0 不允许 |
57
+ | `--open-face-recognition` | 0 | 课程前人脸识别,1 开启,0 不开启 |
58
+ | `--is-first-face` | 0 | 0 不识别,1 首次使用,2 每次进入 |
59
+ | `--learning-face-recognition` | 0 | 视频学习中人脸识别,1 开启,0 不开启 |
60
+ | `--face-recognition-times` | 1 | 视频学习中人脸识别次数 |
61
+ | `--study-type` | 1 | 学习模式,1 自由式,2 解锁式 |
62
+ | `--is-remind` | 0 | 未学提醒,1 开启,0 不开启 |
63
+ | `--remind-days` | 1 | 未学提醒推送周期,单位天 |
64
+ | `--remind-time` | 空 | 推送时间,格式 HH:MM:SS |
65
+ | `--remind-content` | 管理员提醒文案 | 未学提醒推送内容 |
66
+ | `--is-accelerate` | 1 | 视频或音频倍速,1 开启,0 不开启 |
67
+ | `--is-drag` | 0 | 视频是否可拖动,1 允许,0 不允许 |
68
+ | `--drag-type` | 1 | 1 仅首次播放不允许拖动,2 每次播放均不允许拖动 |
69
+ | `--evaluate-required` | 0 | 完成学习后打星评价,1 开启,0 不开启 |
70
+ | `--image-file` | 空 | 本地交流群二维码图片路径,命令内部上传到 OSS 并写入 `imageOssUrl`,不进入图片库;支持 jpg/jpeg/png |
71
+ | `--image-oss-url` | 空 | 已上传到 OSS/CDN 的交流群二维码完整访问 URL;与 `--image-file` 二选一 |
72
+ | `--is-hang` | 0 | 文档防挂机,1 开启,0 不开启 |
73
+ | `--hang-time` | 0 | 文档防挂机时间,单位分钟,最多 60 |
74
+ | `--comment-switch` | 1 | 课程评论,1 开启,0 不开启 |
75
+
76
+ 该命令请求 `PUT /skills/course/advanceSetting/{id}`,请求体固定带 `action=advanced`。
77
+
78
+ **交流群二维码 `imageOssUrl` 取值规则:**
79
+
80
+ 1. 如果用户提供的是本地二维码图片,直接使用 `--image-file`。命令会在内部调用 OSS 上传能力,使用 `Module: "image"` 上传,并把签名里的 `editorHost`(优先)或 `cdnhost` 与 OSS object 拼成完整 URL 写入 `imageOssUrl`。该图片不会进入图片库。
81
+
82
+ ```bash
83
+ soke-cli course +advanced \
84
+ --course-id <courseId> \
85
+ --image-file "./qrcode.png"
86
+ ```
36
87
 
37
- | 序号 | 设置项 | 说明 | 后台操作路径 |
38
- |------|--------|------|-------------|
39
- | 1 | **学习模式** `study_type` | 必修/选修模式、闯关模式(顺序解锁)、自由模式 | 后台 → 课程管理 → 课程列表 → 编辑 → 学习设置 |
40
- | 2 | **倍速播放** `speed` | 允许学员使用倍速播放(0.5x - 2.0x) | 后台 → 课程管理 → 课程列表 → 编辑 → 学习设置 → 播放控制 |
41
- | 3 | **人脸识别** `face_recognition` | 开启后学员学习时需人脸验证,防挂机/替学 | 后台 → 课程管理 → 课程列表 → 编辑 → 学习设置 → 人脸识别 |
42
- | 4 | **学习提醒** `reminders` | 配置定时提醒推送(未完成学员、推送时间、频次) | 后台 → 课程管理 → 课程列表 → 编辑 → 学习设置 → 提醒设置 |
43
- | 5 | **课程评价** `rating` | 开启学员评分/评论功能,可设为审核后展示 | 后台 → 课程管理 → 课程列表 → 编辑 → 评价设置 |
44
- | 6 | **证书设置** `certificate` | 配置结业证书模板(背景图、字段、盖章)和通过条件 | 后台 → 课程管理 → 课程列表 → 编辑 → 证书设置 |
45
- | 7 | **证书签名** `signature` | 配置证书上的签名图片(讲师/负责人手写签名) | 后台 → 课程管理 → 课程列表 → 编辑 → 证书设置 → 签名管理 |
46
- | 8 | **钉钉二维码** `dingtalk_qrcode` | 配置钉钉群二维码,学员学习页展示入群入口 | 后台 → 课程管理 → 课程列表 → 编辑 → 学习设置 → 钉钉二维码 |
88
+ 2. 如果用户已经有 OSS/CDN 完整访问 URL,直接传 `--image-oss-url`:
47
89
 
48
- > 操作路径示例以标准后台结构为准,实际路径可能因后台版本略有差异。
90
+ ```bash
91
+ soke-cli course +advanced \
92
+ --course-id <courseId> \
93
+ --image-oss-url "$IMAGE_URL"
94
+ ```
95
+
96
+ 3. `--image-file` 和 `--image-oss-url` 只能传一个。不要把图片 UUID、素材 UUID 或纯 `data.object` 当作 `imageOssUrl`;该字段需要可访问的完整图片 URL。
97
+
98
+ ## ⚠️ CLI 暂不支持的设置
99
+
100
+ | 设置项 | 说明 | 后台操作路径 |
101
+ |--------|------|-------------|
102
+ | **证书设置** `certificate` | 配置结业证书模板(背景图、字段、盖章)和通过条件 | 后台 → 课程管理 → 课程列表 → 编辑 → 证书设置 |
103
+ | **证书签名** `signature` | 配置证书上的签名图片(讲师/负责人手写签名) | 后台 → 课程管理 → 课程列表 → 编辑 → 证书设置 → 签名管理 |
49
104
 
50
105
  ## 输出标准
51
106
 
@@ -57,18 +112,24 @@ soke course +update \
57
112
  - 描述: {newDescription 摘要}
58
113
  ```
59
114
 
60
- 当用户询问高级设置时,列出上述 9 项并以表格形式呈现,引导至对应后台路径。
115
+ 高级设置更新成功后:
116
+
117
+ ```
118
+ ✅ 课程高级设置更新成功
119
+ - 课程: {courseId}
120
+ - 结果: 1
121
+ ```
61
122
 
62
123
  ## 注意事项
63
124
 
64
- 1. `course +update` 仅支持 `title` 和 `description` 两个字段的修改
65
- 2. 封面图修改属于素材上传范围,不在本技能覆盖内
66
- 3. 分类修改需通过专门的分类设置功能或后台操作
67
- 4. 高级设置项之间可能存在依赖关系(如证书依赖签名设置),建议按表格顺序逐项配置
125
+ 1. `course +update` 支持标题、学分、描述、封面图和分类 ID 修改
126
+ 2. 封面图地址来自图片库列表接口返回的 `photoUri`
127
+ 3. 分类修改可通过 `--category-id` 更新
128
+ 4. 高级设置项之间可能存在依赖关系(如开启视频学习中人脸识别后再设置识别次数),建议按表格顺序逐项配置
68
129
  5. 钉钉二维码设置与课程复制时的行为有关联(复制时不携带,见 `soke-course-copy`)
69
130
 
70
131
  ## 检查清单
71
132
 
72
- - [ ] CLI 操作:title/description 已准备完毕,courseId 确认存在
73
- - [ ] 高级设置需求已识别,已提供对应后台路径
74
- - [ ] 所有 9 项高级设置均已告知用户为后台操作
133
+ - [ ] CLI 操作:title/description 或高级设置参数已准备完毕,courseId 确认存在
134
+ - [ ] 高级设置需求已识别,优先使用 `course +advanced`
135
+ - [ ] 证书/签名等未支持设置已提供对应后台路径
@@ -1,155 +1,123 @@
1
1
  ---
2
2
  name: soke-exam-question-pool
3
- summary: 授客可练习题库(题库列表、题库详情、题目列表、题库练习交卷),通过 soke-cli exam-question-pool 命令操作
4
- version: 1.1.0
5
- description: "授客可练习题库:按 examQuestionPool 接口链路先查询题库列表,再用题库 uuid 查询详情、题目列表,可进行题库练习交卷。当用户需要查看可练习题库、题库详情、题目内容、答案和解析,或提交题库练习交卷时使用。 | Soke question pool: use the examQuestionPool API flow to list pools, get pool detail, list questions, and finish a practice session."
3
+ summary: 授客可练习题库交互式练习系统
4
+ version: 2.0.0
5
+ description: 授客可练习题库交互式练习
6
6
  metadata:
7
7
  requires:
8
- bins: ["soke-cli"]
9
- cliHelp: "soke-cli exam-question-pool --help"
8
+ bins: [soke-cli]
9
+ cliHelp: soke-cli exam-question-pool --help
10
10
  ---
11
11
 
12
- # 可练习题库 (examQuestionPool)
12
+ # 可练习题库交互式练习系统
13
13
 
14
- **CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md),其中包含认证、配置、权限处理**
14
+ 核心链路全量分页选库随机逐题实时反馈
15
15
 
16
- ## 核心链路
16
+ ## 交互流程总览
17
17
 
18
- 这组命令对接 `/skills/examQuestionPool/...` 接口。推荐调用顺序:
18
+ 用户触发练习Step1全量分页拉取全部题库展示供选择Step2用户选择一个题库Step3拉取该题库全部题目加载答题状态Step4从未答题目中随机抽一道呈现判分Step5询问下一题结束重开循环Step4
19
19
 
20
- 1. `+list` 获取题库列表,从默认输出的 `uuid` 取题库 UUID。
21
- 2. `+get --pool-id <uuid>` 查询详情,确认题库列表的 `uuid` 与传入 `pool-id` 一致。
22
- 3. `+questions --pool-id <uuid>` 使用同一个 `pool-id` 查询题目。
23
- 4. `+finish --pool-id <uuid> --answers '<答案JSON>'` 进行题库练习交卷。
20
+ ## Step1全量分页拉取题库列表
24
21
 
25
- `--page`、`--page-size` 用于第一步题库列表分页查询。
22
+ soke-cli exam-question-pool +list --page 1 --page-size 100 --status 1 --format json
26
23
 
27
- ## Shortcuts 总览
24
+ 循环拉取检查data.hasMore若为1则继续翻页直到hasMore为0合并所有页data.list按uuid去重
25
+ 重要API分页存在跨页重叠bug相邻两页可能返回相同uuid的题库必须按uuid去重不能简单拼接
26
+ 优先使用page-size100一次拉全减少分页次数和重叠风险
28
27
 
29
- | Shortcut | 说明 |
30
- |----------|------|
31
- | `+list` | 获取可练习题库列表,返回后续 `pool-id` 所需的题库 `uuid` |
32
- | `+get` | 根据题库 `pool-id` 获取可练习题库详情 |
33
- | `+questions` | 根据 `pool-id`(题库id),即题库列表的 `uuid`,获取题库题目 |
34
- | `+finish` | 根据 `pool-id` 进行题库练习交卷 |
28
+ ### 展示规则
35
29
 
36
- ## +list
30
+ 每个题库一行选项只显示序号和题库名称格式为title
31
+ 不要显示题目数question_count和状态pass_status
32
+ 题库总数小于等于20一次性展示全部
33
+ 题库总数大于20分页展示每页最多20个末尾追加下一页翻到底后追加上一页
37
34
 
38
- 获取可练习题库列表。
35
+ ## Step2用户选择题库
39
36
 
40
- ```bash
41
- soke-cli exam-question-pool +list \
42
- --page 1 \
43
- --page-size 10
44
- ```
37
+ 用户输入编号取pool_id为选中项的uuid
38
+ 若用户说随机选一个从未完成题库中随机选全部完成则全量随机
45
39
 
46
- | 参数 | 必需 | 说明 |
47
- |------|------|------|
48
- | `--page` | 否 | 页码,从 1 开始,默认 1 |
49
- | `--page-size` | 否 | 每页条数,默认 10 |
40
+ ## Step3拉取题目和初始化状态
50
41
 
51
- 默认输出为横向单行文本,每条题库数据显示:
42
+ soke-cli exam-question-pool +questions --pool-id UUID --format json
52
43
 
53
- | 字段 | 说明 |
54
- |------|------|
55
- | `uuid` | 题库 UUID,后续作为 `--pool-id` |
56
- | `title` | 题库标题 |
57
- | `description` | 题库描述,默认会清理简单 HTML 标签和换行 |
58
- | `题目数量` | 来自 `question_count` |
59
- | `创建时间` | 来自 `create_exercise_time` |
44
+ 注意pool-id的值不要加引号否则会报参数格式错误
60
45
 
61
- ## +get
46
+ 提取data.content中所有题目uuid type title choices answer show_answer analysis
62
47
 
63
- 根据题库 UUID 获取可练习题库详情。
48
+ ### 答题状态文件
64
49
 
65
- ```bash
66
- soke-cli exam-question-pool +get \
67
- --pool-id "<上一步题库列表的 uuid,即题库id>"
68
- ```
50
+ 路径C:\Users\soke\.qclaw\workspace\.exam-state\{pool-uuid}.json
69
51
 
70
- | 参数 | 必需 | 说明 |
71
- |------|------|------|
72
- | `--pool-id` | 是 | 题库 ID,必须来自 `+list` 默认输出中的 `uuid` |
52
+ 格式pool_id uuid pool_title 题库名 total 5 correct 0 answered 空数组
73
53
 
74
- 默认输出为横向单行文本,题库详情数据:
54
+ 文件不存在或pool_id不匹配新建answered为空数组
55
+ 答完一题追加uuid到answered正确则correct加1
56
+ 结束答题保留state
57
+ 重新开始清空answered为空数组correct为0
58
+ answered长度大于等于total自动提示本轮全部答完
59
+ 已展示但未作答的题目不算已答用户在题目展示后说退出结束退出答题等该题不计入answered不计入correct不出现在本轮总结表格中只有用户实际选择了选项或输入了答案并提交才算作答
75
60
 
76
- | 字段 | 说明 |
77
- |------|------|
78
- | `uuid` | 题库 UUID,应与请求 `--pool-id` 一致 |
79
- | `title` | 题库标题 |
80
- | `description` | 题库描述,默认会清理简单 HTML 标签和换行 |
81
- | `题目数量` | 来自 `question_count` |
82
- | `创建时间` | 来自 `create_exercise_time` |
83
- | `总题数` | 来自 `data.all_count` |
61
+ ## Step4随机出题和呈现
84
62
 
63
+ ### 随机逻辑
85
64
 
86
- ## +questions
65
+ 从data.content排除answered中已有uuid
66
+ 剩余题目随机选一道
67
+ 每次进入题库出题顺序随机不固定
87
68
 
88
- 根据同一个题库 UUID 获取题目明细。
69
+ ### 用户输出红线
89
70
 
90
- ```bash
91
- soke-cli exam-question-pool +questions \
92
- --pool-id "<题库列表的 uuid,即题库id>"
93
- ```
71
+ 严禁在面向用户的任何输出中暴露内部标识字段包括但不限于uuid pool_id source_id category_id target_id dept_user_id company_id answer_type display
72
+ 这些字段仅用于内部逻辑和状态文件不要出现在题目展示判分反馈进度统计小结表格或任何用户可见的文本中
73
+ 如果需要区分题目在内部用uuid但在用户界面只用序号或题目内容来标识
74
+ 用户看到的内容应该像正常的练习题一样干净简洁没有任何技术性ID字段
94
75
 
95
- | 参数 | 必需 | 说明 |
96
- |------|------|------|
97
- | `--pool-id` | 是 | 题库 ID,复用列表或详情中的同一个 UUID |
76
+ ### 按题型呈现
98
77
 
99
- 默认输出为 JSON,是题目数据本身。
78
+ A填空题type fill文本输入禁止变选择题
79
+ 纯文本呈现题目提示用户输入答案
80
+ 题目展示标题填空题第X题共N题题目将title中的span标签替换为括号加下划线提示多个空请用英文逗号分隔如答案1答案2答案3
81
+ 重要提示示例绝不能使用当前题目的正确答案只能用答案1答案2答案3等占位符
82
+ 填空判分show_answer为二维数组用户逗号分隔答案按序对应每个空匹配子数组中任一值即算对忽略首尾空格大小写不敏感全对正确部分对逐空标注全错错误
100
83
 
101
- 关键字段:
84
+ B判断题type determine
85
+ 标题判断题第X题共N题选项A正确B错误判分show_answer A正确B错误
102
86
 
103
- | 字段 | 说明 |
104
- |------|------|
105
- | `uuid` | 题目 UUID |
106
- | `title` | 题目标题 |
107
- | `type` | 题目类型 |
108
- | `choices` | 选项列表 |
109
- | `show_answer` | 展示答案 |
110
- | `analysis` | 题目解析 |
87
+ C单选题type single_choice
88
+ 标题单选题第X题共N题选项A choices0 title B choices1 title等判分show_answer如A用户选了选项A即对
111
89
 
112
- ## 推荐操作顺序
90
+ D多选题type choice
91
+ 标题多选题第X题共N题选项同单选判分用户所选字母集合与show_answer字母集合完全一致顺序无关
113
92
 
114
- ```bash
115
- # 1. 查询题库列表,取输出中的 uuid
116
- soke-cli exam-question-pool +list --page 1 --page-size 10
93
+ E不定项选择type uncertain_choice
94
+ 同多选题标题标注不定项选择
117
95
 
118
- # 2. 查询题库详情
119
- soke-cli exam-question-pool +get --pool-id "<pool_uuid>"
96
+ ## Step5判分反馈和循环
120
97
 
121
- # 3. 查询同一题库的题目列表
122
- soke-cli exam-question-pool +questions --pool-id "<pool_uuid>"
98
+ 答完后纯文本反馈正确或错误你的答案正确答案解析如有进度已答n题共total题正确m题pct百分比
99
+ 然后询问下一步下一题结束答题重新开始本轮
100
+ 下一题保存状态回到Step4
101
+ 结束答题保存状态显示本轮小结退出当前题目未作答则不计入总结
102
+ 重新开始本轮清空answered和correct回到Step4
103
+ 本轮答完时仅提供重新开始和结束
123
104
 
124
- # 4. 题库练习交卷
125
- soke-cli exam-question-pool +finish \
126
- --pool-id "<pool_uuid>" \
127
- --answers '{"<question_uuid>":[0,1]}'
128
- ```
105
+ ### 本轮小结规则
129
106
 
130
- ## +finish
107
+ 总结表格只包含实际作答的题目即uuid已写入answered的题目
108
+ 已展示但用户说退出未作答的题目不出现在总结中下次进入该题库时仍会出现
109
+ 进度统计以状态文件中的answered和correct为准不要自行脑补
131
110
 
132
- 提交可练习题库练习交卷。
111
+ ## Shortcuts参考
133
112
 
134
- ```bash
135
- soke-cli exam-question-pool +finish \
136
- --pool-id "70DE9AFB-1C18-4F5C-B158-E25182ECBE1A" \
137
- --answers '{"A93647C7-7ECF-44D6-931D-DE84344DA580":["1","1","1"],"0E7E8283-EB5F-489C-9778-34A9B2F13BA7":[0]}'
138
- ```
113
+ list获取可练习题库列表
114
+ get获取题库详情
115
+ questions获取题库全部题目
139
116
 
140
- | 参数 | 必需 | 说明 |
141
- |------|------|------|
142
- | `--pool-id` | 是 | 题库 ID,复用列表或详情中的同一个 UUID |
143
- | `--answers` | 是 | 答案 JSON 原文,key 为题目 ID,数组为答题选项 |
117
+ ## 重要注意
144
118
 
145
- `--answers` 会加密之后进行传输。
146
-
147
- 返回结果默认展示:
148
-
149
- | 字段 | 说明 |
150
- |------|------|
151
- | `rightCount` | 答对题目数 |
152
- | `allCount` | 全部题目数量 |
153
- | `rate` | 题库练习进度 |
154
-
155
- 默认输出示例:`题库id:70DE9AFB-1C18-4F5C-B158-E25182ECBE1A,答对题目数:2,全部题目数量:0,题库练习进度:0%`。使用 `--format json` 时输出接口原始字段。
119
+ data.content数量可能与all_count不一致过滤题以实际返回为准
120
+ 填空show_answer是string二维数组每空可能有多个可接受值
121
+ 状态文件路径C:\Users\soke\.qclaw\workspace\.exam-state\uuid.json先确保目录存在
122
+ 每次出题前根据当前状态重新计算未答题池保证随机性
123
+ 填空题提示示例不能泄露正确答案统一用答案1答案2答案3占位
@@ -1,25 +1,64 @@
1
1
  ---
2
2
  name: soke-training-demand
3
- summary: 培训需求收集:查询需求、查询分类、提交培训需求和投票
4
- version: 1.0.0
3
+ summary: 培训需求收集:分步引导提交培训需求、浏览需求列表和投票
4
+ version: 2.5.0
5
5
  description: "用于通过 soke-cli 对接授客AI培训需求收集接口。当用户需要查看培训需求列表、获取需求分类、提交新的培训需求、或给培训需求投票时使用。"
6
6
  metadata:
7
7
  requires:
8
8
  bins: ["soke-cli"]
9
+ executionGuard:
10
+ - "提交培训需求时,MUST 严格按 4 步依次执行(1->2->3->4),每完成一步 MUST 等待用户回复后才能进入下一步。NEVER 跳步、NEVER 合并多步为一步、NEVER 在用户未回复时自行推进。"
11
+ - "步骤 2(选择标签)是独立步骤,NEVER 被跳过(除非分类 tag 为空/null)。即使用户在步骤 1 选择了分类,也 MUST 先展示标签列表让用户选择或跳过,然后才能进入步骤 3。"
12
+ - "每一步输出后 MUST STOP 等待用户输入。NEVER 在同一个回复中同时展示两个步骤的提示。"
13
+ - "NEVER 自行发挥、NEVER 添加 skill 未定义的步骤或提示文字。所有输出格式和提示语必须严格按本 skill 中常见工作流的定义,一字不差。"
14
+ - "步骤 2 展示标签时,MUST 严格使用步骤 1 中用户选定的那个分类对象(通过用户选择的序号从 +list-categories 返回的 data.list 数组中精确取出)的 tag 字段。NEVER 使用其他分类的 tag、NEVER 凭记忆猜测标签、NEVER 用列表中其他位置分类的 tag。"
9
15
  cliHelp: "soke-cli training-demand --help"
10
16
  ---
11
17
 
12
18
  # 培训需求收集
13
19
 
14
- **CRITICAL — 开始前 MUST 先读取 [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md),其中包含认证、配置和权限处理。**
20
+ **CRITICAL — 开始前 MUST 先读取 ../soke-shared/SKILL.md,其中包含认证、配置和权限处理。**
21
+
22
+ ## 🛑 执行守卫(EXECUTION GUARD)
23
+
24
+ > **以下规则是硬性约束,违反任何一条即为执行错误:**
25
+ >
26
+ > 1. **逐步执行**:提交需求 MUST 严格按 4 步顺序(1->2->3->4)逐步引导,每步 MUST 等待用户回复后再进入下一步。NEVER 跳步、NEVER 合步。
27
+ > 2. **步骤独立**:每个步骤 MUST 单独输出为一个回复。NEVER 在同一个回复中同时展示两个步骤的提示。步骤 1 输出后 STOP 等用户选分类;步骤 2 输出后 STOP 等用户选标签;步骤 3 输出后 STOP 等用户输入描述;步骤 4 输出后 STOP 等用户选紧急程度。
28
+ > 3. **步骤 2 不可省略**:步骤 2(选择标签)是独立步骤,NEVER 被省略(除非分类 tag 为空/null)。NEVER 在步骤 1 的回复中同时展示标签选项。
29
+ > 4. **严禁自行发挥**:所有提示语、输出格式 MUST 严格照搬本 skill 常见工作流中的定义,NEVER 自行发挥、NEVER 添加额外文字或解释、NEVER 改变提示格式。
30
+ >
31
+ > 5. **标签-分类严格绑定**:步骤 2 展示标签时,MUST 严格使用步骤 1 中用户选定的分类对象(通过序号从 +list-categories 的 data.list 中精确取出)的 tag 字段。NEVER 用其他分类的 tag、NEVER 凭记忆猜测、NEVER 用列表中其他位置分类的 tag。不确定时 MUST 重新调用 +list-categories 按序号精确匹配。
15
32
 
16
33
  ## 核心规则
17
34
 
18
- - 提交需求前,先执行 `+list-categories`,使用返回的分类 `uuid`、`title` 和 `tag`。
19
- - 创建需求的 `--tag` 不是自由填写,必须从所选分类返回的 `tag` 字段中选择;多个分类时合并这些分类的 tag 值。
20
- - 投票前,先执行 `+list`,使用返回的培训需求 `uuid`。不要把分类 `uuid` 传给投票接口。
35
+ - 分类、标签必须与管理后台设置完全一致,**禁止自行拓展或创造分类/标签**。标签来源仅限用户所选分类的 tag 字段。
36
+ - 提交培训需求必须严格按以下 **4 步顺序** 引导用户,不可跳步或合并:
37
+ 1. **选择分类**(单选) 2. **选择标签**(选填,可多选≤5,可跳过,无标签时自动跳过) → 3. **填写培训需求**(≤200字,必填) → 4. **紧急程度**(1-5,选填)
38
+ - 分类:从 +list-categories 返回的 data.list[].title 中选择,**仅限单选**,不可同时选多个分类。
39
+ - 标签:从所选分类的 data.list[].tag 字段中按逗号拆分,编号列出供用户选择。**标签为选填,用户可以选择标签也可以不选直接跳过**。可多选最多5个。若该分类 tag 为空或不存在,提示"📌 该分类暂无标签",自动跳过标签步骤进入步骤3。
40
+ - 培训需求描述:即 --title,**必填,最多 200 字符**,纯文本输入。
41
+ - 紧急程度:即 --level,1=普通、2=较普通、3=一般、4=较紧急、5=最紧急,**选填**,不选时默认 0(不设置等级)。
42
+ - 投票前,先执行 +list,使用返回的培训需求 uuid。不要把分类 uuid 传给投票接口。
21
43
  - 创建和投票是写操作。用户意图不明确时,先确认要提交或投票的对象。
22
- - 默认用 `--format json` 获取结构化输出;需要人工快速查看时可省略 format 输出表格。
44
+ - 默认用 --format json 获取结构化输出。
45
+
46
+ ### 提交成功后的展示规则
47
+ - **不显示需求 UUID**:提交成功后向用户展示的详情表格中,不要包含 uuid 字段。UUID 仅用于内部投票等操作,不向用户暴露。
48
+ - **时间加8小时**:API 返回的 create_time 是 UTC 时间,向用户展示时必须加 8 小时转换为 UTC+8(北京时间)。例如返回 "2026-07-23 01:56:31" 应展示为 "2026-07-23 09:56:31"。
49
+
50
+ ### 标签处理规则
51
+
52
+ - **隐藏接口字段**:所选分类的 tag 字段原始值是接口内部数据,**严禁在对话中向用户展示**(如不得出现"所选分类的 tag 字段为:公司介绍,规章制度"之类的话)。步骤 2 只展示编号后的标签选项列表,不暴露原始 tag 字段值或任何接口字段名。
53
+
54
+ +list-categories 返回的每个分类对象中 tag 字段是一个逗号分隔的字符串,例如 "企业文化培训,企业发展历程培训,营销战略发展规则培训"。提交需求时:
55
+ - **标签来源仅限当前分类**:从用户所选的那个分类的 tag 字段按逗号拆分出所有可选标签,编号列出供用户选择。**严禁跨分类混合标签或自行创造标签**。
56
+ - **🛑 标签-分类严格绑定(防错硬约束)**:步骤 2 展示标签时,MUST 从步骤 1 中用户选定的分类对象(即 +list-categories 返回的 data.list 中,按用户选择的序号精确匹配的那一条)的 tag 字段按逗号拆分。NEVER 使用其他分类的 tag 字段、NEVER 凭记忆猜测标签内容、NEVER 用列表中其他位置分类的 tag。如果记忆可能出错或不确定,MUST 重新执行 +list-categories 并严格按序号匹配对应分类对象后再拆分其 tag。
57
+ - 用户选中后,将选中的标签用逗号拼接传给 --tag。
58
+ - **标签选填**:标签为选填项,用户可以选择标签也可以**不选任何标签直接跳过**。跳过时不传 --tag(CLI 会从 --category-tag 自动合并)。用户输入"0"、"不选"、"跳过"等表示不选择标签,直接进入步骤 3。
59
+ - **最多选 5 个标签**:选择超过5个时提醒"❌ 最多只能选择5个标签,请减少选择"。
60
+ - **无标签时自动跳过**:若所选分类的 tag 为空字符串("")或不存在/为 null,提示"📌 该分类暂无标签,无需选择",自动跳过步骤 2 进入步骤 3。
61
+ - --category-tag 必须传所选分类的原始完整 tag 字段值(未拆分、未修改)。
23
62
 
24
63
  ## 命令
25
64
 
@@ -37,7 +76,7 @@ soke-cli training-demand +list \
37
76
  --format json
38
77
  ```
39
78
 
40
- 列表返回的 `data.list[].uuid` 是投票使用的培训需求 UUID。
79
+ 列表返回的 data.list[].uuid 是投票使用的培训需求 UUID。
41
80
 
42
81
  ### 查询培训需求分类
43
82
 
@@ -45,32 +84,26 @@ soke-cli training-demand +list \
45
84
  soke-cli training-demand +list-categories --format json
46
85
  ```
47
86
 
48
- 分类返回的 `data.list[].uuid`、`data.list[].title``data.list[].tag` 只用于创建需求。
87
+ 分类返回的 data.list[].uuiddata.list[].title 和 data.list[].tag 只用于创建需求。
49
88
 
50
89
  ### 提交培训需求
51
90
 
52
- 推荐从分类列表提取分类后,用分类 UUID 提交:
53
-
54
- `--title` 是培训需求描述;`--category-uuid` 来自分类列表;`--tag` 可省略,CLI 会从所选分类返回的 `tag` 自动合并;`--level` 是培训需求等级,可省略,默认 `0`。用户指定等级时只能使用 `1-5`。
91
+ 单分类提交时使用 --category-uuid:
55
92
 
56
93
  ```bash
57
94
  soke-cli training-demand +create \
58
95
  --title "门店销售沟通训练" \
96
+ --tag "职场心态,需求测试" \
59
97
  --level 0 \
60
98
  --category-uuid "FA0C937C-EE52-463B-BE3A-C13F96C426AE" \
61
99
  --format json
62
100
  ```
63
101
 
64
- 需要指定部分标签时,显式传 `--tag`:
65
-
66
- ```bash
67
- soke-cli training-demand +create \
68
- --title "门店销售沟通训练" \
69
- --tag "职场心态,需求测试" \
70
- --level 1 \
71
- --category-uuid "FA0C937C-EE52-463B-BE3A-C13F96C426AE" \
72
- --format json
73
- ```
102
+ - --title:培训需求描述,**必填,最多 200 字符**。
103
+ - --tag:从所选分类 tag 中用户选中的标签,逗号拼接;不传时 CLI 从 --category-tag 自动合并。
104
+ - --level:紧急程度,1=普通、5=最紧急,**选填**,默认 0。
105
+ - --category-uuid:所选分类的 uuid。
106
+ - 分类为单选,不使用 --category-list。
74
107
 
75
108
  ### 给培训需求投票
76
109
 
@@ -80,35 +113,109 @@ soke-cli training-demand +vote \
80
113
  --format json
81
114
  ```
82
115
 
83
- `--uuid` 必须来自 `+list` 返回的需求 UUID。
116
+ --uuid 必须来自 +list 返回的需求 UUID。
84
117
 
85
118
  ## 常见工作流
86
119
 
87
- 1. 用户说“我想提一个培训需求”:
88
- - 先问清楚培训需求描述和分类偏好;等级没说明时使用默认 `0`。
89
- - 执行 `+list-categories --format json`。
90
- - 匹配或让用户选择分类,并从所选分类的 `tag` 中确定标签;用户未指定具体标签时,直接使用所选分类的全部 tag。
91
- - 执行 `+create`。
92
-
93
- 2. 用户说“帮我给某个需求投票”:
94
- - 执行 `+list --keyword "<关键词>" --format json`。
95
- - 用需求标题和创建人等信息确认目标。
96
- - 执行 `+vote --uuid "<需求uuid>"`。
97
-
98
- 3. 用户只想浏览需求:
99
- - 执行 `+list --page 1 --limit 10 --create-time-order desc`。
100
- - 返回标题、分类、标签、票数、是否已投票和需求 UUID。
120
+ ### 提交培训需求(严格 4 步流程)
121
+
122
+ 用户说"我想提一个培训需求"或类似意图时,**必须**按以下 4 步依次引导,不可跳步:
123
+
124
+ **步骤 1 — 选择分类(单选)**
125
+ **🛑 本步骤 MUST 单独输出,NEVER 与步骤 2 合并在同一回复中。**
126
+
127
+ 1. 执行 soke-cli training-demand +list-categories --format json
128
+ 2. 将返回的 data.list[].title 编号列出,格式严格如下(NEVER 自行发挥格式):
129
+ ```
130
+ 请选择培训需求分类(单选):
131
+ 1. 企业文化
132
+ 2. 职业素养
133
+ 3. 企业培训
134
+ ...
135
+ ```
136
+ 让用户**单选一个分类**。
137
+ 3. 记录用户所选分类的 uuid、title 和 tag(原始完整值)。
138
+ 4. **🛑 STOP HERE** — 等待用户选择分类后,再进入步骤 2。NEVER 在同一回复中展示步骤 2 的标签列表。
139
+
140
+ **步骤 2 — 选择标签(选填,可多选≤5,可跳过;无标签时自动跳过)**
141
+ **🛑 本步骤 MUST 单独输出,NEVER 与步骤 1 合并在同一回复中。**
142
+
143
+ 1. **展示分类标签**:从步骤 1 记录的所选分类 tag 字段中按逗号拆分,编号列出所有可选标签。**严禁在对话中暴露 tag 字段原始值或接口字段名**,只展示编号列表供用户选择。格式示例:
144
+ **🛑 关键防错**:MUST 确保标签来自步骤 1 中用户选定分类对象的 tag 字段。用户选择分类序号 N 后,MUST 从 +list-categories 返回的 data.list[N-1](序号从1开始,数组索引从0开始)取出分类对象,然后用其 tag 字段拆分展示。NEVER 凭记忆选其他分类的 tag、NEVER 用序号偏移后的分类。如不确定,必须重新调用 +list-categories 并严格按序号匹配。
145
+ ```
146
+ 请选择标签(选填,可多选,最多5个,也可不选直接跳过):
147
+ 1. 企业文化培训
148
+ 2. 企业发展历程培训
149
+ 3. 营销战略发展规则培训
150
+ ...
151
+
152
+ 请输入序号(多选用逗号分隔,如 1,3,5;不选可输入"0"或"跳过")
153
+ ```
154
+ 2. **无标签判断**:若所选分类的 tag 为空字符串("")或不存在/为 null,直接显示:
155
+ ```
156
+ 📌 该分类暂无标签,无需选择
157
+ ```
158
+ 然后自动跳过步骤 2,进入步骤 3。
159
+ 3. **选填,可跳过**:标签为选填项,用户可以选择标签也可以**不选任何标签直接跳过**。用户输入"0"、"不选"、"跳过"等表示不选择标签,直接进入步骤 3。
160
+ 4. **多选交互**:让用户输入序号多选标签(如"1,3,5"),最多选 5 个;选择超过 5 个时提醒"❌ 最多只能选择5个标签,请减少选择"。
161
+ 5. **确认选择**:若用户选择了标签,简要展示确认(如"✅ 已选择标签:企业文化培训, 营销战略发展规则培训"),提交时用逗号拼接为 --tag 参数值。若用户跳过,显示"⏭ 未选择标签,继续下一步"。
162
+ 6. **⚠️ 重要**:标签来源仅限当前所选分类的 tag 字段,严禁跨分类混合标签或自行创造标签。
163
+ 7. **🛑 STOP HERE** — 等待用户选择/跳过标签后,再进入步骤 3。NEVER 在同一回复中同时展示步骤 3 的提示。
164
+
165
+ **步骤 3 — 填写培训需求描述(必填,≤200字符)**
166
+ **🛑 本步骤 MUST 单独输出,NEVER 与步骤 2 合并在同一回复中。**
167
+
168
+ 1. 提示用户输入培训需求描述(纯文本),提示语严格如下(NEVER 自行发挥):
169
+ ```
170
+ 请输入培训需求描述(必填,最多200字符):
171
+ ```
172
+ 2. 记录输入内容,即 --title 参数值。
173
+ 3. 若用户输入超过 200 字符,提醒"❌ 需求描述最多200字符,请缩短或重新填写"。
174
+ 4. **🛑 STOP HERE** — 等待用户输入需求描述后,再进入步骤 4。NEVER 在同一回复中同时展示步骤 4 的提示。
175
+
176
+ **步骤 4 — 紃急程度(选填)**
177
+ **🛑 本步骤 MUST 单独输出,NEVER 与步骤 3 合并在同一回复中。**
178
+
179
+ 1. 提示用户选择紧急程度,提示语严格如下(NEVER 自行发挥):
180
+ ```
181
+ 请选择紧急程度(选填,不选默认为0):
182
+ 1 = 普通
183
+ 2 = 较普通
184
+ 3 = 一般
185
+ 4 = 较紧急
186
+ 5 = 最紧急
187
+
188
+ 输入数字或输入"0"/"跳过"表示不设置
189
+ ```
190
+ 2. 不选则默认 0(不设置等级)。用户输入"0"或"跳过"表示不设置。
191
+ 3. 记录选择值,即 --level 参数值。
192
+
193
+ **最终提交**
194
+ 用步骤 1-4 收集的数据执行 +create。提交前可向用户展示汇总确认。
195
+
196
+ ### 投票需求
197
+
198
+ 用户说"帮我给某个需求投票":
199
+ - 执行 +list --keyword "<关键词>" --format json。
200
+ - 用需求标题和创建人等信息确认目标。
201
+ - 执行 +vote --uuid "<需求uuid>"。
202
+
203
+ ### 浏览需求
204
+
205
+ 用户只想浏览需求:
206
+ - 执行 +list --page 1 --limit 10 --create-time-order desc。
207
+ - 返回标题、分类、标签、票数、是否已投票和需求 UUID。
101
208
 
102
209
  ## 字段依赖
103
210
 
104
211
  | 场景 | 依赖字段 | 来源 |
105
212
  |------|----------|------|
106
- | 创建需求 | `category_list[].uuid` / `category_list[].title` / `tag` | `+list-categories``data.list[]` |
107
- | 投票 | `uuid` | `+list``data.list[].uuid` |
213
+ | 创建需求 | --category-uuid / --tag / --title / --level | +list-categories 的 data.list[] + 用户输入 |
214
+ | 投票 | uuid | +list 的 data.list[].uuid |
108
215
 
109
216
  ## 排错
110
217
 
111
- - 创建失败提示分类无效:重新执行 `+list-categories`,不要使用需求列表中的分类名称手写 UUID。
112
- - 创建失败提示标签无效:重新执行 `+list-categories`,从所选分类返回的 `tag` 中选择,不要自行编写标签。
218
+ - 创建失败提示分类无效:重新执行 +list-categories,不要自行手写分类 UUID。
219
+ - 创建失败提示标签无效:重新执行 +list-categories,从所选分类返回的 tag 中选择,不要自行编写标签。**确保 --category-tag 传的是原始完整 tag 字段值**。
113
220
  - 投票失败提示需求无效:确认传入的是培训需求 UUID,不是分类 UUID。
114
- - 鉴权失败:按 `soke-shared` 执行 `soke-cli auth login` 后重试。
221
+ - 鉴权失败:按 soke-shared 执行 soke-cli auth login 后重试。