@sokeai/cli 1.0.64 → 1.0.65
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 +1 -1
- package/skills/.claude/settings.local.json +7 -0
- package/skills/soke-ai-training/SKILL.md +138 -3
- package/skills/soke-assign/SKILL.md +58 -338
- package/skills/soke-course/SKILL.md +310 -417
- package/skills/soke-course/agents/openai.yaml +7 -0
- package/skills/soke-course/examples/create-basic.md +70 -0
- package/skills/soke-course/references/intent-cases.md +99 -0
- package/skills/soke-course/references/sop-full-workflow.md +172 -0
- package/skills/soke-course/references/sop-lesson-types.md +66 -0
- package/skills/soke-course/references/sop-publish-check.md +74 -0
- package/skills/soke-course/references/subs/ai/SOP.md +153 -0
- package/skills/soke-course/references/subs/category/SOP.md +112 -0
- package/skills/soke-course/references/subs/charge/SOP.md +107 -0
- package/skills/soke-course/references/subs/copy/SOP.md +80 -0
- package/skills/soke-course/references/subs/publish/SOP.md +138 -0
- package/skills/soke-course/references/subs/query/SOP.md +163 -0
- package/skills/soke-course/references/subs/settings/SOP.md +74 -0
- package/skills/soke-course/references/subs/template/SOP.md +223 -0
- package/skills/soke-course/references/troubleshoot.md +68 -0
- package/skills/soke-course/scripts/check_readiness.sh +82 -0
- package/skills/soke-lesson/SKILL.md +78 -472
- package/skills/soke-material/SKILL.md +64 -349
|
@@ -1,507 +1,400 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: soke-course
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
cliHelp: "soke-cli course --help"
|
|
3
|
+
version: 5.0.0
|
|
4
|
+
description: >
|
|
5
|
+
线上课创建与发布的端到端编排技能,课程发布主管。
|
|
6
|
+
负责识别用户意图、选择执行流程、校验前置条件、调度 3 个并列技能完成全链路操作。
|
|
7
|
+
当用户想创建课程、上传课件、配置设置、发布课程、指派学员时触发。
|
|
8
|
+
author: Soke Team
|
|
9
|
+
tags: [课程管理, 流程编排, 发布管理]
|
|
11
10
|
---
|
|
12
11
|
|
|
13
|
-
#
|
|
12
|
+
# 课程发布主管
|
|
14
13
|
|
|
15
|
-
**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`./soke-cli安装指南.md`](./soke-cli安装指南.md)
|
|
14
|
+
> **CRITICAL — 开始前 MUST 先用 Read 工具读取 [`./soke-cli安装指南.md`](./soke-cli安装指南.md),其中包含认证、配置、权限处理。**
|
|
16
15
|
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
1. 已安装 `soke-cli`
|
|
20
|
-
2. 已登录授权: `soke-cli auth login`
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
soke-cli auth login
|
|
24
|
-
soke-cli config show # 验证登录状态
|
|
25
|
-
```
|
|
16
|
+
## 交互规范(必须遵守)
|
|
26
17
|
|
|
27
|
-
|
|
18
|
+
**任何需要用户从固定选项中做选择的场景,必须调用 `ask_user_question` 工具弹窗,禁止纯文本罗列让用户打字。**
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
适用场景:
|
|
21
|
+
- 选择课程分类(列出所有分类,最后一项为"🆕 新建分类")
|
|
22
|
+
- 歧义消解(不确定用户想做什么时)
|
|
23
|
+
- 确认是否继续("还要加课件吗?"/"调顺序吗?"/"确认发布?")
|
|
24
|
+
- 选择发布对象(部门/用户列表)
|
|
25
|
+
- 中断恢复(从已有课程列表中选择继续哪个)
|
|
26
|
+
- 任何其他有 2-4 个固定选项的决策点
|
|
30
27
|
|
|
28
|
+
弹窗标准格式:
|
|
31
29
|
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
│ 7. (可选)指派 → 分配给部门/学员 → 学员开始学习 │
|
|
40
|
-
│ 8. 查询学习状态 → 查看学员进度/完成率 │
|
|
41
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
30
|
+
ask_user_question
|
|
31
|
+
question: "选择课程分类"
|
|
32
|
+
header: "分类"
|
|
33
|
+
options:
|
|
34
|
+
- label: "📁 技术研发" description: "一级分类"
|
|
35
|
+
- label: "📁 企业管理" description: "一级分类"
|
|
36
|
+
- label: "🆕 新建分类" description: "前往管理后台新建分类"
|
|
42
37
|
```
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
分类查询 素材上传 (file +upload)
|
|
48
|
-
│ │
|
|
49
|
-
▼ ▼
|
|
50
|
-
category-id media-id, filename, filesize, object, ext, type
|
|
51
|
-
│ │
|
|
52
|
-
▼ ▼
|
|
53
|
-
创建课程 ──→ course-id ──→ 创建课件 (course +lesson-create) ──→ lesson-id
|
|
54
|
-
│
|
|
55
|
-
▼
|
|
56
|
-
发布课程 ◄── 课件数量 ≥ 1
|
|
57
|
-
│
|
|
58
|
-
▼
|
|
59
|
-
指派给学员 ◄── assign +create (可选)
|
|
60
|
-
│
|
|
61
|
-
▼
|
|
62
|
-
学员可开始学习
|
|
63
|
-
│
|
|
64
|
-
▼
|
|
65
|
-
查询学习记录/进度
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
---
|
|
39
|
+
## 使用前提
|
|
69
40
|
|
|
70
|
-
|
|
41
|
+
1. 已安装 `soke-cli`
|
|
42
|
+
2. 已登录授权 — 首次执行时自动检查并引导登录
|
|
71
43
|
|
|
72
|
-
|
|
44
|
+
**登录状态检查与自动登录(必须执行):**
|
|
73
45
|
|
|
74
46
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
# JSON 输出供解析:
|
|
78
|
-
soke-cli course +list-categories --format json
|
|
47
|
+
# 第一步:检查登录状态
|
|
48
|
+
soke-cli config show
|
|
79
49
|
```
|
|
80
50
|
|
|
81
|
-
|
|
82
|
-
- `data.list[].uuid` → 分类 ID(创建课程时传入 `--category-id`)
|
|
83
|
-
- `data.list[].title` → 分类名称
|
|
84
|
-
- `data.list[].parent_id` → 父分类 ID
|
|
51
|
+
若返回包含 `user_token` → ✅ 已登录,继续。
|
|
85
52
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
## 步骤2: 创建课程
|
|
53
|
+
若返回无 `user_token` 或报错 → ⚠️ 未登录,立即执行:
|
|
89
54
|
|
|
90
55
|
```bash
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
--description "课程描述(可选)"
|
|
95
|
-
|
|
96
|
-
# JSON 输出:
|
|
97
|
-
soke-cli course +create --title "标题" --category-id "CATEGORY-UUID" --format json
|
|
56
|
+
# 第二步:自动打开浏览器完成 OAuth 授权
|
|
57
|
+
# soke-cli auth login 会自动调用系统默认浏览器打开授权页面
|
|
58
|
+
soke-cli auth login
|
|
98
59
|
```
|
|
99
60
|
|
|
100
|
-
|
|
101
|
-
| 参数 | 必填 | 说明 |
|
|
102
|
-
|------|------|------|
|
|
103
|
-
| `--title` | 是 | 课程标题 |
|
|
104
|
-
| `--category-id` | 是 | 分类 ID(从步骤1获取) |
|
|
105
|
-
| `--description` | 否 | 课程描述 |
|
|
61
|
+
`soke-cli auth login` 执行后会自动打开浏览器到授客AI开放平台授权页,用户在浏览器中完成登录授权即可。授权成功后 CLI 终端会显示 `✅ 已登录`,Token 自动保存至 `~/.soke-cli/config.json`。
|
|
106
62
|
|
|
107
|
-
|
|
63
|
+
> 如果浏览器没有自动打开,终端会输出授权链接,手动复制到浏览器打开即可完成授权。
|
|
108
64
|
|
|
109
|
-
|
|
65
|
+
**任何课程操作之前,必须先通过上述两步确认登录状态。未登录时禁止跳过,必须完成登录后再继续。**
|
|
110
66
|
|
|
111
|
-
##
|
|
67
|
+
## 一、触发描述
|
|
112
68
|
|
|
113
|
-
|
|
69
|
+
### 触发词
|
|
114
70
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
71
|
+
| 意图 | 触发词 |
|
|
72
|
+
|------|--------|
|
|
73
|
+
| 创建课程 | 创建/新建/做课/开课/生成课程 |
|
|
74
|
+
| 课件管理 | 添加课件/加视频/加音频/加文档/课件排序/调顺序 |
|
|
75
|
+
| 课程设置 | 设置学分/积分/讲师/封面/标签/修改分类/简介 |
|
|
76
|
+
| 高级设置 | 倍速/人脸/提醒/学习模式/解锁/评价/证书/签名/钉钉群 |
|
|
77
|
+
| 收费设置 | 收费/价格/试看/免费/付费 |
|
|
78
|
+
| 发布 | 发布/上线/定时发布/审批 |
|
|
79
|
+
| 指派 | 指派/安排学习/分配学员/必修/选修 |
|
|
80
|
+
| 查询 | 学习进度/完成率/谁学了/谁完成 |
|
|
81
|
+
| 维护 | 关闭/删除/下架/复制/克隆 |
|
|
82
|
+
| 分类管理 | 分类/课程分类/添加分类/新建分类 |
|
|
118
83
|
|
|
119
|
-
|
|
120
|
-
|
|
84
|
+
### 上下文触发
|
|
85
|
+
- 对话已有 course-id → 在当前课程上操作,不创建新课程
|
|
86
|
+
- 用户上传文件 + 提"课件"/"课程" → 课件子流程
|
|
121
87
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
88
|
+
### 不触发(交给独立 skill)
|
|
89
|
+
- 纯考试/题库/试卷
|
|
90
|
+
- 学习地图
|
|
91
|
+
- 纯素材浏览(不提课程)
|
|
92
|
+
- 单查学员档案(无课程上下文)
|
|
125
93
|
|
|
126
|
-
|
|
127
|
-
| 字段 | 用途 | 说明 |
|
|
128
|
-
|------|------|------|
|
|
129
|
-
| `data.uuid` | `--media-id` | 素材 UUID |
|
|
130
|
-
| `data.filename` | `--filename` | 文件名 |
|
|
131
|
-
| `data.filesize` | `--filesize` | 文件大小(字节) |
|
|
132
|
-
| `data.object` | `--object` | OSS 对象路径 |
|
|
133
|
-
| `data.ext` | `--ext` | 文件扩展名 |
|
|
134
|
-
| `data.type` | `--type` | 文件类型 |
|
|
94
|
+
## 二、输入要求
|
|
135
95
|
|
|
136
|
-
|
|
96
|
+
### 创建课程
|
|
97
|
+
必填: 课程标题 + 课程分类
|
|
98
|
+
可选: 描述/学分/讲师/标签/封面
|
|
137
99
|
|
|
138
|
-
|
|
100
|
+
### 添加课件
|
|
101
|
+
必填: 课件内容(文件路径或文本)
|
|
102
|
+
从上下文获取: course-id
|
|
139
103
|
|
|
140
|
-
|
|
104
|
+
### 发布
|
|
105
|
+
从上下文获取: course-id
|
|
106
|
+
前置: Gate Check 全部通过
|
|
141
107
|
|
|
142
|
-
|
|
108
|
+
### 指派
|
|
109
|
+
必填: 部门名或用户名 + course-id
|
|
143
110
|
|
|
144
|
-
|
|
145
|
-
soke-cli course +lesson-create \
|
|
146
|
-
--course-id "COURSE-UUID" \
|
|
147
|
-
--title "第一课" \
|
|
148
|
-
--media-id "MATERIAL-UUID" \
|
|
149
|
-
--type "video" \
|
|
150
|
-
--length 600 \
|
|
151
|
-
--object "uploads/20260601/video.mp4" \
|
|
152
|
-
--filename "video.mp4" \
|
|
153
|
-
--ext "mp4" \
|
|
154
|
-
--filesize 10485760 \
|
|
155
|
-
--sort 0
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
**参数来源映射**:
|
|
159
|
-
| 参数 | 必填 | 来源 |
|
|
160
|
-
|------|------|------|
|
|
161
|
-
| `--course-id` | 是 | 步骤2 `data.uuid` |
|
|
162
|
-
| `--title` | 是 | 自定义标题 |
|
|
163
|
-
| `--media-id` | 是 | 步骤3 `data.uuid` |
|
|
164
|
-
| `--type` | 是 | 步骤3 `data.type` |
|
|
165
|
-
| `--length` | 否 | 媒体时长(秒) |
|
|
166
|
-
| `--object` | 否 | 步骤3 `data.object` |
|
|
167
|
-
| `--filename` | 否 | 步骤3 `data.filename` |
|
|
168
|
-
| `--ext` | 否 | 步骤3 `data.ext` |
|
|
169
|
-
| `--filesize` | 否 | 步骤3 `data.filesize` |
|
|
170
|
-
| `--sort` | 否 | 排序值(默认 0) |
|
|
111
|
+
## 三、执行流程
|
|
171
112
|
|
|
172
|
-
|
|
113
|
+
### 3.1 意图路由
|
|
173
114
|
|
|
174
|
-
### 批量上传文件
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
FILES=("lesson1.mp4" "lesson2.mp4" "handout.pdf")
|
|
178
|
-
|
|
179
|
-
for file in "${FILES[@]}"; do
|
|
180
|
-
RESULT=$(soke-cli file +upload --file "$file" --format json)
|
|
181
|
-
MEDIA_ID=$(echo "$RESULT" | jq -r '.data.uuid')
|
|
182
|
-
FILE_TYPE=$(echo "$RESULT" | jq -r '.data.type')
|
|
183
|
-
FILE_NAME=$(echo "$RESULT" | jq -r '.data.filename')
|
|
184
|
-
FILE_SIZE=$(echo "$RESULT" | jq -r '.data.filesize')
|
|
185
|
-
OBJECT=$(echo "$RESULT" | jq -r '.data.object')
|
|
186
|
-
EXT=$(echo "$RESULT" | jq -r '.data.ext')
|
|
187
|
-
|
|
188
|
-
LENGTH=0
|
|
189
|
-
[[ "$FILE_TYPE" == "video" ]] && LENGTH=600
|
|
190
|
-
[[ "$FILE_TYPE" == "audio" ]] && LENGTH=300
|
|
191
|
-
|
|
192
|
-
TITLE=$(basename "$file" | sed 's/\.[^.]*$//')
|
|
193
|
-
|
|
194
|
-
soke-cli course +lesson-create \
|
|
195
|
-
--course-id "$COURSE_ID" --title "$TITLE" \
|
|
196
|
-
--media-id "$MEDIA_ID" --type "$FILE_TYPE" --length "$LENGTH" \
|
|
197
|
-
--object "$OBJECT" --filename "$FILE_NAME" --ext "$EXT" --filesize "$FILE_SIZE"
|
|
198
|
-
done
|
|
199
115
|
```
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
116
|
+
用户消息 → 关键词 → 意图 → 路由
|
|
117
|
+
|
|
118
|
+
create → 3.2 全流程创建
|
|
119
|
+
add_lesson → 3.3 课件子流程
|
|
120
|
+
settings → 3.4 设置子流程(→ read references/subs/settings/SOP.md)
|
|
121
|
+
publish → 3.5 发布子流程(→ read references/subs/publish/SOP.md)
|
|
122
|
+
assign → 3.6 指派子流程
|
|
123
|
+
query → 3.7 查询子流程(→ read references/subs/query/SOP.md)
|
|
124
|
+
maintain → 3.8 维护子流程
|
|
125
|
+
category → read references/subs/category/SOP.md
|
|
210
126
|
```
|
|
211
127
|
|
|
212
|
-
|
|
128
|
+
歧义消解: 上下文有 course-id → 当前课程操作 | 有文件附件 → 倾向课件 | 不确定 → `ask_user_question` 弹窗列出可能的操作让用户点选(如"创建课程"/"添加课件"/"修改设置")
|
|
129
|
+
|
|
130
|
+
### 3.2 全流程创建(主链路)
|
|
131
|
+
|
|
132
|
+
> 完整 SOP 见 references/sop-full-workflow.md
|
|
133
|
+
|
|
134
|
+
#### Phase 1: 创建课程骨架
|
|
135
|
+
|
|
136
|
+
Step 1.1 权限检查(自动登录)
|
|
137
|
+
exec: soke-cli config show
|
|
138
|
+
→ 有 user_token → ✅ 跳过登录
|
|
139
|
+
→ 无 user_token → exec: soke-cli auth login(自动打开浏览器)
|
|
140
|
+
等待用户在浏览器中完成授权
|
|
141
|
+
再次 exec: soke-cli config show 确认 user_token 已写入
|
|
142
|
+
登录完成 → 继续下一步
|
|
143
|
+
|
|
144
|
+
Step 1.2 获取分类
|
|
145
|
+
→ read references/subs/category/SOP.md 执行
|
|
146
|
+
执行: soke course +list-categories 获取分类树
|
|
147
|
+
策略:
|
|
148
|
+
1. 用户已指定分类名 → 精确/模糊匹配到唯一结果 → 直接使用
|
|
149
|
+
2. 匹配到多个结果 → `ask_user_question` 弹窗让用户选一个,最后加一项"🆕 新建分类"
|
|
150
|
+
3. 用户未指定 → `ask_user_question` 弹窗列出所有一级分类,最后加一项"🆕 新建分类"
|
|
151
|
+
4. 用户说"随便" → 取第一个一级分类
|
|
152
|
+
→ 用户选"🆕 新建分类" → 告知:"CLI 暂不支持新建分类,请前往管理后台 → 课程管理 → 分类设置 → 新增分类" → 新建完成后说"分类建好了"再继续
|
|
153
|
+
提取: category-id → 存上下文
|
|
154
|
+
|
|
155
|
+
Step 1.3 创建课程
|
|
156
|
+
自身: course +create --title "xxx" --category-id "xxx"
|
|
157
|
+
提取: course-id → 存上下文
|
|
158
|
+
|
|
159
|
+
Step 1.4 选择模板(创建课程后立即触发)
|
|
160
|
+
→ read references/subs/template/SOP.md 执行
|
|
161
|
+
弹窗: `ask_user_question` 列出 7 个模板(含"7. 不选择模板")
|
|
162
|
+
用户选 1-6 → 输出该模板的配置清单(标注后台路径) → 确认后继续
|
|
163
|
+
用户选 7 → 不输出配置,直接进入路由弹窗
|
|
164
|
+
详见: references/subs/template/SOP.md
|
|
165
|
+
|
|
166
|
+
Gate 1→2: ✅ 有 course-id
|
|
167
|
+
|
|
168
|
+
Phase 1 完成后 → `ask_user_question` 弹窗: "下一步?" → ["添加课件"/"先做设置"/"直接发布"]
|
|
169
|
+
选"添加课件" → 进入 Phase 2
|
|
170
|
+
选"先做设置" → 跳到 Phase 3
|
|
171
|
+
选"直接发布" → 跳到 Phase 4(需通过 Gate Check)
|
|
172
|
+
|
|
173
|
+
#### Phase 2: 构建课件
|
|
174
|
+
|
|
175
|
+
Step 2.1 选择素材来源
|
|
176
|
+
→ `ask_user_question` 弹窗: "从哪儿添加课件素材?" → ["📁 本地上传"/"📚 素材库选择"]
|
|
177
|
+
选"本地上传" → 进入 Step 2.2
|
|
178
|
+
选"素材库选择" → 进入 Step 2.2b
|
|
213
179
|
|
|
214
|
-
|
|
180
|
+
Step 2.2 本地上传
|
|
181
|
+
可上传: 视频(.mp4/.avi/.mov/.mkv/.webm)、音频(.mp3/.wav/.ogg/.flac/.aac)、文档(.pdf/.ppt/.pptx/.doc/.docx/.xls/.xlsx)
|
|
182
|
+
⚠️ 不支持 CLI: 图片/文章/外链/小测验/作业 → 告知后台路径
|
|
183
|
+
→ 用户提供本地文件路径
|
|
184
|
+
→ 调度 soke-material: file +upload(自动根据扩展名判断类型)
|
|
185
|
+
提取: media-id + 全字段信息 → 存 media_ids[]
|
|
186
|
+
→ 进入 Step 2.3
|
|
215
187
|
|
|
216
|
-
|
|
188
|
+
Step 2.2b 素材库选择
|
|
189
|
+
→ 调度 soke-material
|
|
190
|
+
exec: soke file list-files(分页拉取全量素材列表)
|
|
191
|
+
展示: 文件名 / 类型 / 大小 / 日期(分页或截取前 20 条)
|
|
192
|
+
告知用户: "输入关键词搜索素材(文件名模糊匹配),或输入序号选择"
|
|
193
|
+
用户输入关键词 → 在素材列表中模糊匹配 → 弹窗列匹配项
|
|
194
|
+
用户选序号 → 确认该素材 → 提取全字段信息 → 存 media_ids[]
|
|
195
|
+
无目标素材 → 弹窗: "素材库中没找到,要不要切换到本地上传?" → ["切本地上传"/"重新搜索"]
|
|
196
|
+
选"切本地上传" → 回到 Step 2.2
|
|
197
|
+
→ 进入 Step 2.3
|
|
217
198
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
199
|
+
Step 2.3 创建课件
|
|
200
|
+
→ 调度 soke-lesson
|
|
201
|
+
参数全部来自 Step 2.2 或 Step 2.2b 的返回
|
|
202
|
+
提取: lesson-id
|
|
203
|
+
存: lesson_ids[]
|
|
221
204
|
|
|
222
|
-
|
|
205
|
+
Step 2.4 循环
|
|
206
|
+
→ `ask_user_question` 弹窗: "还要加课件吗?" → ["继续加课件"/"不了,进入下一步"]
|
|
223
207
|
|
|
224
|
-
|
|
208
|
+
Step 2.5 排序(可选)
|
|
209
|
+
→ `ask_user_question` 弹窗: "需要调整课件顺序吗?" → ["调整顺序"/"保持现状"]
|
|
210
|
+
选"调整" → 调度 soke-lesson 排序
|
|
225
211
|
|
|
226
|
-
|
|
212
|
+
Gate 2→3: ✅ 课件 ≥ 1
|
|
227
213
|
|
|
228
|
-
|
|
214
|
+
#### Phase 3: 课程设置
|
|
229
215
|
|
|
230
|
-
|
|
216
|
+
→ read references/subs/settings/SOP.md 执行
|
|
217
|
+
基础: title/description(course +update)
|
|
231
218
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# 指派给部门
|
|
241
|
-
soke-cli assign +create \
|
|
242
|
-
--module "course" \
|
|
243
|
-
--target-id "COURSE-UUID" \
|
|
244
|
-
--dept-ids "DEPT-ID" \
|
|
245
|
-
--dept-names "部门名称" \
|
|
246
|
-
--learn-type "required"
|
|
247
|
-
|
|
248
|
-
# 指派给用户
|
|
249
|
-
soke-cli assign +create \
|
|
250
|
-
--module "course" \
|
|
251
|
-
--target-id "COURSE-UUID" \
|
|
252
|
-
--user-ids "USER-ID" \
|
|
253
|
-
--user-names "学员姓名" \
|
|
254
|
-
--learn-type "required"
|
|
255
|
-
|
|
256
|
-
# 同时指派给多个部门和用户
|
|
257
|
-
soke-cli assign +create \
|
|
258
|
-
--module "course" --target-id "COURSE-UUID" \
|
|
259
|
-
--dept-ids "DEPT1,DEPT2" --dept-names "部门1,部门2" \
|
|
260
|
-
--user-ids "USER1,USER2" --user-names "学员1,学员2" \
|
|
261
|
-
--learn-type "required"
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
**指派参数**:
|
|
265
|
-
| 参数 | 必填 | 说明 |
|
|
266
|
-
|------|------|------|
|
|
267
|
-
| `--module` | 是 | 固定 `course` |
|
|
268
|
-
| `--target-id` | 是 | 课程 ID |
|
|
269
|
-
| `--learn-type` | 是 | `required`(必修) / `optional`(选修) |
|
|
270
|
-
| `--dept-ids` | 否 | 部门 ID,逗号分隔 |
|
|
271
|
-
| `--dept-names` | 否 | 部门名(与 ids 一一对应) |
|
|
272
|
-
| `--user-ids` | 否 | 用户 ID,逗号分隔 |
|
|
273
|
-
| `--user-names` | 否 | 用户名(与 ids 一一对应) |
|
|
274
|
-
|
|
275
|
-
---
|
|
219
|
+
→ read references/subs/template/SOP.md Step 3 执行
|
|
220
|
+
将当前所有设置项以表格形式展示(仅「设置项」+「当前值」两列)
|
|
221
|
+
告知用户: "想修改哪项?直接告诉我就行。"
|
|
222
|
+
用户指令处理:
|
|
223
|
+
- 标题/描述 → exec: course +update(✅ CLI 支持) → 刷新表格
|
|
224
|
+
- 其他设置 → "已记录: {项} → {新值}(需在后台操作: {路径})" → 刷新表格
|
|
225
|
+
- "可以了"/"继续" → 退出 Phase 3
|
|
226
|
+
循环直到用户确认
|
|
276
227
|
|
|
277
|
-
|
|
228
|
+
Gate 3→4: 无硬阻塞
|
|
278
229
|
|
|
279
|
-
|
|
230
|
+
#### Phase 4: 发布
|
|
280
231
|
|
|
281
|
-
|
|
282
|
-
|
|
232
|
+
→ read references/subs/publish/SOP.md 执行
|
|
233
|
+
Gate Check: 标题/分类/课件数量/转码状态
|
|
234
|
+
通过 → course +publish
|
|
235
|
+
定时/审批/批量 → ⚠️ CLI 不支持
|
|
283
236
|
|
|
284
|
-
|
|
285
|
-
soke-cli course +list-course-users \
|
|
286
|
-
--course-id "COURSE-UUID" --userid-list "USER1,USER2"
|
|
237
|
+
Gate 4→5: ✅ status=1
|
|
287
238
|
|
|
288
|
-
|
|
289
|
-
soke-cli course +list-course-users \
|
|
290
|
-
--course-id "COURSE-UUID" \
|
|
291
|
-
--finish-start-time 1700000000000 --finish-end-time 1700100000000
|
|
292
|
-
```
|
|
239
|
+
#### Phase 5: 指派学员
|
|
293
240
|
|
|
294
|
-
|
|
241
|
+
→ 调度 soke-assign
|
|
242
|
+
|
|
243
|
+
Step 5.1 拉取部门列表
|
|
244
|
+
exec: soke assign +list-departments
|
|
245
|
+
提取: 全量部门名称+ID → 存内存
|
|
295
246
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
247
|
+
Step 5.2 用户输入关键词搜索
|
|
248
|
+
告知用户: "请输入要指派的部门名称(支持模糊搜索)"
|
|
249
|
+
用户输入关键词 → 在部门列表中模糊匹配(不区分大小写,支持部分匹配)
|
|
250
|
+
匹配结果:
|
|
251
|
+
- 唯一匹配 → 直接确认使用
|
|
252
|
+
- 多个匹配 → `ask_user_question` 弹窗列出匹配的部门让用户选
|
|
253
|
+
- 无匹配 → 建议换个关键词,或 `ask_user_question` 弹窗列所有部门
|
|
300
254
|
|
|
301
|
-
|
|
255
|
+
Step 5.3 确认指派方式
|
|
256
|
+
→ `ask_user_question` 弹窗: "必修还是选修?" → ["必修"/"选修"]
|
|
302
257
|
|
|
303
|
-
|
|
258
|
+
Step 5.4 执行指派
|
|
259
|
+
exec: soke assign +create --module course --module-id <courseId> --compulsory 1|0 --user-ids "<用部门 ID 查到的人员>"
|
|
304
260
|
|
|
305
|
-
|
|
306
|
-
soke-cli course +list-lesson-learns \
|
|
307
|
-
--course-id "COURSE-UUID" --lesson-id "LESSON-UUID"
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
### 课件列表
|
|
261
|
+
#### Phase 6: 运营维护
|
|
311
262
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
263
|
+
→ read references/subs/query/SOP.md 执行(进度/记录/人脸)
|
|
264
|
+
→ read references/subs/publish/SOP.md 执行(关闭/删除,⚠️)
|
|
265
|
+
→ read references/subs/copy/SOP.md 执行(复制,⚠️)
|
|
315
266
|
|
|
316
|
-
|
|
317
|
-
soke-cli course +lesson-list --course-id "ID" --type "video" --keyword "关键词"
|
|
318
|
-
```
|
|
267
|
+
### 3.3 课件子流程
|
|
319
268
|
|
|
320
|
-
|
|
269
|
+
前提: 上下文有 course-id
|
|
270
|
+
流程: = Phase 2(判断类型→上传→创建→循环→排序)
|
|
321
271
|
|
|
322
|
-
|
|
272
|
+
### 3.4 设置子流程
|
|
323
273
|
|
|
324
|
-
|
|
274
|
+
前提: 上下文有 course-id
|
|
275
|
+
流程: read references/subs/settings/SOP.md + references/subs/charge/SOP.md 执行
|
|
325
276
|
|
|
326
|
-
|
|
327
|
-
|------|------|------|
|
|
328
|
-
| `+list-categories` | 查询课程分类列表 | read |
|
|
329
|
-
| `+list-courses` | 查询课程列表 | read |
|
|
330
|
-
| `+get-course` | 查询课程详情 | read |
|
|
331
|
-
| `+create` | 创建课程 | write |
|
|
332
|
-
| `+update` | 更新课程 | write |
|
|
333
|
-
| `+publish` | 发布课程 | write |
|
|
277
|
+
### 3.5 发布子流程
|
|
334
278
|
|
|
335
|
-
|
|
279
|
+
前提: course-id + status=0
|
|
280
|
+
流程: read references/subs/publish/SOP.md 执行 → Gate Check → 发布 → 询问指派
|
|
336
281
|
|
|
337
|
-
|
|
338
|
-
|------|------|------|
|
|
339
|
-
| `+lesson-create` | 创建课件 | write |
|
|
340
|
-
| `+lesson-get` | 查询课件详情 | read |
|
|
341
|
-
| `+lesson-list` | 查询课件列表(type/keyword) | read |
|
|
342
|
-
| `+list-lessons` | 查询课件列表(时间范围) | read |
|
|
282
|
+
### 3.6 指派子流程
|
|
343
283
|
|
|
344
|
-
|
|
284
|
+
前提: course-id + status=1
|
|
285
|
+
流程: 调度 soke-assign → 拉全量部门 → 用户输入关键词搜索 → 确认 → 指派
|
|
345
286
|
|
|
346
|
-
|
|
347
|
-
|------|------|
|
|
348
|
-
| `file +upload` | 上传文件到素材库 |
|
|
349
|
-
| `file +create` | 手动创建素材记录 |
|
|
350
|
-
| `file +list-files` | 查询素材列表 |
|
|
351
|
-
| `file +get-info` | 查询素材详情 |
|
|
352
|
-
| `file +download` | 获取下载链接 |
|
|
353
|
-
| `file +list-categories` | 查询素材分类 |
|
|
287
|
+
### 3.7 查询子流程
|
|
354
288
|
|
|
355
|
-
|
|
289
|
+
前提: course-id
|
|
290
|
+
流程: read references/subs/query/SOP.md 执行 → 进度/记录/人脸
|
|
356
291
|
|
|
357
|
-
|
|
358
|
-
|------|------|
|
|
359
|
-
| `+list-course-users` | 课程学员学习记录 |
|
|
360
|
-
| `+get-course-user` | 学员个人详情 |
|
|
361
|
-
| `+list-lesson-learns` | 课件学习记录 |
|
|
362
|
-
| `+list-lesson-faces` | 人脸识别记录 |
|
|
292
|
+
### 3.8 维护子流程
|
|
363
293
|
|
|
364
|
-
|
|
294
|
+
流程: read references/subs/publish/SOP.md(关闭/删除)/ references/subs/copy/SOP.md(复制)/ references/subs/category/SOP.md(分类)
|
|
365
295
|
|
|
366
|
-
|
|
367
|
-
|------|------|
|
|
368
|
-
| `assign +list-departments` | 查询可用部门 |
|
|
369
|
-
| `assign +list-users` | 查询可用用户 |
|
|
370
|
-
| `assign +create` | 创建指派 |
|
|
371
|
-
| `assign +list` | 查询指派记录 |
|
|
296
|
+
### SOP 执行 5 步法
|
|
372
297
|
|
|
373
|
-
|
|
298
|
+
1. READ `references/subs/<name>/SOP.md` → 理解输入输出
|
|
299
|
+
2. BUILD 从上下文提取参数
|
|
300
|
+
3. EXEC 按 SOP 流程调用 CLI
|
|
301
|
+
4. PARSE 按 SOP 输出标准解析
|
|
302
|
+
5. STORE 关键值写入上下文
|
|
374
303
|
|
|
375
|
-
|
|
304
|
+
上下文变量: course_id / category_id / lesson_ids[] / media_ids[] / course_status / current_phase
|
|
376
305
|
|
|
377
|
-
|
|
306
|
+
## 四、输出标准
|
|
378
307
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
| `分类不存在` | category-id 无效 | 查询 `+list-categories` |
|
|
386
|
-
| `素材不存在` | media-id 无效 | 确认上传成功 |
|
|
387
|
-
| `指派失败` | 资源未发布 | 先发布课程 |
|
|
308
|
+
### 每步即时输出
|
|
309
|
+
```
|
|
310
|
+
✅ <做了什么>
|
|
311
|
+
📋 <关键数据>
|
|
312
|
+
⏭️ <下一步建议>
|
|
313
|
+
```
|
|
388
314
|
|
|
389
|
-
###
|
|
315
|
+
### 阶段状态报告
|
|
316
|
+
```
|
|
317
|
+
📋 课程: <标题> (id: <uuid>)
|
|
318
|
+
Phase 1 ✅ 已创建
|
|
319
|
+
Phase 2 🔄 课件 3 个
|
|
320
|
+
├─ ✅ 第1课: 环境搭建 (video, 转码完成)
|
|
321
|
+
├─ ✅ 第2课: Pandas (video, 转码中)
|
|
322
|
+
└─ ✅ 第3课: 数据清洗.pdf (document)
|
|
323
|
+
Phase 3 ⏸️ 设置
|
|
324
|
+
Phase 4 ⏸️ 发布(阻塞: 第2课转码中)
|
|
325
|
+
Phase 5 ⏸️ 指派
|
|
326
|
+
下一步: 等转码完成后发布
|
|
327
|
+
```
|
|
390
328
|
|
|
391
|
-
|
|
392
|
-
# 1. 认证状态
|
|
393
|
-
soke-cli config show # 确认用户凭证不为空
|
|
329
|
+
### Gate Check 矩阵
|
|
394
330
|
|
|
395
|
-
#
|
|
396
|
-
|
|
331
|
+
| # | 检查项 | 获取方式 | 严重度 | 不通过时 |
|
|
332
|
+
|---|--------|---------|--------|---------|
|
|
333
|
+
| 1 | 标题非空 | +get-course.title | 🔴阻塞 | 请设置标题 |
|
|
334
|
+
| 2 | 分类已选 | +get-course.category_id | 🔴阻塞 | 请选择分类 |
|
|
335
|
+
| 3 | 课件≥1 | +lesson-list count | 🔴阻塞 | 至少1个课件 |
|
|
336
|
+
| 4 | 无转码失败 | +lesson-list.transcode_status | 🔴阻塞 | 课件[X]转码失败 |
|
|
337
|
+
| 5 | 无转码中 | +lesson-list.transcode_status | 🟡警告 | 课件[X]转码中,确认发布? |
|
|
338
|
+
| 6 | 付费方式 | 需确认 | 🟡警告 | — |
|
|
397
339
|
|
|
398
|
-
|
|
399
|
-
|
|
340
|
+
### 最终交付
|
|
341
|
+
```
|
|
342
|
+
📦 课程已发布: <标题>
|
|
343
|
+
🔗 ID: <uuid> | 📊 课件: 5 个 | 👥 已指派: 研发部(32人)
|
|
344
|
+
⏭️ 查看进度: 说"看看学习进度"
|
|
345
|
+
```
|
|
400
346
|
|
|
401
|
-
|
|
402
|
-
soke-cli course +get-course --course-id "ID" --format json | jq '.data.status'
|
|
403
|
-
# status=1 表示已发布
|
|
347
|
+
## 五、注意事项
|
|
404
348
|
|
|
405
|
-
|
|
406
|
-
|
|
349
|
+
### 硬规则
|
|
350
|
+
1. 不编造参数 — UUID 来自真实返回
|
|
351
|
+
2. 不跳过 Gate — 发布前逐项校验
|
|
352
|
+
3. 不静默失败 — 失败: 查排错文档 → 中文告知 → 修复建议 → 保存进度 → 提供选项
|
|
353
|
+
4. 类型必须匹配 — 课件与素材类型一致
|
|
354
|
+
5. 一个 course-id 贯穿全部
|
|
407
355
|
|
|
408
|
-
|
|
409
|
-
```
|
|
356
|
+
### 架构分工
|
|
410
357
|
|
|
411
|
-
|
|
358
|
+
**外部并列技能**(独立 skill,通过 skill 调度):
|
|
359
|
+
- 上传文件到素材库 → soke-material
|
|
360
|
+
- 基于素材创建课件 → soke-lesson
|
|
361
|
+
- 将课程指派给学员 → soke-assign
|
|
412
362
|
|
|
413
|
-
|
|
363
|
+
**内嵌 SOP**(references/subs/ 下,按需 read 执行):
|
|
364
|
+
- 管理课程分类 → references/subs/category/SOP.md
|
|
365
|
+
- 配置课程设置 → references/subs/settings/SOP.md
|
|
366
|
+
- 设置收费 → references/subs/charge/SOP.md
|
|
367
|
+
- 发布校验和发布 → references/subs/publish/SOP.md
|
|
368
|
+
- 复制课程 → references/subs/copy/SOP.md
|
|
369
|
+
- 查询学习数据 → references/subs/query/SOP.md
|
|
370
|
+
- AI生成课程 → references/subs/ai/SOP.md
|
|
371
|
+
- 课程模板(7套预置配置) → references/subs/template/SOP.md
|
|
414
372
|
|
|
415
|
-
|
|
416
|
-
# === 1. 查询分类 ===
|
|
417
|
-
CATEGORY_ID=$(soke-cli course +list-categories --format json | jq -r '.data.list[0].uuid')
|
|
418
|
-
|
|
419
|
-
# === 2. 创建课程 ===
|
|
420
|
-
COURSE_ID=$(soke-cli course +create \
|
|
421
|
-
--title "Python 数据分析实战" \
|
|
422
|
-
--category-id "$CATEGORY_ID" \
|
|
423
|
-
--format json | jq -r '.data.uuid')
|
|
424
|
-
|
|
425
|
-
# === 3. 上传素材 ===
|
|
426
|
-
UPLOAD=$(soke-cli file +upload --file "./lesson1.mp4" --format json)
|
|
427
|
-
MEDIA_ID=$(echo "$UPLOAD" | jq -r '.data.uuid')
|
|
428
|
-
FILE_TYPE=$(echo "$UPLOAD" | jq -r '.data.type')
|
|
429
|
-
FILENAME=$(echo "$UPLOAD" | jq -r '.data.filename')
|
|
430
|
-
FILESIZE=$(echo "$UPLOAD" | jq -r '.data.filesize')
|
|
431
|
-
OBJECT=$(echo "$UPLOAD" | jq -r '.data.object')
|
|
432
|
-
EXT=$(echo "$UPLOAD" | jq -r '.data.ext')
|
|
433
|
-
|
|
434
|
-
# === 4. 创建课件 ===
|
|
435
|
-
soke-cli course +lesson-create \
|
|
436
|
-
--course-id "$COURSE_ID" --title "第一课:环境搭建" \
|
|
437
|
-
--media-id "$MEDIA_ID" --type "$FILE_TYPE" --length 600 \
|
|
438
|
-
--object "$OBJECT" --filename "$FILENAME" --ext "$EXT" --filesize "$FILESIZE"
|
|
439
|
-
|
|
440
|
-
# === 5. 发布课程 ===
|
|
441
|
-
soke-cli course +publish --course-id "$COURSE_ID"
|
|
442
|
-
|
|
443
|
-
# === 6. 指派学员 ===
|
|
444
|
-
DEPT_ID=$(soke-cli assign +list-departments --keyword "研发" --format json | jq -r '.data.list[0].uuid')
|
|
445
|
-
soke-cli assign +create \
|
|
446
|
-
--module "course" --target-id "$COURSE_ID" \
|
|
447
|
-
--dept-ids "$DEPT_ID" --dept-names "研发部" \
|
|
448
|
-
--learn-type "required"
|
|
449
|
-
|
|
450
|
-
# === 7. 验证 ===
|
|
451
|
-
soke-cli course +get-course --course-id "$COURSE_ID" --format json | jq .
|
|
452
|
-
soke-cli course +lesson-list --course-id "$COURSE_ID" --format json | jq '.data.list'
|
|
453
|
-
```
|
|
373
|
+
### 已知 CLI 缺失
|
|
454
374
|
|
|
455
|
-
|
|
375
|
+
统一话术: "XXX 功能暂不支持 CLI 操作,请在后台手动设置。"
|
|
456
376
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
|
460
|
-
|
|
461
|
-
|
|
|
462
|
-
|
|
|
463
|
-
|
|
|
464
|
-
|
|
|
465
|
-
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
## 权限要求
|
|
482
|
-
|
|
483
|
-
| 操作 | 权限范围 |
|
|
484
|
-
|------|----------|
|
|
485
|
-
| 课程读写 | `course:course:write` / `course:course:readonly` |
|
|
486
|
-
| 课件读写 | `course:courseware:write` / `course:courseware:readonly` |
|
|
487
|
-
| 素材读写 | `file:file:write` / `file:file:readonly` |
|
|
488
|
-
| 指派读写 | `assign:write` / `assign:read` |
|
|
489
|
-
| 学习记录 | `course:courseUser:readonly` / `course:lessonLearn:readonly` |
|
|
490
|
-
|
|
491
|
-
## 注意事项
|
|
492
|
-
|
|
493
|
-
1. **课程至少需要 1 个课件才能发布**
|
|
494
|
-
2. **课件参数全部从素材上传响应提取**,不手动构造
|
|
495
|
-
3. **时长根据文件类型自动设置**: video=600s, audio=300s, 其他=0
|
|
496
|
-
4. **课程发布后学员才可见**
|
|
497
|
-
5. **指派是可选的**,未指派时学员看不到课程
|
|
498
|
-
6. **所有时间参数使用毫秒级 Unix 时间戳**
|
|
499
|
-
|
|
500
|
-
## 相关文档
|
|
501
|
-
|
|
502
|
-
- [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md) — 认证、配置、权限
|
|
503
|
-
- [`../soke-material/SKILL.md`](../soke-material/SKILL.md) — 文件上传和素材管理
|
|
504
|
-
- [`../soke-lesson/SKILL.md`](../soke-lesson/SKILL.md) — 课件创建和管理
|
|
505
|
-
- [`../soke-assign/SKILL.md`](../soke-assign/SKILL.md) — 指派管理
|
|
506
|
-
- [`references/examples.md`](./references/examples.md) — 更多使用示例
|
|
507
|
-
- [`references/course-list-courses.md`](./references/course-list-courses.md) — 课程查询参考
|
|
377
|
+
| 类别 | 缺失 |
|
|
378
|
+
|------|------|
|
|
379
|
+
| 课件类型 | image/article/link/quiz/homework |
|
|
380
|
+
| 分类 | 新增分类 |
|
|
381
|
+
| 课程设置 | credit/point/lector_id/tags/cover上传/简介插图 |
|
|
382
|
+
| 高级设置 | 学习模式/倍速/人脸/提醒/评价/证书/签名/钉钉群 |
|
|
383
|
+
| 收费 | 价格/试看 |
|
|
384
|
+
| 发布 | 定时/审批/批量 |
|
|
385
|
+
| 维护 | 关闭/删除/复制 |
|
|
386
|
+
|
|
387
|
+
### 中断恢复
|
|
388
|
+
用户"继续"/"接着做": 检查 course-id → 有:查状态+课件→报告→继续 | 无:列课程→选→恢复
|
|
389
|
+
|
|
390
|
+
## 六、交付前自查
|
|
391
|
+
|
|
392
|
+
- [ ] 每步有明确调度目标
|
|
393
|
+
- [ ] 关键返回值已存入上下文
|
|
394
|
+
- [ ] 每步完成有下一步建议
|
|
395
|
+
- [ ] 发布前过完整 Gate Check
|
|
396
|
+
- [ ] CLI 不支持功能已告知替代路径
|
|
397
|
+
- [ ] 失败有修复建议
|
|
398
|
+
- [ ] 所有固定选项的决策点均使用 `ask_user_question` 弹窗(禁止纯文本罗列让用户打字)
|
|
399
|
+
- [ ] 分类选择弹窗最后一项始终为"🆕 新建分类"
|
|
400
|
+
- [ ] 状态报告完整
|