@sokeai/cli 1.0.77 → 1.0.79

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 (291) hide show
  1. package/package.json +1 -1
  2. package/scripts/install.js +2 -2
  3. package/scripts/local-test.js +1 -1
  4. package/scripts/test-auto-detect.js +20 -3
  5. package/skills/README.md +25 -174
  6. package/skills/SKILL.md +17 -239
  7. package/skills/mono/README.md +10 -0
  8. package/skills/mono/SKILL.md +223 -0
  9. package/skills/{soke-course/soke-cli/345/256/211/350/243/205/346/214/207/345/215/227.md → mono/references/installation.md} +0 -3
  10. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/README.md +2 -1
  11. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-engineer/parts/part1-basic.md +1 -1
  12. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/publish-gate.md +1 -0
  13. package/skills/mono/references/modules/soke-ai-coach-director/platform/soke-ai-training/soke-ai-training.md +123 -0
  14. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/exec-handbook.md +5 -5
  15. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/exec-part1.md +5 -5
  16. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/platform-api-pitfalls.md +1 -1
  17. package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/subs/part1/SOP.md +2 -2
  18. package/skills/mono/references/modules/soke-ai-coach-director/scripts/gate_check.py +114 -0
  19. package/skills/mono/references/modules/soke-ai-coach-director/scripts/validate_operations.py +410 -0
  20. package/skills/{soke-ai-training/SKILL.md → mono/references/modules/soke-ai-training/MODULE.md} +3 -1
  21. package/skills/mono/references/modules/soke-assign/README.md +308 -0
  22. package/skills/{soke-certificate/SKILL.md → mono/references/modules/soke-certificate/MODULE.md} +2 -2
  23. package/skills/mono/references/modules/soke-course/MODULE.md +402 -0
  24. package/skills/mono/references/modules/soke-course/README.md +291 -0
  25. package/skills/{soke-course → mono/references/modules/soke-course}/references/examples.md +3 -3
  26. package/skills/{soke-exam/SKILL.md → mono/references/modules/soke-exam/MODULE.md} +1 -1
  27. package/skills/{soke-learning-map/SKILL.md → mono/references/modules/soke-learning-map/MODULE.md} +5 -6
  28. package/skills/{soke-learning-profile/SKILL.md → mono/references/modules/soke-learning-profile/MODULE.md} +2 -2
  29. package/skills/mono/references/modules/soke-lesson/README.md +53 -0
  30. package/skills/mono/references/modules/soke-material/README.md +49 -0
  31. package/skills/{soke-photo-gallery/SKILL.md → mono/references/modules/soke-photo-gallery/MODULE.md} +2 -3
  32. package/skills/mono/references/modules/soke-supervisor/MODULE.md +186 -0
  33. package/skills/mono/references/modules/soke-task/MODULE.md +146 -0
  34. package/skills/{soke-training-demand/SKILL.md → mono/references/modules/soke-training-demand/MODULE.md} +1 -1
  35. package/skills/mono/references/shared/cli-basics.md +185 -0
  36. package/skills/mono/scripts/check_readiness.py +28 -0
  37. package/skills/{soke-ai-coach-director → mono}/scripts/validate_operations.py +2 -2
  38. package/skills/multi/README.md +18 -0
  39. package/skills/multi/soke-ai-coach-director/CHANGELOG.md +203 -0
  40. package/skills/multi/soke-ai-coach-director/README.md +124 -0
  41. package/skills/multi/soke-ai-coach-director/SKILL.md +220 -0
  42. package/skills/multi/soke-ai-coach-director/assets/ERRORS-TEMPLATE.md +5 -0
  43. package/skills/multi/soke-ai-coach-director/assets/FEATURE_REQUESTS-TEMPLATE.md +5 -0
  44. package/skills/multi/soke-ai-coach-director/assets/LEARNINGS-TEMPLATE.md +45 -0
  45. package/skills/multi/soke-ai-coach-director/assets/SKILL-TEMPLATE.md +177 -0
  46. package/skills/multi/soke-ai-coach-director/coaching/knowledge-packager/knowledge-packager.md +91 -0
  47. package/skills/multi/soke-ai-coach-director/coaching/prompt-engineer/parts/part1-basic.md +59 -0
  48. package/skills/multi/soke-ai-coach-director/coaching/prompt-engineer/parts/part2-roles.md +97 -0
  49. package/skills/multi/soke-ai-coach-director/coaching/prompt-engineer/parts/part3-flow.md +72 -0
  50. package/skills/multi/soke-ai-coach-director/coaching/prompt-engineer/parts/part4-scoring.md +87 -0
  51. package/skills/multi/soke-ai-coach-director/coaching/prompt-engineer/parts/part5-constraints.md +48 -0
  52. package/skills/multi/soke-ai-coach-director/coaching/prompt-engineer/prompt-engineer.md +76 -0
  53. package/skills/multi/soke-ai-coach-director/coaching/prompt-optimizer/prompt-optimizer.md +381 -0
  54. package/skills/multi/soke-ai-coach-director/coaching/role-profiler/role-profiler.md +87 -0
  55. package/skills/multi/soke-ai-coach-director/platform/adapters/README.md +68 -0
  56. package/skills/multi/soke-ai-coach-director/platform/adapters/qclaw.md +67 -0
  57. package/skills/multi/soke-ai-coach-director/platform/adapters/workbuddy.md +44 -0
  58. package/skills/multi/soke-ai-coach-director/platform/adapters/wukong.md +70 -0
  59. package/skills/multi/soke-ai-coach-director/platform/adapters/zework.md +89 -0
  60. package/skills/multi/soke-ai-coach-director/platform/api-fallback.md +262 -0
  61. package/skills/multi/soke-ai-coach-director/platform/interaction.md +103 -0
  62. package/skills/multi/soke-ai-coach-director/platform/publish-gate.md +45 -0
  63. package/skills/multi/soke-ai-coach-director/platform/resource-finalizer.md +103 -0
  64. package/skills/{soke-ai-coach-director → multi/soke-ai-coach-director}/platform/soke-ai-training/soke-ai-training.md +1 -1
  65. package/skills/multi/soke-ai-coach-director/platform/sync-engine.md +39 -0
  66. package/skills/multi/soke-ai-coach-director/references/cases/AI/345/256/242/346/210/267/350/247/222/350/211/262/346/250/241/346/235/277/345/272/223.md +265 -0
  67. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203Bad Case/346/240/267/346/234/254/345/272/223.md" +206 -0
  68. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/345/210/233/345/273/272/351/227/256/351/242/230/345/272/223.md +666 -0
  69. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/345/234/272/346/231/257/345/210/206/347/261/273/345/272/223.md +213 -0
  70. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/345/256/242/346/210/267/346/235/220/346/226/231/346/270/205/345/215/225/344/270/216/350/256/277/350/260/210/351/242/230/345/272/223.md +229 -0
  71. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/345/276/256/350/260/203/351/227/256/351/242/230/345/272/223.md +833 -0
  72. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/346/212/200/346/234/257/350/276/271/347/225/214/344/270/216/346/216/222/351/232/234/345/272/223.md +239 -0
  73. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/346/217/220/347/244/272/350/257/215/346/250/241/345/235/227/345/272/223.md +249 -0
  74. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/346/225/260/346/215/256/346/214/207/346/240/207/344/270/216/347/234/213/346/235/277/345/217/243/345/276/204/345/272/223.md +282 -0
  75. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/346/265/213/350/257/225/347/224/250/344/276/213/345/272/223.md +254 -0
  76. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/350/257/204/345/210/206/346/240/207/345/207/206/347/273/204/344/273/266/345/272/223.md +264 -0
  77. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/231/252/347/273/203/351/241/271/347/233/256/346/241/210/344/276/213/345/244/215/347/233/230/345/272/223.md +223 -0
  78. package/skills/multi/soke-ai-coach-director/references/cases/AI/351/241/276/345/256/242/350/247/222/350/211/262/346/250/241/346/213/237_GoodCase_BadCase_20260701.md +304 -0
  79. package/skills/multi/soke-ai-coach-director/references/cases/create//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/224/265/350/257/235/347/272/246/350/256/277//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/345/256/242/346/210/267/346/235/220/346/226/231/346/261/207/346/200/273_2026-05-19_1341.md +42 -0
  80. package/skills/multi/soke-ai-coach-director/references/cases/create//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267/347/237/245/350/257/206/345/272/223/347/224/237/346/210/220_20260615.md +23 -0
  81. package/skills/multi/soke-ai-coach-director/references/cases/create//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267/351/231/252/347/273/203/346/217/220/347/244/272/350/257/215/347/224/237/346/210/220_20260615.md +34 -0
  82. package/skills/multi/soke-ai-coach-director/references/cases/create//346/237/220/345/233/275/351/231/205/346/243/200/346/265/213/346/234/272/346/236/204//346/237/220/345/233/275/351/231/205/346/243/200/346/265/213/346/234/272/346/236/204/351/231/252/347/273/203/346/211/247/350/241/214/346/226/271/346/241/210/344/272/244/344/273/230/350/256/260/345/275/225_20260610.md +26 -0
  83. package/skills/multi/soke-ai-coach-director/references/cases/create//351/231/214/346/213/234/344/277/241/346/201/257/346/224/266/351/233/206//351/231/214/346/213/234/344/277/241/346/201/257/346/224/266/351/233/206_/346/217/220/347/244/272/350/257/215/346/220/255/345/273/272_20260622.md +30 -0
  84. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_V1.2_20260616.md +254 -0
  85. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215_/345/216/213/347/274/251/347/211/210_V2.0_20260616.md +96 -0
  86. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215/344/274/230/345/214/226_20260616.md +20 -0
  87. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277AI/351/231/252/347/273/203/347/263/273/347/273/237_/346/265/213/350/257/225/345/217/215/351/246/210/346/261/207/346/200/273_2026-06-01.md +434 -0
  88. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277KYC/344/277/241/344/273/273/345/200/274/347/246/201/344/273/244_2026-06-09_0932.md +22 -0
  89. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277KYC/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_v2_20260608.md +261 -0
  90. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_v1.2.md +354 -0
  91. package/skills/multi/soke-ai-coach-director/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/346/217/220/347/244/272/350/257/215/344/274/230/345/214/226_V2_/350/257/212/346/226/255/344/272/244/344/273/230_20260609.md +26 -0
  92. package/skills/multi/soke-ai-coach-director/references/cases//345/233/233/345/244/247/345/234/272/346/231/257_GoodCase_BadCase_20260701.md +194 -0
  93. package/skills/multi/soke-ai-coach-director/references/cases//346/241/210/344/276/213/345/272/223/350/241/245/345/205/205_2026-06-24.md +41 -0
  94. package/skills/multi/soke-ai-coach-director/references/change-log-partwise-refactor.md +74 -0
  95. package/skills/multi/soke-ai-coach-director/references/env-check.md +146 -0
  96. package/skills/multi/soke-ai-coach-director/references/exec-common.md +126 -0
  97. package/skills/multi/soke-ai-coach-director/references/exec-handbook.md +621 -0
  98. package/skills/multi/soke-ai-coach-director/references/exec-part1.md +86 -0
  99. package/skills/multi/soke-ai-coach-director/references/exec-part2.md +145 -0
  100. package/skills/multi/soke-ai-coach-director/references/exec-part3.md +91 -0
  101. package/skills/multi/soke-ai-coach-director/references/exec-part4.md +187 -0
  102. package/skills/multi/soke-ai-coach-director/references/gate-check-matrix.md +46 -0
  103. package/skills/{soke-learning-map/soke-cli/345/256/211/350/243/205/346/214/207/345/215/227.md → multi/soke-ai-coach-director/references/installation.md} +0 -3
  104. package/skills/multi/soke-ai-coach-director/references/micro-tune-labels.md +30 -0
  105. package/skills/multi/soke-ai-coach-director/references/platform-api-pitfalls.md +49 -0
  106. package/skills/multi/soke-ai-coach-director/references/role-resource-matching.md +45 -0
  107. package/skills/multi/soke-ai-coach-director/references/self-improvement-examples.md +376 -0
  108. package/skills/multi/soke-ai-coach-director/references/self-learning-engine.md +489 -0
  109. package/skills/multi/soke-ai-coach-director/references/shared.md +185 -0
  110. package/skills/multi/soke-ai-coach-director/references/subs/part1/SOP.md +17 -0
  111. package/skills/multi/soke-ai-coach-director/references/subs/part2/SOP.md +34 -0
  112. package/skills/multi/soke-ai-coach-director/references/subs/part3/SOP.md +27 -0
  113. package/skills/multi/soke-ai-coach-director/references/subs/part4/SOP.md +31 -0
  114. package/skills/multi/soke-ai-coach-director/references/subs/publish/SOP.md +81 -0
  115. package/skills/multi/soke-ai-coach-director/references/subs/tune/SOP.md +92 -0
  116. package/skills/multi/soke-ai-coach-director/references/verified-cli-cheatsheet.md +56 -0
  117. package/skills/multi/soke-ai-coach-director/scripts/activator.sh +4 -0
  118. package/skills/multi/soke-ai-coach-director/scripts/error-detector.sh +4 -0
  119. package/skills/multi/soke-ai-coach-director/scripts/extract-skill.sh +7 -0
  120. package/skills/multi/soke-ai-coach-director/scripts/gate_check.py +114 -0
  121. package/skills/multi/soke-ai-coach-director/scripts/validate_operations.py +410 -0
  122. package/skills/multi/soke-ai-training/SKILL.md +249 -0
  123. package/skills/{soke-cli/345/256/211/350/243/205/346/214/207/345/215/227.md → multi/soke-ai-training/references/installation.md} +0 -3
  124. package/skills/multi/soke-ai-training/references/shared.md +185 -0
  125. package/skills/{soke-assign → multi/soke-assign}/README.md +3 -5
  126. package/skills/multi/soke-assign/SKILL.md +101 -0
  127. package/skills/{soke-course/SKILL.md → multi/soke-assign/references/dependencies/soke-course.md} +1 -1
  128. package/skills/multi/soke-assign/references/dependencies/soke-exam.md +600 -0
  129. package/skills/multi/soke-assign/references/installation.md +451 -0
  130. package/skills/multi/soke-assign/references/shared.md +185 -0
  131. package/skills/multi/soke-certificate/SKILL.md +715 -0
  132. package/skills/multi/soke-certificate/references/installation.md +451 -0
  133. package/skills/multi/soke-certificate/references/shared.md +185 -0
  134. package/skills/{soke-course → multi/soke-course}/README.md +5 -7
  135. package/skills/multi/soke-course/SKILL.md +399 -0
  136. package/skills/multi/soke-course/agents/openai.yaml +7 -0
  137. package/skills/multi/soke-course/examples/create-basic.md +70 -0
  138. package/skills/multi/soke-course/references/course-list-courses.md +216 -0
  139. package/skills/multi/soke-course/references/dependencies/soke-assign.md +103 -0
  140. package/skills/multi/soke-course/references/dependencies/soke-lesson.md +119 -0
  141. package/skills/multi/soke-course/references/dependencies/soke-material.md +105 -0
  142. package/skills/multi/soke-course/references/examples.md +480 -0
  143. package/skills/multi/soke-course/references/installation.md +451 -0
  144. package/skills/multi/soke-course/references/intent-cases.md +99 -0
  145. package/skills/multi/soke-course/references/shared.md +185 -0
  146. package/skills/multi/soke-course/references/sop-full-workflow.md +177 -0
  147. package/skills/multi/soke-course/references/sop-lesson-types.md +66 -0
  148. package/skills/multi/soke-course/references/sop-publish-check.md +76 -0
  149. package/skills/multi/soke-course/references/subs/ai/SOP.md +153 -0
  150. package/skills/multi/soke-course/references/subs/category/SOP.md +112 -0
  151. package/skills/multi/soke-course/references/subs/charge/SOP.md +107 -0
  152. package/skills/multi/soke-course/references/subs/copy/SOP.md +80 -0
  153. package/skills/multi/soke-course/references/subs/publish/SOP.md +168 -0
  154. package/skills/multi/soke-course/references/subs/query/SOP.md +165 -0
  155. package/skills/multi/soke-course/references/subs/settings/SOP.md +136 -0
  156. package/skills/multi/soke-course/references/subs/template/SOP.md +223 -0
  157. package/skills/multi/soke-course/references/troubleshoot.md +68 -0
  158. package/skills/multi/soke-course/scripts/check_readiness.py +87 -0
  159. package/skills/multi/soke-exam/SKILL.md +598 -0
  160. package/skills/multi/soke-exam/references/exam-get-exam-user.md +212 -0
  161. package/skills/multi/soke-exam/references/installation.md +451 -0
  162. package/skills/multi/soke-exam/references/shared.md +185 -0
  163. package/skills/multi/soke-exam-question-pool/SKILL.md +121 -0
  164. package/skills/multi/soke-exam-question-pool/references/installation.md +451 -0
  165. package/skills/multi/soke-exam-question-pool/references/shared.md +185 -0
  166. package/skills/multi/soke-learning-map/SKILL.md +553 -0
  167. package/skills/multi/soke-learning-map/references/dependencies/soke-assign.md +103 -0
  168. package/skills/{soke-task/SKILL.md → multi/soke-learning-map/references/dependencies/soke-task.md} +1 -1
  169. package/skills/multi/soke-learning-map/references/installation.md +451 -0
  170. package/skills/multi/soke-learning-map/references/shared.md +185 -0
  171. package/skills/multi/soke-learning-profile/SKILL.md +221 -0
  172. package/skills/multi/soke-learning-profile/references/installation.md +451 -0
  173. package/skills/multi/soke-learning-profile/references/shared.md +185 -0
  174. package/skills/multi/soke-lesson/SKILL.md +117 -0
  175. package/skills/multi/soke-lesson/references/installation.md +451 -0
  176. package/skills/multi/soke-lesson/references/shared.md +185 -0
  177. package/skills/multi/soke-material/SKILL.md +103 -0
  178. package/skills/multi/soke-material/references/installation.md +451 -0
  179. package/skills/multi/soke-material/references/shared.md +185 -0
  180. package/skills/multi/soke-photo-gallery/SKILL.md +284 -0
  181. package/skills/multi/soke-photo-gallery/references/installation.md +451 -0
  182. package/skills/multi/soke-photo-gallery/references/shared.md +185 -0
  183. package/skills/multi/soke-shared/SKILL.md +183 -0
  184. package/skills/multi/soke-supervisor/SKILL.md +184 -0
  185. package/skills/multi/soke-supervisor/references/installation.md +451 -0
  186. package/skills/multi/soke-supervisor/references/shared.md +185 -0
  187. package/skills/multi/soke-task/SKILL.md +144 -0
  188. package/skills/multi/soke-task/references/installation.md +451 -0
  189. package/skills/multi/soke-task/references/shared.md +185 -0
  190. package/skills/multi/soke-training-demand/SKILL.md +219 -0
  191. package/skills/multi/soke-training-demand/references/installation.md +451 -0
  192. package/skills/multi/soke-training-demand/references/shared.md +185 -0
  193. package/skills/soke-course/scripts/check_readiness.sh +0 -82
  194. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/345/256/242/346/210/267/350/247/222/350/211/262/346/250/241/346/235/277/345/272/223.md" +0 -0
  195. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203Bad Case/346/240/267/346/234/254/345/272/223.md" +0 -0
  196. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/345/210/233/345/273/272/351/227/256/351/242/230/345/272/223.md" +0 -0
  197. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/345/234/272/346/231/257/345/210/206/347/261/273/345/272/223.md" +0 -0
  198. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/345/256/242/346/210/267/346/235/220/346/226/231/346/270/205/345/215/225/344/270/216/350/256/277/350/260/210/351/242/230/345/272/223.md" +0 -0
  199. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/345/276/256/350/260/203/351/227/256/351/242/230/345/272/223.md" +0 -0
  200. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/346/212/200/346/234/257/350/276/271/347/225/214/344/270/216/346/216/222/351/232/234/345/272/223.md" +0 -0
  201. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/346/217/220/347/244/272/350/257/215/346/250/241/345/235/227/345/272/223.md" +0 -0
  202. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/346/225/260/346/215/256/346/214/207/346/240/207/344/270/216/347/234/213/346/235/277/345/217/243/345/276/204/345/272/223.md" +0 -0
  203. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/346/265/213/350/257/225/347/224/250/344/276/213/345/272/223.md" +0 -0
  204. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/350/257/204/345/210/206/346/240/207/345/207/206/347/273/204/344/273/266/345/272/223.md" +0 -0
  205. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/231/252/347/273/203/351/241/271/347/233/256/346/241/210/344/276/213/345/244/215/347/233/230/345/272/223.md" +0 -0
  206. /package/skills/{soke-ai-coach-director → mono}/references/cases/AI/351/241/276/345/256/242/350/247/222/350/211/262/346/250/241/346/213/237_GoodCase_BadCase_20260701.md" +0 -0
  207. /package/skills/{soke-ai-coach-director → mono}/references/cases/create//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/224/265/350/257/235/347/272/246/350/256/277//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/345/256/242/346/210/267/346/235/220/346/226/231/346/261/207/346/200/273_2026-05-19_1341.md" +0 -0
  208. /package/skills/{soke-ai-coach-director → mono}/references/cases/create//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267/347/237/245/350/257/206/345/272/223/347/224/237/346/210/220_20260615.md" +0 -0
  209. /package/skills/{soke-ai-coach-director → mono}/references/cases/create//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267//346/226/260/350/203/275/346/272/220/350/275/246/344/270/273/350/264/267/351/231/252/347/273/203/346/217/220/347/244/272/350/257/215/347/224/237/346/210/220_20260615.md" +0 -0
  210. /package/skills/{soke-ai-coach-director → mono}/references/cases/create//346/237/220/345/233/275/351/231/205/346/243/200/346/265/213/346/234/272/346/236/204//346/237/220/345/233/275/351/231/205/346/243/200/346/265/213/346/234/272/346/236/204/351/231/252/347/273/203/346/211/247/350/241/214/346/226/271/346/241/210/344/272/244/344/273/230/350/256/260/345/275/225_20260610.md" +0 -0
  211. /package/skills/{soke-ai-coach-director → mono}/references/cases/create//351/231/214/346/213/234/344/277/241/346/201/257/346/224/266/351/233/206//351/231/214/346/213/234/344/277/241/346/201/257/346/224/266/351/233/206_/346/217/220/347/244/272/350/257/215/346/220/255/345/273/272_20260622.md" +0 -0
  212. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_V1.2_20260616.md" +0 -0
  213. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215_/345/216/213/347/274/251/347/211/210_V2.0_20260616.md" +0 -0
  214. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215/344/274/230/345/214/226_20260616.md" +0 -0
  215. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277AI/351/231/252/347/273/203/347/263/273/347/273/237_/346/265/213/350/257/225/345/217/215/351/246/210/346/261/207/346/200/273_2026-06-01.md" +0 -0
  216. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277KYC/344/277/241/344/273/273/345/200/274/347/246/201/344/273/244_2026-06-09_0932.md" +0 -0
  217. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277KYC/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_v2_20260608.md" +0 -0
  218. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_v1.2.md" +0 -0
  219. /package/skills/{soke-ai-coach-director → mono}/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/346/217/220/347/244/272/350/257/215/344/274/230/345/214/226_V2_/350/257/212/346/226/255/344/272/244/344/273/230_20260609.md" +0 -0
  220. /package/skills/{soke-ai-coach-director → mono}/references/cases//345/233/233/345/244/247/345/234/272/346/231/257_GoodCase_BadCase_20260701.md" +0 -0
  221. /package/skills/{soke-ai-coach-director → mono}/references/cases//346/241/210/344/276/213/345/272/223/350/241/245/345/205/205_2026-06-24.md" +0 -0
  222. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/CHANGELOG.md +0 -0
  223. /package/skills/{soke-ai-coach-director/SKILL.md → mono/references/modules/soke-ai-coach-director/MODULE.md} +0 -0
  224. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/assets/ERRORS-TEMPLATE.md +0 -0
  225. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/assets/FEATURE_REQUESTS-TEMPLATE.md +0 -0
  226. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/assets/LEARNINGS-TEMPLATE.md +0 -0
  227. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/assets/SKILL-TEMPLATE.md +0 -0
  228. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/knowledge-packager/knowledge-packager.md +0 -0
  229. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-engineer/parts/part2-roles.md +0 -0
  230. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-engineer/parts/part3-flow.md +0 -0
  231. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-engineer/parts/part4-scoring.md +0 -0
  232. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-engineer/parts/part5-constraints.md +0 -0
  233. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-engineer/prompt-engineer.md +0 -0
  234. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/prompt-optimizer/prompt-optimizer.md +0 -0
  235. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/coaching/role-profiler/role-profiler.md +0 -0
  236. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/adapters/README.md +0 -0
  237. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/adapters/qclaw.md +0 -0
  238. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/adapters/workbuddy.md +0 -0
  239. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/adapters/wukong.md +0 -0
  240. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/adapters/zework.md +0 -0
  241. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/api-fallback.md +0 -0
  242. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/interaction.md +0 -0
  243. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/resource-finalizer.md +0 -0
  244. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/platform/sync-engine.md +0 -0
  245. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/change-log-partwise-refactor.md +0 -0
  246. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/env-check.md +0 -0
  247. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/exec-common.md +0 -0
  248. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/exec-part2.md +0 -0
  249. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/exec-part3.md +0 -0
  250. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/exec-part4.md +0 -0
  251. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/gate-check-matrix.md +0 -0
  252. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/micro-tune-labels.md +0 -0
  253. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/role-resource-matching.md +0 -0
  254. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/self-improvement-examples.md +0 -0
  255. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/self-learning-engine.md +0 -0
  256. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/subs/part2/SOP.md +0 -0
  257. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/subs/part3/SOP.md +0 -0
  258. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/subs/part4/SOP.md +0 -0
  259. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/subs/publish/SOP.md +0 -0
  260. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/subs/tune/SOP.md +0 -0
  261. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/references/verified-cli-cheatsheet.md +0 -0
  262. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/scripts/activator.sh +0 -0
  263. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/scripts/error-detector.sh +0 -0
  264. /package/skills/{soke-ai-coach-director → mono/references/modules/soke-ai-coach-director}/scripts/extract-skill.sh +0 -0
  265. /package/skills/{soke-assign/SKILL.md → mono/references/modules/soke-assign/MODULE.md} +0 -0
  266. /package/skills/{soke-course → mono/references/modules/soke-course}/agents/openai.yaml +0 -0
  267. /package/skills/{soke-course → mono/references/modules/soke-course}/examples/create-basic.md +0 -0
  268. /package/skills/{soke-course → mono/references/modules/soke-course}/references/course-list-courses.md +0 -0
  269. /package/skills/{soke-course → mono/references/modules/soke-course}/references/intent-cases.md +0 -0
  270. /package/skills/{soke-course → mono/references/modules/soke-course}/references/sop-full-workflow.md +0 -0
  271. /package/skills/{soke-course → mono/references/modules/soke-course}/references/sop-lesson-types.md +0 -0
  272. /package/skills/{soke-course → mono/references/modules/soke-course}/references/sop-publish-check.md +0 -0
  273. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/ai/SOP.md +0 -0
  274. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/category/SOP.md +0 -0
  275. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/charge/SOP.md +0 -0
  276. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/copy/SOP.md +0 -0
  277. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/publish/SOP.md +0 -0
  278. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/query/SOP.md +0 -0
  279. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/settings/SOP.md +0 -0
  280. /package/skills/{soke-course → mono/references/modules/soke-course}/references/subs/template/SOP.md +0 -0
  281. /package/skills/{soke-course → mono/references/modules/soke-course}/references/troubleshoot.md +0 -0
  282. /package/skills/{soke-exam → mono/references/modules/soke-exam}/references/exam-get-exam-user.md +0 -0
  283. /package/skills/{soke-exam-question-pool/SKILL.md → mono/references/modules/soke-exam-question-pool/MODULE.md} +0 -0
  284. /package/skills/{soke-lesson/SKILL.md → mono/references/modules/soke-lesson/MODULE.md} +0 -0
  285. /package/skills/{soke-material/SKILL.md → mono/references/modules/soke-material/MODULE.md} +0 -0
  286. /package/skills/{soke-shared/SKILL.md → mono/references/modules/soke-shared/MODULE.md} +0 -0
  287. /package/skills/{soke-ai-coach-director → mono}/scripts/gate_check.py +0 -0
  288. /package/skills/{soke-ai-coach-director → multi/soke-ai-coach-director}/references/cases/micro-tune//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/347/263/273/345/210/227//344/274/201/344/270/232/345/256/266/347/216/213/346/200/273/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_V1.1_20260616.md" +0 -0
  289. /package/skills/{soke-ai-coach-director → multi/soke-ai-coach-director}/references/cases/micro-tune//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/347/263/273/345/210/227//345/206/234/346/210/267/345/274/240/350/200/201/346/235/277/346/217/220/347/244/272/350/257/215_/344/274/230/345/214/226/347/211/210_v1.1.md" +0 -0
  290. /package/skills/{soke-lesson → multi/soke-lesson}/README.md +0 -0
  291. /package/skills/{soke-material → multi/soke-material}/README.md +0 -0
@@ -0,0 +1,410 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ soke-ai-coach-director · 执行手册验证器
4
+ Usage:
5
+ python3 scripts/validate_operations.py <part> <operations.json>
6
+ python3 scripts/validate_operations.py part1 ./part1-create.json
7
+ python3 scripts/validate_operations.py part2 ./part2-operations.json
8
+ python3 scripts/validate_operations.py part3 ./part3-operations.json
9
+ python3 scripts/validate_operations.py part4 ./part4-operations.json
10
+ python3 scripts/validate_operations.py part5 ./part5-operations.json
11
+
12
+ 退出码:
13
+ 0 = 全部通过
14
+ 1 = 有错误(详情打印到 stderr)
15
+ """
16
+
17
+ import json
18
+ import sys
19
+ import os
20
+ from typing import Any
21
+
22
+
23
+ # ---------- Part1: step1-create.json / part1-create.json ----------
24
+
25
+ def validate_part1(data: dict) -> list[str]:
26
+ """Part1 不是 operations 数组,而是单个 JSON 对象。"""
27
+ errors = []
28
+
29
+ # name
30
+ name = data.get("name")
31
+ if not isinstance(name, str) or not (1 <= len(name) <= 100):
32
+ errors.append(f"name: 必须是 1-100 字符的字符串,当前 type={type(name).__name__} value={name!r}")
33
+
34
+ # description
35
+ desc = data.get("description")
36
+ if not isinstance(desc, str) or len(desc) < 20:
37
+ errors.append(f"description: 必须是 ≥20 字符的字符串,当前 len={len(desc) if isinstance(desc, str) else 0}")
38
+
39
+ # tags
40
+ tags = data.get("tags")
41
+ if not isinstance(tags, list):
42
+ errors.append(f"tags: 必须是数组,当前 type={type(tags).__name__}")
43
+ elif not (3 <= len(tags) <= 5):
44
+ errors.append(f"tags: 必须是 3-5 个元素,当前 {len(tags)}")
45
+ elif not all(isinstance(t, str) and t for t in tags):
46
+ errors.append("tags: 所有元素必须是非空字符串")
47
+
48
+ # key_points: 必须是字符串(最高频错误)
49
+ kp = data.get("key_points")
50
+ if not isinstance(kp, str) or not kp:
51
+ errors.append(f"key_points: 必须是非空字符串(不能是数组),当前 type={type(kp).__name__}")
52
+ # 回查: 如果是数组,提示
53
+ if isinstance(kp, list):
54
+ errors.append("key_points: ❌ 被写成数组,平台会接受但字段为空。改为分号拼接的单字符串")
55
+
56
+ # scene_lang
57
+ if data.get("scene_lang") not in {"zh", "tw", "en"}:
58
+ errors.append(f"scene_lang: 必须是 zh、tw 或 en,当前 {data.get('scene_lang')!r}")
59
+
60
+ # scenario_cover 或 cover_url(CLI 接受两者)
61
+ cover = data.get("scenario_cover") or data.get("cover_url")
62
+ if cover != "https://newsokeeditorcdn.soke.cn/public/ai/cover/lingshou_daogou.png":
63
+ errors.append(f"scenario_cover/cover_url: 必须使用固定默认图 URL,当前 {cover!r}")
64
+
65
+ return errors
66
+
67
+
68
+ # ---------- Part2: operations 数组(update_basic + replace_ai_roles) ----------
69
+
70
+ def validate_part2(operations: list) -> list[str]:
71
+ errors = []
72
+
73
+ for i, op in enumerate(operations):
74
+ if op.get("type") != "update_basic":
75
+ continue
76
+ data = op.get("data", {})
77
+ if "scene_lang" in data and data.get("scene_lang") not in {"zh", "tw", "en"}:
78
+ errors.append(f"operations[{i}].data.scene_lang: 必须是 zh、tw 或 en,当前 {data.get('scene_lang')!r}")
79
+
80
+ # 操作 1: update_basic (OS)
81
+ os_ops = [o for o in operations if o.get("type") == "update_basic"]
82
+ if not os_ops:
83
+ errors.append("❌ 缺操作 1: update_basic(OS 整体设定)—— 会导致平台无 OS,角色行为退化")
84
+ else:
85
+ for op in os_ops:
86
+ os_text = op.get("data", {}).get("ai_roles_overall_description")
87
+ if not isinstance(os_text, str):
88
+ errors.append(f"ai_roles_overall_description: 必须是字符串,当前 type={type(os_text).__name__}")
89
+ elif len(os_text) < 500:
90
+ errors.append(f"ai_roles_overall_description: 必须 ≥500 字符(当前 {len(os_text)}),A1-A7 全文不摘要")
91
+
92
+ # 操作 2: replace_ai_roles
93
+ role_ops = [o for o in operations if o.get("type") == "replace_ai_roles"]
94
+ if not role_ops:
95
+ errors.append("❌ 缺操作 2: replace_ai_roles(角色数据)—— 会导致平台有 OS 无角色")
96
+ else:
97
+ for ri, op in enumerate(role_ops):
98
+ # v2.26: 检测 ai_roles_overall_description 是否被错误放入 replace_ai_roles.data
99
+ wrong_os = op.get("data", {}).get("ai_roles_overall_description")
100
+ if wrong_os is not None:
101
+ errors.append(
102
+ "❌ ai_roles_overall_description 被错误放入 replace_ai_roles.data!"
103
+ "必须移到 update_basic.data 中,否则平台静默丢弃、API 不报错。"
104
+ )
105
+ roles = op.get("data", {}).get("roles")
106
+ if not isinstance(roles, list) or not roles:
107
+ errors.append(f"replace_ai_roles.data.roles: 必须是非空数组")
108
+ continue
109
+ for i, r in enumerate(roles):
110
+ # 外壳字段必须在 role_data 外层(source_type 允许同时存在于两处)
111
+ for shell_field in ["customization_level", "is_custom_role", "customized_fields"]:
112
+ if shell_field not in r:
113
+ errors.append(f"roles[{i}]: 缺外壳字段 {shell_field}(必须在 role_data 外层)")
114
+ # source_type 是特殊情况:顶层必须有,role_data 里可以有也可以没有
115
+ if "source_type" not in r:
116
+ errors.append(f"roles[{i}]: 缺外壳字段 source_type(必须在 role_data 外层)")
117
+
118
+ rd = r.get("role_data", {})
119
+ for k in ["name", "description", "communication_style", "background",
120
+ "personality_type", "personality", "avatar", "voice_id"]:
121
+ if not rd.get(k):
122
+ errors.append(f"roles[{i}].role_data.{k}: 空/缺失")
123
+
124
+ # knowledge_level 必须是数组
125
+ kl = rd.get("knowledge_level")
126
+ if not isinstance(kl, list):
127
+ errors.append(f"roles[{i}].role_data.knowledge_level: 必须是数组(如 ['小白']),当前 type={type(kl).__name__}")
128
+
129
+ # tags 必须是数组 2-4 个
130
+ tags = rd.get("tags")
131
+ if not isinstance(tags, list) or not (2 <= len(tags) <= 4):
132
+ errors.append(f"roles[{i}].role_data.tags: 必须是 2-4 个元素的数组,当前 {tags!r}")
133
+
134
+ # avatar URL 必须在平台头像库中(v2.24.2 新增)
135
+ avatar_url = rd.get("avatar", "")
136
+ if avatar_url and "/public/ai/avatar/" in avatar_url:
137
+ errors.append(f"roles[{i}].role_data.avatar: ❌ URL 路径错误!正确路径是 `/public/ai/roles_avatars/` 不是 `/public/ai/avatar/`(长龙航空事故)")
138
+ elif avatar_url and "/public/ai/roles_avatars/" not in avatar_url and "/public/ai/cover/" not in avatar_url:
139
+ print(f"⚠️ roles[{i}].role_data.avatar: URL 不在平台头像库路径下(/public/ai/roles_avatars/ 或 /public/ai/cover/)", file=sys.stderr)
140
+ to = rd.get("taboos_objections")
141
+ # taboos_objections 必须是数组
142
+ to = rd.get("taboos_objections")
143
+ if not isinstance(to, list):
144
+ errors.append(f"roles[{i}].role_data.taboos_objections: 必须是数组")
145
+
146
+ # background 四段完整性检查(中英文任一全套即通过)
147
+ bg = rd.get("background", "") or ""
148
+ cn_segs = ["我是谁", "我的困扰", "我的过往经历", "我今天的心态"]
149
+ en_segs = ["Who I am", "My concern", "My past experience", "My mindset today"]
150
+ cn_missing = [s for s in cn_segs if s not in bg]
151
+ en_missing = [s for s in en_segs if s not in bg]
152
+ if cn_missing and en_missing:
153
+ for s in cn_missing:
154
+ errors.append(f"roles[{i}].role_data.background: 缺四段画像段落 '{s}'")
155
+
156
+ return errors
157
+
158
+
159
+ # ---------- Part3: operations 数组(update_basic + add_conversation_step) ----------
160
+
161
+ def validate_part3(operations: list) -> list[str]:
162
+ errors = []
163
+
164
+ # 开场语
165
+ open_ops = [o for o in operations if o.get("type") == "update_basic"]
166
+ if not open_ops:
167
+ errors.append("缺 update_basic 操作(开场语)")
168
+ else:
169
+ d = open_ops[0].get("data", {})
170
+ od = d.get("opening_dialogue")
171
+ if not isinstance(od, str) or len(od) < 20:
172
+ errors.append(f"opening_dialogue: 必须 ≥20 字符,当前 len={len(od) if isinstance(od, str) else 0}")
173
+ odt = d.get("opening_dialogue_type")
174
+ if odt != 1:
175
+ errors.append(f"opening_dialogue_type: 必须是数字 1(不是字符串),当前 {odt!r}")
176
+
177
+ # 对话环节
178
+ steps = [o for o in operations if o.get("type") == "add_conversation_step"]
179
+ if not (3 <= len(steps) <= 7):
180
+ errors.append(f"对话环节数: 必须 3-7 个,当前 {len(steps)}")
181
+
182
+ for i, s in enumerate(steps):
183
+ d = s.get("data", {})
184
+ # sort_order 平台自动生成(创建时不传,更新时才传)- 不强制
185
+ for k in ["step_name", "student_objective", "ai_task", "max_rounds"]:
186
+ if d.get(k) in (None, "", []):
187
+ errors.append(f"step[{i}].data.{k}: 空/缺失")
188
+
189
+ # sort_order 如果传了,必须是字符串(平台创建时不传也可以)
190
+ so = d.get("sort_order")
191
+ if so is not None and not isinstance(so, str):
192
+ errors.append(f"step[{i}].sort_order: 必须是字符串(如 '1'),当前 type={type(so).__name__}")
193
+
194
+ # max_rounds 必须是整数 3-10
195
+ mr = d.get("max_rounds")
196
+ if not isinstance(mr, int) or not (3 <= mr <= 10):
197
+ errors.append(f"step[{i}].max_rounds: 必须是 3-10 的整数,当前 {mr!r}")
198
+
199
+ # ai_task 应含条件逻辑(中英文任一)和退出条件
200
+ at = d.get("ai_task", "") or ""
201
+ has_if_logic = any(kw in at for kw in ["IF", "如果", "进入条件", "行为分支"]) or "条件" in at
202
+ has_exit = any(kw in at for kw in ["退出", "结束", "退出条件"])
203
+ if not has_if_logic:
204
+ errors.append(f"step[{i}].ai_task: 缺条件逻辑(IF/进入条件/行为分支/如果)")
205
+ if not has_exit:
206
+ errors.append(f"step[{i}].ai_task: 缺退出条件")
207
+
208
+ # 原子性检查:开场语 + 环节应在同一批 operations
209
+ if open_ops and steps:
210
+ # 这里只能检查是否在同一数组,不能检查是否同一次 apply(由 SKILL.md 约束)
211
+ pass
212
+
213
+ return errors
214
+
215
+
216
+ # ---------- Part4: operations 数组(replace_scoring_criteria_config 双层包装) ----------
217
+
218
+ def validate_part4(operations: list) -> list[str]:
219
+ errors = []
220
+
221
+ p4_ops = [o for o in operations if o.get("type") == "replace_scoring_criteria_config"]
222
+ if not p4_ops:
223
+ errors.append("缺 replace_scoring_criteria_config 操作")
224
+ return errors
225
+
226
+ for ri, op in enumerate(p4_ops):
227
+ config = op.get("data", {}).get("config")
228
+ if not isinstance(config, dict):
229
+ errors.append(f"op[{ri}].data.config: 必须是对象")
230
+ continue
231
+
232
+ # v2.26 硬阻断: shell 字段必须在 config 顶层,不在 criteria_data 内
233
+ cd = config.get("criteria_data") or {}
234
+ SHELL_FIELDS = ["scenario_criteria_id", "customization_level", "is_custom_criteria", "customized_fields"]
235
+ for k in SHELL_FIELDS:
236
+ if k not in config:
237
+ errors.append(f"❌ op[{ri}].data.config.{k}: 缺失(v2.26 硬阻断:shell 字段必须在 config 顶层,否则 UI 不显示评分标准)")
238
+ if k in cd:
239
+ errors.append(
240
+ f"❌ op[{ri}]: shell 字段 {k} 被错误放入 criteria_data 内层!"
241
+ f"必须移到 data.config 顶层。错放会导致 UI 显示「请选择或创建评分标准」空状态,API 不报错。"
242
+ )
243
+
244
+ # 第 2 层 criteria_data 包装(必须存在)
245
+ if not isinstance(cd, dict) or not cd:
246
+ errors.append(f"op[{ri}].data.config.criteria_data: ❌ 缺第 2 层 criteria_data 包装(平台会接受但存储错误)")
247
+ continue
248
+
249
+ # 必填字段(实际影响平台存储和 UI 展示)
250
+ # name/description/dimensions 是 API 硬必填
251
+ for k in ["name", "description", "dimensions"]:
252
+ if cd.get(k) in (None, "", []):
253
+ errors.append(f"op[{ri}].data.config.criteria_data.{k}: 空/缺失(必填)")
254
+ # v2.26: criteria_data 内业务字段硬阻断
255
+ if cd.get("total_weight") not in (100, None):
256
+ errors.append(f"op[{ri}].criteria_data.total_weight: 必须 100,当前 {cd.get('total_weight')!r}")
257
+ for k in ["tags", "source_type", "status"]:
258
+ if k not in cd:
259
+ errors.append(f"op[{ri}].criteria_data.{k}: ❌ 缺失(v2.26 硬阻断)")
260
+ elif k == "tags" and (not isinstance(cd.get(k), list) or len(cd.get(k)) == 0):
261
+ errors.append(f"op[{ri}].criteria_data.tags: 必须是非空数组")
262
+ elif k == "source_type" and cd.get(k) not in ("enterprise", "custom"):
263
+ errors.append(f"op[{ri}].criteria_data.source_type: 必须 'enterprise',当前 {cd.get(k)!r}")
264
+ elif k == "status" and cd.get(k) != 1:
265
+ errors.append(f"op[{ri}].criteria_data.status: 必须 1,当前 {cd.get(k)!r}")
266
+
267
+ if cd.get("source_type") not in ("enterprise", "custom"):
268
+ errors.append(f"op[{ri}].criteria_data.source_type: 应为 'enterprise' 或 'custom',当前 {cd.get('source_type')!r}")
269
+
270
+ # total_weight 是警告不是错误(中文版不加也成功)
271
+ if "total_weight" in cd and cd.get("total_weight") != 100:
272
+ print(f"⚠️ op[{ri}].criteria_data.total_weight: 建议 100,当前 {cd.get('total_weight')!r}", file=sys.stderr)
273
+
274
+ dims = cd.get("dimensions", [])
275
+ if not isinstance(dims, list) or len(dims) < 2:
276
+ errors.append(f"op[{ri}].criteria_data.dimensions: 必须 ≥2 个维度")
277
+ else:
278
+ weight_sum = sum(d.get("weight", 0) for d in dims)
279
+ if weight_sum != 100:
280
+ errors.append(f"op[{ri}].dimensions weight sum: 必须 100,当前 {weight_sum}")
281
+
282
+ for i, d in enumerate(dims):
283
+ # 硬必填(API + UI)
284
+ for k in ["id", "code", "name", "weight", "scoring_rule", "criteria", "sort_order"]:
285
+ if d.get(k) in (None, "", []):
286
+ errors.append(f"op[{ri}].dimensions[{i}].{k}: 空/缺失(必填)")
287
+ # description 建议字段
288
+ if "description" not in d or d.get("description") in (None, "", []):
289
+ print(f"⚠️ op[{ri}].dimensions[{i}].description: 建议字段", file=sys.stderr)
290
+
291
+ # sort_order 必须是数字
292
+ so = d.get("sort_order")
293
+ if not isinstance(so, int):
294
+ errors.append(f"op[{ri}].dimensions[{i}].sort_order: 必须是数字(不是字符串),当前 type={type(so).__name__}")
295
+
296
+ # criteria 至少 2 个
297
+ crit = d.get("criteria", [])
298
+ if not isinstance(crit, list) or len(crit) < 2:
299
+ errors.append(f"op[{ri}].dimensions[{i}].criteria: 至少 2 个评分点")
300
+
301
+ # code 必须是英文
302
+ code = d.get("code", "")
303
+ if code and not code.isascii():
304
+ errors.append(f"op[{ri}].dimensions[{i}].code: 必须是英文,当前 {code!r}")
305
+
306
+ return errors
307
+
308
+
309
+ # ---------- Part5: operations 数组(update_basic 6 项固定配置) ----------
310
+
311
+ def validate_part5(operations: list) -> list[str]:
312
+ errors = []
313
+
314
+ ops = [o for o in operations if o.get("type") == "update_basic"]
315
+ if not ops:
316
+ errors.append("缺 update_basic 操作")
317
+ return errors
318
+
319
+ d = ops[0].get("data", {})
320
+ # Part5 固定配置(以平台实际接受值为准)
321
+ # min/max_practice_duration 平台允许 0 或正整数(0=不限)
322
+ # max_practice_attempts=10, passing_score=60, completion_rule=all_steps 是平台默认值
323
+ checks = {
324
+ "max_practice_attempts": (lambda v: isinstance(v, int) and v > 0, "正整数"),
325
+ "passing_score": (lambda v: isinstance(v, int) and 0 < v <= 100, "1-100 整数"),
326
+ "completion_rule": (lambda v: v == "all_steps", "'all_steps'"),
327
+ "pass_difficulty": (lambda v: isinstance(v, int) and 1 <= v <= 3, "1-3 整数"),
328
+ }
329
+ for k, (check, hint) in checks.items():
330
+ actual = d.get(k)
331
+ if actual is None:
332
+ errors.append(f"{k}: 缺失(Part5 必填)")
333
+ elif not check(actual):
334
+ errors.append(f"{k}: 必须为 {hint},当前 {actual!r}")
335
+ # ai_assistance_enabled 应为 True
336
+ if d.get("ai_assistance_enabled") is not True:
337
+ errors.append(f"ai_assistance_enabled: 必须为 True,当前 {d.get('ai_assistance_enabled')!r}")
338
+ # 禁止字段(已在 Part1/Part3 同步过)
339
+ for forbidden in ["opening_dialogue", "opening_dialogue_type", "key_points", "name", "description", "tags", "scenario_cover"]:
340
+ if forbidden in d:
341
+ errors.append(f"{forbidden}: ❌ Part5 不应同步此字段(已在 Part1 同步)")
342
+
343
+ return errors
344
+
345
+
346
+ # ---------- 入口 ----------
347
+
348
+ def load_json(path: str) -> Any:
349
+ with open(path, "r", encoding="utf-8") as f:
350
+ return json.load(f)
351
+
352
+
353
+ def main() -> int:
354
+ if len(sys.argv) != 3:
355
+ print(__doc__, file=sys.stderr)
356
+ return 2
357
+
358
+ part = sys.argv[1].lower().strip()
359
+ path = sys.argv[2]
360
+
361
+ if not os.path.isfile(path):
362
+ print(f"❌ 文件不存在: {path}", file=sys.stderr)
363
+ return 2
364
+
365
+ try:
366
+ data = load_json(path)
367
+ except json.JSONDecodeError as e:
368
+ print(f"❌ JSON 解析失败: {e}", file=sys.stderr)
369
+ return 2
370
+
371
+ validators = {
372
+ "part1": (validate_part1, "dict"),
373
+ "part2": (validate_part2, "list"),
374
+ "part3": (validate_part3, "list"),
375
+ "part4": (validate_part4, "list"),
376
+ "part5": (validate_part5, "list"),
377
+ }
378
+
379
+ if part not in validators:
380
+ print(f"❌ 未知 part: {part},支持: {list(validators.keys())}", file=sys.stderr)
381
+ return 2
382
+
383
+ func, expected_type = validators[part]
384
+ if expected_type == "dict" and not isinstance(data, dict):
385
+ print(f"❌ {part} 期望 JSON 对象,实际 {type(data).__name__}", file=sys.stderr)
386
+ return 1
387
+ # 支持两种格式:
388
+ # 1. 纯 operations 数组 [...]
389
+ # 2. CLI request-file 对象 {operations: [...], idempotency_key, ...}
390
+ if expected_type == "list":
391
+ if isinstance(data, dict) and "operations" in data:
392
+ data = data["operations"]
393
+ if not isinstance(data, list):
394
+ print(f"❌ {part} 期望 JSON 数组或 {{operations:[...]}} 对象,实际 {type(data).__name__}", file=sys.stderr)
395
+ return 1
396
+
397
+ errors = func(data)
398
+
399
+ if not errors:
400
+ print(f"✅ {part} 验证通过({len(errors)} 个错误)")
401
+ return 0
402
+ else:
403
+ print(f"❌ {part} 验证失败({len(errors)} 个错误):", file=sys.stderr)
404
+ for e in errors:
405
+ print(f" - {e}", file=sys.stderr)
406
+ return 1
407
+
408
+
409
+ if __name__ == "__main__":
410
+ sys.exit(main())
@@ -11,7 +11,7 @@ metadata:
11
11
 
12
12
  # AI教练知识包与场景管理
13
13
 
14
- **CRITICAL — 开始前 MUST 先读取 [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md),其中包含认证、配置和权限处理。**
14
+ **CRITICAL — 开始前 MUST 先读取 [`../soke-shared/MODULE.md`](../soke-shared/MODULE.md),其中包含认证、配置和权限处理。**
15
15
 
16
16
  ## 使用前提
17
17
 
@@ -91,6 +91,8 @@ soke-cli ai-training +get-plan --scenario-id scenario_micro_loan_sales --format
91
91
 
92
92
  ### 创建场景
93
93
 
94
+ `scene_lang` 是场景语言代码,合法值仅有 `zh`(简体中文)、`tw`(繁体中文)和 `en`(英文)。CLI flags 与 `--request-file` 使用同一枚举校验;不要传入 `简体中文`、`中文`、`zh-CN` 或其他值。
95
+
94
96
  如果封面图由本地智能体生成,先上传封面并拿到可写入 `scenario_cover` 的 CDN URL:
95
97
 
96
98
  ```bash