novelws 1.2.0

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 (320) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/LICENSE +22 -0
  3. package/README.md +372 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +50 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/check.d.ts +6 -0
  9. package/dist/commands/check.d.ts.map +1 -0
  10. package/dist/commands/check.js +32 -0
  11. package/dist/commands/check.js.map +1 -0
  12. package/dist/commands/init.d.ts +6 -0
  13. package/dist/commands/init.d.ts.map +1 -0
  14. package/dist/commands/init.js +160 -0
  15. package/dist/commands/init.js.map +1 -0
  16. package/dist/commands/plugin.d.ts +6 -0
  17. package/dist/commands/plugin.d.ts.map +1 -0
  18. package/dist/commands/plugin.js +135 -0
  19. package/dist/commands/plugin.js.map +1 -0
  20. package/dist/commands/upgrade.d.ts +6 -0
  21. package/dist/commands/upgrade.d.ts.map +1 -0
  22. package/dist/commands/upgrade.js +92 -0
  23. package/dist/commands/upgrade.js.map +1 -0
  24. package/dist/core/config.d.ts +72 -0
  25. package/dist/core/config.d.ts.map +1 -0
  26. package/dist/core/config.js +136 -0
  27. package/dist/core/config.js.map +1 -0
  28. package/dist/core/errors.d.ts +59 -0
  29. package/dist/core/errors.d.ts.map +1 -0
  30. package/dist/core/errors.js +125 -0
  31. package/dist/core/errors.js.map +1 -0
  32. package/dist/core/platform.d.ts +27 -0
  33. package/dist/core/platform.d.ts.map +1 -0
  34. package/dist/core/platform.js +75 -0
  35. package/dist/core/platform.js.map +1 -0
  36. package/dist/core/template.d.ts +35 -0
  37. package/dist/core/template.d.ts.map +1 -0
  38. package/dist/core/template.js +94 -0
  39. package/dist/core/template.js.map +1 -0
  40. package/dist/plugins/identifier.d.ts +13 -0
  41. package/dist/plugins/identifier.d.ts.map +1 -0
  42. package/dist/plugins/identifier.js +72 -0
  43. package/dist/plugins/identifier.js.map +1 -0
  44. package/dist/plugins/installers/base.d.ts +27 -0
  45. package/dist/plugins/installers/base.d.ts.map +1 -0
  46. package/dist/plugins/installers/base.js +30 -0
  47. package/dist/plugins/installers/base.js.map +1 -0
  48. package/dist/plugins/installers/github.d.ts +22 -0
  49. package/dist/plugins/installers/github.d.ts.map +1 -0
  50. package/dist/plugins/installers/github.js +133 -0
  51. package/dist/plugins/installers/github.js.map +1 -0
  52. package/dist/plugins/installers/local.d.ts +16 -0
  53. package/dist/plugins/installers/local.d.ts.map +1 -0
  54. package/dist/plugins/installers/local.js +69 -0
  55. package/dist/plugins/installers/local.js.map +1 -0
  56. package/dist/plugins/installers/npm.d.ts +20 -0
  57. package/dist/plugins/installers/npm.d.ts.map +1 -0
  58. package/dist/plugins/installers/npm.js +99 -0
  59. package/dist/plugins/installers/npm.js.map +1 -0
  60. package/dist/plugins/manager.d.ts +77 -0
  61. package/dist/plugins/manager.d.ts.map +1 -0
  62. package/dist/plugins/manager.js +349 -0
  63. package/dist/plugins/manager.js.map +1 -0
  64. package/dist/plugins/registry.d.ts +48 -0
  65. package/dist/plugins/registry.d.ts.map +1 -0
  66. package/dist/plugins/registry.js +111 -0
  67. package/dist/plugins/registry.js.map +1 -0
  68. package/dist/plugins/types.d.ts +66 -0
  69. package/dist/plugins/types.d.ts.map +1 -0
  70. package/dist/plugins/types.js +2 -0
  71. package/dist/plugins/types.js.map +1 -0
  72. package/dist/plugins/validator.d.ts +19 -0
  73. package/dist/plugins/validator.d.ts.map +1 -0
  74. package/dist/plugins/validator.js +164 -0
  75. package/dist/plugins/validator.js.map +1 -0
  76. package/dist/utils/logger.d.ts +13 -0
  77. package/dist/utils/logger.d.ts.map +1 -0
  78. package/dist/utils/logger.js +48 -0
  79. package/dist/utils/logger.js.map +1 -0
  80. package/dist/utils/project.d.ts +24 -0
  81. package/dist/utils/project.d.ts.map +1 -0
  82. package/dist/utils/project.js +61 -0
  83. package/dist/utils/project.js.map +1 -0
  84. package/dist/version.d.ts +3 -0
  85. package/dist/version.d.ts.map +1 -0
  86. package/dist/version.js +21 -0
  87. package/dist/version.js.map +1 -0
  88. package/package.json +76 -0
  89. package/plugins/authentic-voice/README.md +31 -0
  90. package/plugins/authentic-voice/commands/authentic-voice.md +73 -0
  91. package/plugins/authentic-voice/commands/authenticity-audit.md +37 -0
  92. package/plugins/authentic-voice/config.yaml +30 -0
  93. package/plugins/authentic-voice/experts/authentic-editor.md +27 -0
  94. package/plugins/export/README.md +319 -0
  95. package/plugins/export/commands/export.md +460 -0
  96. package/plugins/export/commands/generate-cover.md +256 -0
  97. package/plugins/export/commands/metadata.md +309 -0
  98. package/plugins/export/config.yaml +47 -0
  99. package/plugins/export/experts/publishing-expert.md +171 -0
  100. package/plugins/export/templates/epub/chapter-template.html +13 -0
  101. package/plugins/export/templates/epub/cover-template.html +14 -0
  102. package/plugins/export/templates/epub/stylesheet.css +200 -0
  103. package/plugins/export/templates/pdf/ebook-style.css +137 -0
  104. package/plugins/export/templates/pdf/print-style.css +179 -0
  105. package/plugins/export/templates/platforms/jinjiang-format.md +101 -0
  106. package/plugins/export/templates/platforms/qidian-format.md +108 -0
  107. package/plugins/export/templates/platforms/tomato-format.md +95 -0
  108. package/plugins/translate/README.md +265 -0
  109. package/plugins/translate/commands/glossary.md +731 -0
  110. package/plugins/translate/commands/translate-preview.md +543 -0
  111. package/plugins/translate/commands/translate.md +649 -0
  112. package/plugins/translate/config.yaml +43 -0
  113. package/plugins/translate/experts/literary-translator.md +605 -0
  114. package/templates/commands/analyze.md +1485 -0
  115. package/templates/commands/checklist.md +434 -0
  116. package/templates/commands/clarify.md +257 -0
  117. package/templates/commands/constitution.md +257 -0
  118. package/templates/commands/expert.md +136 -0
  119. package/templates/commands/plan.md +749 -0
  120. package/templates/commands/recap.md +613 -0
  121. package/templates/commands/relations.md +96 -0
  122. package/templates/commands/revise.md +341 -0
  123. package/templates/commands/specify.md +682 -0
  124. package/templates/commands/tasks.md +142 -0
  125. package/templates/commands/timeline.md +73 -0
  126. package/templates/commands/track-init.md +137 -0
  127. package/templates/commands/track.md +463 -0
  128. package/templates/commands/write.md +1264 -0
  129. package/templates/config/keyword-mappings.json +106 -0
  130. package/templates/knowledge/audit-config.json +26 -0
  131. package/templates/knowledge/character-profiles.md +152 -0
  132. package/templates/knowledge/character-voices.md +137 -0
  133. package/templates/knowledge/locations.md +184 -0
  134. package/templates/knowledge/world-setting.md +121 -0
  135. package/templates/knowledge-base/README.md +285 -0
  136. package/templates/knowledge-base/character-archetypes/01-hero.md +233 -0
  137. package/templates/knowledge-base/character-archetypes/02-mentor.md +177 -0
  138. package/templates/knowledge-base/character-archetypes/03-shadow.md +221 -0
  139. package/templates/knowledge-base/character-archetypes/04-ally.md +178 -0
  140. package/templates/knowledge-base/character-archetypes/05-shapeshifter.md +177 -0
  141. package/templates/knowledge-base/character-archetypes/06-trickster.md +181 -0
  142. package/templates/knowledge-base/character-archetypes/07-threshold-guardian.md +177 -0
  143. package/templates/knowledge-base/character-archetypes/08-herald.md +180 -0
  144. package/templates/knowledge-base/character-archetypes/09-father.md +249 -0
  145. package/templates/knowledge-base/character-archetypes/10-mother.md +202 -0
  146. package/templates/knowledge-base/character-archetypes/11-child.md +183 -0
  147. package/templates/knowledge-base/character-archetypes/12-sage.md +202 -0
  148. package/templates/knowledge-base/character-archetypes/README.md +60 -0
  149. package/templates/knowledge-base/character-archetypes/application-guide.md +222 -0
  150. package/templates/knowledge-base/character-archetypes/archetype-combinations.md +242 -0
  151. package/templates/knowledge-base/character-archetypes/config.yaml +28 -0
  152. package/templates/knowledge-base/character-archetypes/examples-analysis.md +223 -0
  153. package/templates/knowledge-base/craft/character-arc.md +1153 -0
  154. package/templates/knowledge-base/craft/dialogue.md +1170 -0
  155. package/templates/knowledge-base/craft/pacing.md +1200 -0
  156. package/templates/knowledge-base/craft/scene-structure.md +1136 -0
  157. package/templates/knowledge-base/craft/show-not-tell.md +1012 -0
  158. package/templates/knowledge-base/emotional-beats/01-first-meeting.md +145 -0
  159. package/templates/knowledge-base/emotional-beats/02-bonding-moment.md +226 -0
  160. package/templates/knowledge-base/emotional-beats/03-declaration.md +284 -0
  161. package/templates/knowledge-base/emotional-beats/04-triumph.md +240 -0
  162. package/templates/knowledge-base/emotional-beats/05-reunion.md +396 -0
  163. package/templates/knowledge-base/emotional-beats/06-forgiveness.md +204 -0
  164. package/templates/knowledge-base/emotional-beats/07-betrayal.md +204 -0
  165. package/templates/knowledge-base/emotional-beats/08-loss.md +214 -0
  166. package/templates/knowledge-base/emotional-beats/09-rejection.md +254 -0
  167. package/templates/knowledge-base/emotional-beats/10-failure.md +244 -0
  168. package/templates/knowledge-base/emotional-beats/11-misunderstanding.md +205 -0
  169. package/templates/knowledge-base/emotional-beats/12-farewell.md +283 -0
  170. package/templates/knowledge-base/emotional-beats/13-revelation.md +242 -0
  171. package/templates/knowledge-base/emotional-beats/14-point-of-no-return.md +215 -0
  172. package/templates/knowledge-base/emotional-beats/15-dark-night.md +244 -0
  173. package/templates/knowledge-base/emotional-beats/16-sacrifice.md +246 -0
  174. package/templates/knowledge-base/emotional-beats/17-awakening.md +246 -0
  175. package/templates/knowledge-base/emotional-beats/18-confrontation.md +217 -0
  176. package/templates/knowledge-base/emotional-beats/19-bittersweet-goodbye.md +368 -0
  177. package/templates/knowledge-base/emotional-beats/20-moral-dilemma.md +248 -0
  178. package/templates/knowledge-base/emotional-beats/21-temptation.md +240 -0
  179. package/templates/knowledge-base/emotional-beats/22-redemption.md +210 -0
  180. package/templates/knowledge-base/emotional-beats/README.md +104 -0
  181. package/templates/knowledge-base/emotional-beats/beat-sequences.md +276 -0
  182. package/templates/knowledge-base/emotional-beats/config.yaml +30 -0
  183. package/templates/knowledge-base/emotional-beats/pacing-guide.md +390 -0
  184. package/templates/knowledge-base/genres/historical.md +1127 -0
  185. package/templates/knowledge-base/genres/mystery.md +1123 -0
  186. package/templates/knowledge-base/genres/revenge.md +846 -0
  187. package/templates/knowledge-base/genres/romance.md +948 -0
  188. package/templates/knowledge-base/genres/sci-fi.md +156 -0
  189. package/templates/knowledge-base/genres/thriller.md +166 -0
  190. package/templates/knowledge-base/genres/wuxia.md +143 -0
  191. package/templates/knowledge-base/references/README.md +96 -0
  192. package/templates/knowledge-base/references/china-1920s/culture.md +423 -0
  193. package/templates/knowledge-base/references/china-1920s/daily-life.md +616 -0
  194. package/templates/knowledge-base/references/china-1920s/overview.md +298 -0
  195. package/templates/knowledge-base/references/china-1920s/society.md +703 -0
  196. package/templates/knowledge-base/references/china-1920s/warlords.md +427 -0
  197. package/templates/knowledge-base/references/cultivation-world/daily-life.md +108 -0
  198. package/templates/knowledge-base/references/cultivation-world/overview.md +64 -0
  199. package/templates/knowledge-base/references/cultivation-world/power-system.md +108 -0
  200. package/templates/knowledge-base/references/cultivation-world/sects.md +104 -0
  201. package/templates/knowledge-base/references/cultivation-world/world-setting.md +108 -0
  202. package/templates/knowledge-base/references/modern-workplace/corporate.md +115 -0
  203. package/templates/knowledge-base/references/modern-workplace/daily-life.md +129 -0
  204. package/templates/knowledge-base/references/modern-workplace/overview.md +73 -0
  205. package/templates/knowledge-base/references/modern-workplace/relationships.md +107 -0
  206. package/templates/knowledge-base/references/modern-workplace/tech-industry.md +131 -0
  207. package/templates/knowledge-base/references/tang-dynasty/culture.md +135 -0
  208. package/templates/knowledge-base/references/tang-dynasty/daily-life.md +139 -0
  209. package/templates/knowledge-base/references/tang-dynasty/overview.md +76 -0
  210. package/templates/knowledge-base/references/tang-dynasty/politics.md +121 -0
  211. package/templates/knowledge-base/references/tang-dynasty/society.md +126 -0
  212. package/templates/knowledge-base/requirements/README.md +240 -0
  213. package/templates/knowledge-base/requirements/anti-ai-v3.md +46 -0
  214. package/templates/knowledge-base/requirements/anti-ai-v4.md +430 -0
  215. package/templates/knowledge-base/requirements/fast-paced.md +552 -0
  216. package/templates/knowledge-base/requirements/no-poison.md +60 -0
  217. package/templates/knowledge-base/requirements/romance-angst.md +102 -0
  218. package/templates/knowledge-base/requirements/romance-sweet.md +63 -0
  219. package/templates/knowledge-base/requirements/serious-literature.md +45 -0
  220. package/templates/knowledge-base/requirements/strong-emotion.md +60 -0
  221. package/templates/knowledge-base/styles/README.md +302 -0
  222. package/templates/knowledge-base/styles/ancient-style.md +579 -0
  223. package/templates/knowledge-base/styles/literary.md +439 -0
  224. package/templates/knowledge-base/styles/minimal.md +472 -0
  225. package/templates/knowledge-base/styles/natural-voice.md +930 -0
  226. package/templates/knowledge-base/styles/web-novel.md +525 -0
  227. package/templates/memory/constitution.md +140 -0
  228. package/templates/memory/personal-voice.md +113 -0
  229. package/templates/scripts/README.md +187 -0
  230. package/templates/scripts/bash/analyze-story.sh +170 -0
  231. package/templates/scripts/bash/check-consistency.sh +463 -0
  232. package/templates/scripts/bash/check-plot.sh +374 -0
  233. package/templates/scripts/bash/check-timeline.sh +346 -0
  234. package/templates/scripts/bash/check-world.sh +395 -0
  235. package/templates/scripts/bash/check-writing-state.sh +854 -0
  236. package/templates/scripts/bash/clarify-story.sh +117 -0
  237. package/templates/scripts/bash/common.sh +151 -0
  238. package/templates/scripts/bash/constitution.sh +114 -0
  239. package/templates/scripts/bash/generate-tasks.sh +65 -0
  240. package/templates/scripts/bash/init-tracking.sh +183 -0
  241. package/templates/scripts/bash/manage-relations.sh +174 -0
  242. package/templates/scripts/bash/plan-story.sh +100 -0
  243. package/templates/scripts/bash/specify-story.sh +93 -0
  244. package/templates/scripts/bash/tasks-story.sh +96 -0
  245. package/templates/scripts/bash/test-word-count.sh +182 -0
  246. package/templates/scripts/bash/tests/bench-preload-cache.sh +100 -0
  247. package/templates/scripts/bash/tests/run-all-benchmarks.sh +16 -0
  248. package/templates/scripts/bash/tests/test-cache-semantics.sh +199 -0
  249. package/templates/scripts/bash/tests/test-cross-platform.sh +35 -0
  250. package/templates/scripts/bash/tests/test-edge-cases-bash.sh +60 -0
  251. package/templates/scripts/bash/tests/test-phase1-bash.sh +28 -0
  252. package/templates/scripts/bash/tests/test-preload-cache.sh +123 -0
  253. package/templates/scripts/bash/tests/test-regex-precompile.sh +89 -0
  254. package/templates/scripts/bash/tests/test-regression-bash.sh +42 -0
  255. package/templates/scripts/bash/tests/test-task6-verification.sh +200 -0
  256. package/templates/scripts/bash/text-audit.sh +144 -0
  257. package/templates/scripts/bash/track-progress.sh +194 -0
  258. package/templates/scripts/powershell/analyze-story.ps1 +171 -0
  259. package/templates/scripts/powershell/check-analyze-stage.ps1 +110 -0
  260. package/templates/scripts/powershell/check-consistency.ps1 +138 -0
  261. package/templates/scripts/powershell/check-plot.ps1 +139 -0
  262. package/templates/scripts/powershell/check-timeline.ps1 +112 -0
  263. package/templates/scripts/powershell/check-writing-state.ps1 +490 -0
  264. package/templates/scripts/powershell/check-writing-state.ps1.backup +135 -0
  265. package/templates/scripts/powershell/clarify-story.ps1 +107 -0
  266. package/templates/scripts/powershell/common.ps1 +36 -0
  267. package/templates/scripts/powershell/constitution.ps1 +142 -0
  268. package/templates/scripts/powershell/generate-tasks.ps1 +75 -0
  269. package/templates/scripts/powershell/init-tracking.ps1 +98 -0
  270. package/templates/scripts/powershell/manage-relations.ps1 +134 -0
  271. package/templates/scripts/powershell/plan-story.ps1 +96 -0
  272. package/templates/scripts/powershell/specify-story.ps1 +82 -0
  273. package/templates/scripts/powershell/tests/bench-ps-cache.ps1 +80 -0
  274. package/templates/scripts/powershell/tests/test-cross-platform.ps1 +27 -0
  275. package/templates/scripts/powershell/tests/test-edge-cases-ps.ps1 +29 -0
  276. package/templates/scripts/powershell/tests/test-phase1-ps.ps1 +28 -0
  277. package/templates/scripts/powershell/tests/test-ps-cache.ps1 +73 -0
  278. package/templates/scripts/powershell/tests/test-regression-ps.ps1 +40 -0
  279. package/templates/scripts/powershell/text-audit.ps1 +100 -0
  280. package/templates/scripts/powershell/track-progress.ps1 +105 -0
  281. package/templates/skills/genre-knowledge/fantasy/SKILL.md +355 -0
  282. package/templates/skills/genre-knowledge/mystery/SKILL.md +337 -0
  283. package/templates/skills/genre-knowledge/romance/SKILL.md +228 -0
  284. package/templates/skills/genre-knowledge/sci-fi/SKILL.md +65 -0
  285. package/templates/skills/genre-knowledge/thriller/SKILL.md +95 -0
  286. package/templates/skills/quality-assurance/consistency-checker/SKILL.md +341 -0
  287. package/templates/skills/quality-assurance/continuity-tracker/SKILL.md +157 -0
  288. package/templates/skills/quality-assurance/forgotten-elements/SKILL.md +147 -0
  289. package/templates/skills/quality-assurance/getting-started/SKILL.md +224 -0
  290. package/templates/skills/quality-assurance/pacing-monitor/SKILL.md +143 -0
  291. package/templates/skills/quality-assurance/pov-validator/SKILL.md +135 -0
  292. package/templates/skills/quality-assurance/pre-write-checklist/SKILL.md +583 -0
  293. package/templates/skills/quality-assurance/requirement-detector/CONFLICT_RESOLUTION.md +119 -0
  294. package/templates/skills/quality-assurance/requirement-detector/EXAMPLES.md +146 -0
  295. package/templates/skills/quality-assurance/requirement-detector/KEYWORDS.md +160 -0
  296. package/templates/skills/quality-assurance/requirement-detector/SKILL.md +149 -0
  297. package/templates/skills/quality-assurance/setting-detector/SKILL.md +611 -0
  298. package/templates/skills/quality-assurance/style-detector/CONFLICT_RESOLUTION.md +126 -0
  299. package/templates/skills/quality-assurance/style-detector/EXAMPLES.md +206 -0
  300. package/templates/skills/quality-assurance/style-detector/KEYWORDS.md +207 -0
  301. package/templates/skills/quality-assurance/style-detector/SKILL.md +126 -0
  302. package/templates/skills/quality-assurance/workflow-guide/SKILL.md +381 -0
  303. package/templates/skills/writing-techniques/character-arc/SKILL.md +267 -0
  304. package/templates/skills/writing-techniques/dialogue-techniques/SKILL.md +366 -0
  305. package/templates/skills/writing-techniques/multi-thread-narrative/SKILL.md +553 -0
  306. package/templates/skills/writing-techniques/multi-thread-narrative/experts/thread-analyst.md +226 -0
  307. package/templates/skills/writing-techniques/pacing-control/SKILL.md +377 -0
  308. package/templates/skills/writing-techniques/reader-expectation/SKILL.md +578 -0
  309. package/templates/skills/writing-techniques/reader-expectation/experts/expectation-analyst.md +209 -0
  310. package/templates/skills/writing-techniques/revision-polish/SKILL.md +496 -0
  311. package/templates/skills/writing-techniques/revision-polish/experts/revision-editor.md +221 -0
  312. package/templates/skills/writing-techniques/scene-structure/SKILL.md +361 -0
  313. package/templates/skills/writing-techniques/style-learning/SKILL.md +436 -0
  314. package/templates/specification-example.md +146 -0
  315. package/templates/tracking/character-state.json +78 -0
  316. package/templates/tracking/plot-tracker.json +62 -0
  317. package/templates/tracking/relationships.json +70 -0
  318. package/templates/tracking/timeline.json +49 -0
  319. package/templates/tracking/tracking-log.md +110 -0
  320. package/templates/tracking/validation-rules.json +128 -0
@@ -0,0 +1,463 @@
1
+ #!/usr/bin/env bash
2
+ # 综合一致性检查脚本
3
+
4
+ set -e
5
+
6
+ # 加载通用函数
7
+ SCRIPT_DIR=$(dirname "$0")
8
+ source "$SCRIPT_DIR/common.sh"
9
+
10
+ # 检查模式
11
+ CHECKLIST_MODE=false
12
+ if [ "$1" = "--checklist" ]; then
13
+ CHECKLIST_MODE=true
14
+ fi
15
+
16
+ # 获取当前故事目录
17
+ STORY_DIR=$(get_current_story)
18
+
19
+ if [ -z "$STORY_DIR" ]; then
20
+ echo "错误: 未找到故事项目" >&2
21
+ exit 1
22
+ fi
23
+
24
+ # 文件路径
25
+ PROGRESS="$STORY_DIR/progress.json"
26
+ PLOT_TRACKER="$STORY_DIR/spec/tracking/plot-tracker.json"
27
+ TIMELINE="$STORY_DIR/spec/tracking/timeline.json"
28
+ RELATIONSHIPS="$STORY_DIR/spec/tracking/relationships.json"
29
+ CHARACTER_STATE="$STORY_DIR/spec/tracking/character-state.json"
30
+
31
+ # ANSI颜色代码
32
+ RED='\033[0;31m'
33
+ GREEN='\033[0;32m'
34
+ YELLOW='\033[1;33m'
35
+ BLUE='\033[0;34m'
36
+ NC='\033[0m' # No Color
37
+
38
+ # 统计变量
39
+ TOTAL_CHECKS=0
40
+ PASSED_CHECKS=0
41
+ WARNINGS=0
42
+ ERRORS=0
43
+
44
+ # 检查函数
45
+ check() {
46
+ local name="$1"
47
+ local condition="$2"
48
+ local error_msg="$3"
49
+
50
+ ((TOTAL_CHECKS++))
51
+
52
+ if eval "$condition"; then
53
+ echo -e "${GREEN}✓${NC} $name"
54
+ ((PASSED_CHECKS++))
55
+ else
56
+ echo -e "${RED}✗${NC} $name: $error_msg"
57
+ ((ERRORS++))
58
+ fi
59
+ }
60
+
61
+ warn() {
62
+ local msg="$1"
63
+ echo -e "${YELLOW}⚠${NC} 警告: $msg"
64
+ ((WARNINGS++))
65
+ }
66
+
67
+ # 检查章节号一致性
68
+ check_chapter_consistency() {
69
+ echo "📖 检查章节号一致性"
70
+ echo "───────────────────"
71
+
72
+ if [ -f "$PROGRESS" ] && [ -f "$PLOT_TRACKER" ]; then
73
+ PROGRESS_CHAPTER=$(jq -r '.statistics.currentChapter // 0' "$PROGRESS")
74
+ PLOT_CHAPTER=$(jq -r '.currentState.chapter // 0' "$PLOT_TRACKER")
75
+
76
+ check "章节号同步" \
77
+ "[ '$PROGRESS_CHAPTER' = '$PLOT_CHAPTER' ]" \
78
+ "progress.json(${PROGRESS_CHAPTER}) != plot-tracker.json(${PLOT_CHAPTER})"
79
+
80
+ if [ -f "$CHARACTER_STATE" ]; then
81
+ CHAR_CHAPTER=$(jq -r '.protagonist.currentStatus.chapter // 0' "$CHARACTER_STATE")
82
+ check "角色状态章节同步" \
83
+ "[ '$PROGRESS_CHAPTER' = '$CHAR_CHAPTER' ]" \
84
+ "与character-state.json(${CHAR_CHAPTER})不一致"
85
+ fi
86
+ else
87
+ warn "部分追踪文件缺失,无法完成章节检查"
88
+ fi
89
+
90
+ echo ""
91
+ }
92
+
93
+ # 检查时间线连续性
94
+ check_timeline_consistency() {
95
+ echo "⏰ 检查时间线连续性"
96
+ echo "───────────────────"
97
+
98
+ if [ -f "$TIMELINE" ]; then
99
+ # 检查时间事件是否按章节递增
100
+ TIMELINE_ISSUES=$(jq '
101
+ .events |
102
+ sort_by(.chapter) |
103
+ . as $sorted |
104
+ reduce range(1; length) as $i (0;
105
+ if $sorted[$i].chapter <= $sorted[$i-1].chapter then . + 1 else . end
106
+ )' "$TIMELINE")
107
+
108
+ check "时间事件顺序" \
109
+ "[ '$TIMELINE_ISSUES' = '0' ]" \
110
+ "发现${TIMELINE_ISSUES}个乱序事件"
111
+
112
+ # 检查当前时间是否更新
113
+ CURRENT_TIME=$(jq -r '.storyTime.current // ""' "$TIMELINE")
114
+ check "当前时间设置" \
115
+ "[ -n '$CURRENT_TIME' ]" \
116
+ "当前故事时间未设置"
117
+ else
118
+ warn "时间线文件不存在"
119
+ fi
120
+
121
+ echo ""
122
+ }
123
+
124
+ # 检查角色状态合理性
125
+ check_character_consistency() {
126
+ echo "👥 检查角色状态合理性"
127
+ echo "─────────────────────"
128
+
129
+ if [ -f "$CHARACTER_STATE" ] && [ -f "$RELATIONSHIPS" ]; then
130
+ # 检查主角是否存在于两个文件中
131
+ PROTAG_NAME=$(jq -r '.protagonist.name // ""' "$CHARACTER_STATE")
132
+
133
+ if [ -n "$PROTAG_NAME" ]; then
134
+ HAS_RELATIONS=$(jq --arg name "$PROTAG_NAME" \
135
+ 'has($name)' "$RELATIONSHIPS" 2>/dev/null || echo "false")
136
+
137
+ check "主角关系记录" \
138
+ "[ '$HAS_RELATIONS' = 'true' ]" \
139
+ "主角'$PROTAG_NAME'在relationships.json中无记录"
140
+ fi
141
+
142
+ # 检查角色位置逻辑
143
+ LAST_LOCATION=$(jq -r '.protagonist.currentStatus.location // ""' "$CHARACTER_STATE")
144
+ check "主角位置记录" \
145
+ "[ -n '$LAST_LOCATION' ]" \
146
+ "主角当前位置未记录"
147
+ else
148
+ warn "角色追踪文件不完整"
149
+ fi
150
+
151
+ echo ""
152
+ }
153
+
154
+ # 检查伏笔回收计划
155
+ check_foreshadowing_plan() {
156
+ echo "🎯 检查伏笔管理"
157
+ echo "──────────────"
158
+
159
+ if [ -f "$PLOT_TRACKER" ]; then
160
+ # 统计伏笔状态
161
+ TOTAL_FORESHADOW=$(jq '.foreshadowing | length' "$PLOT_TRACKER")
162
+ ACTIVE_FORESHADOW=$(jq '[.foreshadowing[] | select(.status == "active")] | length' "$PLOT_TRACKER")
163
+
164
+ if [ -f "$PROGRESS" ]; then
165
+ CURRENT_CHAPTER=$(jq -r '.statistics.currentChapter // 0' "$PROGRESS")
166
+
167
+ # 检查超期未回收的伏笔
168
+ OVERDUE=$(jq --arg current "$CURRENT_CHAPTER" '
169
+ [.foreshadowing[] |
170
+ select(.status == "active" and .planted.chapter and
171
+ (($current | tonumber) - .planted.chapter) > 50)] |
172
+ length' "$PLOT_TRACKER")
173
+
174
+ check "伏笔回收及时性" \
175
+ "[ '$OVERDUE' = '0' ]" \
176
+ "有${OVERDUE}个伏笔超过50章未回收"
177
+ fi
178
+
179
+ echo " 📊 伏笔统计: 总计${TOTAL_FORESHADOW}个,活跃${ACTIVE_FORESHADOW}个"
180
+
181
+ # 警告过多活跃伏笔
182
+ if [ "$ACTIVE_FORESHADOW" -gt 10 ]; then
183
+ warn "活跃伏笔过多(${ACTIVE_FORESHADOW}个),可能造成读者困惑"
184
+ fi
185
+ else
186
+ warn "情节追踪文件不存在"
187
+ fi
188
+
189
+ echo ""
190
+ }
191
+
192
+ # 检查文件完整性
193
+ check_file_integrity() {
194
+ echo "📁 检查文件完整性"
195
+ echo "────────────────"
196
+
197
+ check "progress.json" "[ -f '$PROGRESS' ]" "文件不存在"
198
+ check "plot-tracker.json" "[ -f '$PLOT_TRACKER' ]" "文件不存在"
199
+ check "timeline.json" "[ -f '$TIMELINE' ]" "文件不存在"
200
+ check "relationships.json" "[ -f '$RELATIONSHIPS' ]" "文件不存在"
201
+ check "character-state.json" "[ -f '$CHARACTER_STATE' ]" "文件不存在"
202
+
203
+ # 检查JSON格式是否有效
204
+ for file in "$PROGRESS" "$PLOT_TRACKER" "$TIMELINE" "$RELATIONSHIPS" "$CHARACTER_STATE"; do
205
+ if [ -f "$file" ]; then
206
+ filename=$(basename "$file")
207
+ if jq empty "$file" 2>/dev/null; then
208
+ check "$filename格式" "true" ""
209
+ else
210
+ check "$filename格式" "false" "JSON格式无效"
211
+ fi
212
+ fi
213
+ done
214
+
215
+ echo ""
216
+ }
217
+
218
+ # 生成报告
219
+ generate_report() {
220
+ echo "═══════════════════════════════════════"
221
+ echo "📊 综合一致性检查报告"
222
+ echo "═══════════════════════════════════════"
223
+ echo ""
224
+
225
+ check_file_integrity
226
+ check_chapter_consistency
227
+ check_timeline_consistency
228
+ check_character_consistency
229
+ check_foreshadowing_plan
230
+
231
+ echo "═══════════════════════════════════════"
232
+ echo "📈 检查结果汇总"
233
+ echo "───────────────────"
234
+ echo " 总检查项: ${TOTAL_CHECKS}"
235
+ echo -e " ${GREEN}通过: ${PASSED_CHECKS}${NC}"
236
+ echo -e " ${YELLOW}警告: ${WARNINGS}${NC}"
237
+ echo -e " ${RED}错误: ${ERRORS}${NC}"
238
+
239
+ if [ "$ERRORS" -eq 0 ] && [ "$WARNINGS" -eq 0 ]; then
240
+ echo ""
241
+ echo -e "${GREEN}✅ 完美!所有检查项全部通过${NC}"
242
+ elif [ "$ERRORS" -eq 0 ]; then
243
+ echo ""
244
+ echo -e "${YELLOW}⚠️ 存在${WARNINGS}个警告,建议关注${NC}"
245
+ else
246
+ echo ""
247
+ echo -e "${RED}❌ 发现${ERRORS}个错误,需要修正${NC}"
248
+ fi
249
+
250
+ echo "═══════════════════════════════════════"
251
+ echo ""
252
+ echo "检查时间: $(date '+%Y-%m-%d %H:%M:%S')"
253
+
254
+ # 记录检查结果
255
+ if [ -f "$STORY_DIR/spec/tracking" ]; then
256
+ echo "{
257
+ \"timestamp\": \"$(date -Iseconds)\",
258
+ \"total\": $TOTAL_CHECKS,
259
+ \"passed\": $PASSED_CHECKS,
260
+ \"warnings\": $WARNINGS,
261
+ \"errors\": $ERRORS
262
+ }" > "$STORY_DIR/spec/tracking/.last-check.json"
263
+ fi
264
+ }
265
+
266
+ # 生成 checklist 格式输出
267
+ output_checklist() {
268
+ # 静默执行检查逻辑
269
+ exec 3>&1 4>&2 # 保存原始输出
270
+ exec 1>/dev/null 2>&1 # 重定向到null
271
+
272
+ check_file_integrity
273
+ check_chapter_consistency
274
+ check_timeline_consistency
275
+ check_character_consistency
276
+ check_foreshadowing_plan
277
+
278
+ exec 1>&3 2>&4 # 恢复输出
279
+
280
+ # 获取章节号用于检查
281
+ local progress_chapter=""
282
+ local plot_chapter=""
283
+ local char_chapter=""
284
+ if [ -f "$PROGRESS" ] && [ -f "$PLOT_TRACKER" ]; then
285
+ progress_chapter=$(jq -r '.statistics.currentChapter // 0' "$PROGRESS" 2>/dev/null || echo "0")
286
+ plot_chapter=$(jq -r '.currentState.chapter // 0' "$PLOT_TRACKER" 2>/dev/null || echo "0")
287
+ fi
288
+ if [ -f "$CHARACTER_STATE" ]; then
289
+ char_chapter=$(jq -r '.protagonist.currentStatus.chapter // 0' "$CHARACTER_STATE" 2>/dev/null || echo "0")
290
+ fi
291
+
292
+ # 检查伏笔状态
293
+ local total_foreshadow=0
294
+ local active_foreshadow=0
295
+ local overdue_foreshadow=0
296
+ if [ -f "$PLOT_TRACKER" ]; then
297
+ total_foreshadow=$(jq '.foreshadowing | length' "$PLOT_TRACKER" 2>/dev/null || echo "0")
298
+ active_foreshadow=$(jq '[.foreshadowing[] | select(.status == "active")] | length' "$PLOT_TRACKER" 2>/dev/null || echo "0")
299
+
300
+ if [ -f "$PROGRESS" ]; then
301
+ local current_chapter=$(jq -r '.statistics.currentChapter // 0' "$PROGRESS" 2>/dev/null || echo "0")
302
+ overdue_foreshadow=$(jq --arg current "$current_chapter" '[.foreshadowing[] | select(.status == "active" and .planted.chapter and (($current | tonumber) - .planted.chapter) > 50)] | length' "$PLOT_TRACKER" 2>/dev/null || echo "0")
303
+ fi
304
+ fi
305
+
306
+ # 输出 checklist 格式
307
+ cat <<EOF
308
+ # 数据同步一致性检查 Checklist
309
+
310
+ **检查时间**: $(date '+%Y-%m-%d %H:%M:%S')
311
+ **检查对象**: spec/tracking/ 目录所有JSON文件
312
+ **检查范围**: 文件完整性、章节同步、时间线连续性、角色状态、伏笔管理
313
+
314
+ ---
315
+
316
+ ## 文件完整性
317
+
318
+ - [$([ -f "$PROGRESS" ] && echo "x" || echo " ")] CHK001 progress.json 存在且格式有效
319
+ - [$([ -f "$PLOT_TRACKER" ] && echo "x" || echo " ")] CHK002 plot-tracker.json 存在且格式有效
320
+ - [$([ -f "$TIMELINE" ] && echo "x" || echo " ")] CHK003 timeline.json 存在且格式有效
321
+ - [$([ -f "$RELATIONSHIPS" ] && echo "x" || echo " ")] CHK004 relationships.json 存在且格式有效
322
+ - [$([ -f "$CHARACTER_STATE" ] && echo "x" || echo " ")] CHK005 character-state.json 存在且格式有效
323
+
324
+ ## 章节号同步
325
+
326
+ EOF
327
+
328
+ if [ "$progress_chapter" = "$plot_chapter" ]; then
329
+ echo "- [x] CHK006 progress.json 与 plot-tracker.json 章节号一致(第 $progress_chapter 章)"
330
+ else
331
+ echo "- [!] CHK006 progress.json(${progress_chapter}) 与 plot-tracker.json(${plot_chapter}) 章节号不一致"
332
+ fi
333
+
334
+ if [ -n "$char_chapter" ]; then
335
+ if [ "$progress_chapter" = "$char_chapter" ]; then
336
+ echo "- [x] CHK007 progress.json 与 character-state.json 章节号一致"
337
+ else
338
+ echo "- [!] CHK007 progress.json(${progress_chapter}) 与 character-state.json(${char_chapter}) 章节号不一致"
339
+ fi
340
+ else
341
+ echo "- [ ] CHK007 character-state.json 章节号检查(文件不存在或缺少数据)"
342
+ fi
343
+
344
+ cat <<EOF
345
+
346
+ ## 时间线连续性
347
+
348
+ - [$([ -f "$TIMELINE" ] && echo "x" || echo " ")] CHK008 时间线事件按章节有序排列
349
+ - [$([ -f "$TIMELINE" ] && echo "x" || echo " ")] CHK009 当前故事时间已设置
350
+
351
+ ## 角色状态
352
+
353
+ EOF
354
+
355
+ if [ -f "$CHARACTER_STATE" ] && [ -f "$RELATIONSHIPS" ]; then
356
+ local protag_name=$(jq -r '.protagonist.name // ""' "$CHARACTER_STATE" 2>/dev/null)
357
+ if [ -n "$protag_name" ]; then
358
+ echo "- [x] CHK010 主角信息完整($protag_name)"
359
+ local has_relations=$(jq --arg name "$protag_name" 'has($name)' "$RELATIONSHIPS" 2>/dev/null || echo "false")
360
+ if [ "$has_relations" = "true" ]; then
361
+ echo "- [x] CHK011 主角在 relationships.json 中有关系记录"
362
+ else
363
+ echo "- [!] CHK011 主角'$protag_name'在 relationships.json 中无关系记录"
364
+ fi
365
+ else
366
+ echo "- [ ] CHK010 主角信息完整(缺少数据)"
367
+ echo "- [ ] CHK011 主角关系记录(缺少数据)"
368
+ fi
369
+
370
+ local last_location=$(jq -r '.protagonist.currentStatus.location // ""' "$CHARACTER_STATE" 2>/dev/null)
371
+ if [ -n "$last_location" ]; then
372
+ echo "- [x] CHK012 主角当前位置已记录($last_location)"
373
+ else
374
+ echo "- [!] CHK012 主角当前位置未记录"
375
+ fi
376
+ else
377
+ echo "- [ ] CHK010 主角信息完整(文件不存在)"
378
+ echo "- [ ] CHK011 主角关系记录(文件不存在)"
379
+ echo "- [ ] CHK012 主角当前位置已记录(文件不存在)"
380
+ fi
381
+
382
+ cat <<EOF
383
+
384
+ ## 伏笔管理
385
+
386
+ EOF
387
+
388
+ if [ "$total_foreshadow" -gt 0 ]; then
389
+ echo "- [x] CHK013 伏笔记录存在(总计 $total_foreshadow 个,活跃 $active_foreshadow 个)"
390
+
391
+ if [ "$overdue_foreshadow" -eq 0 ]; then
392
+ echo "- [x] CHK014 伏笔回收及时(无超期未回收)"
393
+ else
394
+ echo "- [!] CHK014 伏笔回收及时(有 $overdue_foreshadow 个超过50章未回收)"
395
+ fi
396
+
397
+ if [ "$active_foreshadow" -le 10 ]; then
398
+ echo "- [x] CHK015 活跃伏笔数量合理($active_foreshadow ≤ 10)"
399
+ else
400
+ echo "- [!] CHK015 活跃伏笔数量过多($active_foreshadow > 10,可能造成读者困惑)"
401
+ fi
402
+ else
403
+ echo "- [ ] CHK013 伏笔记录存在(未找到伏笔记录)"
404
+ echo "- [ ] CHK014 伏笔回收及时(无数据)"
405
+ echo "- [ ] CHK015 活跃伏笔数量合理(无数据)"
406
+ fi
407
+
408
+ cat <<EOF
409
+
410
+ ---
411
+
412
+ ## 检查统计
413
+
414
+ - **总检查项**: ${TOTAL_CHECKS}
415
+ - **已通过**: ${PASSED_CHECKS}
416
+ - **警告**: ${WARNINGS}
417
+ - **错误**: ${ERRORS}
418
+
419
+ ---
420
+
421
+ ## 后续行动
422
+
423
+ EOF
424
+
425
+ if [ "$ERRORS" -gt 0 ]; then
426
+ echo "- [ ] 修复上述标记为 [!] 的不一致问题"
427
+ fi
428
+ if [ "$WARNINGS" -gt 0 ]; then
429
+ echo "- [ ] 关注警告项,考虑是否需要改进"
430
+ fi
431
+ if [ "$ERRORS" -eq 0 ] && [ "$WARNINGS" -eq 0 ]; then
432
+ echo "*所有检查通过,无需行动*"
433
+ fi
434
+
435
+ cat <<EOF
436
+
437
+ ---
438
+
439
+ **检查工具**: check-consistency.sh
440
+ **版本**: 1.1 (支持 checklist 输出)
441
+ EOF
442
+ }
443
+
444
+ # 主函数
445
+ main() {
446
+ if [ "$CHECKLIST_MODE" = true ]; then
447
+ output_checklist
448
+ else
449
+ generate_report
450
+ fi
451
+
452
+ # 根据结果返回适当的退出码
453
+ if [ "$ERRORS" -gt 0 ]; then
454
+ exit 1
455
+ elif [ "$WARNINGS" -gt 0 ]; then
456
+ exit 0 # 警告不算失败
457
+ else
458
+ exit 0
459
+ fi
460
+ }
461
+
462
+ # 执行主函数
463
+ main