@sokeai/cli 1.0.79 → 1.0.81

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.
Files changed (128) hide show
  1. package/package.json +1 -1
  2. package/scripts/install.js +8 -0
  3. package/scripts/run.js +3 -2
  4. package/skills/mono/.workbuddy/memory/2026-09-01.md +2 -0
  5. package/skills/mono/.workbuddy/memory/MEMORY.md +4 -0
  6. package/skills/mono/ARCHITECTURE_AND_EXTENSION_GUIDE.md +572 -0
  7. package/skills/mono/README.md +2 -0
  8. package/skills/mono/SKILL.md +125 -119
  9. package/skills/mono/SKILL_MD_/344/274/230/345/214/226/346/226/271/346/241/210.md +478 -0
  10. package/skills/mono/references/modules/README.md +74 -0
  11. package/skills/mono/references/modules/soke-ai-coach-director/CHANGELOG.md +1 -1
  12. package/skills/mono/references/modules/soke-ai-coach-director/MODULE.md +12 -0
  13. package/skills/mono/references/modules/soke-ai-coach-director/README.md +1 -1
  14. package/skills/mono/references/modules/soke-ai-coach-director/coaching/prompt-optimizer/prompt-optimizer.md +3 -3
  15. package/skills/mono/references/modules/soke-ai-coach-director/platform/adapters/README.md +4 -2
  16. package/skills/mono/references/modules/soke-ai-coach-director/platform/adapters/qclaw.md +3 -1
  17. package/skills/mono/references/modules/soke-ai-coach-director/platform/adapters/{wukong.md → qwen.md} +18 -18
  18. package/skills/mono/references/modules/soke-ai-coach-director/platform/adapters/workbuddy.md +1 -1
  19. package/skills/mono/references/modules/soke-ai-coach-director/platform/api-fallback.md +1 -1
  20. package/skills/mono/references/modules/soke-ai-coach-director/platform/interaction.md +1 -1
  21. package/skills/mono/references/modules/soke-ai-coach-director/platform/platform-support-matrix.md +28 -0
  22. package/skills/mono/references/modules/soke-ai-coach-director/platform/soke-ai-training/soke-ai-training.md +5 -3
  23. package/skills/mono/references/modules/soke-ai-coach-director/platform/sync-engine.md +2 -2
  24. package/skills/mono/references/modules/soke-ai-coach-director/references/env-check.md +3 -0
  25. package/skills/mono/references/modules/soke-ai-coach-director/references/exec-handbook.md +2 -2
  26. package/skills/mono/references/modules/soke-ai-coach-director/references/subs/publish/SOP.md +3 -3
  27. package/skills/mono/references/modules/soke-ai-training/MODULE.md +55 -7
  28. package/skills/mono/references/modules/soke-assign/MODULE.md +50 -11
  29. package/skills/mono/references/modules/soke-certificate/MODULE.md +47 -1
  30. package/skills/mono/references/modules/soke-course/CHANGELOG.md +93 -0
  31. package/skills/mono/references/modules/soke-course/MODULE.md +110 -352
  32. package/skills/mono/references/modules/soke-course/README.md +45 -291
  33. package/skills/mono/references/modules/soke-course/cli-facts.md +107 -0
  34. package/skills/mono/references/modules/soke-course/intent-cases.md +41 -0
  35. package/skills/mono/references/modules/soke-course/scripts/check_readiness.sh +45 -0
  36. package/skills/mono/references/modules/soke-course/sop-publish-check.md +46 -0
  37. package/skills/mono/references/modules/soke-course/subs/assign/SOP.md +40 -0
  38. package/skills/mono/references/modules/soke-course/subs/batch/SOP.md +96 -0
  39. package/skills/mono/references/modules/soke-course/{references/subs → subs}/category/SOP.md +18 -27
  40. package/skills/mono/references/modules/soke-course/subs/charge/SOP.md +22 -0
  41. package/skills/mono/references/modules/soke-course/subs/copy/SOP.md +35 -0
  42. package/skills/mono/references/modules/soke-course/subs/exam/SOP.md +39 -0
  43. package/skills/mono/references/modules/soke-course/subs/phase1-create/SOP.md +66 -0
  44. package/skills/mono/references/modules/soke-course/subs/phase2-lesson/SOP.md +34 -0
  45. package/skills/mono/references/modules/soke-course/subs/photo/SOP.md +26 -0
  46. package/skills/mono/references/modules/soke-course/subs/publish/SOP.md +26 -0
  47. package/skills/mono/references/modules/soke-course/subs/query/SOP.md +36 -0
  48. package/skills/mono/references/modules/soke-course/{references/subs → subs}/settings/SOP.md +3 -4
  49. package/skills/mono/references/modules/soke-course/subs/template/SOP.md +58 -0
  50. package/skills/mono/references/modules/soke-exam/MODULE.md +49 -1
  51. package/skills/mono/references/modules/soke-exam-question-pool/MODULE.md +45 -5
  52. package/skills/mono/references/modules/soke-learning-map/MODULE.md +71 -12
  53. package/skills/mono/references/modules/soke-learning-profile/MODULE.md +46 -3
  54. package/skills/mono/references/modules/soke-lesson/MODULE.md +34 -20
  55. package/skills/mono/references/modules/soke-material/MODULE.md +33 -19
  56. package/skills/mono/references/modules/soke-photo-gallery/MODULE.md +40 -20
  57. package/skills/mono/references/modules/soke-shared/MODULE.md +9 -0
  58. package/skills/mono/references/modules/soke-supervisor/MODULE.md +32 -1
  59. package/skills/mono/references/modules/soke-task/MODULE.md +48 -1
  60. package/skills/mono/references/modules/soke-training-demand/MODULE.md +38 -17
  61. package/skills/mono/references/shared/README.md +50 -0
  62. package/skills/mono/references/shared/async-task.md +30 -0
  63. package/skills/mono/references/shared/auth-check.md +57 -0
  64. package/skills/mono/references/shared/command-discovery.md +34 -0
  65. package/skills/mono/references/shared/environment-check.md +31 -0
  66. package/skills/mono/references/shared/error-handling.md +27 -0
  67. package/skills/mono/references/shared/file-input.md +31 -0
  68. package/skills/mono/references/shared/interaction.md +39 -0
  69. package/skills/mono/references/shared/object-context.md +51 -0
  70. package/skills/mono/references/shared/output-policy.md +39 -0
  71. package/skills/mono/references/shared/pagination.md +41 -0
  72. package/skills/mono/references/shared/rule-ownership.md +57 -0
  73. package/skills/mono/references/shared/state-machine.md +35 -0
  74. package/skills/mono/references/shared/write-guard.md +34 -0
  75. package/skills/mono/references/shared/write-verify.md +33 -0
  76. package/skills/mono/references/workflows/README.md +115 -0
  77. package/skills/mono/scripts/check_package.py +310 -0
  78. package/skills/mono/scripts/check_readiness.py +1 -1
  79. package/skills/mono/scripts/check_syntax.py +35 -0
  80. package/skills/mono//357/275/223/357/275/217/357/275/213/357/275/205/357/274/215/357/275/203/357/275/214/357/275/211/346/225/264/344/275/223/346/236/266/346/236/204.html +13 -0
  81. package/skills/multi/soke-course/.skill-metadata.yaml +40 -0
  82. package/skills/multi/soke-course/CHANGELOG.md +77 -0
  83. package/skills/multi/soke-course/README.md +27 -274
  84. package/skills/multi/soke-course/SKILL.md +135 -353
  85. package/skills/multi/soke-course/_user_meta.json +5 -0
  86. package/skills/multi/soke-course/agents/openai.yaml +1 -5
  87. package/skills/multi/soke-course/references/cli-facts.md +105 -0
  88. package/skills/multi/soke-course/references/examples.md +30 -454
  89. package/skills/multi/soke-course/references/intent-cases.md +65 -99
  90. package/skills/multi/soke-course/references/sop-full-workflow.md +81 -177
  91. package/skills/multi/soke-course/references/sop-lesson-types.md +21 -58
  92. package/skills/multi/soke-course/references/sop-publish-check.md +14 -71
  93. package/skills/multi/soke-course/references/subs/assign/SOP.md +37 -0
  94. package/skills/multi/soke-course/references/subs/category/SOP.md +18 -27
  95. package/skills/multi/soke-course/references/subs/exam/SOP.md +28 -0
  96. package/skills/multi/soke-course/references/subs/lesson/SOP.md +28 -0
  97. package/skills/multi/soke-course/references/subs/material/SOP.md +24 -0
  98. package/skills/multi/soke-course/references/subs/photo/SOP.md +23 -0
  99. package/skills/multi/soke-course/references/subs/publish/SOP.md +15 -157
  100. package/skills/multi/soke-course/references/subs/query/SOP.md +22 -151
  101. package/skills/multi/soke-course/references/subs/settings/SOP.md +3 -4
  102. package/skills/multi/soke-course/references/subs/template/SOP.md +37 -210
  103. package/skills/multi/soke-course/references/troubleshoot.md +37 -54
  104. package/skills/multi/soke-course/scripts/check_readiness.sh +45 -0
  105. package/skills/multi/soke-course/{references/installation.md → soke-cli-install-guide.md} +3 -0
  106. package/skills/mono/references/modules/soke-course/agents/openai.yaml +0 -7
  107. package/skills/mono/references/modules/soke-course/references/course-list-courses.md +0 -216
  108. package/skills/mono/references/modules/soke-course/references/examples.md +0 -480
  109. package/skills/mono/references/modules/soke-course/references/intent-cases.md +0 -99
  110. package/skills/mono/references/modules/soke-course/references/sop-full-workflow.md +0 -177
  111. package/skills/mono/references/modules/soke-course/references/sop-lesson-types.md +0 -66
  112. package/skills/mono/references/modules/soke-course/references/sop-publish-check.md +0 -76
  113. package/skills/mono/references/modules/soke-course/references/subs/ai/SOP.md +0 -153
  114. package/skills/mono/references/modules/soke-course/references/subs/charge/SOP.md +0 -107
  115. package/skills/mono/references/modules/soke-course/references/subs/copy/SOP.md +0 -80
  116. package/skills/mono/references/modules/soke-course/references/subs/publish/SOP.md +0 -168
  117. package/skills/mono/references/modules/soke-course/references/subs/query/SOP.md +0 -165
  118. package/skills/mono/references/modules/soke-course/references/subs/template/SOP.md +0 -223
  119. package/skills/mono/references/modules/soke-course/references/troubleshoot.md +0 -68
  120. package/skills/multi/soke-course/examples/create-basic.md +0 -70
  121. package/skills/multi/soke-course/references/course-list-courses.md +0 -216
  122. package/skills/multi/soke-course/references/dependencies/soke-assign.md +0 -103
  123. package/skills/multi/soke-course/references/dependencies/soke-lesson.md +0 -119
  124. package/skills/multi/soke-course/references/dependencies/soke-material.md +0 -105
  125. package/skills/multi/soke-course/references/shared.md +0 -185
  126. package/skills/multi/soke-course/references/subs/ai/SOP.md +0 -153
  127. package/skills/multi/soke-course/scripts/check_readiness.py +0 -87
  128. /package/skills/mono/references/{installation.md → shared/installation.md} +0 -0
@@ -0,0 +1,34 @@
1
+ # soke-cli 高风险写操作守卫
2
+
3
+ 本文件定义发布、删除、指派、绑定、批量写入等高风险操作的共用规则。
4
+
5
+ ## 风险等级
6
+
7
+ - L0:查询、列表、详情
8
+ - L1:创建草稿、上传素材
9
+ - L2:更新、绑定、批量写入、分配对象
10
+ - L3:发布、删除、关闭、批量指派、平台同步
11
+
12
+ ## 通用要求
13
+
14
+ - L2 及以上必须先展示目标、影响范围和对象。
15
+ - L3 必须获得明确确认。
16
+ - 删除和关闭类操作必须明确说明不可逆影响。
17
+ - 批量操作必须说明数量、字段和失败处理方式。
18
+ - 平台同步必须说明将要修改的场景、知识包或配置摘要。
19
+
20
+ ## 确认摘要模板
21
+
22
+ ```text
23
+ 操作:<动作>
24
+ 目标:<对象名称>
25
+ 范围:<影响范围>
26
+ 影响:<简要说明>
27
+ 是否确认?
28
+ ```
29
+
30
+ ## 规则
31
+
32
+ - 未确认前不执行写操作。
33
+ - 不把预览结果当作执行结果。
34
+ - 重试前先确认上一步是否已经成功,避免重复写入。
@@ -0,0 +1,33 @@
1
+ # soke-cli 写操作验证与幂等
2
+
3
+ 本文件定义写操作后的验证、重试和幂等处理。
4
+
5
+ ## 统一流程
6
+
7
+ 1. 执行写操作。
8
+ 2. 检查退出码和返回状态。
9
+ 3. 提取真实 ID 或任务 ID。
10
+ 4. 只在必要时进行回读验证。
11
+ 5. 保存状态,供下一步使用。
12
+
13
+ ## 幂等原则
14
+
15
+ - 能使用 idempotency-key 的地方必须使用。
16
+ - 重试前先判断上一次是否可能已经成功。
17
+ - 不要因为没有看到完整输出就重复创建。
18
+ - 异步任务必须保存 task ID 或等价标识。
19
+
20
+ ## 回读规则
21
+
22
+ - 回读只验证本次写入的关键结果,不做无意义全量复核。
23
+ - 回读结果如与写入结果不一致,优先判断是否存在平台延迟或最终一致性问题。
24
+ - 不要用回读替代写操作。
25
+
26
+ ## 适用场景
27
+
28
+ - 课程创建后查课程 ID
29
+ - 素材上传后查 uuid
30
+ - 课件创建后查 lesson-id
31
+ - 任务创建后查 task-id
32
+ - 场景同步后查版本 ID
33
+ - 发布后查状态
@@ -0,0 +1,115 @@
1
+ # 跨模块工作流
2
+
3
+ 这里存放跨业务模块的流程编排。模块自身的字段、命令和专项限制仍以对应模块文档为准。
4
+
5
+ ## 使用规则
6
+
7
+ 先按用户的核心动作选择一条工作流,再读取对应模块文档。不要因为出现“课程”“素材”或“学习”等名词,就自动进入完整创建流程。
8
+
9
+ ## 通用前置
10
+
11
+ 所有需要访问授客平台的流程统一遵循:
12
+
13
+ ```text
14
+ environment-check → auth-check → 业务输入检查
15
+ → 执行当前操作 → 提取真实 ID → 执行依赖该 ID 的后续操作
16
+ ```
17
+
18
+ - 环境检测见 `../shared/environment-check.md`。
19
+ - 登录与企业绑定见 `../shared/auth-check.md`。
20
+ - 纯本地输入检查可以在环境检测前准备,但平台操作必须先完成环境和登录验证。
21
+ - “提取真实 ID”是上传、创建或查询成功后的结果,不要求所有操作在执行前都已有 ID。
22
+ - 只在必要时加载具体模块文档,避免全量读取。
23
+
24
+ ## 课程与素材工作流
25
+
26
+ ### 仅上传素材
27
+
28
+ ```text
29
+ environment-check → auth-check → 文件检查 → 上传素材 → 返回素材真实 ID
30
+ ```
31
+
32
+ 适用于用户只要求把视频、音频或文档放入素材库,不创建课程或课件。
33
+
34
+ 入口:`../modules/soke-material/MODULE.md`。
35
+
36
+ ### 已有课程添加课件
37
+
38
+ ```text
39
+ environment-check → auth-check → 确认 course-id
40
+ → 上传素材或选择已有素材 → 获取素材真实 ID
41
+ → 创建课件 → 可选排序
42
+ ```
43
+
44
+ 入口:
45
+
46
+ - `../modules/soke-material/MODULE.md`
47
+ - `../modules/soke-lesson/MODULE.md`
48
+
49
+ ### 从零创建并发布课程
50
+
51
+ ```text
52
+ environment-check → auth-check → 课程分类 → 创建课程
53
+ → 上传/选择素材 → 创建课件 → 配置课程
54
+ → 发布课程 → 指派学员
55
+ ```
56
+
57
+ 入口:
58
+
59
+ - `../modules/soke-course/MODULE.md`
60
+ - `../modules/soke-material/MODULE.md`
61
+ - `../modules/soke-lesson/MODULE.md`
62
+ - `../modules/soke-assign/MODULE.md`
63
+
64
+ ### 命令前缀说明
65
+
66
+ 本 Mono Skill 的 CLI 命令统一使用 `soke-cli` 前缀。执行前先用当前版本的帮助确认命令和参数,不要凭文档旧例猜测:
67
+
68
+ ```bash
69
+ soke-cli --help
70
+ soke-cli file --help
71
+ soke-cli course --help
72
+ ```
73
+
74
+ 课程相关示例:
75
+
76
+ ```bash
77
+ soke-cli file +upload --path "/absolute/path/to/file"
78
+ soke-cli course +lesson-create --course-id <course-id> --title "课件标题"
79
+ ```
80
+
81
+ 若其他资料出现 `soke file ...`、`soke course ...` 或其他旧前缀,只能视为历史写法;实际执行时统一改用 `soke-cli`,并以当前 CLI 帮助为准。
82
+
83
+ ## 课程工作流的选择判断
84
+
85
+ | 用户表达 | 应选择 |
86
+ |---|---|
87
+ | “上传文件”“把视频放素材库” | 仅上传素材 |
88
+ | “给这门课程添加视频/课件” | 已有课程添加课件 |
89
+ | “创建一门课程并上传课件” | 从零创建并发布课程;是否发布需另行确认 |
90
+ | “从素材库添加到课程” | 已有课程添加课件;不重复上传 |
91
+
92
+ 注意:上传素材和创建课件是两个不同动作。素材上传成功返回的 `uuid`、`object` 等字段,必须原样传给课件创建流程;不能用文件名或自行编造的 ID 代替。
93
+
94
+ ## 考试创建与成绩查询
95
+
96
+ ```text
97
+ 题库分类 → 创建题库 → 创建试题 → 创建试卷 → 发布试卷 → 创建考试 → 指派 → 查询成绩
98
+ ```
99
+
100
+ 入口:`../modules/soke-exam/MODULE.md`。
101
+
102
+ ## 学习地图与统计导出
103
+
104
+ ```text
105
+ 地图分类 → 创建地图 → 查询课程 → 创建阶段 → 发布地图 → 指派 → 创建导出任务 → 查询任务状态
106
+ ```
107
+
108
+ 入口:`../modules/soke-learning-map/MODULE.md`;导出任务规则见 `../modules/soke-task/MODULE.md`。
109
+
110
+ ## 规则
111
+
112
+ - 跨模块流程只传递 CLI 返回的真实 ID。
113
+ - 发布、指派、删除、批量写入和平台同步前必须取得明确确认。
114
+ - 前一步未成功或缺少真实 ID 时,不得推进下一步。
115
+ - 具体模块文档与当前 CLI `--help` 不一致时,以当前 CLI 为准。
@@ -0,0 +1,310 @@
1
+ #!/usr/bin/env python3
2
+ """Run static quality checks for the standalone Mono Skill package."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import ast
7
+ import re
8
+ import sys
9
+ from pathlib import Path
10
+
11
+
12
+ OLD_COMMAND_PATTERNS = (
13
+ r"(?<![-\w])soke\s+(?:file|course|exam|assign|api|learning-map)\b",
14
+ )
15
+ STALE_PATHS = (
16
+ "references/installation.md",
17
+ "./references/installation.md",
18
+ )
19
+ REQUIRED_MODULE_FILES = ("references/modules/README.md",)
20
+ ADAPTER_DIR = "references/modules/soke-ai-coach-director/platform/adapters"
21
+ ADAPTER_MATRIX = "references/modules/soke-ai-coach-director/platform/platform-support-matrix.md"
22
+ REQUIRED_ADAPTER_FILES = ("README.md", "workbuddy.md", "qwen.md", "zework.md", "qclaw.md")
23
+ ADAPTER_INDEX_MARKERS = {
24
+ "workbuddy.md": ("WorkBuddy", "workbuddy.md"),
25
+ "qwen.md": ("千问", "qwen.md"),
26
+ "zework.md": ("Zework", "zework.md"),
27
+ "qclaw.md": ("QClaw", "qclaw.md"),
28
+ }
29
+ MODULE_EXCLUSIONS = {"soke-shared"}
30
+ MODULE_CONTRACT_GROUPS = {
31
+ "responsibility": ("职责", "技能定位"),
32
+ "input": ("输入", "使用前提", "材料完整性检查", "输入完整性", "输入包", "材料缺口"),
33
+ "process": ("流程", "任务类型", "推荐同步", "创建型任务流程"),
34
+ "business-output": ("业务产出", "完成判定", "完成条件"),
35
+ "failure": ("失败", "降级", "异常", "缺失规则", "错误处理"),
36
+ "verification": ("验证", "检查清单", "回读", "核对", "质量闸门", "完成判定"),
37
+ "special-cases": ("业务特例", "注意", "关键硬规则"),
38
+ "output": ("输出", "完成摘要"),
39
+ }
40
+ ENTRY_BUSINESS_MARKERS = (
41
+ "conversation_steps",
42
+ "scoring_rule",
43
+ "ai_roles[]",
44
+ "base_updated_at",
45
+ "advisor_golden_script",
46
+ )
47
+
48
+ REQUIRED_SHARED_FILES = (
49
+ "README.md",
50
+ "rule-ownership.md",
51
+ "installation.md",
52
+ "environment-check.md",
53
+ "auth-check.md",
54
+ "cli-basics.md",
55
+ "command-discovery.md",
56
+ "object-context.md",
57
+ "pagination.md",
58
+ "interaction.md",
59
+ "write-guard.md",
60
+ "output-policy.md",
61
+ "write-verify.md",
62
+ "async-task.md",
63
+ "file-input.md",
64
+ "state-machine.md",
65
+ "error-handling.md",
66
+ )
67
+
68
+
69
+ def check_links(package: Path) -> list[str]:
70
+ failures: list[str] = []
71
+ pattern = re.compile(r"\]\(([^)]+)\)")
72
+ for path in sorted(package.rglob("*.md")):
73
+ text = path.read_text(encoding="utf-8", errors="replace")
74
+ for link in pattern.findall(text):
75
+ if link.startswith(("http://", "https://", "#", "mailto:")):
76
+ continue
77
+ target = link.split("#", 1)[0]
78
+ if target and not (path.parent / target).exists():
79
+ failures.append(f"{path.relative_to(package)} -> {target}")
80
+ return failures
81
+
82
+
83
+ def check_old_commands(package: Path) -> list[str]:
84
+ failures: list[str] = []
85
+ patterns = [re.compile(pattern) for pattern in OLD_COMMAND_PATTERNS]
86
+ for path in sorted(package.rglob("*.md")):
87
+ text = path.read_text(encoding="utf-8", errors="replace")
88
+ for line_number, line in enumerate(text.splitlines(), start=1):
89
+ if "历史写法" in line or "旧前缀" in line:
90
+ continue
91
+ if any(pattern.search(line) for pattern in patterns):
92
+ failures.append(f"{path.relative_to(package)}:{line_number}")
93
+ return failures
94
+
95
+
96
+ def check_stale_paths(package: Path) -> list[str]:
97
+ failures: list[str] = []
98
+ for path in sorted(package.rglob("*.md")):
99
+ text = path.read_text(encoding="utf-8", errors="replace")
100
+ for line_number, line in enumerate(text.splitlines(), start=1):
101
+ for stale_path in STALE_PATHS:
102
+ if stale_path in line and "references/shared/installation.md" not in line:
103
+ failures.append(f"{path.relative_to(package)}:{line_number} contains {stale_path}")
104
+ return failures
105
+
106
+
107
+ def check_shared_files(package: Path) -> list[str]:
108
+ shared = package / "references" / "shared"
109
+ return [f"references/shared/{name}" for name in REQUIRED_SHARED_FILES if not (shared / name).is_file()]
110
+
111
+
112
+ def check_modules(package: Path) -> list[str]:
113
+ failures: list[str] = []
114
+ modules = package / "references" / "modules"
115
+ shared_markers = ("shared/", "../shared/")
116
+ for path in sorted(modules.glob("*/MODULE.md")):
117
+ text = path.read_text(encoding="utf-8", errors="replace")
118
+ relative = str(path.relative_to(package))
119
+ if path.parent.name in MODULE_EXCLUSIONS:
120
+ continue
121
+ if not any(marker in text for marker in shared_markers):
122
+ failures.append(f"{relative}: missing shared entrypoint")
123
+ if not re.search(r"共享前置|共用前置|shared/", text, re.IGNORECASE):
124
+ failures.append(f"{relative}: missing shared entrypoint section")
125
+ headings = "\n".join(
126
+ line.lstrip("#").strip().lower()
127
+ for line in text.splitlines()
128
+ if re.match(r"^#{2,4}\s+|^\*\*[^*]+\*\*", line)
129
+ )
130
+ missing = [
131
+ name for name, markers in MODULE_CONTRACT_GROUPS.items()
132
+ if not any(marker.lower() in headings for marker in markers)
133
+ ]
134
+ for name in missing:
135
+ failures.append(f"{relative}: missing contract group {name}")
136
+ return failures
137
+
138
+
139
+ def check_route_consistency(package: Path) -> list[str]:
140
+ failures: list[str] = []
141
+ modules_dir = package / "references" / "modules"
142
+ index = modules_dir / "README.md"
143
+ entry = package / "SKILL.md"
144
+ if not index.is_file() or not entry.is_file():
145
+ return ["route-consistency: missing SKILL.md or modules README"]
146
+ module_names = {
147
+ path.parent.name
148
+ for path in modules_dir.glob("*/MODULE.md")
149
+ if path.parent.name not in MODULE_EXCLUSIONS
150
+ }
151
+ index_text = index.read_text(encoding="utf-8", errors="replace")
152
+ entry_text = entry.read_text(encoding="utf-8", errors="replace")
153
+ for name in sorted(module_names):
154
+ marker = f"`{name}`"
155
+ link_marker = f"modules/{name}/MODULE.md"
156
+ if marker not in index_text:
157
+ failures.append(f"modules/README.md: missing module {name}")
158
+ if link_marker not in entry_text:
159
+ failures.append(f"SKILL.md: missing route link for {name}")
160
+ return failures
161
+
162
+
163
+ def check_entry_bloat(package: Path) -> list[str]:
164
+ failures: list[str] = []
165
+ entry = package / "SKILL.md"
166
+ if not entry.is_file():
167
+ return ["SKILL.md: missing entrypoint"]
168
+ text = entry.read_text(encoding="utf-8", errors="replace")
169
+ for marker in ENTRY_BUSINESS_MARKERS:
170
+ if marker in text:
171
+ failures.append(f"SKILL.md: contains module-specific marker {marker}")
172
+ return failures
173
+
174
+
175
+ def check_required_module_files(package: Path) -> list[str]:
176
+ return [name for name in REQUIRED_MODULE_FILES if not (package / name).is_file()]
177
+
178
+
179
+ def check_platform_adapters(package: Path) -> list[str]:
180
+ failures: list[str] = []
181
+ adapter_dir = package / ADAPTER_DIR
182
+ matrix = package / ADAPTER_MATRIX
183
+ if not matrix.is_file():
184
+ return [f"{ADAPTER_MATRIX}: missing support matrix"]
185
+ matrix_text = matrix.read_text(encoding="utf-8", errors="replace")
186
+ for name in REQUIRED_ADAPTER_FILES:
187
+ if not (adapter_dir / name).is_file():
188
+ failures.append(f"{ADAPTER_DIR}/{name}: missing adapter file")
189
+ index = adapter_dir / "README.md"
190
+ if index.is_file():
191
+ text = index.read_text(encoding="utf-8", errors="replace")
192
+ for filename, markers in ADAPTER_INDEX_MARKERS.items():
193
+ if all(marker not in text for marker in markers):
194
+ failures.append(f"{ADAPTER_DIR}/README.md: missing index entry for {filename}")
195
+ if filename not in matrix_text:
196
+ failures.append(f"{ADAPTER_MATRIX}: missing matrix entry for {filename}")
197
+ for path in sorted(adapter_dir.glob("*.md")):
198
+ if path.name == "README.md":
199
+ continue
200
+ text = path.read_text(encoding="utf-8", errors="replace")
201
+ relative = str(path.relative_to(package))
202
+ if "适配器" not in text:
203
+ failures.append(f"{relative}: missing adapter declaration")
204
+ if not any(marker in text for marker in ("运行环境检测", "适配器路由")):
205
+ failures.append(f"{relative}: missing environment routing section")
206
+ business_markers = ("exec-part", "conversation_steps")
207
+ if any(marker in text for marker in business_markers):
208
+ failures.append(f"{relative}: adapter contains business-layer rules")
209
+ return failures
210
+
211
+
212
+ def check_shared_duplication(package: Path) -> list[str]:
213
+ failures: list[str] = []
214
+ modules = package / "references" / "modules"
215
+ patterns = (
216
+ ("pagination", re.compile(r"(?:所有|通用|统一).{0,12}(?:分页|去重)")),
217
+ ("interaction", re.compile(r"(?:所有|通用|统一).{0,12}(?:确认|选择)(?!分类|标签)")),
218
+ ("output-policy", re.compile(r"(?:所有|通用|统一).{0,12}(?:脱敏|不回显|不显示)")),
219
+ ("write-verify", re.compile(r"(?:所有|通用|统一).{0,12}(?:回读|幂等|重试前)")),
220
+ )
221
+ for path in sorted(modules.glob("*/MODULE.md")):
222
+ text = path.read_text(encoding="utf-8", errors="replace")
223
+ if path.parent.name == "soke-shared":
224
+ continue
225
+ for line_number, line in enumerate(text.splitlines(), start=1):
226
+ if "共享前置" in line or "按需加载" in line or "业务特有" in line:
227
+ continue
228
+ if "标签-分类严格绑定" in line or "标签来源仅限当前分类" in line:
229
+ continue
230
+ for name, pattern in patterns:
231
+ if pattern.search(line):
232
+ failures.append(f"{name}: {path.relative_to(package)}:{line_number}")
233
+ return failures
234
+
235
+
236
+ def check_auth_duplication(package: Path) -> list[str]:
237
+ failures: list[str] = []
238
+ modules = package / "references" / "modules"
239
+ for path in sorted(modules.glob("*/MODULE.md")):
240
+ if path.parent.name == "soke-shared":
241
+ continue
242
+ text = path.read_text(encoding="utf-8", errors="replace")
243
+ lines = text.splitlines()
244
+ for line_number, line in enumerate(lines, start=1):
245
+ if "auth login" in line or "config show" in line:
246
+ context = "\n".join(lines[max(0, line_number - 3):line_number + 2])
247
+ if any(marker in context for marker in ("登录失败", "未登录", "认证错误", "重新登录", "按共享层", "参见共享")):
248
+ continue
249
+ if "共享前置" not in line and "按需加载" not in line and "兼容" not in line:
250
+ failures.append(f"{path.relative_to(package)}:{line_number}")
251
+ return failures
252
+
253
+
254
+ def check_python(package: Path) -> list[str]:
255
+ failures: list[str] = []
256
+ for path in sorted(package.rglob("*.py")):
257
+ try:
258
+ ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
259
+ except (OSError, SyntaxError, UnicodeError) as exc:
260
+ failures.append(f"{path.relative_to(package)}: {exc}")
261
+ return failures
262
+
263
+
264
+ def check_cache_files(package: Path) -> list[str]:
265
+ return [
266
+ str(path.relative_to(package))
267
+ for path in sorted(package.rglob("*"))
268
+ if path.is_file() and (path.suffix == ".pyc" or path.name == "__pycache__")
269
+ ]
270
+
271
+
272
+ def report(name: str, failures: list[str]) -> bool:
273
+ if failures:
274
+ print(f"FAIL {name} count={len(failures)}")
275
+ for failure in failures[:20]:
276
+ print(f" - {failure}")
277
+ if len(failures) > 20:
278
+ print(f" - ... {len(failures) - 20} more")
279
+ return False
280
+ print(f"PASS {name}")
281
+ return True
282
+
283
+
284
+ def main() -> int:
285
+ package = Path(__file__).resolve().parent.parent
286
+ checks = (
287
+ ("shared-files", check_shared_files(package)),
288
+ ("module-index", check_required_module_files(package)),
289
+ ("platform-adapters", check_platform_adapters(package)),
290
+ ("markdown-links", check_links(package)),
291
+ ("stale-paths", check_stale_paths(package)),
292
+ ("command-prefix", check_old_commands(package)),
293
+ ("module-contracts", check_modules(package)),
294
+ ("route-consistency", check_route_consistency(package)),
295
+ ("entry-bloat", check_entry_bloat(package)),
296
+ ("auth-duplication", check_auth_duplication(package)),
297
+ ("shared-duplication", check_shared_duplication(package)),
298
+ ("python-syntax", check_python(package)),
299
+ ("python-cache", check_cache_files(package)),
300
+ )
301
+ passed = all(report(name, failures) for name, failures in checks)
302
+ if passed:
303
+ print("PACKAGE_CHECK_PASS")
304
+ return 0
305
+ print("PACKAGE_CHECK_FAIL")
306
+ return 1
307
+
308
+
309
+ if __name__ == "__main__":
310
+ sys.exit(main())
@@ -11,7 +11,7 @@ from pathlib import Path
11
11
 
12
12
  def main() -> int:
13
13
  package = Path(__file__).resolve().parent.parent
14
- guide = package / "references" / "installation.md"
14
+ guide = package / "references" / "shared" / "installation.md"
15
15
  executable = shutil.which("soke-cli")
16
16
  print("🔍 soke-cli Mono Skill — 环境检查")
17
17
  print(f" {'✅' if guide.is_file() else '❌'} 安装指南")
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env python3
2
+ """Check Python syntax without writing __pycache__ files."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import ast
7
+ import sys
8
+ from pathlib import Path
9
+
10
+
11
+ def main() -> int:
12
+ package = Path(__file__).resolve().parent.parent
13
+ files = sorted(package.rglob("*.py"))
14
+ failures: list[tuple[Path, Exception]] = []
15
+
16
+ for path in files:
17
+ try:
18
+ source = path.read_text(encoding="utf-8")
19
+ ast.parse(source, filename=str(path))
20
+ except (OSError, SyntaxError, UnicodeError) as exc:
21
+ failures.append((path, exc))
22
+ print(f"FAIL {path}: {exc}")
23
+ else:
24
+ print(f"OK {path}")
25
+
26
+ if failures:
27
+ print(f"Python 语法检查失败:{len(failures)} 个文件")
28
+ return 1
29
+
30
+ print(f"Python 语法检查通过:{len(files)} 个文件(未写入 __pycache__)")
31
+ return 0
32
+
33
+
34
+ if __name__ == "__main__":
35
+ sys.exit(main())
@@ -0,0 +1,13 @@
1
+ <!doctype html><html lang="zh-CN" data-page-node-id="giwDng1lMQa5QKK8yCk6IX"><head data-page-node-id="TgEtDCFS1kvRuFzGYBlc2E"><meta charset="utf-8" data-page-node-id="JrkCtnBihQB8AD2kxMvJ6g"><meta name="viewport" content="width=device-width, initial-scale=1" data-page-node-id="2Sx1tfupCzGyrWFUsNMAlp"><title>Soke CLI Mono 架构与子技能开发指南</title><style>:root{--ink:#182230;--muted:#64748b;--line:#d8dee8;--paper:#fff;--bg:#f4f6f9;--blue:#2563eb;--blue-soft:#eaf1ff;--teal:#0f766e;--teal-soft:#e7f7f4;--amber:#b45309;--amber-soft:#fff4df;--rose:#be123c;--rose-soft:#fff0f3;--dark:#1e293b}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;line-height:1.65}.shell{display:grid;grid-template-columns:250px minmax(0,1fr);min-height:100vh}.side{position:sticky;top:0;height:100vh;padding:28px 20px;background:#172033;color:#dbe5f5}.brand{font-size:18px;font-weight:700;color:#fff;margin-bottom:4px}.version{font-size:12px;color:#9fb0ca;margin-bottom:25px}.side a{display:block;color:#b9c8dc;text-decoration:none;font-size:13px;padding:8px 10px;border-radius:6px;margin:2px 0}.side a:hover,.side a.active{background:#2b3b57;color:#fff}.main{max-width:1180px;width:100%;margin:0 auto;padding:52px 58px 80px}.hero{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:34px 38px;margin-bottom:26px}.eyebrow{font-size:12px;color:var(--blue);font-weight:700;letter-spacing:.04em}.hero h1{font-size:34px;line-height:1.2;margin:8px 0 14px;color:#111827}.hero p{max-width:760px;color:var(--muted);margin:0}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:18px 0 28px}.card{background:var(--paper);border:1px solid var(--line);border-radius:8px;padding:20px}.card h3{margin:0 0 6px;font-size:16px}.card p{margin:0;color:var(--muted);font-size:13px}.section{margin:34px 0}.section h2{font-size:24px;margin:0 0 14px;padding-top:10px}.section h3{font-size:17px;margin:24px 0 8px}.lead{color:var(--muted)}.flow{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:16px 0;padding:18px;background:var(--blue-soft);border:1px solid #cbdcff;border-radius:8px}.step{background:#fff;border:1px solid #b9cdfb;border-radius:6px;padding:8px 12px;font-size:13px}.arrow{color:var(--blue);font-weight:700}.layer{display:grid;grid-template-columns:150px 1fr;gap:0;border:1px solid var(--line);border-radius:8px;overflow:hidden;margin:12px 0;background:#fff}.layer strong{padding:15px;background:var(--dark);color:#fff;font-size:14px}.layer span{padding:15px;color:var(--muted);font-size:14px}.callout{border-left:4px solid var(--blue);background:var(--blue-soft);padding:14px 18px;margin:15px 0;border-radius:0 7px 7px 0}.callout.teal{border-color:var(--teal);background:var(--teal-soft)}.callout.amber{border-color:var(--amber);background:var(--amber-soft)}table{width:100%;border-collapse:collapse;background:#fff;border:1px solid var(--line);border-radius:8px;overflow:hidden;font-size:13px;margin:14px 0}th,td{text-align:left;padding:11px 13px;border-bottom:1px solid var(--line);vertical-align:top}th{background:#f0f3f8;color:#334155;font-weight:700}tr:last-child td{border-bottom:0}code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em;background:#eef2f7;padding:2px 5px;border-radius:4px;color:#334155}pre{background:#111827;color:#dbeafe;padding:17px 19px;border-radius:8px;overflow:auto;font-size:13px;line-height:1.7}ul,ol{padding-left:23px}.check{list-style:none;padding:0}.check li{padding:6px 0}.check li:before{content:"□";color:var(--blue);font-weight:700;margin-right:9px}.footer{margin-top:42px;padding-top:22px;border-top:1px solid var(--line);color:var(--muted);font-size:12px}@media(max-width:850px){.shell{display:block}.side{position:static;height:auto;padding:16px}.side nav{display:flex;gap:4px;overflow:auto}.side a{white-space:nowrap}.main{padding:24px 16px 52px}.hero{padding:25px 22px}.hero h1{font-size:28px}.grid{grid-template-columns:1fr}.layer{grid-template-columns:1fr}.layer strong{padding-bottom:8px}.layer span{padding-top:8px}}</style></head><body data-page-node-id="hBr5gBr6y2g0GxZdAJIBNn"><div class="shell" data-page-node-id="8r8xclmvTJ0stdUtApgALA"><aside class="side" data-page-node-id="5ONDK7D3MujiLqBQFXqXxV"><div class="brand" data-page-node-id="LyyqHmlQ0znRHstqxkg8uD">Soke CLI Mono</div><div class="version" data-page-node-id="I4HNFqNSZhk3CVoAaZAMR3">架构与扩展指南 · v1.0</div><nav data-page-node-id="cl9a43syiqtRoZsHaKddLj"><a href="#overview" class="active" data-page-node-id="AzNoIvBUY0qcHwv2sZxiRs">总览</a><a href="#layers" data-page-node-id="EaoCUuW5vhGnggH1YVqrDq">分层架构</a><a href="#graph" data-page-node-id="TFcXoUSoOzGvuRS9njTeV2">业务图谱</a><a href="#new" data-page-node-id="pkKXQw7qqCamsGgyAbMWNr">新增子技能</a><a href="#team" data-page-node-id="dqKe24KB6DLi8Qj5DdukSx">多人协作</a><a href="#done" data-page-node-id="lVjPGaXoEvpQ4WSrFR2t7D">完成定义</a></nav></aside><main class="main" data-page-node-id="tOex177WSBnspCDCjHsJCv"><header class="hero" id="overview" data-page-node-id="3UGjuIWEj4o0iXCx0G99lk"><div class="eyebrow" data-page-node-id="aYpL00Bu7rv9BrCCPidycy">TEAM DEVELOPMENT REFERENCE</div><h1 data-page-node-id="dGZmzs6IwY8BLVr7OOlB0I">架构与子技能开发指南</h1><p data-page-node-id="boh94yFhpQnTkwonRRjEXJ">面向后续功能开发、多人协作和代码审查的长期参考。核心目标是让每个新需求都能找到清晰归属、唯一事实源和可验证的完成标准。</p></header><div class="grid" data-page-node-id="Acm2xC9pEYEwQEqC6c5Gni"><div class="card" data-page-node-id="0UvgYzmZnbAH6AXZ1Oa8hG"><h3 data-page-node-id="NY3MUpL80tB6vl579CZUbZ">共享规则</h3><p data-page-node-id="SOk4nQlvTOGAXAhjCQDALy">认证、分页、确认、脱敏、验证等跨模块能力。</p></div><div class="card" data-page-node-id="kn1upIYiqcDMH2OkvA1hSS"><h3 data-page-node-id="pgyuGX4a8iGSoKKtbK6Rvr">业务模块</h3><p data-page-node-id="YqvlC7LaEgkPwPEzFAlZgt">围绕业务对象组织职责、输入、流程和特例。</p></div><div class="card" data-page-node-id="goTUEHYIZH3lL5hcTFfNM2"><h3 data-page-node-id="p40svXjR8ThFBQD7Rfy2wM">质量闸门</h3><p data-page-node-id="4Z1PLUocPSTZXQd4fTrL3N">通过自动检查和真实场景验收保障交付质量。</p></div></div><section class="section" id="layers" data-page-node-id="WrEzMzBZNeSVVU8OCCABZF"><h2 data-page-node-id="qQyRaEezstNyTSFcrJEM78">分层架构</h2><p class="lead" data-page-node-id="VMoCI95gHJaGtRiMvwHu9Y">每一层只解决自己的问题,避免规则重复和职责越界。</p><div class="layer" data-page-node-id="ZquIm8qjzZpxZDFfWrsjtp"><strong data-page-node-id="0UnwLNokY6yKwRiQejMEFv">入口调度层</strong><span data-page-node-id="9FoMM8aGWJ8qE9Niuyiud0"><code data-page-node-id="WVTAfxdcThrBeumsF25QyV">SKILL.md</code>:意图识别、模块路由、读取顺序、确认边界。</span></div><div class="layer" data-page-node-id="BPDKv88dkLjA9e2FqtA0vo"><strong data-page-node-id="BAxiDWEIrzjxFzDFHYRap2">共享能力层</strong><span data-page-node-id="jMEOtirCFjiP1PHaDDgUZd"><code data-page-node-id="Nzz8FEIT8K3qDNL22VCnkA">references/shared/</code>:安装、认证、对象、分页、交互、写保护、输出、异步、错误。</span></div><div class="layer" data-page-node-id="pV68pHR0V0RG8DlYo9Pzv2"><strong data-page-node-id="OBAFgL33r6Sesm7v3GVsua">业务模块层</strong><span data-page-node-id="G9jvTLxXCn2nGzB656GWqB"><code data-page-node-id="r4siLY3OIFfxZcGzd3SXKU">references/modules/</code>:课程、考试、地图、指派、AI 教练、AI 陪练等业务对象。</span></div><div class="layer" data-page-node-id="puBHsQUhSCZ3SqT5rPP3bT"><strong data-page-node-id="Yd0rOYJliphPZFPTohknWz">工作流层</strong><span data-page-node-id="WdbekBCV3evDeSDLgIAxsO"><code data-page-node-id="HNTPA5Eh3FQQcw7iEKqa7H">references/workflows/</code>:描述多个模块之间的对象交接,不复制内部规则。</span></div><div class="layer" data-page-node-id="fx4t6yTIc9PpPpNErEJJvi"><strong data-page-node-id="6uuEY50GSP7dNsgzVEPCLO">平台适配层</strong><span data-page-node-id="Yj9BG5JuUyHOcV156k78Ht"><code data-page-node-id="LRjEQ1mmD928psOqv4FNK7">platform/adapters/</code>:WorkBuddy、千问、Zework、QClaw 和通用降级。</span></div><div class="layer" data-page-node-id="eEWvMfyJ6qihlf6oj7oVqc"><strong data-page-node-id="pRg52H4BScmpgbzAtWBFCe">质量保障层</strong><span data-page-node-id="BSRFRDfFZwjnFVqskhJZXp"><code data-page-node-id="87UBBuPG1tSRQRu6xUOq13">scripts/</code>:包结构、链接、命令、入口、矩阵和语法检查。</span></div><div class="callout" data-page-node-id="jpi21HFD5ArGFRDj4TpZkO"><strong data-page-node-id="73NNBGvzUWmj6jA3EsjxY5">边界原则:</strong>共享规则只定义通用约束,模块只保留业务差异,工作流只定义对象交接,适配器只处理平台差异。</div></section><section class="section" id="graph" data-page-node-id="UBY2g5sA518yL239SYyPSH"><h2 data-page-node-id="HTSDTz25YZM5wfeXtfmRU2">业务知识图谱</h2><h3 data-page-node-id="BcfOQ0TeSRkO3EaDQX0dNp">课程链路</h3><div class="flow" data-page-node-id="SAABExsHL0rkseJTGxFNPB"><span class="step" data-page-node-id="kk5VtxAltHqcZvIGOlJXSr">素材上传</span><span class="arrow" data-page-node-id="h8bB8jokSjiZMLKuHfzZIW">→</span><span class="step" data-page-node-id="CoEQpduHe84TDLuEwzyTaU">课件创建</span><span class="arrow" data-page-node-id="RFV8htB44MxH1HrNMyQeGG">→</span><span class="step" data-page-node-id="Tq5UqksDXnf3xV4dlhNePi">课程配置与发布</span><span class="arrow" data-page-node-id="nQ53pFphwEiSvIpoO6rcgF">→</span><span class="step" data-page-node-id="yxgMmWQrdw1XNiWFxOkp02">学习对象指派</span></div><p class="lead" data-page-node-id="nOxJUhGawHWGvHjviqSrOx"><code data-page-node-id="BBYVJc3EwUgdXUisriyW9d">soke-material</code> 的真实素材 ID 是 <code data-page-node-id="rnxqv6tcvvTMS74NvAZ5XW">soke-lesson</code> 的输入,发布后的课程再交给 <code data-page-node-id="s0lFjMwojqypqm4C62pVnn">soke-assign</code>。</p><h3 data-page-node-id="dEK570LEeRc6O99IDI0yu0">考试与学习路径</h3><div class="flow" data-page-node-id="y5GetxBR6zSLtcjaTxHjiq"><span class="step" data-page-node-id="1Syzp3AzpmduEF8aUR5DtM">题库与试卷</span><span class="arrow" data-page-node-id="cKaJlguetpZW8hhFge7xFd">→</span><span class="step" data-page-node-id="ZH475n1nMNulXcE8XzcLUn">考试发布</span><span class="arrow" data-page-node-id="CFCOOGw9zR1IGBSMhCJ11r">→</span><span class="step" data-page-node-id="yrTYvC20p7EnixQ5Gusga2">指派</span><span class="arrow" data-page-node-id="o2uVtTYVctYFPPwGG2kJWx">→</span><span class="step" data-page-node-id="cOQE6ahOb9IZlAJuAeDtVe">成绩或练习分析</span></div><h3 data-page-node-id="Lq3MOCPJJfBXJGReHAmja2">AI 链路</h3><div class="flow" data-page-node-id="BZiZKr3XGkrQEBUHxG7Y1Z"><span class="step" data-page-node-id="XCeJjqa1nn8HJY9CTroNts">原始材料</span><span class="arrow" data-page-node-id="VlIDpSLG3noC3Yxqb98Glb">→</span><span class="step" data-page-node-id="Ula23fEbhAIEGU4NHgnhDY">一次提炼</span><span class="arrow" data-page-node-id="bNUvLaXvVW0Fb3ISgrl6VX">→</span><span class="step" data-page-node-id="FuNtkwS2zoohT2nFQY5cJ1">AI 陪练 Part1-Part5</span><span class="arrow" data-page-node-id="6tkUw3juOuhOEmnwmJDB44">→</span><span class="step" data-page-node-id="D2BPoOFLO3a1Mhpop5fJ6W">同步、闸门、发布</span><span class="arrow" data-page-node-id="9kCNqqpiHmRegnX85jbGUG">→</span><span class="step" data-page-node-id="waGDjvCbVZMmkh7a3yDMjm">知识包绑定</span></div><div class="callout teal" data-page-node-id="4Ub1yxmifViToph92UiTQS"><strong data-page-node-id="aa1ACwJn3p0M7BoC8o4Erz">知识包边界:</strong><code data-page-node-id="VC4MnEmtAeMCkwwAwWdFCY">soke-ai-coach-director</code> 负责原始材料提炼和陪练场景,<code data-page-node-id="WdgNNU7q7hDFPv9PYdbHHr">soke-ai-training</code> 复用提炼稿,负责 source、entries、版本和绑定,不做二次提炼。</div></section><section class="section" id="new" data-page-node-id="3BhSyVEea9DDFkGKIhLav7"><h2 data-page-node-id="veQ7fpE9a2o68bTovtwCmc">新增子技能</h2><h3 data-page-node-id="rNA9c7dEXNzpo5wESzzjgE">先判断归属层</h3><table data-page-node-id="MjrVxqgaK3wuDfAwpPFDXd"><thead data-page-node-id="rZHJSPhWE0BjMUMGTujMYg"><tr data-page-node-id="LpWI0AFxJluOTNLbpGWLlF"><th data-page-node-id="WxmYuaPzKmZaNpG7vZq7Yv">需求特征</th><th data-page-node-id="EALHHpfARXtpiv3WcqFYVB">放置位置</th></tr></thead><tbody data-page-node-id="wwQVck3OzZbsd7ERBvktQd"><tr data-page-node-id="VW2mV6I3T8bZ0HunI7VXHx"><td data-page-node-id="txSxg19BthpJLLBqnXLB5S">多个模块复用的通用能力</td><td data-page-node-id="ua9wJeCGacPEYHKiwkobw7"><code data-page-node-id="V4fLhIofsUMEIc1E75Rbai">references/shared/</code></td></tr><tr data-page-node-id="NiIbpxXqfM3ksx3OJekCRV"><td data-page-node-id="HVkZ0oxfLaIuaCAA4yjwaw">已有业务对象的新动作</td><td data-page-node-id="pem6sF4Jmiy1WkrZKGvuBe">修改现有模块</td></tr><tr data-page-node-id="mrvucDZUNpvdEO70W8hCCB"><td data-page-node-id="OrQHsndeHbfeocPjFyVuVb">新的业务对象</td><td data-page-node-id="fvEhChEvSqWU0GGlGBBM1T">新建 <code data-page-node-id="exz5sElw7xTfBac3BDwvcd">references/modules/soke-xxx/</code></td></tr><tr data-page-node-id="HXB23MLSv8MXdAeggxvITF"><td data-page-node-id="C5SSrhIFAZe3Znvs6ezbYN">两个以上模块串联</td><td data-page-node-id="cEfpbLSiIz1dqg08axPzsp"><code data-page-node-id="CkyAIt1Twy8lxdAuKhd3Wr">references/workflows/</code></td></tr><tr data-page-node-id="ffX8mJchTVzF6pjAV5Uy52"><td data-page-node-id="lfct0GkdnJikF6ogyEQCtY">平台显示、交互或命令差异</td><td data-page-node-id="lTD1L9I2pipupC11Hvkv0O">平台适配器</td></tr><tr data-page-node-id="3ZnRT6zQJba6oqpJfS35O0"><td data-page-node-id="5T5GxguycDeaFu8veRfzEq">可自动验证的约束</td><td data-page-node-id="w9WheTCXbHDWQLK7JGsCRB"><code data-page-node-id="vtcMia9eiUdu8wBkFEClcB">scripts/</code></td></tr></tbody></table><h3 data-page-node-id="CnFEXrV2FcSlJYIY1NyOOx">九步开发法</h3><ol data-page-node-id="JPT9Afgja4CYKHHiZ3ASOk"><li data-page-node-id="vUWdepQ4eAfsYTj7DcBMgP">写清需求边界:谁、对什么对象、做什么动作、得到什么结果。</li><li data-page-node-id="RV0q98CrbpK0yfPRO9eYQi">确认对象与状态:输入、父对象、状态变化、真实 ID、幂等性。</li><li data-page-node-id="1jRWdA7U7yatwQy1GUt51V">选择归属层:共享、现有模块、新模块、工作流、适配器或检查器。</li><li data-page-node-id="TFJYlTQfud3L0EyDix9ali">查询当前 CLI 帮助:<code data-page-node-id="jaKE4bRQeuVqerBNJY6h4B">soke-cli --help</code>、父命令帮助、叶子命令帮助。</li><li data-page-node-id="qeSD6sjsnBIQup85QPzo9c">实现最小闭环:前置检查 → 查询 ID → 确认 → 执行 → 验证 → 输出。</li><li data-page-node-id="KoVn8FCWD5x5dpG1ca84eF">接入入口和索引:更新 <code data-page-node-id="GZ0n9GcaOGdUscdyfXMLd8">SKILL.md</code> 与模块责任矩阵。</li><li data-page-node-id="mg0fzV8lRAstYzmk5Gv5ER">补充专项规则:只保留字段、状态、红线和异常特例。</li><li data-page-node-id="f57PeavpPcGhPUFbqhDiTg">加入自动检查:文件、链接、路径、命令、入口、重复规则和语法。</li><li data-page-node-id="ybCqR9YkniRkQ7H5rrvirr">完成真实场景验收:从用户输入走到最终输出。</li></ol><h3 data-page-node-id="b7Gv8C2nZ9vYpdNGkjvotd">标准模块入口</h3><pre data-page-node-id="Jx1mY6zzNBowH3gFLnfoK0"># soke-new-feature
2
+
3
+ ## 共享前置
4
+ ## 职责
5
+ ## 不负责
6
+ ## 输入
7
+ ## 流程
8
+ ## 业务特例
9
+ ## 输出</pre></section><section class="section" id="team" data-page-node-id="d3VYQLYzAt0eWlNh9qwSCk"><h2 data-page-node-id="GKpa9zUfBtABhUwkyE5U4M">多人协作</h2><table data-page-node-id="vCkaFp5zA8FYEJV09OwNtC"><thead data-page-node-id="V6tNCg56HMFb1OsKx9EDkT"><tr data-page-node-id="jhRvfzPBRR3BfSgpHZhidt"><th data-page-node-id="mtMSADRfBTrV9kiCcVfuSL">角色</th><th data-page-node-id="BItHgaKZ2ic54hHfm5uNuD">负责范围</th></tr></thead><tbody data-page-node-id="wUUpil19MMtAtg2ExHnCsw"><tr data-page-node-id="18dzPu19rkyz45Pe956Dr9"><td data-page-node-id="6hWvurXnqpkpP3oczaihWz">架构维护者</td><td data-page-node-id="XOnaYibc0axdhTmVWA5yIP"><code data-page-node-id="1CjIVrkctLqqxjOGG0K2Qv">SKILL.md</code>、共享规则、唯一来源矩阵</td></tr><tr data-page-node-id="4U4reJFx3exoSjh81Ivosy"><td data-page-node-id="AFMMnAKO31o3vYbofQSoD5">业务开发者</td><td data-page-node-id="ABGLaGTdcTPwuFWi4fXbGd">单个业务模块目录</td></tr><tr data-page-node-id="sfRUCkep3yCDGbGf580yWJ"><td data-page-node-id="Gr8SEsO5tT0vrR7xM1NnKJ">工作流开发者</td><td data-page-node-id="2V3C1U7PUGCkEzx2UmYIwJ">跨模块流程和交接契约</td></tr><tr data-page-node-id="a9zpBuZc25C4DQ0lY0JSB8"><td data-page-node-id="pLnqS4kDoshivWS8QEbWjF">平台开发者</td><td data-page-node-id="sTshb4uexItvlh03djXGKH">单个平台适配器和支持矩阵</td></tr><tr data-page-node-id="uvOhtksLZJ4OwntYvf7Jmj"><td data-page-node-id="qkv1v6AxB5usMPHDb3CmSv">质量维护者</td><td data-page-node-id="1lp7y28c0lgY9sLUIm3lMH"><code data-page-node-id="xPixrKQ0u94Wa9lgQ6qrRs">check_package.py</code> 和检查规则</td></tr><tr data-page-node-id="3UwFSLCZyudfKvGLB6ozbf"><td data-page-node-id="ox8UMqW0jeoTOEl9xNJ1Yp">验收人员</td><td data-page-node-id="8eAZRswAnsQx7iXacTOsm1">CLI 帮助、真实场景和回归验证</td></tr></tbody></table><div class="callout amber" data-page-node-id="Op4hjfdAUDptMW1G2P52Tq"><strong data-page-node-id="tR47VF8Rviw8d8yFYrw2rA">协作红线:</strong>同一时间尽量不要多人修改同一个入口文件。若两人同时修改共享规则、两个模块争夺同一对象,或检查器与业务特例冲突,应先建立唯一事实源再继续。</div><h3 data-page-node-id="ftuxYAUh0sS3UZG6mZo9RN">开发前声明</h3><pre data-page-node-id="gBRBGmUOegituWg62PME04">修改文件:
10
+ 不修改文件:
11
+ 依赖模块:
12
+ 验收命令:</pre><h3 data-page-node-id="VVKHm4QGMGDAuAY82lydCw">合并前命令</h3><pre data-page-node-id="1NLuLCca9sAU7b7KumPjwc">/Users/edy/.workbuddy/binaries/python/versions/3.13.12/bin/python3 skills/mono/scripts/check_package.py
13
+ git diff --check</pre></section><section class="section" id="done" data-page-node-id="3xh6FXGiDSbZQ0bItCBHbp"><h2 data-page-node-id="u6IaLWDdr1LHqUK0vXr7Ds">完成定义</h2><ul class="check" data-page-node-id="wbba9yBsn76PFfdd8qUBJV"><li data-page-node-id="UkEAvj0Fim04MrAYkoJjqu">业务对象和职责边界已定义。</li><li data-page-node-id="LFOcoshvBfUKTSFcHIzvH5">归属层级已确定,不重复已有能力。</li><li data-page-node-id="2MxghxOszQ2XfrMPTOeqwj">模块入口符合标准结构。</li><li data-page-node-id="h46s2uKubsUfWH9EEywr5R">真实 ID 来源和状态变化明确。</li><li data-page-node-id="7bQn1ADDqSkgp85Fa55DUo">写操作有确认、验证和幂等策略。</li><li data-page-node-id="AtTYlRAova1jTvb0mSlL0A">入口路由、模块矩阵和工作流已更新。</li><li data-page-node-id="oCxHmNIk5myJfWb1OCtYXA">机器检查通过。</li><li data-page-node-id="P9MDiYmBAMuDEz2BBtR3Kr"><code data-page-node-id="IOqmxF6WOiBzFHfJCd5GUC">git diff --check</code> 通过。</li><li data-page-node-id="wxjf0ab6FEYAj9CCHunZNM">至少完成一条真实场景验收。</li><li data-page-node-id="9SwE0JW33gaVJFEPgcA8RZ">变更范围和剩余风险已记录。</li></ul><div class="footer" data-page-node-id="FxzHq4ATuOKVbwuW9IFovi">唯一原则:先判层级,再定边界;先定义对象,再选命令;先复用共享,再写特例;先完成闭环,再扩展异常。</div></section></main></div></body></html>
@@ -0,0 +1,40 @@
1
+ examples:
2
+ - id: create-and-publish
3
+ title:
4
+ zh: 创建课程并发布
5
+ description:
6
+ zh: 从零创建一门线上课,走完课件、发布全流程
7
+ prompt:
8
+ zh: |-
9
+ 帮我创建一门线上课:
10
+
11
+ 课程标题:{{课程标题}}
12
+ 课程分类:{{可选,分类名称}}
13
+
14
+ 创建完成后引导我添加课件并发布。
15
+ - id: add-courseware
16
+ title:
17
+ zh: 给课程加课件
18
+ description:
19
+ zh: 给已有课程添加视频/音频/文档/图片/小测验课件
20
+ prompt:
21
+ zh: |-
22
+ 给课程「{{课程名称}}」添加课件:
23
+
24
+ 素材:{{本地文件路径或"从素材库选择"或"小测验/图片"}}
25
+ - id: publish-and-assign
26
+ title:
27
+ zh: 发布并指派学员
28
+ description:
29
+ zh: 对已有课程执行发布校验、发布,并指派给部门
30
+ prompt:
31
+ zh: |-
32
+ 把课程「{{课程名称}}」发布,并指派给{{部门名称}},{{必修|选修}}。
33
+ - id: query-progress
34
+ title:
35
+ zh: 查学习进度
36
+ description:
37
+ zh: 查询课程完成率、学员进度、作业提交情况
38
+ prompt:
39
+ zh: |-
40
+ 看看课程「{{课程名称}}」的学习进度和完成率。