@lemoncat7/dsh-partner 2.8.1 → 2.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (833) hide show
  1. package/docs/THIRD_PARTY_LICENSES.md +10 -0
  2. package/docs/blocked-delivery-recovery.md +7 -0
  3. package/docs/concern-attention.md +19 -0
  4. package/docs/observation-contract.md +21 -0
  5. package/docs/pendant-loading.md +30 -0
  6. package/docs/releases/2.8.2.md +7 -0
  7. package/docs/releases/2.8.3.md +20 -0
  8. package/lib/agent-runtime.d.ts +7 -0
  9. package/lib/agent-runtime.d.ts.map +1 -1
  10. package/lib/agent-runtime.js +119 -35
  11. package/lib/agent-runtime.js.map +1 -1
  12. package/lib/api/features/pendant-api.d.ts.map +1 -1
  13. package/lib/api/features/pendant-api.js +11 -2
  14. package/lib/api/features/pendant-api.js.map +1 -1
  15. package/lib/api.d.ts +1 -0
  16. package/lib/api.d.ts.map +1 -1
  17. package/lib/api.js +41 -6
  18. package/lib/api.js.map +1 -1
  19. package/lib/autonomy.d.ts.map +1 -1
  20. package/lib/autonomy.js +9 -2
  21. package/lib/autonomy.js.map +1 -1
  22. package/lib/channel-message.d.ts +2 -0
  23. package/lib/channel-message.d.ts.map +1 -1
  24. package/lib/channel-message.js.map +1 -1
  25. package/lib/channels/direct/message-format.js +127 -127
  26. package/lib/channels/direct/message-format.js.map +1 -1
  27. package/lib/channels/manager.d.ts.map +1 -1
  28. package/lib/channels/manager.js +4 -3
  29. package/lib/channels/manager.js.map +1 -1
  30. package/lib/channels/notification-delivery.d.ts.map +1 -1
  31. package/lib/channels/notification-delivery.js +10 -0
  32. package/lib/channels/notification-delivery.js.map +1 -1
  33. package/lib/channels/weixin/connect.d.ts.map +1 -1
  34. package/lib/client-api.d.ts +17 -2
  35. package/lib/client-api.d.ts.map +1 -1
  36. package/lib/client-api.js +8 -1
  37. package/lib/client-api.js.map +1 -1
  38. package/lib/client.d.ts.map +1 -1
  39. package/lib/client.js +2398 -1970
  40. package/lib/client.js.map +4 -4
  41. package/lib/client.pendant.js +4157 -0
  42. package/lib/collaboration/composition.js +1 -1
  43. package/lib/collaboration/composition.js.map +1 -1
  44. package/lib/concern-attention.d.ts +19 -0
  45. package/lib/concern-attention.d.ts.map +1 -0
  46. package/lib/concern-attention.js +36 -0
  47. package/lib/concern-attention.js.map +1 -0
  48. package/lib/concern-domain.d.ts +10 -1
  49. package/lib/concern-domain.d.ts.map +1 -1
  50. package/lib/concern-domain.js +4 -0
  51. package/lib/concern-domain.js.map +1 -1
  52. package/lib/concern-execution-notes.d.ts +18 -0
  53. package/lib/concern-execution-notes.d.ts.map +1 -0
  54. package/lib/concern-execution-notes.js +41 -0
  55. package/lib/concern-execution-notes.js.map +1 -0
  56. package/lib/concern-execution-receipt.d.ts +4 -0
  57. package/lib/concern-execution-receipt.d.ts.map +1 -0
  58. package/lib/concern-execution-receipt.js +28 -0
  59. package/lib/concern-execution-receipt.js.map +1 -0
  60. package/lib/concern-execution.d.ts +32 -0
  61. package/lib/concern-execution.d.ts.map +1 -0
  62. package/lib/concern-execution.js +112 -0
  63. package/lib/concern-execution.js.map +1 -0
  64. package/lib/concern-management-tool.d.ts.map +1 -1
  65. package/lib/concern-management-tool.js +21 -19
  66. package/lib/concern-management-tool.js.map +1 -1
  67. package/lib/concern-note-source.d.ts +7 -0
  68. package/lib/concern-note-source.d.ts.map +1 -0
  69. package/lib/concern-note-source.js +25 -0
  70. package/lib/concern-note-source.js.map +1 -0
  71. package/lib/concern-resources.d.ts +27 -0
  72. package/lib/concern-resources.d.ts.map +1 -0
  73. package/lib/concern-resources.js +36 -0
  74. package/lib/concern-resources.js.map +1 -0
  75. package/lib/concern-sources.d.ts +1 -1
  76. package/lib/concern-sources.d.ts.map +1 -1
  77. package/lib/concern-store.d.ts +10 -1
  78. package/lib/concern-store.d.ts.map +1 -1
  79. package/lib/concern-store.js +135 -36
  80. package/lib/concern-store.js.map +1 -1
  81. package/lib/concern-tool.d.ts +1 -0
  82. package/lib/concern-tool.d.ts.map +1 -1
  83. package/lib/concern-tool.js +8 -4
  84. package/lib/concern-tool.js.map +1 -1
  85. package/lib/decision/conversation.d.ts +11 -0
  86. package/lib/decision/conversation.d.ts.map +1 -0
  87. package/lib/decision/conversation.js +52 -0
  88. package/lib/decision/conversation.js.map +1 -0
  89. package/lib/decision/events.d.ts +16 -0
  90. package/lib/decision/events.d.ts.map +1 -0
  91. package/lib/decision/events.js +9 -0
  92. package/lib/decision/events.js.map +1 -0
  93. package/lib/domain.d.ts +2 -0
  94. package/lib/domain.d.ts.map +1 -1
  95. package/lib/domain.js.map +1 -1
  96. package/lib/heartbeat.d.ts +12 -10
  97. package/lib/heartbeat.d.ts.map +1 -1
  98. package/lib/heartbeat.js +55 -26
  99. package/lib/heartbeat.js.map +1 -1
  100. package/lib/index.d.ts.map +1 -1
  101. package/lib/index.js +4 -1
  102. package/lib/index.js.map +1 -1
  103. package/lib/memory-prompt-context.js +1 -0
  104. package/lib/memory-prompt-context.js.map +1 -1
  105. package/lib/memory-reflection.js +1 -1
  106. package/lib/observation-contract.d.ts +9 -0
  107. package/lib/observation-contract.d.ts.map +1 -0
  108. package/lib/observation-contract.js +19 -0
  109. package/lib/observation-contract.js.map +1 -0
  110. package/lib/observation-executor.d.ts +5 -0
  111. package/lib/observation-executor.d.ts.map +1 -1
  112. package/lib/observation-executor.js +23 -1
  113. package/lib/observation-executor.js.map +1 -1
  114. package/lib/observation-loop.d.ts +7 -0
  115. package/lib/observation-loop.d.ts.map +1 -1
  116. package/lib/observation-loop.js +65 -4
  117. package/lib/observation-loop.js.map +1 -1
  118. package/lib/observation-progress.d.ts +18 -0
  119. package/lib/observation-progress.d.ts.map +1 -0
  120. package/lib/observation-progress.js +57 -0
  121. package/lib/observation-progress.js.map +1 -0
  122. package/lib/observation-sources.d.ts +14 -0
  123. package/lib/observation-sources.d.ts.map +1 -0
  124. package/lib/observation-sources.js +12 -0
  125. package/lib/observation-sources.js.map +1 -0
  126. package/lib/pendant/badge-art.d.ts +9 -0
  127. package/lib/pendant/badge-art.d.ts.map +1 -0
  128. package/lib/pendant/badge-art.js +68 -0
  129. package/lib/pendant/badge-art.js.map +1 -0
  130. package/lib/pendant/card-image.d.ts.map +1 -1
  131. package/lib/pendant/card-image.js +11 -9
  132. package/lib/pendant/card-image.js.map +1 -1
  133. package/lib/pendant/renderer-loader.d.ts +9 -0
  134. package/lib/pendant/renderer-loader.d.ts.map +1 -0
  135. package/lib/pendant/renderer-loader.js +12 -0
  136. package/lib/pendant/renderer-loader.js.map +1 -0
  137. package/lib/pendant/renderer.d.ts +2 -6
  138. package/lib/pendant/renderer.d.ts.map +1 -1
  139. package/lib/pendant/renderer.js +1 -67
  140. package/lib/pendant/renderer.js.map +1 -1
  141. package/lib/pendant/static-card.d.ts +20 -0
  142. package/lib/pendant/static-card.d.ts.map +1 -0
  143. package/lib/pendant/static-card.js +55 -0
  144. package/lib/pendant/static-card.js.map +1 -0
  145. package/lib/pendant/widget.d.ts.map +1 -1
  146. package/lib/pendant/widget.js +9 -5
  147. package/lib/pendant/widget.js.map +1 -1
  148. package/lib/pendant-renderer.js +14 -14
  149. package/lib/requirements/service.d.ts.map +1 -1
  150. package/lib/requirements/service.js +2 -0
  151. package/lib/requirements/service.js.map +1 -1
  152. package/lib/requirements/worker.d.ts.map +1 -1
  153. package/lib/requirements/worker.js +1 -0
  154. package/lib/requirements/worker.js.map +1 -1
  155. package/lib/scheduler/continuations.d.ts.map +1 -1
  156. package/lib/scheduler/continuations.js +17 -3
  157. package/lib/scheduler/continuations.js.map +1 -1
  158. package/lib/skills/builtin.d.ts.map +1 -1
  159. package/lib/skills/builtin.js +2 -0
  160. package/lib/skills/builtin.js.map +1 -1
  161. package/lib/skills/drama-builtin.d.ts.map +1 -1
  162. package/lib/skills/drama-builtin.js +13 -1
  163. package/lib/skills/drama-builtin.js.map +1 -1
  164. package/lib/skills/story-builtins.d.ts +3 -0
  165. package/lib/skills/story-builtins.d.ts.map +1 -0
  166. package/lib/skills/story-builtins.js +72 -0
  167. package/lib/skills/story-builtins.js.map +1 -0
  168. package/lib/skills/viora-canvas-builtin.d.ts.map +1 -1
  169. package/lib/skills/viora-canvas-builtin.js +12 -1
  170. package/lib/skills/viora-canvas-builtin.js.map +1 -1
  171. package/lib/snapshot-cache.d.ts +7 -0
  172. package/lib/snapshot-cache.d.ts.map +1 -0
  173. package/lib/snapshot-cache.js +26 -0
  174. package/lib/snapshot-cache.js.map +1 -0
  175. package/lib/tasks/result.js +1 -1
  176. package/lib/tasks/result.js.map +1 -1
  177. package/lib/ui/memory/concern-board.d.ts +1 -1
  178. package/lib/ui/memory/concern-board.d.ts.map +1 -1
  179. package/lib/ui/memory/concern-board.js +14 -6
  180. package/lib/ui/memory/concern-board.js.map +1 -1
  181. package/lib/ui/memory/concern-deletion.d.ts.map +1 -1
  182. package/lib/ui/memory/concern-deletion.js +2 -1
  183. package/lib/ui/memory/concern-deletion.js.map +1 -1
  184. package/lib/ui/memory/concern-editor.d.ts.map +1 -1
  185. package/lib/ui/memory/concern-editor.js +5 -3
  186. package/lib/ui/memory/concern-editor.js.map +1 -1
  187. package/lib/ui/memory/concern-execution-fields.d.ts +7 -0
  188. package/lib/ui/memory/concern-execution-fields.d.ts.map +1 -0
  189. package/lib/ui/memory/concern-execution-fields.js +8 -0
  190. package/lib/ui/memory/concern-execution-fields.js.map +1 -0
  191. package/lib/ui/memory/concern-execution-status.d.ts +8 -0
  192. package/lib/ui/memory/concern-execution-status.d.ts.map +1 -0
  193. package/lib/ui/memory/concern-execution-status.js +31 -0
  194. package/lib/ui/memory/concern-execution-status.js.map +1 -0
  195. package/lib/ui/memory/concern-feedback.d.ts +15 -0
  196. package/lib/ui/memory/concern-feedback.d.ts.map +1 -0
  197. package/lib/ui/memory/concern-feedback.js +13 -0
  198. package/lib/ui/memory/concern-feedback.js.map +1 -0
  199. package/lib/ui/memory/concern-panel.d.ts.map +1 -1
  200. package/lib/ui/memory/concern-panel.js +11 -3
  201. package/lib/ui/memory/concern-panel.js.map +1 -1
  202. package/package.json +7 -1
  203. package/resources/skills/novel-game-creation/manifest.json +393 -0
  204. package/resources/skills/novel-game-creation/upstream/LICENSE +21 -0
  205. package/resources/skills/novel-game-creation/upstream/README.md +420 -0
  206. package/resources/skills/novel-game-creation/upstream/README_ZH.md +421 -0
  207. package/resources/skills/novel-game-creation/upstream/VERSION +1 -0
  208. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/BUILD_BRIEF.md +219 -0
  209. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/.vercelignore +3 -0
  210. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/RUN.md +138 -0
  211. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/bg/compound_new_guofeng.webp +0 -0
  212. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/finale/fate_coda.webp +0 -0
  213. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/finale/meng.webp +0 -0
  214. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/finale/pan.webp +0 -0
  215. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/finale/pinger.webp +0 -0
  216. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/finale/xuee.webp +0 -0
  217. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/finale/yue.webp +0 -0
  218. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_accord_five.webp +0 -0
  219. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_afterglow_five.webp +0 -0
  220. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_alliance.webp +0 -0
  221. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/public_day10.webp +0 -0
  222. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/public_day15.webp +0 -0
  223. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/public_day5.webp +0 -0
  224. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/group/title_new_guofeng.webp +0 -0
  225. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/joint/pan_pinger.webp +0 -0
  226. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/joint/pan_xuee.webp +0 -0
  227. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/joint/yue_meng.webp +0 -0
  228. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/joint/yue_pan.webp +0 -0
  229. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/joint/yue_pinger.webp +0 -0
  230. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/meng/explicit.webp +0 -0
  231. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/meng/prelude.webp +0 -0
  232. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/milestone/meng.webp +0 -0
  233. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/milestone/pan.webp +0 -0
  234. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/milestone/pinger.webp +0 -0
  235. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/milestone/xuee.webp +0 -0
  236. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/milestone/yue.webp +0 -0
  237. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/pan/explicit.webp +0 -0
  238. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/pan/prelude.webp +0 -0
  239. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/pinger/explicit.webp +0 -0
  240. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/pinger/prelude.webp +0 -0
  241. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/xuee/explicit.webp +0 -0
  242. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/xuee/prelude.webp +0 -0
  243. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/yue/explicit.webp +0 -0
  244. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/cg/yue/prelude.webp +0 -0
  245. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/heroine/meng/night.webp +0 -0
  246. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/heroine/pan/night.webp +0 -0
  247. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/heroine/pinger/night.webp +0 -0
  248. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/heroine/xuee/night.webp +0 -0
  249. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/heroine/yue/night.webp +0 -0
  250. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/household/li_jiaoer.webp +0 -0
  251. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/assets/scene/gate_collector.webp +0 -0
  252. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/css/new-guofeng.css +1494 -0
  253. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/css/style.css +2508 -0
  254. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/index.html +18 -0
  255. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/js/assets.js +147 -0
  256. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/js/audio.js +332 -0
  257. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/js/data.js +7470 -0
  258. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/js/engine.js +13066 -0
  259. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/js/main.js +3051 -0
  260. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/js/text.js +32 -0
  261. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/package.json +11 -0
  262. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/app/vercel.json +23 -0
  263. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/build/art/generated-art.json +161 -0
  264. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/example.json +12 -0
  265. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/qa/README.md +26 -0
  266. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/qa/playable-model.json +99 -0
  267. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/qa/verification.json +41 -0
  268. package/resources/skills/novel-game-creation/upstream/examples/jin-ping-mei/qa/verify_playable_model.mjs +152 -0
  269. package/resources/skills/novel-game-creation/upstream/manifest.json +498 -0
  270. package/resources/skills/novel-game-creation/upstream/skills/game-art-direction/SKILL.md +47 -0
  271. package/resources/skills/novel-game-creation/upstream/skills/game-art-direction/agents/openai.yaml +4 -0
  272. package/resources/skills/novel-game-creation/upstream/skills/game-art-direction/references/art-direction-method.md +40 -0
  273. package/resources/skills/novel-game-creation/upstream/skills/game-build/SKILL.md +66 -0
  274. package/resources/skills/novel-game-creation/upstream/skills/game-build/agents/openai.yaml +4 -0
  275. package/resources/skills/novel-game-creation/upstream/skills/game-build/references/blender-asset-workflow.md +24 -0
  276. package/resources/skills/novel-game-creation/upstream/skills/game-build/references/build-brief-contract.md +72 -0
  277. package/resources/skills/novel-game-creation/upstream/skills/game-build/references/generative-media-pipeline.md +25 -0
  278. package/resources/skills/novel-game-creation/upstream/skills/game-build/references/playable-model-contract.md +46 -0
  279. package/resources/skills/novel-game-creation/upstream/skills/game-build/references/tts-production-contract.md +23 -0
  280. package/resources/skills/novel-game-creation/upstream/skills/game-concept/SKILL.md +54 -0
  281. package/resources/skills/novel-game-creation/upstream/skills/game-concept/agents/openai.yaml +4 -0
  282. package/resources/skills/novel-game-creation/upstream/skills/game-concept/references/concept-method.md +47 -0
  283. package/resources/skills/novel-game-creation/upstream/skills/game-qa/SKILL.md +39 -0
  284. package/resources/skills/novel-game-creation/upstream/skills/game-qa/agents/openai.yaml +4 -0
  285. package/resources/skills/novel-game-creation/upstream/skills/game-qa/references/qa-contract.md +66 -0
  286. package/resources/skills/novel-game-creation/upstream/skills/game-qa/references/test-design-method.md +49 -0
  287. package/resources/skills/novel-game-creation/upstream/skills/game-world-design/SKILL.md +50 -0
  288. package/resources/skills/novel-game-creation/upstream/skills/game-world-design/agents/openai.yaml +4 -0
  289. package/resources/skills/novel-game-creation/upstream/skills/game-world-design/references/narrative-design-method.md +35 -0
  290. package/resources/skills/novel-game-creation/upstream/skills/game-world-design/references/numeric-design-method.md +22 -0
  291. package/resources/skills/novel-game-creation/upstream/skills/game-world-design/references/world-design-method.md +57 -0
  292. package/resources/skills/novel-game-creation/upstream/skills/novel-game-analyze/SKILL.md +68 -0
  293. package/resources/skills/novel-game-creation/upstream/skills/novel-game-analyze/agents/openai.yaml +4 -0
  294. package/resources/skills/novel-game-creation/upstream/skills/novel-game-analyze/references/gameability-protocol.md +65 -0
  295. package/resources/skills/novel-game-creation/upstream/skills/novel-to-game/SKILL.md +54 -0
  296. package/resources/skills/novel-game-creation/upstream/skills/novel-to-game/agents/openai.yaml +4 -0
  297. package/resources/skills/novel-game-creation/upstream/skills/novel-to-game/references/intake-method.md +50 -0
  298. package/resources/skills/novel-game-creation/upstream/skills/novel-to-game/references/pipeline-contract.md +60 -0
  299. package/resources/skills/story-creation/manifest.json +1477 -0
  300. package/resources/skills/story-creation/upstream/LICENSE.upstream +21 -0
  301. package/resources/skills/story-creation/upstream/manifest.json +1861 -0
  302. package/resources/skills/story-creation/upstream/roles/chapter-extractor.md +254 -0
  303. package/resources/skills/story-creation/upstream/roles/character-designer.md +168 -0
  304. package/resources/skills/story-creation/upstream/roles/consistency-checker.md +192 -0
  305. package/resources/skills/story-creation/upstream/roles/narrative-writer.md +105 -0
  306. package/resources/skills/story-creation/upstream/roles/story-architect.md +139 -0
  307. package/resources/skills/story-creation/upstream/roles/story-explorer.md +262 -0
  308. package/resources/skills/story-creation/upstream/roles/story-researcher.md +303 -0
  309. package/resources/skills/story-creation/upstream/skills/browser-cdp/SKILL.md +175 -0
  310. package/resources/skills/story-creation/upstream/skills/story/SKILL.md +129 -0
  311. package/resources/skills/story-creation/upstream/skills/story/VERSION +1 -0
  312. package/resources/skills/story-creation/upstream/skills/story/references/author-memory-maintenance.md +75 -0
  313. package/resources/skills/story-creation/upstream/skills/story/references/author-memory.md +117 -0
  314. package/resources/skills/story-creation/upstream/skills/story/scripts/author_memory_commit.py +1635 -0
  315. package/resources/skills/story-creation/upstream/skills/story-cover/SKILL.md +336 -0
  316. package/resources/skills/story-creation/upstream/skills/story-cover/references/cover-styles.md +210 -0
  317. package/resources/skills/story-creation/upstream/skills/story-deslop/SKILL.md +274 -0
  318. package/resources/skills/story-creation/upstream/skills/story-deslop/references/agent-calls.md +5 -0
  319. package/resources/skills/story-creation/upstream/skills/story-deslop/references/anti-ai-writing.md +556 -0
  320. package/resources/skills/story-creation/upstream/skills/story-deslop/references/author-memory-maintenance.md +75 -0
  321. package/resources/skills/story-creation/upstream/skills/story-deslop/references/author-memory.md +117 -0
  322. package/resources/skills/story-creation/upstream/skills/story-deslop/references/banned-words.md +151 -0
  323. package/resources/skills/story-creation/upstream/skills/story-deslop/references/deslop-gates.md +171 -0
  324. package/resources/skills/story-creation/upstream/skills/story-deslop/references/style-resolution.md +27 -0
  325. package/resources/skills/story-creation/upstream/skills/story-deslop/scripts/author_memory_commit.py +1635 -0
  326. package/resources/skills/story-creation/upstream/skills/story-deslop/scripts/check-ai-patterns.js +1586 -0
  327. package/resources/skills/story-creation/upstream/skills/story-deslop/scripts/check-degeneration.js +349 -0
  328. package/resources/skills/story-creation/upstream/skills/story-deslop/scripts/normalize-punctuation.js +415 -0
  329. package/resources/skills/story-creation/upstream/skills/story-deslop/scripts/style-whitelist.js +39 -0
  330. package/resources/skills/story-creation/upstream/skills/story-import/SKILL.md +127 -0
  331. package/resources/skills/story-creation/upstream/skills/story-import/references/character-state-reverse.md +82 -0
  332. package/resources/skills/story-creation/upstream/skills/story-import/references/deep-analysis.md +47 -0
  333. package/resources/skills/story-creation/upstream/skills/story-import/references/format-and-structure.md +168 -0
  334. package/resources/skills/story-creation/upstream/skills/story-import/references/import-report.md +64 -0
  335. package/resources/skills/story-creation/upstream/skills/story-import/references/import-special-cases.md +34 -0
  336. package/resources/skills/story-creation/upstream/skills/story-import/references/import-tracking.md +95 -0
  337. package/resources/skills/story-creation/upstream/skills/story-import/references/length-routing.md +134 -0
  338. package/resources/skills/story-creation/upstream/skills/story-import/references/outline-reverse-rules.md +79 -0
  339. package/resources/skills/story-creation/upstream/skills/story-import/references/outline-reverse.md +24 -0
  340. package/resources/skills/story-creation/upstream/skills/story-import/references/state-tracking.md +43 -0
  341. package/resources/skills/story-creation/upstream/skills/story-import/references/structure-mapping-long.md +448 -0
  342. package/resources/skills/story-creation/upstream/skills/story-import/references/structure-mapping-short.md +187 -0
  343. package/resources/skills/story-creation/upstream/skills/story-import/references/tracking-initialization.md +31 -0
  344. package/resources/skills/story-creation/upstream/skills/story-import/references/tracking-transaction.md +146 -0
  345. package/resources/skills/story-creation/upstream/skills/story-import/scripts/build_outline_brief.py +332 -0
  346. package/resources/skills/story-creation/upstream/skills/story-import/scripts/check-outline-contract.js +520 -0
  347. package/resources/skills/story-creation/upstream/skills/story-import/scripts/tracking_commit.py +1691 -0
  348. package/resources/skills/story-creation/upstream/skills/story-import/scripts/wordcount_core.py +405 -0
  349. package/resources/skills/story-creation/upstream/skills/story-long-analyze/SKILL.md +140 -0
  350. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/author-facing.md +252 -0
  351. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/deconstruction-notes.md +270 -0
  352. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/final-checks.md +19 -0
  353. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/index-rebuild.md +11 -0
  354. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/inspiration-library.md +105 -0
  355. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/pipeline-ops.md +154 -0
  356. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
  357. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
  358. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/stage2-extraction.md +229 -0
  359. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
  360. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
  361. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/stage5-report.md +33 -0
  362. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/style-profile-generator.md +76 -0
  363. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/style-profile-protocol.md +133 -0
  364. package/resources/skills/story-creation/upstream/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
  365. package/resources/skills/story-creation/upstream/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
  366. package/resources/skills/story-creation/upstream/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
  367. package/resources/skills/story-creation/upstream/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
  368. package/resources/skills/story-creation/upstream/skills/story-long-analyze/scripts/manage_analysis_run.py +1145 -0
  369. package/resources/skills/story-creation/upstream/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
  370. package/resources/skills/story-creation/upstream/skills/story-long-scan/SKILL.md +193 -0
  371. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/genre-trends.md +197 -0
  372. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/platform-ciweimao.md +19 -0
  373. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/platform-fanqie.md +45 -0
  374. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/platform-jjwxc.md +28 -0
  375. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/platform-qidian.md +35 -0
  376. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/platform-qimao.md +27 -0
  377. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/publishing-guide.md +114 -0
  378. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/reader-profiling.md +105 -0
  379. package/resources/skills/story-creation/upstream/skills/story-long-scan/references/topic-decision.md +82 -0
  380. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/aggregate-rank.js +682 -0
  381. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/cdp-utils.js +242 -0
  382. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/ciweimao-rank-scraper.js +240 -0
  383. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/fanqie-rank-scraper.js +658 -0
  384. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/jjwxc-rank-scraper.js +400 -0
  385. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/qidian-rank-scraper.js +592 -0
  386. package/resources/skills/story-creation/upstream/skills/story-long-scan/scripts/qimao-rank-scraper.js +435 -0
  387. package/resources/skills/story-creation/upstream/skills/story-long-write/SKILL.md +136 -0
  388. package/resources/skills/story-creation/upstream/skills/story-long-write/references/agent-calls.md +47 -0
  389. package/resources/skills/story-creation/upstream/skills/story-long-write/references/anti-ai-writing.md +556 -0
  390. package/resources/skills/story-creation/upstream/skills/story-long-write/references/artifact-protocols.md +183 -0
  391. package/resources/skills/story-creation/upstream/skills/story-long-write/references/author-memory-maintenance.md +75 -0
  392. package/resources/skills/story-creation/upstream/skills/story-long-write/references/author-memory.md +117 -0
  393. package/resources/skills/story-creation/upstream/skills/story-long-write/references/banned-words.md +151 -0
  394. package/resources/skills/story-creation/upstream/skills/story-long-write/references/benchmark-recall.md +16 -0
  395. package/resources/skills/story-creation/upstream/skills/story-long-write/references/character-basics.md +445 -0
  396. package/resources/skills/story-creation/upstream/skills/story-long-write/references/character-design-methods.md +428 -0
  397. package/resources/skills/story-creation/upstream/skills/story-long-write/references/character-relations.md +433 -0
  398. package/resources/skills/story-creation/upstream/skills/story-long-write/references/commercial-core-methods.md +502 -0
  399. package/resources/skills/story-creation/upstream/skills/story-long-write/references/cross-book-recall.md +88 -0
  400. package/resources/skills/story-creation/upstream/skills/story-long-write/references/deslop-gates.md +171 -0
  401. package/resources/skills/story-creation/upstream/skills/story-long-write/references/dialogue-mastery.md +288 -0
  402. package/resources/skills/story-creation/upstream/skills/story-long-write/references/emotion-on-page.md +116 -0
  403. package/resources/skills/story-creation/upstream/skills/story-long-write/references/emotional-arc-design.md +313 -0
  404. package/resources/skills/story-creation/upstream/skills/story-long-write/references/emotional-methods.md +209 -0
  405. package/resources/skills/story-creation/upstream/skills/story-long-write/references/female-audience-writing.md +188 -0
  406. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//344/270/234/346/226/271/344/273/231/344/276/240.md +51 -0
  407. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//344/274/240/347/273/237/347/216/204/345/271/273.md +51 -0
  408. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/216/206/345/217/262/345/217/244/344/273/243.md +51 -0
  409. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/216/206/345/217/262/350/204/221/346/264/236.md +51 -0
  410. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/217/214/347/224/267/344/270/273.md +53 -0
  411. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/217/244/350/250/200/350/204/221/346/264/236.md +51 -0
  412. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/217/244/351/243/216/344/270/226/346/203/205.md +51 -0
  413. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/245/263/351/242/221/346/202/254/347/226/221.md +51 -0
  414. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/245/263/351/242/221/347/247/215/347/224/260.md +51 -0
  415. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/256/253/346/226/227/345/256/205/346/226/227.md +51 -0
  416. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/271/264/344/273/243.md +53 -0
  417. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//345/277/253/347/251/277.md +51 -0
  418. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/202/254/347/226/221/347/201/265/345/274/202.md +51 -0
  419. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/202/254/347/226/221/350/204/221/346/264/236.md +51 -0
  420. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/210/230/347/245/236/350/265/230/345/251/277.md +51 -0
  421. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/212/227/346/210/230/350/260/215/346/210/230.md +51 -0
  422. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/230/237/345/205/211/347/222/200/347/222/250.md +51 -0
  423. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/260/221/345/233/275/350/250/200/346/203/205.md +51 -0
  424. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//346/270/270/346/210/217/344/275/223/350/202/262.md +51 -0
  425. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//347/216/204/345/271/273/350/204/221/346/264/236.md +53 -0
  426. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//347/216/204/345/271/273/350/250/200/346/203/205.md +51 -0
  427. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//347/216/260/350/250/200/350/204/221/346/264/236.md +51 -0
  428. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//347/247/221/345/271/273/346/234/253/344/270/226.md +51 -0
  429. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//350/201/214/345/234/272/345/251/232/346/201/213.md +51 -0
  430. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//350/245/277/346/226/271/345/245/207/345/271/273.md +51 -0
  431. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//350/261/252/351/227/250/346/200/273/350/243/201.md +53 -0
  432. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//351/203/275/345/270/202/344/277/256/347/234/237.md +51 -0
  433. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//351/203/275/345/270/202/346/227/245/345/270/270.md +53 -0
  434. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//351/203/275/345/270/202/347/247/215/347/224/260.md +51 -0
  435. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//351/203/275/345/270/202/350/204/221/346/264/236.md +53 -0
  436. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//351/203/275/345/270/202/351/253/230/346/255/246.md +53 -0
  437. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards//351/235/222/346/230/245/347/224/234/345/256/240.md +51 -0
  438. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-prose-cards.md +91 -0
  439. package/resources/skills/story-creation/upstream/skills/story-long-write/references/genre-readers.md +235 -0
  440. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-chapter-hooks.md +225 -0
  441. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-chapter-quality.md +177 -0
  442. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-format.md +36 -0
  443. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-genre-catalog.md +394 -0
  444. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-genre-mechanics.md +415 -0
  445. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-reversal.md +335 -0
  446. package/resources/skills/story-creation/upstream/skills/story-long-write/references/long-suspense.md +352 -0
  447. package/resources/skills/story-creation/upstream/skills/story-long-write/references/opening-design.md +349 -0
  448. package/resources/skills/story-creation/upstream/skills/story-long-write/references/outline-conflict.md +457 -0
  449. package/resources/skills/story-creation/upstream/skills/story-long-write/references/outline-methods.md +287 -0
  450. package/resources/skills/story-creation/upstream/skills/story-long-write/references/outline-rhythm.md +389 -0
  451. package/resources/skills/story-creation/upstream/skills/story-long-write/references/outline-structure-theory.md +273 -0
  452. package/resources/skills/story-creation/upstream/skills/story-long-write/references/plot-core-methods.md +522 -0
  453. package/resources/skills/story-creation/upstream/skills/story-long-write/references/plot-emotion-system.md +354 -0
  454. package/resources/skills/story-creation/upstream/skills/story-long-write/references/plot-frameworks.md +711 -0
  455. package/resources/skills/story-creation/upstream/skills/story-long-write/references/plot-special-topics.md +622 -0
  456. package/resources/skills/story-creation/upstream/skills/story-long-write/references/project-files.md +114 -0
  457. package/resources/skills/story-creation/upstream/skills/story-long-write/references/reader-contract-and-progression.md +117 -0
  458. package/resources/skills/story-creation/upstream/skills/story-long-write/references/reference-index.md +86 -0
  459. package/resources/skills/story-creation/upstream/skills/story-long-write/references/stop-and-fix.md +9 -0
  460. package/resources/skills/story-creation/upstream/skills/story-long-write/references/style-combat-face.md +352 -0
  461. package/resources/skills/story-creation/upstream/skills/story-long-write/references/style-craft.md +327 -0
  462. package/resources/skills/story-creation/upstream/skills/story-long-write/references/style-genre-modules.md +510 -0
  463. package/resources/skills/story-creation/upstream/skills/story-long-write/references/style-resolution.md +27 -0
  464. package/resources/skills/story-creation/upstream/skills/story-long-write/references/tracking-initialization.md +31 -0
  465. package/resources/skills/story-creation/upstream/skills/story-long-write/references/tracking-transaction.md +146 -0
  466. package/resources/skills/story-creation/upstream/skills/story-long-write/references/workflow-chapter.md +104 -0
  467. package/resources/skills/story-creation/upstream/skills/story-long-write/references/workflow-daily.md +75 -0
  468. package/resources/skills/story-creation/upstream/skills/story-long-write/references/workflow-outline.md +157 -0
  469. package/resources/skills/story-creation/upstream/skills/story-long-write/references/workflow-revision.md +89 -0
  470. package/resources/skills/story-creation/upstream/skills/story-long-write/references/workflow-setup.md +170 -0
  471. package/resources/skills/story-creation/upstream/skills/story-long-write/references/workflow-volume.md +142 -0
  472. package/resources/skills/story-creation/upstream/skills/story-long-write/references/writer-prompt-fallback.md +24 -0
  473. package/resources/skills/story-creation/upstream/skills/story-long-write/references/writing-craft.md +442 -0
  474. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/author_memory_commit.py +1635 -0
  475. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/build_architect_brief.py +260 -0
  476. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/build_writer_prompt.py +611 -0
  477. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/check-ai-patterns.js +1586 -0
  478. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/check-degeneration.js +349 -0
  479. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/check-outline-contract.js +520 -0
  480. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/check-outline-copy.js +313 -0
  481. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/normalize-punctuation.js +415 -0
  482. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/outline_view.py +286 -0
  483. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/storyctl.py +561 -0
  484. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/style-whitelist.js +39 -0
  485. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/tracking_commit.py +1691 -0
  486. package/resources/skills/story-creation/upstream/skills/story-long-write/scripts/wordcount_core.py +405 -0
  487. package/resources/skills/story-creation/upstream/skills/story-review/SKILL.md +231 -0
  488. package/resources/skills/story-creation/upstream/skills/story-review/references/agent-prompts.md +184 -0
  489. package/resources/skills/story-creation/upstream/skills/story-review/references/anti-ai-writing.md +556 -0
  490. package/resources/skills/story-creation/upstream/skills/story-review/references/author-memory-maintenance.md +75 -0
  491. package/resources/skills/story-creation/upstream/skills/story-review/references/author-memory.md +117 -0
  492. package/resources/skills/story-creation/upstream/skills/story-review/references/banned-words.md +151 -0
  493. package/resources/skills/story-creation/upstream/skills/story-review/references/batch-review.md +19 -0
  494. package/resources/skills/story-creation/upstream/skills/story-review/references/character-relations.md +433 -0
  495. package/resources/skills/story-creation/upstream/skills/story-review/references/dialogue-mastery.md +288 -0
  496. package/resources/skills/story-creation/upstream/skills/story-review/references/plot-core-methods.md +522 -0
  497. package/resources/skills/story-creation/upstream/skills/story-review/references/quality-rubric.md +55 -0
  498. package/resources/skills/story-creation/upstream/skills/story-review/references/review-quality.md +246 -0
  499. package/resources/skills/story-creation/upstream/skills/story-review/references/review-tracking.md +10 -0
  500. package/resources/skills/story-creation/upstream/skills/story-review/references/rubrics/fanqie.md +18 -0
  501. package/resources/skills/story-creation/upstream/skills/story-review/references/rubrics/qidian.md +19 -0
  502. package/resources/skills/story-creation/upstream/skills/story-review/references/rubrics/zhihu.md +20 -0
  503. package/resources/skills/story-creation/upstream/skills/story-review/references/solo.md +52 -0
  504. package/resources/skills/story-creation/upstream/skills/story-review/references/style-resolution.md +27 -0
  505. package/resources/skills/story-creation/upstream/skills/story-review/references/tracking-initialization.md +31 -0
  506. package/resources/skills/story-creation/upstream/skills/story-review/references/tracking-transaction.md +146 -0
  507. package/resources/skills/story-creation/upstream/skills/story-review/scripts/author_memory_commit.py +1635 -0
  508. package/resources/skills/story-creation/upstream/skills/story-review/scripts/check-ai-patterns.js +1586 -0
  509. package/resources/skills/story-creation/upstream/skills/story-review/scripts/check-degeneration.js +349 -0
  510. package/resources/skills/story-creation/upstream/skills/story-review/scripts/normalize-punctuation.js +415 -0
  511. package/resources/skills/story-creation/upstream/skills/story-review/scripts/style-whitelist.js +39 -0
  512. package/resources/skills/story-creation/upstream/skills/story-review/scripts/tracking_commit.py +1691 -0
  513. package/resources/skills/story-creation/upstream/skills/story-review/scripts/wordcount_core.py +405 -0
  514. package/resources/skills/story-creation/upstream/skills/story-setup/SKILL.md +165 -0
  515. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/agent-quality.md +72 -0
  516. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/agent-reference-profiles.md +55 -0
  517. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/anti-ai-writing.md +556 -0
  518. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/banned-words.md +151 -0
  519. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
  520. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/character-basics.md +445 -0
  521. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/character-design-methods.md +428 -0
  522. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/character-relations.md +433 -0
  523. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/deslop-gates.md +171 -0
  524. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/dialogue-mastery.md +288 -0
  525. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
  526. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/emotional-arc-design.md +313 -0
  527. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/format-and-structure.md +168 -0
  528. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//344/270/234/346/226/271/344/273/231/344/276/240.md +51 -0
  529. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//344/274/240/347/273/237/347/216/204/345/271/273.md +51 -0
  530. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/216/206/345/217/262/345/217/244/344/273/243.md +51 -0
  531. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/216/206/345/217/262/350/204/221/346/264/236.md +51 -0
  532. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/217/214/347/224/267/344/270/273.md +53 -0
  533. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/217/244/350/250/200/350/204/221/346/264/236.md +51 -0
  534. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/217/244/351/243/216/344/270/226/346/203/205.md +51 -0
  535. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/245/263/351/242/221/346/202/254/347/226/221.md +51 -0
  536. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/245/263/351/242/221/347/247/215/347/224/260.md +51 -0
  537. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/256/253/346/226/227/345/256/205/346/226/227.md +51 -0
  538. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/271/264/344/273/243.md +53 -0
  539. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//345/277/253/347/251/277.md +51 -0
  540. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/202/254/347/226/221/347/201/265/345/274/202.md +51 -0
  541. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/202/254/347/226/221/350/204/221/346/264/236.md +51 -0
  542. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/210/230/347/245/236/350/265/230/345/251/277.md +51 -0
  543. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/212/227/346/210/230/350/260/215/346/210/230.md +51 -0
  544. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/230/237/345/205/211/347/222/200/347/222/250.md +51 -0
  545. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/260/221/345/233/275/350/250/200/346/203/205.md +51 -0
  546. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//346/270/270/346/210/217/344/275/223/350/202/262.md +51 -0
  547. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//347/216/204/345/271/273/350/204/221/346/264/236.md +53 -0
  548. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//347/216/204/345/271/273/350/250/200/346/203/205.md +51 -0
  549. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//347/216/260/350/250/200/350/204/221/346/264/236.md +51 -0
  550. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//347/247/221/345/271/273/346/234/253/344/270/226.md +51 -0
  551. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//350/201/214/345/234/272/345/251/232/346/201/213.md +51 -0
  552. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//350/245/277/346/226/271/345/245/207/345/271/273.md +51 -0
  553. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//350/261/252/351/227/250/346/200/273/350/243/201.md +53 -0
  554. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//351/203/275/345/270/202/344/277/256/347/234/237.md +51 -0
  555. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//351/203/275/345/270/202/346/227/245/345/270/270.md +53 -0
  556. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//351/203/275/345/270/202/347/247/215/347/224/260.md +51 -0
  557. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//351/203/275/345/270/202/350/204/221/346/264/236.md +53 -0
  558. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//351/203/275/345/270/202/351/253/230/346/255/246.md +53 -0
  559. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards//351/235/222/346/230/245/347/224/234/345/256/240.md +51 -0
  560. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-prose-cards.md +91 -0
  561. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/genre-readers.md +235 -0
  562. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-chapter-hooks.md +225 -0
  563. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-emotional-methods.md +209 -0
  564. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-genre-catalog.md +394 -0
  565. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-genre-mechanics.md +415 -0
  566. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-quality.md +42 -0
  567. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-reversal.md +335 -0
  568. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/long-suspense.md +352 -0
  569. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/opening-design.md +349 -0
  570. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/outline-conflict.md +457 -0
  571. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/outline-methods.md +287 -0
  572. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/outline-rhythm.md +389 -0
  573. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/plot-core-methods.md +522 -0
  574. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-chapter-hooks.md +225 -0
  575. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-emotional-methods.md +179 -0
  576. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-genre-formulas.md +417 -0
  577. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-paragraph-hooks.md +146 -0
  578. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-quality.md +39 -0
  579. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-reversal.md +355 -0
  580. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/short-suspense.md +352 -0
  581. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/style-combat-face.md +352 -0
  582. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/style-genre-modules.md +510 -0
  583. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/style-resolution.md +27 -0
  584. package/resources/skills/story-creation/upstream/skills/story-setup/references/agent-references/writing-craft.md +442 -0
  585. package/resources/skills/story-creation/upstream/skills/story-setup/references/diagnostics.md +38 -0
  586. package/resources/skills/story-creation/upstream/skills/story-short-analyze/SKILL.md +224 -0
  587. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-character-basics.md +453 -0
  588. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-character-design.md +438 -0
  589. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-character-relations.md +395 -0
  590. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-method.md +42 -0
  591. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-paragraph-hooks.md +146 -0
  592. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-reader-profile.md +245 -0
  593. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-report-style.md +45 -0
  594. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-short-genres.md +65 -0
  595. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-short-hooks.md +77 -0
  596. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-short-mechanics.md +82 -0
  597. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-short-patterns.md +50 -0
  598. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-short-suspense.md +98 -0
  599. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/analysis-writing-techniques.md +477 -0
  600. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/deconstruction-examples.md +79 -0
  601. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/optional-modules.md +97 -0
  602. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/output-contract.md +127 -0
  603. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/quality-checklist.md +80 -0
  604. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/real-market-data.md +90 -0
  605. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/source-story-quality.md +221 -0
  606. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
  607. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/stage4-6-reversal-summary.md +611 -0
  608. package/resources/skills/story-creation/upstream/skills/story-short-analyze/references/zhihu-style.md +54 -0
  609. package/resources/skills/story-creation/upstream/skills/story-short-scan/SKILL.md +182 -0
  610. package/resources/skills/story-creation/upstream/skills/story-short-scan/references/manual-rank-input.md +36 -0
  611. package/resources/skills/story-creation/upstream/skills/story-short-scan/references/platform-dianzhong.md +24 -0
  612. package/resources/skills/story-creation/upstream/skills/story-short-scan/references/platform-heiyan.md +21 -0
  613. package/resources/skills/story-creation/upstream/skills/story-short-scan/references/real-market-data.md +90 -0
  614. package/resources/skills/story-creation/upstream/skills/story-short-scan/references/topic-match.md +38 -0
  615. package/resources/skills/story-creation/upstream/skills/story-short-scan/scripts/aggregate-rank.js +682 -0
  616. package/resources/skills/story-creation/upstream/skills/story-short-scan/scripts/cdp-utils.js +242 -0
  617. package/resources/skills/story-creation/upstream/skills/story-short-scan/scripts/dz-browse-scraper.js +232 -0
  618. package/resources/skills/story-creation/upstream/skills/story-short-scan/scripts/heiyan-booklist-scraper.js +345 -0
  619. package/resources/skills/story-creation/upstream/skills/story-short-write/SKILL.md +136 -0
  620. package/resources/skills/story-creation/upstream/skills/story-short-write/references/agent-calls.md +13 -0
  621. package/resources/skills/story-creation/upstream/skills/story-short-write/references/author-memory-maintenance.md +75 -0
  622. package/resources/skills/story-creation/upstream/skills/story-short-write/references/author-memory.md +117 -0
  623. package/resources/skills/story-creation/upstream/skills/story-short-write/references/banned-words.md +151 -0
  624. package/resources/skills/story-creation/upstream/skills/story-short-write/references/benchmark-recall.md +40 -0
  625. package/resources/skills/story-creation/upstream/skills/story-short-write/references/cross-book-recall.md +62 -0
  626. package/resources/skills/story-creation/upstream/skills/story-short-write/references/dialogue-mastery.md +288 -0
  627. package/resources/skills/story-creation/upstream/skills/story-short-write/references/emotional-methods.md +179 -0
  628. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +159 -0
  629. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +156 -0
  630. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +163 -0
  631. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +167 -0
  632. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +178 -0
  633. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +166 -0
  634. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +159 -0
  635. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//346/262/231/351/233/225/350/204/221/346/264/236.md +151 -0
  636. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +153 -0
  637. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +210 -0
  638. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-writing-formulas.md +417 -0
  639. package/resources/skills/story-creation/upstream/skills/story-short-write/references/genre-writing-techniques.md +490 -0
  640. package/resources/skills/story-creation/upstream/skills/story-short-write/references/hooks-chapter.md +225 -0
  641. package/resources/skills/story-creation/upstream/skills/story-short-write/references/hooks-paragraph.md +146 -0
  642. package/resources/skills/story-creation/upstream/skills/story-short-write/references/output-contract.md +127 -0
  643. package/resources/skills/story-creation/upstream/skills/story-short-write/references/reference-index.md +23 -0
  644. package/resources/skills/story-creation/upstream/skills/story-short-write/references/scene-craft.md +40 -0
  645. package/resources/skills/story-creation/upstream/skills/story-short-write/references/short-craft.md +147 -0
  646. package/resources/skills/story-creation/upstream/skills/story-short-write/references/short-deslop.md +133 -0
  647. package/resources/skills/story-creation/upstream/skills/story-short-write/references/short-format.md +199 -0
  648. package/resources/skills/story-creation/upstream/skills/story-short-write/references/short-prose-quality.md +224 -0
  649. package/resources/skills/story-creation/upstream/skills/story-short-write/references/short-reversal.md +355 -0
  650. package/resources/skills/story-creation/upstream/skills/story-short-write/references/short-suspense.md +352 -0
  651. package/resources/skills/story-creation/upstream/skills/story-short-write/references/style-resolution.md +27 -0
  652. package/resources/skills/story-creation/upstream/skills/story-short-write/references/submission-craft.md +35 -0
  653. package/resources/skills/story-creation/upstream/skills/story-short-write/references/villain-and-reveal.md +153 -0
  654. package/resources/skills/story-creation/upstream/skills/story-short-write/references/workflow-design.md +85 -0
  655. package/resources/skills/story-creation/upstream/skills/story-short-write/references/workflow-draft.md +116 -0
  656. package/resources/skills/story-creation/upstream/skills/story-short-write/references/workflow-revision.md +99 -0
  657. package/resources/skills/story-creation/upstream/skills/story-short-write/references/writing-workflow.md +50 -0
  658. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/author_memory_commit.py +1635 -0
  659. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/check-ai-patterns.js +1586 -0
  660. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/check-degeneration.js +349 -0
  661. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/check-delivery-contract.js +241 -0
  662. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/check-outline-copy.js +313 -0
  663. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/check-phase2-contract.js +363 -0
  664. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/normalize-punctuation.js +415 -0
  665. package/resources/skills/story-creation/upstream/skills/story-short-write/scripts/style-whitelist.js +39 -0
  666. package/resources/skills/video-recap-production/manifest.json +673 -0
  667. package/resources/skills/video-recap-production/upstream/CHANGELOG.md +371 -0
  668. package/resources/skills/video-recap-production/upstream/LICENSE +21 -0
  669. package/resources/skills/video-recap-production/upstream/README.en.md +468 -0
  670. package/resources/skills/video-recap-production/upstream/README.md +459 -0
  671. package/resources/skills/video-recap-production/upstream/manifest.json +839 -0
  672. package/resources/skills/video-recap-production/upstream/skills/video-assemble/SKILL.md +112 -0
  673. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/audio-modes.md +63 -0
  674. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/explicit-audio-mix.md +75 -0
  675. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/foreground-compose.md +118 -0
  676. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/LICENSE.duo-video +21 -0
  677. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/SOURCE.md +15 -0
  678. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_draft_meta_info.json +69 -0
  679. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_combination_segment.json +84 -0
  680. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_combination_video_material.json +98 -0
  681. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_draft.json +204 -0
  682. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_material_video.json +83 -0
  683. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_meta_material_value.json +23 -0
  684. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_project_info.json +133 -0
  685. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_segment.json +70 -0
  686. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_jy_text_styles.json +30 -0
  687. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_yj_material_audio.json +41 -0
  688. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/jianying/empty_yj_material_text.json +109 -0
  689. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/narration-adoption.md +103 -0
  690. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/packaging.md +45 -0
  691. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/pair-media.md +74 -0
  692. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/source-score.md +147 -0
  693. package/resources/skills/video-recap-production/upstream/skills/video-assemble/references/subtitle-track.md +202 -0
  694. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/adoption/__init__.py +1 -0
  695. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
  696. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
  697. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
  698. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
  699. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
  700. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/artifacts.py +47 -0
  701. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/assemble.py +591 -0
  702. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/assemble_constants.py +51 -0
  703. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/assembly_contract.py +318 -0
  704. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/assembly_settings.py +138 -0
  705. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/audio_automation.py +195 -0
  706. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/audio_mix.py +465 -0
  707. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/compose_foreground.py +293 -0
  708. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/export_jianying.py +254 -0
  709. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/__init__.py +1 -0
  710. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/builders.py +718 -0
  711. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/model.py +105 -0
  712. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/optional.py +23 -0
  713. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/schema.py +53 -0
  714. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/templates.py +37 -0
  715. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/timeline_contract.py +223 -0
  716. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/tracks.py +72 -0
  717. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/jianying/writer.py +383 -0
  718. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/lib.py +218 -0
  719. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/media.py +190 -0
  720. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/narration_audio.py +413 -0
  721. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/packaging.py +122 -0
  722. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/pair_media.py +216 -0
  723. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/render_preflight.py +33 -0
  724. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/source_score.py +469 -0
  725. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/source_subtitles.py +423 -0
  726. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
  727. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/subtitles/core.py +330 -0
  728. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/subtitles/render.py +82 -0
  729. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/subtitles/track.py +324 -0
  730. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
  731. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/timeline.py +217 -0
  732. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/timeline_emit.py +167 -0
  733. package/resources/skills/video-recap-production/upstream/skills/video-assemble/scripts/visual_render.py +448 -0
  734. package/resources/skills/video-recap-production/upstream/skills/video-cut/SKILL.md +108 -0
  735. package/resources/skills/video-recap-production/upstream/skills/video-cut/references/shot-review.md +50 -0
  736. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/cut.py +41 -0
  737. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/cut_cli.py +308 -0
  738. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/cut_contract.py +424 -0
  739. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/cut_render.py +304 -0
  740. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/lib.py +114 -0
  741. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/media_geometry.py +238 -0
  742. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/narration_mapping.py +71 -0
  743. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/narrative_selection.py +244 -0
  744. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/sentence_boundaries.py +585 -0
  745. package/resources/skills/video-recap-production/upstream/skills/video-cut/scripts/shot_review.py +357 -0
  746. package/resources/skills/video-recap-production/upstream/skills/video-recap/SKILL.md +260 -0
  747. package/resources/skills/video-recap-production/upstream/skills/video-recap/references/audio-routing.md +126 -0
  748. package/resources/skills/video-recap-production/upstream/skills/video-recap/references/config-playbook.md +65 -0
  749. package/resources/skills/video-recap-production/upstream/skills/video-recap/references/data-schema.md +545 -0
  750. package/resources/skills/video-recap-production/upstream/skills/video-recap/references/resource-library.md +151 -0
  751. package/resources/skills/video-recap-production/upstream/skills/video-recap/references/shift-left-qc-schema.md +23 -0
  752. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/doctor.py +556 -0
  753. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/final_qc.py +527 -0
  754. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/lib.py +220 -0
  755. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/library.py +509 -0
  756. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/materials.py +406 -0
  757. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/mimo_qc.py +33 -0
  758. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/project_binding.py +286 -0
  759. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/__init__.py +1 -0
  760. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_client.py +13 -0
  761. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_contract.py +9 -0
  762. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_evidence.py +287 -0
  763. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_observations.py +175 -0
  764. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_payload.py +206 -0
  765. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_report.py +318 -0
  766. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc/mimo_runner.py +130 -0
  767. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/qc_contract.py +320 -0
  768. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap.py +9 -0
  769. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_cli.py +209 -0
  770. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_inspect.py +452 -0
  771. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_review.py +70 -0
  772. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_runner.py +696 -0
  773. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_runtime.py +260 -0
  774. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_source.py +278 -0
  775. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_stage_qc.py +160 -0
  776. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/recap_timeline.py +621 -0
  777. package/resources/skills/video-recap-production/upstream/skills/video-recap/scripts/resource_lock.py +162 -0
  778. package/resources/skills/video-recap-production/upstream/skills/video-script/SKILL.md +251 -0
  779. package/resources/skills/video-recap-production/upstream/skills/video-script/references/creative-editing-playbook.md +229 -0
  780. package/resources/skills/video-recap-production/upstream/skills/video-script/references/promotional-copy.md +68 -0
  781. package/resources/skills/video-recap-production/upstream/skills/video-script/references/research-guide.md +75 -0
  782. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/agent_text.py +301 -0
  783. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/deslop_qc.py +211 -0
  784. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/evidence_bundle.py +440 -0
  785. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/lib.py +254 -0
  786. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/narration_lint.py +707 -0
  787. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/review.py +40 -0
  788. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/review_grounding.py +238 -0
  789. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/review_response.py +669 -0
  790. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/review_runner.py +186 -0
  791. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/speech_ownership.py +143 -0
  792. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/timeline_fusion.py +108 -0
  793. package/resources/skills/video-recap-production/upstream/skills/video-script/scripts/validate.py +175 -0
  794. package/resources/skills/video-recap-production/upstream/skills/video-understanding/SKILL.md +77 -0
  795. package/resources/skills/video-recap-production/upstream/skills/video-understanding/references/data-schema.md +193 -0
  796. package/resources/skills/video-recap-production/upstream/skills/video-understanding/references/prompt-templates.md +37 -0
  797. package/resources/skills/video-recap-production/upstream/skills/video-understanding/references/research-guide.md +74 -0
  798. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/agent_text.py +301 -0
  799. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/asr.py +279 -0
  800. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
  801. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/brief.py +9 -0
  802. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/briefing/__init__.py +1 -0
  803. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/briefing/builder.py +402 -0
  804. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/briefing/context.py +317 -0
  805. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/briefing/inputs.py +268 -0
  806. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/briefing/timeline.py +326 -0
  807. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/consolidate.py +596 -0
  808. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/deslop_qc.py +211 -0
  809. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/detect.py +504 -0
  810. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/extract.py +62 -0
  811. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/lib.py +419 -0
  812. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/narration_lint.py +707 -0
  813. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/speech_ownership.py +143 -0
  814. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/storyboard.py +445 -0
  815. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/timeline_fusion.py +108 -0
  816. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/understand.py +9 -0
  817. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/understanding_brief.py +190 -0
  818. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/understanding_cache.py +345 -0
  819. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/understanding_runner.py +387 -0
  820. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/understanding_storyboard.py +167 -0
  821. package/resources/skills/video-recap-production/upstream/skills/video-understanding/scripts/vlm.py +674 -0
  822. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/SKILL.md +91 -0
  823. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/references/index-tts.md +31 -0
  824. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
  825. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/dub.py +623 -0
  826. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/lib.py +352 -0
  827. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/providers/__init__.py +1 -0
  828. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/providers/fish_audio.py +91 -0
  829. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
  830. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/tts_audio.py +102 -0
  831. package/resources/skills/video-recap-production/upstream/skills/video-voiceover/scripts/voiceover.py +771 -0
  832. package/resources/skills/viora-canvas-production/manifest.json +5 -1
  833. package/resources/skills/viora-canvas-production/references/story-handoff.md +49 -0
@@ -0,0 +1,864 @@
1
+ #!/usr/bin/env python3
2
+ """Register inspiration atoms from EM mechanism cards, then validate/query the index.
3
+
4
+ 三层灵感库的机械层。原子灵感(IA)不再生成独立文件:每个 IA 是
5
+ `灵感索引.csv` 里的一行登记,机制全文只在 `拆文库/{书}/剧情/情绪模块.md`
6
+ 的 EM 卡一处维护,需要时按 ID 回查。NM/CBA 卡内禁止路径引用,
7
+ 来源只记 `书名/EM-xxx` 式裸 ID;路径解析统一走索引。
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import csv
14
+ import json
15
+ import os
16
+ import re
17
+ import sys
18
+ import tempfile
19
+ from pathlib import Path
20
+ from typing import Any
21
+
22
+ COLUMNS = (
23
+ "item_id",
24
+ "layer",
25
+ "title",
26
+ "source_book",
27
+ "path",
28
+ "source_ids",
29
+ "novel_count",
30
+ "atom_count",
31
+ "grade",
32
+ "tags",
33
+ "status",
34
+ )
35
+ LAYERS = {"原子灵感": "IA-", "单小说灵感合并": "NM-", "跨书灵感聚合": "CBA-"}
36
+ TAG_AXES = {"题材", "读者需求", "情绪", "关系动作", "剧情功能", "节奏位置", "适用阶段", "风险"}
37
+ REQUIRED_CBA_AXES = {"题材", "读者需求", "情绪", "剧情功能", "适用阶段", "风险"}
38
+ CORE_QUERY_AXES = {"题材", "读者需求", "情绪", "剧情功能", "适用阶段"}
39
+ # EM 完整卡必须具备的五个灵感映射字段(缺失=Stage 3 卡片质量问题,报错回拆文侧修复)
40
+ EM_REQUIRED_FIELDS = ("读者想看什么", "情绪链", "戏剧单元", "可替换项", "不可照搬")
41
+ # 专名泄漏扫描范围:排除「不可照搬」——该字段的职责就是点名原书专名
42
+ EM_LEAK_SCAN_FIELDS = ("读者想看什么", "情绪链", "戏剧单元", "可替换项")
43
+ EM_HEADER_RE = re.compile(r"^###\s+[*_]*(EM-[0-9]{2,})(?![0-9])[*_]*\s*(?:[·\-—::||]\s*)?(.*?)[\s*_]*$")
44
+ # 以 EM 编号开头、却不是 `### EM-xxx` 的标题行:下一张卡会被静默并进上一张
45
+ EM_MISPLACED_HEADER_RE = re.compile(r"^#{1,6}\s+[*_【\[]*EM-[0-9]")
46
+ EM_TABLE_SEPARATOR_RE = re.compile(r"^:?-+:?$")
47
+ EM_INDEX_ID_RE = re.compile(r"(EM-[0-9]{2,})")
48
+ # 字段行的两种体裁:表格 `| 字段 | 值 |` 与粗体列表 `- **字段**:值`(前导 `- ` 可省)
49
+ EM_BOLD_FIELD_RE = re.compile(r"^[-*]?\s*\*{2,3}([^*]+?)(?:[::]\*{2,3}|\*{2,3}\s*[::])\s*(.*)$")
50
+ # 同义字段名归一;表头行的首列词不作为字段
51
+ EM_FIELD_ALIASES = {"不可照搬项": "不可照搬", "可替换项目": "可替换项"}
52
+ EM_TABLE_HEADER_KEYS = {"字段", "维度", "---", ""}
53
+ CARD_PATH_RE = re.compile(r"\]\(|\.md\)|原子灵感/|单小说灵感合并/|跨书灵感聚合/|拆文库/")
54
+
55
+
56
+ def atomic_write_text(path: Path, text: str, encoding: str = "utf-8") -> None:
57
+ path.parent.mkdir(parents=True, exist_ok=True)
58
+ fd, temp_name = tempfile.mkstemp(prefix=f".{path.name}.", suffix=".tmp", dir=path.parent)
59
+ try:
60
+ with os.fdopen(fd, "w", encoding=encoding, newline="") as handle:
61
+ handle.write(text)
62
+ handle.flush()
63
+ os.fsync(handle.fileno())
64
+ os.replace(temp_name, path)
65
+ except BaseException:
66
+ try:
67
+ os.unlink(temp_name)
68
+ except OSError:
69
+ pass
70
+ raise
71
+
72
+
73
+ def csv_text(rows: list[dict[str, str]]) -> str:
74
+ import io
75
+
76
+ buffer = io.StringIO(newline="")
77
+ writer = csv.DictWriter(buffer, fieldnames=COLUMNS, lineterminator="\n")
78
+ writer.writeheader()
79
+ writer.writerows(rows)
80
+ return "" + buffer.getvalue()
81
+
82
+
83
+ def normalize_em_field(key: str) -> str:
84
+ """去掉字段名上的粗体标记与空白,再按同义表归一。"""
85
+ return EM_FIELD_ALIASES.get(key.strip().strip("*").strip(), key.strip().strip("*").strip())
86
+
87
+
88
+ def parse_em_module(module_text: str) -> tuple[list[dict[str, str]], list[tuple[str, str]], list[str]]:
89
+ """Return (complete cards, index-only entries, structural problems) from 情绪模块.md text.
90
+
91
+ 完整卡=`### EM-xxx 名称` 小节内的字段行,表格 `|字段|内容|` 与粗体列表 `- **字段**:内容` 都接受;
92
+ 粗体字段同行没写值时,吸收其后到下一个字段/标题为止的列表或段落行作为多行值。
93
+ 索引条目=「其他机制索引」小节里出现 EM-xxx 的行(机制ID|名称|…)。
94
+ 认不出的 EM 标题行和同卡重复字段记为问题:它们意味着下一张卡被并进了上一张。
95
+ """
96
+ lines = module_text.split("\n")
97
+ cards: list[dict[str, str]] = []
98
+ index_entries: list[tuple[str, str]] = []
99
+ problems: list[str] = []
100
+ current: dict[str, str] | None = None
101
+ pending_field: str | None = None
102
+ in_index_section = False
103
+ for line in lines:
104
+ stripped = line.strip()
105
+ header = EM_HEADER_RE.match(stripped)
106
+ if header:
107
+ current = {"em_id": header.group(1), "title": header.group(2)}
108
+ cards.append(current)
109
+ in_index_section = False
110
+ pending_field = None
111
+ continue
112
+ if EM_MISPLACED_HEADER_RE.match(stripped):
113
+ problems.append(f"em_header_unrecognized:{stripped[:40]}——EM 卡标题须写成 `### EM-xxx 名称`")
114
+ current = None
115
+ pending_field = None
116
+ continue
117
+ if stripped.startswith("## "):
118
+ in_index_section = "其他机制索引" in stripped
119
+ current = None
120
+ pending_field = None
121
+ continue
122
+ if current is not None and stripped.startswith("|"):
123
+ pending_field = None
124
+ cells = [cell.strip() for cell in stripped.strip("|").split("|")]
125
+ if len(cells) >= 2:
126
+ key = normalize_em_field(cells[0])
127
+ if key not in EM_TABLE_HEADER_KEYS and not EM_TABLE_SEPARATOR_RE.match(key):
128
+ if key in EM_REQUIRED_FIELDS and key in current:
129
+ problems.append(f"{current['em_id']}:em_field_duplicate:{key}")
130
+ current[key] = cells[1]
131
+ continue
132
+ if current is not None:
133
+ # 多行值:字段名行之后缩进的列表行一律是续行,哪怕它自己带粗体小标题
134
+ if pending_field is not None and stripped and line[:1] in (" ", "\t"):
135
+ appended = stripped.lstrip("-*").strip()
136
+ current[pending_field] = f"{current[pending_field]};{appended}" if current[pending_field] else appended
137
+ continue
138
+ bold = EM_BOLD_FIELD_RE.match(stripped)
139
+ if bold:
140
+ key = normalize_em_field(bold.group(1))
141
+ value = bold.group(2).strip()
142
+ if key in EM_REQUIRED_FIELDS and key in current:
143
+ problems.append(f"{current['em_id']}:em_field_duplicate:{key}")
144
+ current[key] = value
145
+ pending_field = None if value else key
146
+ continue
147
+ if pending_field is not None and stripped.startswith("#"):
148
+ pending_field = None
149
+ continue
150
+ if pending_field is not None and stripped:
151
+ appended = stripped.lstrip("-*").strip()
152
+ if appended:
153
+ current[pending_field] = (
154
+ f"{current[pending_field]};{appended}" if current[pending_field] else appended
155
+ )
156
+ continue
157
+ if in_index_section and stripped:
158
+ match = EM_INDEX_ID_RE.search(stripped)
159
+ if match:
160
+ parts = [part.strip() for part in re.split(r"[||]", stripped.strip("|| ")) if part.strip()]
161
+ name = parts[1] if len(parts) >= 2 and parts[0] == match.group(1) else (parts[0] if parts else match.group(1))
162
+ if name == match.group(1) and len(parts) >= 2:
163
+ name = parts[1]
164
+ index_entries.append((match.group(1), name))
165
+ return cards, index_entries, problems
166
+
167
+
168
+ def resolve_workspace(root: Path, explicit: Path | None = None) -> Path:
169
+ """定位含 `拆文库/` 的工作区——泄漏门名单与 EM 集合校验都依赖它。
170
+
171
+ 显式 `--workspace` 优先;否则从 `--root` 起向上最多探测 5 级。
172
+ 定位失败必须报错而不是回退空名单:名单为空集时泄漏检查等于没跑。
173
+ """
174
+ if explicit is not None:
175
+ if (explicit / "拆文库").is_dir():
176
+ return explicit
177
+ raise ValueError(f"workspace_invalid:{explicit} 下没有 拆文库/")
178
+ candidate = root.resolve()
179
+ for _ in range(6):
180
+ if (candidate / "拆文库").is_dir():
181
+ return candidate
182
+ if candidate.parent == candidate:
183
+ break
184
+ candidate = candidate.parent
185
+ raise ValueError("workspace_not_located:从 --root 向上未找到含 拆文库/ 的目录——用 --workspace 显式指定")
186
+
187
+
188
+ EM_ARROW_RE = re.compile(r"→|⟶|->")
189
+
190
+
191
+ def replaceable_antipattern_hits(value: str, names: set[str]) -> list[str]:
192
+ """「专名→任意X」反模式:箭头左侧命中角色名单即高置信真引用。"""
193
+ hits: set[str] = set()
194
+ for segment in re.split(r"[;;,,、||]", value):
195
+ if not EM_ARROW_RE.search(segment):
196
+ continue
197
+ left = EM_ARROW_RE.split(segment)[0]
198
+ hits.update(name for name in names if name in left)
199
+ return sorted(hits)
200
+
201
+
202
+ def character_names(workspace: Path, book: str) -> set[str]:
203
+ role_dir = workspace / "拆文库" / book / "角色"
204
+ names: set[str] = set()
205
+ if role_dir.is_dir():
206
+ for entry in role_dir.rglob("*.md"):
207
+ stem = re.sub(r"^\d+[-_.、\s]*", "", entry.stem)
208
+ if len(stem) >= 2 and stem not in {"角色关系", "README", "readme", "索引", "目录"}:
209
+ names.add(stem)
210
+ return names
211
+
212
+
213
+ def load_numbered_rows(root: Path) -> tuple[list[tuple[int, dict[str, str]]], list[str]]:
214
+ """索引行连同其文件行号;列数不对的行报错并剔除,行号仍按文件实际位置。"""
215
+ errors: list[str] = []
216
+ index_path = root / "灵感索引.csv"
217
+ try:
218
+ with index_path.open("r", encoding="utf-8-sig", newline="") as handle:
219
+ reader = csv.DictReader(handle)
220
+ rows: list[tuple[int, dict[str, str]]] = []
221
+ for row in reader:
222
+ if None in row or None in row.values():
223
+ errors.append(f"line_{reader.line_num}:column_count_mismatch")
224
+ continue
225
+ rows.append((reader.line_num, row))
226
+ if tuple(reader.fieldnames or ()) != COLUMNS:
227
+ errors.append("index_header_mismatch")
228
+ except (OSError, UnicodeError, csv.Error) as exc:
229
+ return [], [f"index_unreadable:{exc}"]
230
+ return rows, errors
231
+
232
+
233
+ def load_rows(root: Path) -> tuple[list[dict[str, str]], list[str]]:
234
+ numbered, errors = load_numbered_rows(root)
235
+ return [row for _, row in numbered], errors
236
+
237
+
238
+ class RegisterError(ValueError):
239
+ """携带完整问题清单的登记失败——一次报全,避免逐轮试跑。"""
240
+
241
+ def __init__(self, errors: list[str], warnings: list[str] | None = None) -> None:
242
+ super().__init__("\n".join(errors))
243
+ self.errors = errors
244
+ self.warnings = warnings or []
245
+
246
+
247
+ def analyze_module(root: Path, module_path: Path, book: str,
248
+ workspace: Path | None = None) -> dict[str, Any]:
249
+ """解析并检查一本书的 EM 卡,收集全部 errors/warnings,不写盘。"""
250
+ errors: list[str] = []
251
+ warnings: list[str] = []
252
+ if not book or book in {".", ".."} or "/" in book or "\\" in book:
253
+ raise RegisterError([f"book_name_invalid:{book!r}——--book 只写书名本身"])
254
+ try:
255
+ ws = resolve_workspace(root, workspace)
256
+ except ValueError as exc:
257
+ raise RegisterError([str(exc)]) from exc
258
+ try:
259
+ module_text = module_path.read_text(encoding="utf-8-sig")
260
+ except (OSError, UnicodeError) as exc:
261
+ raise RegisterError([f"emotion_module_unreadable:{exc}"]) from exc
262
+ cards, index_entries, problems = parse_em_module(module_text)
263
+ if not cards and not index_entries:
264
+ raise RegisterError(["emotion_module_has_no_em_cards"])
265
+ errors.extend(problems)
266
+
267
+ book_dir = ws / "拆文库" / book
268
+ if not book_dir.is_dir():
269
+ errors.append(f"book_dir_not_found:拆文库/{book}——工作区 {ws} 下没有这本书,泄漏门无法取角色名单")
270
+ elif book_dir.resolve() not in module_path.resolve().parents:
271
+ errors.append(f"module_book_mismatch:{module_path} 不在 拆文库/{book}/ 下——--book 与 --module 必须是同一本书")
272
+ names = character_names(ws, book)
273
+ if not names and book_dir.is_dir():
274
+ warnings.append(f"character_roster_missing:拆文库/{book}/角色/ 不存在或为空——泄漏门本次没有名单可查,请人工确认卡内无专名")
275
+
276
+ seen: set[str] = set()
277
+ atom_rows: list[dict[str, str]] = []
278
+ for card in cards:
279
+ em_id = card["em_id"]
280
+ if em_id in seen:
281
+ errors.append(f"em_id_duplicate:{em_id}")
282
+ continue
283
+ seen.add(em_id)
284
+ card_errors = 0
285
+ if not card["title"].strip():
286
+ errors.append(f"{em_id}:em_title_missing——EM 卡标题须写成 `### {em_id} 名称`")
287
+ card_errors += 1
288
+ absent = [field for field in EM_REQUIRED_FIELDS if field not in card]
289
+ empty = [field for field in EM_REQUIRED_FIELDS if field in card and not card[field].strip()]
290
+ if absent:
291
+ errors.append(f"{em_id}:em_fields_missing:{'|'.join(absent)}——请回 story-long-analyze Stage 3 补全该模块卡")
292
+ card_errors += 1
293
+ if empty:
294
+ errors.append(f"{em_id}:em_field_value_empty:{'|'.join(empty)}——字段在但值为空;多行值须紧跟字段名行(支持列表/段落)")
295
+ card_errors += 1
296
+
297
+ field_texts = {"标题": card.get("title", "")}
298
+ field_texts.update({field: card.get(field, "") for field in EM_LEAK_SCAN_FIELDS})
299
+ hit_locations = {
300
+ name: [field for field, text in field_texts.items() if name in text]
301
+ for name in sorted(names)
302
+ if any(name in text for text in field_texts.values())
303
+ }
304
+ antipattern = replaceable_antipattern_hits(card.get("可替换项", ""), names)
305
+ non_portable = card.get("不可照搬", "")
306
+ for name in antipattern:
307
+ errors.append(f"{em_id}:replaceable_antipattern:{name}——「专名→任意X」把专名写进抽象字段,改写成「功能位→任意X」")
308
+ card_errors += 1
309
+ for name, locations in hit_locations.items():
310
+ if name in antipattern:
311
+ continue
312
+ if name in non_portable:
313
+ errors.append(f"{em_id}:source_specific_name_in_mechanism:{name}@{'|'.join(locations)}——本卡「不可照搬」已点名该专名却仍在抽象字段使用,请回 Stage 3 去专名后重试")
314
+ card_errors += 1
315
+ else:
316
+ warnings.append(f"{em_id}:leak_suspect:{name}@{'|'.join(locations)}——角色卡名与通用职能词无法机械区分,请人工复核;确认是专名请回 Stage 3 修卡")
317
+ if card_errors == 0:
318
+ atom_rows.append(_ia_row(book, em_id, card["title"], grade="full"))
319
+ for em_id, title in index_entries:
320
+ if em_id in seen:
321
+ continue
322
+ seen.add(em_id)
323
+ for name in sorted(name for name in names if name in title):
324
+ warnings.append(f"{em_id}:leak_suspect:{name}@索引标题——请人工复核;确认是专名请回 Stage 3 修索引条目")
325
+ atom_rows.append(_ia_row(book, em_id, title, grade="index"))
326
+ return {
327
+ "book": book,
328
+ "cards_full": len(cards),
329
+ "cards_index": sum(1 for em_id, _ in index_entries if em_id not in {card["em_id"] for card in cards}),
330
+ "character_roster": len(names),
331
+ "errors": errors,
332
+ "warnings": warnings,
333
+ "atom_rows": atom_rows,
334
+ }
335
+
336
+
337
+ def check_atoms(root: Path, module_path: Path, book: str,
338
+ workspace: Path | None = None) -> dict[str, Any]:
339
+ """只读自检:报出一本书的卡数、名单规模与全部问题,不写任何文件。"""
340
+ try:
341
+ report = analyze_module(root, module_path, book, workspace)
342
+ except RegisterError as exc:
343
+ return {"ok": False, "book": book, "errors": exc.errors, "warnings": exc.warnings}
344
+ report.pop("atom_rows")
345
+ report["ok"] = not report["errors"]
346
+ return report
347
+
348
+
349
+ def register_atoms(root: Path, module_path: Path, book: str,
350
+ workspace: Path | None = None) -> dict[str, Any]:
351
+ report = analyze_module(root, module_path, book, workspace)
352
+ if report["errors"]:
353
+ raise RegisterError(report["errors"], report["warnings"])
354
+ atom_rows = report["atom_rows"]
355
+
356
+ existing, errors = load_rows(root) if (root / "灵感索引.csv").is_file() else ([], [])
357
+ if errors:
358
+ raise RegisterError(errors, report["warnings"])
359
+ preserved = [
360
+ row
361
+ for row in existing
362
+ if not (row.get("layer") == "原子灵感" and row.get("source_book") == book)
363
+ ]
364
+ layer_order = {"原子灵感": 0, "单小说灵感合并": 1, "跨书灵感聚合": 2}
365
+ combined = preserved + atom_rows
366
+ combined.sort(
367
+ key=lambda row: (
368
+ layer_order.get(row.get("layer", ""), 9),
369
+ row.get("source_book", ""),
370
+ row.get("item_id", ""),
371
+ )
372
+ )
373
+ atomic_write_text(root / "灵感索引.csv", csv_text(combined), encoding="utf-8")
374
+ return {
375
+ "ok": True,
376
+ "book": book,
377
+ "atoms_full": sum(1 for row in atom_rows if row["grade"] == "full"),
378
+ "atoms_index": sum(1 for row in atom_rows if row["grade"] == "index"),
379
+ "index_writes": 1,
380
+ "character_roster": report["character_roster"],
381
+ "warnings": report["warnings"],
382
+ }
383
+
384
+
385
+ def _ia_row(book: str, em_id: str, title: str, grade: str) -> dict[str, str]:
386
+ return {
387
+ "item_id": em_id.replace("EM-", "IA-"),
388
+ "layer": "原子灵感",
389
+ "title": title.strip(),
390
+ "source_book": book,
391
+ "path": "",
392
+ "source_ids": em_id,
393
+ "novel_count": "1",
394
+ "atom_count": "1",
395
+ "grade": grade,
396
+ "tags": "",
397
+ "status": "active",
398
+ }
399
+
400
+
401
+ def parse_tags(raw: str) -> tuple[dict[str, set[str]], list[str]]:
402
+ result: dict[str, set[str]] = {}
403
+ errors: list[str] = []
404
+ if not raw.strip():
405
+ return result, errors
406
+ for part in raw.split(";"):
407
+ if not part.strip():
408
+ continue
409
+ if "=" not in part:
410
+ errors.append(f"tag_missing_equals:{part}")
411
+ continue
412
+ axis, values = (piece.strip() for piece in part.split("=", 1))
413
+ if axis not in TAG_AXES:
414
+ errors.append(f"tag_axis_unknown:{axis}")
415
+ continue
416
+ parsed = {value.strip() for value in values.split("|") if value.strip()}
417
+ if not parsed:
418
+ errors.append(f"tag_value_empty:{axis}")
419
+ continue
420
+ result.setdefault(axis, set()).update(parsed)
421
+ return result, errors
422
+
423
+
424
+ def positive_int(raw: str) -> int | None:
425
+ try:
426
+ value = int(raw)
427
+ except (TypeError, ValueError):
428
+ return None
429
+ return value if value >= 1 else None
430
+
431
+
432
+ def source_ids(raw: str) -> list[str]:
433
+ return [item.strip() for item in re.split(r"[|;]", raw) if item.strip()]
434
+
435
+
436
+ def load_book_em_ids(workspace: Path, source_book: str) -> tuple[set[str], str | None]:
437
+ module_path = workspace / "拆文库" / source_book / "剧情" / "情绪模块.md"
438
+ try:
439
+ module_text = module_path.read_text(encoding="utf-8-sig")
440
+ except (OSError, UnicodeError):
441
+ return set(), "emotion_module_unreadable"
442
+ cards, index_entries, _ = parse_em_module(module_text)
443
+ ids = {card["em_id"] for card in cards} | {em_id for em_id, _ in index_entries}
444
+ return ids, None
445
+
446
+
447
+ def validate(root: Path, workspace: Path | None = None) -> list[str]:
448
+ numbered, errors = load_numbered_rows(root)
449
+ rows = [row for _, row in numbered]
450
+ try:
451
+ ws: Path | None = resolve_workspace(root, workspace)
452
+ except ValueError as exc:
453
+ ws = None
454
+ workspace_error = str(exc)
455
+ vocabulary = load_vocabulary(root)
456
+ if vocabulary is not None:
457
+ errors.extend(vocabulary_errors(vocabulary))
458
+ seen: set[tuple[str, str, str]] = set()
459
+ ia_by_book: dict[str, dict[str, dict[str, str]]] = {}
460
+ nm_by_book: dict[str, dict[str, dict[str, str]]] = {}
461
+ active_single_book_cba: dict[str, int] = {}
462
+ for number, row in numbered:
463
+ item_id = row.get("item_id", "").strip()
464
+ layer = row.get("layer", "").strip()
465
+ book = row.get("source_book", "").strip()
466
+ prefix = LAYERS.get(layer)
467
+ if not prefix:
468
+ errors.append(f"line_{number}:layer_invalid")
469
+ continue
470
+ unique_key = (layer, book if layer != "跨书灵感聚合" else "", item_id)
471
+ if not item_id.startswith(prefix) or unique_key in seen:
472
+ errors.append(f"line_{number}:item_id_invalid_or_duplicate")
473
+ seen.add(unique_key)
474
+ if layer == "原子灵感":
475
+ ia_by_book.setdefault(book, {})[item_id] = row
476
+ if row.get("path", "").strip():
477
+ errors.append(f"line_{number}:ia_must_not_have_card_file")
478
+ if row.get("grade", "").strip() not in {"full", "index"}:
479
+ errors.append(f"line_{number}:ia_grade_invalid")
480
+ else:
481
+ if layer == "单小说灵感合并":
482
+ nm_by_book.setdefault(book, {})[item_id] = row
483
+ relative = row.get("path", "").strip().replace("\\", "/")
484
+ if not relative.startswith(f"{layer}/") or ".." in relative.split("/"):
485
+ errors.append(f"line_{number}:path_outside_layer")
486
+ card_text = ""
487
+ elif not (root / Path(relative)).is_file():
488
+ errors.append(f"line_{number}:path_missing")
489
+ card_text = ""
490
+ else:
491
+ try:
492
+ card_text = (root / Path(relative)).read_text(encoding="utf-8")
493
+ except (OSError, UnicodeError):
494
+ card_text = ""
495
+ if card_text and CARD_PATH_RE.search(card_text):
496
+ errors.append(f"line_{number}:path_reference_in_card——卡内只允许裸 ID,路径按 ID 查灵感索引.csv")
497
+ if row.get("grade", "").strip():
498
+ errors.append(f"line_{number}:grade_reserved_for_ia")
499
+ tags, tag_errors = parse_tags(row.get("tags", ""))
500
+ errors.extend(f"line_{number}:{error}" for error in tag_errors)
501
+ if layer == "跨书灵感聚合":
502
+ missing = REQUIRED_CBA_AXES - set(tags)
503
+ if missing:
504
+ errors.append(f"line_{number}:cba_tags_missing:{'|'.join(sorted(missing))}")
505
+ if vocabulary is not None:
506
+ for axis, values in sorted(tags.items()):
507
+ if axis not in vocabulary:
508
+ continue
509
+ for value in sorted(values - set(vocabulary[axis])):
510
+ errors.append(f"line_{number}:tag_value_not_in_vocabulary:{axis}={value}——先对照 标签词表.md:同义就用表内值,确属新维度先受控扩表")
511
+ novel_count = positive_int(row.get("novel_count", ""))
512
+ if novel_count is None:
513
+ errors.append(f"line_{number}:novel_count_invalid")
514
+ if positive_int(row.get("atom_count", "")) is None:
515
+ errors.append(f"line_{number}:atom_count_invalid")
516
+ if not row.get("source_ids", "").strip():
517
+ errors.append(f"line_{number}:source_ids_missing")
518
+ if novel_count == 1 and "单书假设" not in card_text:
519
+ errors.append(f"line_{number}:single_book_hypothesis_marker_missing")
520
+ if novel_count is not None and novel_count >= 2 and "跨书重复验证" not in card_text:
521
+ errors.append(f"line_{number}:cross_book_validation_marker_missing")
522
+ elif tags:
523
+ errors.append(f"line_{number}:tags_reserved_for_cba")
524
+
525
+ for book, atoms in ia_by_book.items():
526
+ if ws is None:
527
+ errors.append(f"book_{book}:{workspace_error}")
528
+ module_error: str | None = "workspace_not_located"
529
+ em_ids = set()
530
+ else:
531
+ em_ids, module_error = load_book_em_ids(ws, book)
532
+ if module_error:
533
+ errors.append(f"book_{book}:{module_error}")
534
+ registered: set[str] = set()
535
+ for item_id, row in atoms.items():
536
+ refs = source_ids(row.get("source_ids", ""))
537
+ if len(refs) != 1 or not refs[0].startswith("EM-"):
538
+ errors.append(f"{book}/{item_id}:ia_source_em_invalid")
539
+ continue
540
+ if refs[0].replace("EM-", "IA-") != item_id:
541
+ errors.append(f"{book}/{item_id}:ia_id_must_mirror_em_id")
542
+ registered.add(refs[0])
543
+ if positive_int(row.get("novel_count", "")) != 1 or positive_int(row.get("atom_count", "")) != 1:
544
+ errors.append(f"{book}/{item_id}:ia_counts_must_equal_one")
545
+ if not module_error and registered != em_ids:
546
+ missing = sorted(em_ids - registered)
547
+ extra = sorted(registered - em_ids)
548
+ errors.append(f"book_{book}:ia_em_set_mismatch:missing={missing}:extra={extra}")
549
+
550
+ for book, merges in nm_by_book.items():
551
+ atoms = ia_by_book.get(book, {})
552
+ atom_em = {row.get("source_ids", "").strip() for row in atoms.values()}
553
+ for item_id, row in merges.items():
554
+ refs = source_ids(row.get("source_ids", ""))
555
+ if len(refs) < 2:
556
+ errors.append(f"{book}/{item_id}:nm_requires_at_least_two_sources")
557
+ continue
558
+ unknown = sorted(set(refs) - atom_em)
559
+ if unknown:
560
+ errors.append(f"{book}/{item_id}:nm_source_em_missing:{unknown}")
561
+ if positive_int(row.get("novel_count", "")) != 1:
562
+ errors.append(f"{book}/{item_id}:nm_novel_count_must_equal_one")
563
+ if positive_int(row.get("atom_count", "")) != len(set(refs) & atom_em):
564
+ errors.append(f"{book}/{item_id}:nm_atom_count_mismatch")
565
+
566
+ for row in rows:
567
+ if row.get("layer") != "跨书灵感聚合":
568
+ continue
569
+ cba_id = row.get("item_id", "").strip()
570
+ expanded: set[tuple[str, str]] = set()
571
+ unknown_refs: list[str] = []
572
+ for raw_ref in source_ids(row.get("source_ids", "")):
573
+ if "/" not in raw_ref:
574
+ unknown_refs.append(raw_ref)
575
+ continue
576
+ book, ref = raw_ref.rsplit("/", 1)
577
+ if ref.startswith("NM-") and ref in nm_by_book.get(book, {}):
578
+ for em_ref in source_ids(nm_by_book[book][ref].get("source_ids", "")):
579
+ expanded.add((book, em_ref))
580
+ elif ref.startswith("EM-") and ref.replace("EM-", "IA-") in ia_by_book.get(book, {}):
581
+ expanded.add((book, ref))
582
+ else:
583
+ unknown_refs.append(raw_ref)
584
+ if unknown_refs:
585
+ errors.append(f"{cba_id}:cba_source_missing:{sorted(unknown_refs)}")
586
+ if not expanded:
587
+ errors.append(f"{cba_id}:cba_requires_sources")
588
+ continue
589
+ novels = {book for book, _ in expanded}
590
+ if len(novels) == 1 and row.get("status", "").strip() == "active":
591
+ only = next(iter(novels))
592
+ active_single_book_cba[only] = active_single_book_cba.get(only, 0) + 1
593
+ if positive_int(row.get("novel_count", "")) != len(novels):
594
+ errors.append(f"{cba_id}:cba_novel_count_mismatch")
595
+ if positive_int(row.get("atom_count", "")) != len(expanded):
596
+ errors.append(f"{cba_id}:cba_atom_count_mismatch")
597
+ for book, count in sorted(active_single_book_cba.items()):
598
+ if count > 3:
599
+ errors.append(f"book_{book}:active_single_book_cba_limit_exceeded:{count}")
600
+ return errors
601
+
602
+
603
+ def load_vocabulary(root: Path) -> dict[str, list[str]] | None:
604
+ """读 `灵感库/标签词表.md`:`## 轴` 小节下的 `- 值` 行。文件不存在返回 None。"""
605
+ path = root / "标签词表.md"
606
+ if not path.is_file():
607
+ return None
608
+ vocabulary: dict[str, list[str]] = {}
609
+ current_axis: str | None = None
610
+ try:
611
+ text = path.read_text(encoding="utf-8-sig")
612
+ except (OSError, UnicodeError):
613
+ return None
614
+ for line in text.split("\n"):
615
+ stripped = line.strip()
616
+ if stripped.startswith("## "):
617
+ axis = stripped[3:].strip()
618
+ current_axis = axis if axis in TAG_AXES else None
619
+ if current_axis is not None:
620
+ vocabulary.setdefault(current_axis, [])
621
+ continue
622
+ if current_axis is not None and stripped[:2] in {"- ", "* "}:
623
+ value = stripped[2:].split("(")[0].split("(")[0].strip()
624
+ if value and value not in vocabulary[current_axis]:
625
+ vocabulary[current_axis].append(value)
626
+ return vocabulary
627
+
628
+
629
+ def vocabulary_errors(vocabulary: dict[str, list[str]]) -> list[str]:
630
+ """词表自身的健康检查:必填轴齐全。同义判定交给扩表时的人工比对。"""
631
+ return [
632
+ f"vocabulary_axis_missing:{axis}"
633
+ for axis in sorted(REQUIRED_CBA_AXES - set(vocabulary))
634
+ ]
635
+
636
+
637
+ def coverage(root: Path) -> dict[str, Any]:
638
+ """增量入库的机械导航:报出未进入任何 active CBA 闭包的原子。
639
+
640
+ 跨书聚合的 LLM 工作只需要看 uncovered 原子与现存单书假设卡,
641
+ 不必重读已覆盖的 EM 卡。只读,不写盘。
642
+ """
643
+ rows, errors = load_rows(root)
644
+ if errors:
645
+ raise ValueError(";".join(errors))
646
+ ia_by_book: dict[str, set[str]] = {}
647
+ nm_members: dict[tuple[str, str], set[str]] = {}
648
+ for row in rows:
649
+ book = row.get("source_book", "").strip()
650
+ if row.get("layer") == "原子灵感" and row.get("status", "").strip() == "active":
651
+ for ref in source_ids(row.get("source_ids", "")):
652
+ ia_by_book.setdefault(book, set()).add(ref)
653
+ elif row.get("layer") == "单小说灵感合并":
654
+ nm_members[(book, row.get("item_id", "").strip())] = set(source_ids(row.get("source_ids", "")))
655
+ covered: set[tuple[str, str]] = set()
656
+ single_book_hypotheses: list[str] = []
657
+ for row in rows:
658
+ if row.get("layer") != "跨书灵感聚合" or row.get("status", "").strip() != "active":
659
+ continue
660
+ if positive_int(row.get("novel_count", "")) == 1:
661
+ single_book_hypotheses.append(row.get("item_id", "").strip())
662
+ for raw_ref in source_ids(row.get("source_ids", "")):
663
+ if "/" not in raw_ref:
664
+ continue
665
+ book, ref = raw_ref.rsplit("/", 1)
666
+ if ref.startswith("NM-"):
667
+ covered.update((book, em_ref) for em_ref in nm_members.get((book, ref), set()))
668
+ else:
669
+ covered.add((book, ref))
670
+ books: dict[str, dict[str, Any]] = {}
671
+ uncovered_total = 0
672
+ for book in sorted(ia_by_book):
673
+ uncovered = sorted(em for em in ia_by_book[book] if (book, em) not in covered)
674
+ uncovered_total += len(uncovered)
675
+ books[book] = {
676
+ "atoms": len(ia_by_book[book]),
677
+ "covered": len(ia_by_book[book]) - len(uncovered),
678
+ "uncovered": uncovered,
679
+ }
680
+ return {
681
+ "ok": True,
682
+ "books": books,
683
+ "uncovered_total": uncovered_total,
684
+ "single_book_hypotheses": sorted(single_book_hypotheses),
685
+ }
686
+
687
+
688
+ def requested_tags(values: list[str]) -> dict[str, set[str]]:
689
+ tags, errors = parse_tags(";".join(values))
690
+ if errors:
691
+ raise ValueError(";".join(errors))
692
+ return tags
693
+
694
+
695
+ def query(root: Path, values: list[str], limit: int) -> dict[str, Any]:
696
+ """返回 matches 之外还带纠词元数据:请求值在全库零出现时点名
697
+ `unmatched_tags`,并给出所查各轴的现存值清单——零命中先纠词重查,
698
+ 而不是把词表漂移误记成「库里没有」。"""
699
+ rows, errors = load_rows(root)
700
+ if errors:
701
+ raise ValueError(";".join(errors))
702
+ wanted = requested_tags(values)
703
+ axis_values: dict[str, set[str]] = {axis: set() for axis in wanted}
704
+ matches: list[dict[str, Any]] = []
705
+ for row in rows:
706
+ if row.get("layer") != "跨书灵感聚合" or row.get("status") != "active":
707
+ continue
708
+ tags, tag_errors = parse_tags(row.get("tags", ""))
709
+ if tag_errors:
710
+ continue
711
+ for axis in axis_values:
712
+ axis_values[axis].update(tags.get(axis, set()))
713
+ score = 0
714
+ matched: list[str] = []
715
+ core_match = False
716
+ for axis, wanted_values in wanted.items():
717
+ overlap = wanted_values & tags.get(axis, set())
718
+ if overlap:
719
+ score += (2 if axis in CORE_QUERY_AXES else 1) * len(overlap)
720
+ matched.extend(f"{axis}={value}" for value in sorted(overlap))
721
+ if axis in CORE_QUERY_AXES:
722
+ core_match = True
723
+ if score <= 0 or not core_match:
724
+ continue
725
+ matches.append(
726
+ {
727
+ "item_id": row["item_id"],
728
+ "title": row["title"],
729
+ "path": row["path"],
730
+ "score": score,
731
+ "matched_tags": matched,
732
+ "novel_count": positive_int(row.get("novel_count", "")) or 0,
733
+ "atom_count": positive_int(row.get("atom_count", "")) or 0,
734
+ }
735
+ )
736
+ matches.sort(key=lambda item: (-item["score"], -item["novel_count"], -item["atom_count"], item["item_id"]))
737
+ unmatched = [
738
+ f"{axis}={value}"
739
+ for axis in sorted(wanted)
740
+ for value in sorted(wanted[axis] - axis_values[axis])
741
+ ]
742
+ return {
743
+ "matches": matches[: max(3, min(limit, 8))],
744
+ "unmatched_tags": unmatched,
745
+ "axis_inventory": {axis: sorted(found) for axis, found in sorted(axis_values.items())},
746
+ "vocabulary_loaded": load_vocabulary(root) is not None,
747
+ }
748
+
749
+
750
+ def resolve(root: Path, refs: list[str]) -> dict[str, Any]:
751
+ """按 `书名/EM-xxx`、`书名/NM-xxx` 或 `CBA-xxx` 裸 ID 解析可读位置——需要时才查。"""
752
+ rows, errors = load_rows(root)
753
+ if errors:
754
+ raise ValueError(";".join(errors))
755
+ by_key: dict[tuple[str, str], dict[str, str]] = {}
756
+ for row in rows:
757
+ book = row.get("source_book", "").strip() if row.get("layer") != "跨书灵感聚合" else ""
758
+ by_key[(book, row.get("item_id", "").strip())] = row
759
+ resolved: list[dict[str, str]] = []
760
+ missing: list[str] = []
761
+ for raw_ref in refs:
762
+ if "/" in raw_ref:
763
+ book, ref = raw_ref.rsplit("/", 1)
764
+ else:
765
+ book, ref = "", raw_ref
766
+ item = ref.replace("EM-", "IA-") if ref.startswith("EM-") else ref
767
+ row = by_key.get((book if not item.startswith("CBA-") else "", item))
768
+ if row is None:
769
+ missing.append(raw_ref)
770
+ continue
771
+ if row.get("layer") == "原子灵感":
772
+ location = f"拆文库/{book}/剧情/情绪模块.md#{row.get('source_ids', '')}"
773
+ else:
774
+ location = row.get("path", "")
775
+ resolved.append({"ref": raw_ref, "item_id": row.get("item_id", ""), "title": row.get("title", ""), "location": location})
776
+ return {"ok": not missing, "resolved": resolved, "missing": missing}
777
+
778
+
779
+ def parse_args() -> argparse.Namespace:
780
+ parser = argparse.ArgumentParser()
781
+ subparsers = parser.add_subparsers(dest="command", required=True)
782
+ register_parser = subparsers.add_parser("register-atoms")
783
+ register_parser.add_argument("--root", required=True, type=Path)
784
+ register_parser.add_argument("--module", required=True, type=Path)
785
+ register_parser.add_argument("--book", required=True)
786
+ register_parser.add_argument("--workspace", type=Path, default=None)
787
+ check_parser = subparsers.add_parser("check-atoms")
788
+ check_parser.add_argument("--root", required=True, type=Path)
789
+ check_parser.add_argument("--module", required=True, type=Path)
790
+ check_parser.add_argument("--book", required=True)
791
+ check_parser.add_argument("--workspace", type=Path, default=None)
792
+ validate_parser = subparsers.add_parser("validate")
793
+ validate_parser.add_argument("--root", required=True, type=Path)
794
+ validate_parser.add_argument("--workspace", type=Path, default=None)
795
+ coverage_parser = subparsers.add_parser("coverage")
796
+ coverage_parser.add_argument("--root", required=True, type=Path)
797
+ query_parser = subparsers.add_parser("query")
798
+ query_parser.add_argument("--root", required=True, type=Path)
799
+ query_parser.add_argument("--tag", action="append", default=[])
800
+ query_parser.add_argument("--limit", type=int, default=6)
801
+ resolve_parser = subparsers.add_parser("resolve")
802
+ resolve_parser.add_argument("--root", required=True, type=Path)
803
+ resolve_parser.add_argument("--ref", action="append", default=[], required=True)
804
+ return parser.parse_args()
805
+
806
+
807
+ def main() -> int:
808
+ if hasattr(sys.stdout, "reconfigure"):
809
+ sys.stdout.reconfigure(encoding="utf-8")
810
+ args = parse_args()
811
+ try:
812
+ return run(args)
813
+ except (OSError, UnicodeError) as exc:
814
+ message = f"io_error:{exc}"
815
+ print(json.dumps({"ok": False, "error": message, "errors": [message]}, ensure_ascii=False))
816
+ return 2
817
+
818
+
819
+ def run(args: argparse.Namespace) -> int:
820
+ if args.command == "register-atoms":
821
+ try:
822
+ payload = register_atoms(args.root, args.module, args.book.strip(), args.workspace)
823
+ except ValueError as exc:
824
+ errors = getattr(exc, "errors", None) or [str(exc)]
825
+ warnings = getattr(exc, "warnings", [])
826
+ print(json.dumps({"ok": False, "errors": errors, "warnings": warnings}, ensure_ascii=False))
827
+ return 2
828
+ print(json.dumps(payload, ensure_ascii=False))
829
+ return 0
830
+ if args.command == "check-atoms":
831
+ report = check_atoms(args.root, args.module, args.book.strip(), args.workspace)
832
+ print(json.dumps(report, ensure_ascii=False))
833
+ return 0 if report["ok"] else 1
834
+ if args.command == "validate":
835
+ errors = validate(args.root, args.workspace)
836
+ print(json.dumps({"ok": not errors, "errors": errors}, ensure_ascii=False))
837
+ return 0 if not errors else 1
838
+ if args.command == "coverage":
839
+ try:
840
+ payload = coverage(args.root)
841
+ except ValueError as exc:
842
+ print(json.dumps({"ok": False, "error": str(exc)}, ensure_ascii=False))
843
+ return 2
844
+ print(json.dumps(payload, ensure_ascii=False))
845
+ return 0
846
+ if args.command == "resolve":
847
+ try:
848
+ payload = resolve(args.root, args.ref)
849
+ except ValueError as exc:
850
+ print(json.dumps({"ok": False, "error": str(exc)}, ensure_ascii=False))
851
+ return 2
852
+ print(json.dumps(payload, ensure_ascii=False))
853
+ return 0 if payload["ok"] else 1
854
+ try:
855
+ payload = query(args.root, args.tag, args.limit)
856
+ except ValueError as exc:
857
+ print(json.dumps({"ok": False, "error": str(exc)}, ensure_ascii=False))
858
+ return 2
859
+ print(json.dumps({"ok": True, **payload}, ensure_ascii=False))
860
+ return 0
861
+
862
+
863
+ if __name__ == "__main__":
864
+ sys.exit(main())