novelws 3.1.0 → 5.0.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 (358) hide show
  1. package/CHANGELOG.md +115 -564
  2. package/README.md +81 -598
  3. package/dist/cli.js +1 -3
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +18 -103
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/upgrade.d.ts.map +1 -1
  9. package/dist/commands/upgrade.js +18 -52
  10. package/dist/commands/upgrade.js.map +1 -1
  11. package/dist/core/config.d.ts +7 -36
  12. package/dist/core/config.d.ts.map +1 -1
  13. package/dist/core/config.js +11 -38
  14. package/dist/core/config.js.map +1 -1
  15. package/dist/core/errors.d.ts +0 -31
  16. package/dist/core/errors.d.ts.map +1 -1
  17. package/dist/core/errors.js +0 -58
  18. package/dist/core/errors.js.map +1 -1
  19. package/dist/utils/diagnostics.d.ts +2 -16
  20. package/dist/utils/diagnostics.d.ts.map +1 -1
  21. package/dist/utils/diagnostics.js +7 -73
  22. package/dist/utils/diagnostics.js.map +1 -1
  23. package/dist/utils/project.d.ts +1 -1
  24. package/dist/utils/project.d.ts.map +1 -1
  25. package/dist/utils/project.js +3 -3
  26. package/dist/utils/project.js.map +1 -1
  27. package/package.json +1 -2
  28. package/templates/commands/analyze.md +65 -265
  29. package/templates/commands/expand.md +70 -0
  30. package/templates/commands/plan.md +47 -452
  31. package/templates/commands/specify.md +43 -869
  32. package/templates/commands/write.md +49 -556
  33. package/templates/dot-claude/CLAUDE.md +38 -202
  34. package/templates/resources/anti-ai.md +16 -0
  35. package/templates/resources/style-reference.md +19 -0
  36. package/templates/tracking/character-state.json +1 -76
  37. package/templates/tracking/plot-tracker.json +3 -60
  38. package/templates/tracking/relationships.json +1 -68
  39. package/templates/tracking/timeline.json +1 -47
  40. package/dist/commands/plugin.d.ts +0 -6
  41. package/dist/commands/plugin.d.ts.map +0 -1
  42. package/dist/commands/plugin.js +0 -135
  43. package/dist/commands/plugin.js.map +0 -1
  44. package/dist/plugins/identifier.d.ts +0 -13
  45. package/dist/plugins/identifier.d.ts.map +0 -1
  46. package/dist/plugins/identifier.js +0 -72
  47. package/dist/plugins/identifier.js.map +0 -1
  48. package/dist/plugins/installers/base.d.ts +0 -27
  49. package/dist/plugins/installers/base.d.ts.map +0 -1
  50. package/dist/plugins/installers/base.js +0 -30
  51. package/dist/plugins/installers/base.js.map +0 -1
  52. package/dist/plugins/installers/github.d.ts +0 -22
  53. package/dist/plugins/installers/github.d.ts.map +0 -1
  54. package/dist/plugins/installers/github.js +0 -133
  55. package/dist/plugins/installers/github.js.map +0 -1
  56. package/dist/plugins/installers/local.d.ts +0 -16
  57. package/dist/plugins/installers/local.d.ts.map +0 -1
  58. package/dist/plugins/installers/local.js +0 -69
  59. package/dist/plugins/installers/local.js.map +0 -1
  60. package/dist/plugins/installers/npm.d.ts +0 -20
  61. package/dist/plugins/installers/npm.d.ts.map +0 -1
  62. package/dist/plugins/installers/npm.js +0 -99
  63. package/dist/plugins/installers/npm.js.map +0 -1
  64. package/dist/plugins/manager.d.ts +0 -77
  65. package/dist/plugins/manager.d.ts.map +0 -1
  66. package/dist/plugins/manager.js +0 -349
  67. package/dist/plugins/manager.js.map +0 -1
  68. package/dist/plugins/registry.d.ts +0 -48
  69. package/dist/plugins/registry.d.ts.map +0 -1
  70. package/dist/plugins/registry.js +0 -111
  71. package/dist/plugins/registry.js.map +0 -1
  72. package/dist/plugins/types.d.ts +0 -66
  73. package/dist/plugins/types.d.ts.map +0 -1
  74. package/dist/plugins/types.js +0 -2
  75. package/dist/plugins/types.js.map +0 -1
  76. package/dist/plugins/validator.d.ts +0 -19
  77. package/dist/plugins/validator.d.ts.map +0 -1
  78. package/dist/plugins/validator.js +0 -164
  79. package/dist/plugins/validator.js.map +0 -1
  80. package/dist/utils/logger.d.ts +0 -13
  81. package/dist/utils/logger.d.ts.map +0 -1
  82. package/dist/utils/logger.js +0 -48
  83. package/dist/utils/logger.js.map +0 -1
  84. package/plugins/authentic-voice/README.md +0 -31
  85. package/plugins/authentic-voice/commands/authentic-voice.md +0 -73
  86. package/plugins/authentic-voice/commands/authenticity-audit.md +0 -37
  87. package/plugins/authentic-voice/config.yaml +0 -30
  88. package/plugins/authentic-voice/experts/authentic-editor.md +0 -27
  89. package/plugins/export/README.md +0 -319
  90. package/plugins/export/commands/export.md +0 -460
  91. package/plugins/export/commands/generate-cover.md +0 -256
  92. package/plugins/export/commands/metadata.md +0 -309
  93. package/plugins/export/config.yaml +0 -47
  94. package/plugins/export/experts/publishing-expert.md +0 -171
  95. package/plugins/export/templates/epub/chapter-template.html +0 -13
  96. package/plugins/export/templates/epub/cover-template.html +0 -14
  97. package/plugins/export/templates/epub/stylesheet.css +0 -200
  98. package/plugins/export/templates/pdf/ebook-style.css +0 -137
  99. package/plugins/export/templates/pdf/print-style.css +0 -179
  100. package/plugins/export/templates/platforms/jinjiang-format.md +0 -101
  101. package/plugins/export/templates/platforms/qidian-format.md +0 -108
  102. package/plugins/export/templates/platforms/tomato-format.md +0 -95
  103. package/plugins/translate/README.md +0 -265
  104. package/plugins/translate/commands/glossary.md +0 -731
  105. package/plugins/translate/commands/translate-preview.md +0 -543
  106. package/plugins/translate/commands/translate.md +0 -649
  107. package/plugins/translate/config.yaml +0 -43
  108. package/plugins/translate/experts/literary-translator.md +0 -605
  109. package/templates/commands/character.md +0 -287
  110. package/templates/commands/checklist.md +0 -744
  111. package/templates/commands/clarify.md +0 -269
  112. package/templates/commands/constitution.md +0 -269
  113. package/templates/commands/expert.md +0 -188
  114. package/templates/commands/facts.md +0 -552
  115. package/templates/commands/guide.md +0 -900
  116. package/templates/commands/help-me.md +0 -221
  117. package/templates/commands/recap.md +0 -748
  118. package/templates/commands/relations.md +0 -385
  119. package/templates/commands/revise.md +0 -450
  120. package/templates/commands/search.md +0 -531
  121. package/templates/commands/tasks.md +0 -396
  122. package/templates/commands/timeline.md +0 -309
  123. package/templates/commands/track-init.md +0 -149
  124. package/templates/commands/track.md +0 -704
  125. package/templates/commands/volume-summary.md +0 -471
  126. package/templates/config/keyword-mappings.json +0 -226
  127. package/templates/knowledge/audit-config.json +0 -26
  128. package/templates/knowledge/character-profiles.md +0 -152
  129. package/templates/knowledge/character-voices.md +0 -137
  130. package/templates/knowledge/locations.md +0 -184
  131. package/templates/knowledge/world-setting.md +0 -121
  132. package/templates/knowledge-base/README.md +0 -285
  133. package/templates/knowledge-base/character-archetypes/01-hero.md +0 -233
  134. package/templates/knowledge-base/character-archetypes/02-mentor.md +0 -177
  135. package/templates/knowledge-base/character-archetypes/03-shadow.md +0 -221
  136. package/templates/knowledge-base/character-archetypes/04-ally.md +0 -178
  137. package/templates/knowledge-base/character-archetypes/05-shapeshifter.md +0 -177
  138. package/templates/knowledge-base/character-archetypes/06-trickster.md +0 -181
  139. package/templates/knowledge-base/character-archetypes/07-threshold-guardian.md +0 -177
  140. package/templates/knowledge-base/character-archetypes/08-herald.md +0 -180
  141. package/templates/knowledge-base/character-archetypes/09-father.md +0 -249
  142. package/templates/knowledge-base/character-archetypes/10-mother.md +0 -202
  143. package/templates/knowledge-base/character-archetypes/11-child.md +0 -183
  144. package/templates/knowledge-base/character-archetypes/12-sage.md +0 -202
  145. package/templates/knowledge-base/character-archetypes/README.md +0 -60
  146. package/templates/knowledge-base/character-archetypes/application-guide.md +0 -222
  147. package/templates/knowledge-base/character-archetypes/archetype-combinations.md +0 -242
  148. package/templates/knowledge-base/character-archetypes/config.yaml +0 -28
  149. package/templates/knowledge-base/character-archetypes/examples-analysis.md +0 -223
  150. package/templates/knowledge-base/craft/character-arc.md +0 -1153
  151. package/templates/knowledge-base/craft/dialogue.md +0 -1170
  152. package/templates/knowledge-base/craft/hook-design.md +0 -345
  153. package/templates/knowledge-base/craft/pacing.md +0 -1200
  154. package/templates/knowledge-base/craft/power-system.md +0 -254
  155. package/templates/knowledge-base/craft/scene-structure.md +0 -1136
  156. package/templates/knowledge-base/craft/show-not-tell.md +0 -1012
  157. package/templates/knowledge-base/craft/story-structures.md +0 -134
  158. package/templates/knowledge-base/craft/tension-management.md +0 -168
  159. package/templates/knowledge-base/emotional-beats/01-first-meeting.md +0 -145
  160. package/templates/knowledge-base/emotional-beats/02-bonding-moment.md +0 -226
  161. package/templates/knowledge-base/emotional-beats/03-declaration.md +0 -284
  162. package/templates/knowledge-base/emotional-beats/04-triumph.md +0 -240
  163. package/templates/knowledge-base/emotional-beats/05-reunion.md +0 -396
  164. package/templates/knowledge-base/emotional-beats/06-forgiveness.md +0 -204
  165. package/templates/knowledge-base/emotional-beats/07-betrayal.md +0 -204
  166. package/templates/knowledge-base/emotional-beats/08-loss.md +0 -214
  167. package/templates/knowledge-base/emotional-beats/09-rejection.md +0 -254
  168. package/templates/knowledge-base/emotional-beats/10-failure.md +0 -244
  169. package/templates/knowledge-base/emotional-beats/11-misunderstanding.md +0 -205
  170. package/templates/knowledge-base/emotional-beats/12-farewell.md +0 -283
  171. package/templates/knowledge-base/emotional-beats/13-revelation.md +0 -242
  172. package/templates/knowledge-base/emotional-beats/14-point-of-no-return.md +0 -215
  173. package/templates/knowledge-base/emotional-beats/15-dark-night.md +0 -244
  174. package/templates/knowledge-base/emotional-beats/16-sacrifice.md +0 -246
  175. package/templates/knowledge-base/emotional-beats/17-awakening.md +0 -246
  176. package/templates/knowledge-base/emotional-beats/18-confrontation.md +0 -217
  177. package/templates/knowledge-base/emotional-beats/19-bittersweet-goodbye.md +0 -368
  178. package/templates/knowledge-base/emotional-beats/20-moral-dilemma.md +0 -248
  179. package/templates/knowledge-base/emotional-beats/21-temptation.md +0 -240
  180. package/templates/knowledge-base/emotional-beats/22-redemption.md +0 -210
  181. package/templates/knowledge-base/emotional-beats/README.md +0 -104
  182. package/templates/knowledge-base/emotional-beats/beat-sequences.md +0 -276
  183. package/templates/knowledge-base/emotional-beats/config.yaml +0 -30
  184. package/templates/knowledge-base/emotional-beats/pacing-guide.md +0 -390
  185. package/templates/knowledge-base/genres/game-lit.md +0 -174
  186. package/templates/knowledge-base/genres/historical.md +0 -1127
  187. package/templates/knowledge-base/genres/horror.md +0 -211
  188. package/templates/knowledge-base/genres/military.md +0 -209
  189. package/templates/knowledge-base/genres/mystery.md +0 -1123
  190. package/templates/knowledge-base/genres/rebirth.md +0 -177
  191. package/templates/knowledge-base/genres/revenge.md +0 -846
  192. package/templates/knowledge-base/genres/romance.md +0 -948
  193. package/templates/knowledge-base/genres/sci-fi.md +0 -156
  194. package/templates/knowledge-base/genres/sports.md +0 -216
  195. package/templates/knowledge-base/genres/thriller.md +0 -166
  196. package/templates/knowledge-base/genres/urban.md +0 -170
  197. package/templates/knowledge-base/genres/workplace.md +0 -214
  198. package/templates/knowledge-base/genres/wuxia.md +0 -143
  199. package/templates/knowledge-base/genres/xuanhuan.md +0 -234
  200. package/templates/knowledge-base/genres/youth.md +0 -219
  201. package/templates/knowledge-base/references/README.md +0 -96
  202. package/templates/knowledge-base/references/china-1920s/culture.md +0 -423
  203. package/templates/knowledge-base/references/china-1920s/daily-life.md +0 -616
  204. package/templates/knowledge-base/references/china-1920s/overview.md +0 -298
  205. package/templates/knowledge-base/references/china-1920s/society.md +0 -703
  206. package/templates/knowledge-base/references/china-1920s/warlords.md +0 -427
  207. package/templates/knowledge-base/references/cultivation-world/daily-life.md +0 -108
  208. package/templates/knowledge-base/references/cultivation-world/overview.md +0 -64
  209. package/templates/knowledge-base/references/cultivation-world/power-system.md +0 -108
  210. package/templates/knowledge-base/references/cultivation-world/sects.md +0 -104
  211. package/templates/knowledge-base/references/cultivation-world/world-setting.md +0 -108
  212. package/templates/knowledge-base/references/modern-workplace/corporate.md +0 -115
  213. package/templates/knowledge-base/references/modern-workplace/daily-life.md +0 -129
  214. package/templates/knowledge-base/references/modern-workplace/overview.md +0 -73
  215. package/templates/knowledge-base/references/modern-workplace/relationships.md +0 -107
  216. package/templates/knowledge-base/references/modern-workplace/tech-industry.md +0 -131
  217. package/templates/knowledge-base/references/tang-dynasty/culture.md +0 -135
  218. package/templates/knowledge-base/references/tang-dynasty/daily-life.md +0 -139
  219. package/templates/knowledge-base/references/tang-dynasty/overview.md +0 -76
  220. package/templates/knowledge-base/references/tang-dynasty/politics.md +0 -121
  221. package/templates/knowledge-base/references/tang-dynasty/society.md +0 -126
  222. package/templates/knowledge-base/requirements/README.md +0 -240
  223. package/templates/knowledge-base/requirements/anti-ai-v3.md +0 -46
  224. package/templates/knowledge-base/requirements/anti-ai-v4-deprecated.md +0 -442
  225. package/templates/knowledge-base/requirements/anti-ai-v5-balanced.md +0 -203
  226. package/templates/knowledge-base/requirements/concretization.md +0 -90
  227. package/templates/knowledge-base/requirements/fast-paced.md +0 -552
  228. package/templates/knowledge-base/requirements/no-poison.md +0 -60
  229. package/templates/knowledge-base/requirements/romance-angst.md +0 -102
  230. package/templates/knowledge-base/requirements/romance-sweet.md +0 -63
  231. package/templates/knowledge-base/requirements/serious-literature.md +0 -45
  232. package/templates/knowledge-base/requirements/strong-emotion.md +0 -60
  233. package/templates/knowledge-base/styles/README.md +0 -302
  234. package/templates/knowledge-base/styles/ancient-style.md +0 -579
  235. package/templates/knowledge-base/styles/literary.md +0 -439
  236. package/templates/knowledge-base/styles/minimal.md +0 -472
  237. package/templates/knowledge-base/styles/natural-voice.md +0 -930
  238. package/templates/knowledge-base/styles/web-novel.md +0 -525
  239. package/templates/memory/personal-voice.md +0 -113
  240. package/templates/scripts/README.md +0 -187
  241. package/templates/scripts/bash/analyze-story.sh +0 -170
  242. package/templates/scripts/bash/check-analyze-stage.sh +0 -108
  243. package/templates/scripts/bash/check-consistency.sh +0 -463
  244. package/templates/scripts/bash/check-facts.sh +0 -214
  245. package/templates/scripts/bash/check-plot.sh +0 -374
  246. package/templates/scripts/bash/check-timeline.sh +0 -346
  247. package/templates/scripts/bash/check-world.sh +0 -395
  248. package/templates/scripts/bash/check-writing-state.sh +0 -854
  249. package/templates/scripts/bash/clarify-story.sh +0 -117
  250. package/templates/scripts/bash/common.sh +0 -151
  251. package/templates/scripts/bash/constitution.sh +0 -114
  252. package/templates/scripts/bash/generate-tasks.sh +0 -65
  253. package/templates/scripts/bash/init-tracking.sh +0 -183
  254. package/templates/scripts/bash/manage-relations.sh +0 -174
  255. package/templates/scripts/bash/migrate-tracking.sh +0 -183
  256. package/templates/scripts/bash/plan-story.sh +0 -100
  257. package/templates/scripts/bash/specify-story.sh +0 -93
  258. package/templates/scripts/bash/tasks-story.sh +0 -96
  259. package/templates/scripts/bash/test-word-count.sh +0 -182
  260. package/templates/scripts/bash/tests/bench-preload-cache.sh +0 -100
  261. package/templates/scripts/bash/tests/run-all-benchmarks.sh +0 -16
  262. package/templates/scripts/bash/tests/test-cache-semantics.sh +0 -199
  263. package/templates/scripts/bash/tests/test-cross-platform.sh +0 -35
  264. package/templates/scripts/bash/tests/test-edge-cases-bash.sh +0 -60
  265. package/templates/scripts/bash/tests/test-phase1-bash.sh +0 -28
  266. package/templates/scripts/bash/tests/test-preload-cache.sh +0 -123
  267. package/templates/scripts/bash/tests/test-regex-precompile.sh +0 -89
  268. package/templates/scripts/bash/tests/test-regression-bash.sh +0 -42
  269. package/templates/scripts/bash/tests/test-task6-verification.sh +0 -200
  270. package/templates/scripts/bash/text-audit.sh +0 -144
  271. package/templates/scripts/bash/track-progress.sh +0 -194
  272. package/templates/scripts/powershell/analyze-story.ps1 +0 -174
  273. package/templates/scripts/powershell/check-analyze-stage.ps1 +0 -110
  274. package/templates/scripts/powershell/check-consistency.ps1 +0 -138
  275. package/templates/scripts/powershell/check-facts.ps1 +0 -195
  276. package/templates/scripts/powershell/check-plot.ps1 +0 -139
  277. package/templates/scripts/powershell/check-timeline.ps1 +0 -112
  278. package/templates/scripts/powershell/check-writing-state.ps1 +0 -486
  279. package/templates/scripts/powershell/clarify-story.ps1 +0 -107
  280. package/templates/scripts/powershell/common.ps1 +0 -36
  281. package/templates/scripts/powershell/constitution.ps1 +0 -145
  282. package/templates/scripts/powershell/generate-tasks.ps1 +0 -70
  283. package/templates/scripts/powershell/init-tracking.ps1 +0 -98
  284. package/templates/scripts/powershell/manage-relations.ps1 +0 -134
  285. package/templates/scripts/powershell/migrate-tracking.ps1 +0 -145
  286. package/templates/scripts/powershell/plan-story.ps1 +0 -99
  287. package/templates/scripts/powershell/specify-story.ps1 +0 -85
  288. package/templates/scripts/powershell/tests/bench-ps-cache.ps1 +0 -80
  289. package/templates/scripts/powershell/tests/test-cross-platform.ps1 +0 -27
  290. package/templates/scripts/powershell/tests/test-edge-cases-ps.ps1 +0 -29
  291. package/templates/scripts/powershell/tests/test-phase1-ps.ps1 +0 -28
  292. package/templates/scripts/powershell/tests/test-ps-cache.ps1 +0 -73
  293. package/templates/scripts/powershell/tests/test-regression-ps.ps1 +0 -40
  294. package/templates/scripts/powershell/text-audit.ps1 +0 -102
  295. package/templates/scripts/powershell/track-progress.ps1 +0 -105
  296. package/templates/skills/analysis/character-analysis/SKILL.md +0 -71
  297. package/templates/skills/analysis/foreshadow-analysis/SKILL.md +0 -45
  298. package/templates/skills/analysis/hook-analysis/SKILL.md +0 -111
  299. package/templates/skills/analysis/logic-analysis/SKILL.md +0 -58
  300. package/templates/skills/analysis/opening-analysis/SKILL.md +0 -59
  301. package/templates/skills/analysis/pacing-analysis/SKILL.md +0 -55
  302. package/templates/skills/analysis/power-analysis/SKILL.md +0 -148
  303. package/templates/skills/analysis/reader-analysis/SKILL.md +0 -117
  304. package/templates/skills/analysis/style-analysis/SKILL.md +0 -60
  305. package/templates/skills/analysis/voice-analysis/SKILL.md +0 -42
  306. package/templates/skills/auto-tracking/SKILL.md +0 -280
  307. package/templates/skills/genre-knowledge/fantasy/SKILL.md +0 -355
  308. package/templates/skills/genre-knowledge/mystery/SKILL.md +0 -337
  309. package/templates/skills/genre-knowledge/romance/SKILL.md +0 -228
  310. package/templates/skills/genre-knowledge/sci-fi/SKILL.md +0 -65
  311. package/templates/skills/genre-knowledge/thriller/SKILL.md +0 -95
  312. package/templates/skills/planning/volume-detail/SKILL.md +0 -219
  313. package/templates/skills/quality-assurance/consistency-checker/SKILL.md +0 -412
  314. package/templates/skills/quality-assurance/continuity-tracker/SKILL.md +0 -157
  315. package/templates/skills/quality-assurance/facts-checker/SKILL.md +0 -405
  316. package/templates/skills/quality-assurance/forgotten-elements/SKILL.md +0 -147
  317. package/templates/skills/quality-assurance/getting-started/SKILL.md +0 -224
  318. package/templates/skills/quality-assurance/hook-checker/SKILL.md +0 -164
  319. package/templates/skills/quality-assurance/hook-checker/experts/hook-analyst.md +0 -33
  320. package/templates/skills/quality-assurance/long-series-continuity/SKILL.md +0 -570
  321. package/templates/skills/quality-assurance/pacing-monitor/SKILL.md +0 -143
  322. package/templates/skills/quality-assurance/pov-validator/SKILL.md +0 -135
  323. package/templates/skills/quality-assurance/pre-write-checklist/SKILL.md +0 -583
  324. package/templates/skills/quality-assurance/requirement-detector/CONFLICT_RESOLUTION.md +0 -119
  325. package/templates/skills/quality-assurance/requirement-detector/EXAMPLES.md +0 -146
  326. package/templates/skills/quality-assurance/requirement-detector/KEYWORDS.md +0 -160
  327. package/templates/skills/quality-assurance/requirement-detector/SKILL.md +0 -149
  328. package/templates/skills/quality-assurance/setting-detector/SKILL.md +0 -611
  329. package/templates/skills/quality-assurance/style-detector/CONFLICT_RESOLUTION.md +0 -126
  330. package/templates/skills/quality-assurance/style-detector/EXAMPLES.md +0 -206
  331. package/templates/skills/quality-assurance/style-detector/KEYWORDS.md +0 -207
  332. package/templates/skills/quality-assurance/style-detector/SKILL.md +0 -264
  333. package/templates/skills/quality-assurance/voice-consistency-checker/SKILL.md +0 -103
  334. package/templates/skills/quality-assurance/voice-consistency-checker/experts/voice-analyst.md +0 -21
  335. package/templates/skills/quality-assurance/workflow-guide/SKILL.md +0 -381
  336. package/templates/skills/writing-techniques/character-arc/SKILL.md +0 -267
  337. package/templates/skills/writing-techniques/dialogue-techniques/SKILL.md +0 -366
  338. package/templates/skills/writing-techniques/multi-thread-narrative/SKILL.md +0 -708
  339. package/templates/skills/writing-techniques/multi-thread-narrative/experts/thread-analyst.md +0 -226
  340. package/templates/skills/writing-techniques/pacing-control/SKILL.md +0 -480
  341. package/templates/skills/writing-techniques/reader-expectation/SKILL.md +0 -1026
  342. package/templates/skills/writing-techniques/reader-expectation/experts/expectation-analyst.md +0 -209
  343. package/templates/skills/writing-techniques/revision-polish/SKILL.md +0 -496
  344. package/templates/skills/writing-techniques/revision-polish/experts/revision-editor.md +0 -221
  345. package/templates/skills/writing-techniques/scene-structure/SKILL.md +0 -361
  346. package/templates/skills/writing-techniques/style-learning/SKILL.md +0 -436
  347. package/templates/skills/writing-techniques/writing-balance/.gitkeep +0 -0
  348. package/templates/skills/writing-techniques/writing-balance/SKILL.md +0 -460
  349. package/templates/skills/writing-techniques/writing-techniques/SKILL.md +0 -727
  350. package/templates/specification-example.md +0 -146
  351. package/templates/tracking/story-facts.json +0 -5
  352. package/templates/tracking/summary/characters-summary.json +0 -7
  353. package/templates/tracking/summary/plot-summary.json +0 -13
  354. package/templates/tracking/summary/timeline-summary.json +0 -8
  355. package/templates/tracking/summary/volume-summaries.json +0 -5
  356. package/templates/tracking/tracking-log.md +0 -110
  357. package/templates/tracking/validation-rules.json +0 -128
  358. /package/templates/{memory → resources}/constitution.md +0 -0
@@ -1,463 +0,0 @@
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
@@ -1,214 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
-
4
- # check-facts.sh - Story Facts 引用扫描脚本
5
- # 扫描章节中的 story-facts 注释,生成引用报告
6
-
7
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
9
-
10
- # 颜色输出
11
- RED='\033[0;31m'
12
- GREEN='\033[0;32m'
13
- YELLOW='\033[1;33m'
14
- BLUE='\033[0;34m'
15
- BOLD='\033[1m'
16
- NC='\033[0m' # No Color
17
-
18
- # 默认参数
19
- OUTPUT_JSON=false
20
- STORY_NAME=""
21
-
22
- # 解析参数
23
- while [[ $# -gt 0 ]]; do
24
- case $1 in
25
- --json)
26
- OUTPUT_JSON=true
27
- shift
28
- ;;
29
- --story)
30
- STORY_NAME="$2"
31
- shift 2
32
- ;;
33
- *)
34
- echo "Usage: $0 [--json] [--story <story-name>]" >&2
35
- exit 1
36
- ;;
37
- esac
38
- done
39
-
40
- # 检查 story-facts.json 是否存在
41
- FACTS_FILE="$PROJECT_ROOT/spec/tracking/story-facts.json"
42
- if [[ ! -f "$FACTS_FILE" ]]; then
43
- if [[ "$OUTPUT_JSON" == true ]]; then
44
- echo '{"error": "story-facts.json not found", "chapters": [], "unreferenced_facts": [], "unknown_ids": []}'
45
- else
46
- echo -e "${RED}❌ 未找到 story-facts.json${NC}" >&2
47
- echo -e " 路径: $FACTS_FILE" >&2
48
- echo -e " 请先使用 /facts 命令初始化" >&2
49
- fi
50
- exit 1
51
- fi
52
-
53
- # 读取已注册的 fact ID 列表
54
- # 使用 jq 提取(如果有),否则使用 grep + sed
55
- if command -v jq &> /dev/null; then
56
- REGISTERED_FACTS=$(jq -r '.facts[].id' "$FACTS_FILE" 2>/dev/null || echo "")
57
- else
58
- # 降级方案:使用 grep 提取 "id": "xxx"
59
- REGISTERED_FACTS=$(grep -o '"id"[[:space:]]*:[[:space:]]*"[^"]*"' "$FACTS_FILE" | sed 's/"id"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' || echo "")
60
- fi
61
-
62
- # 转换为数组
63
- if [[ -n "$REGISTERED_FACTS" ]]; then
64
- mapfile -t REGISTERED_FACTS_ARRAY <<< "$REGISTERED_FACTS"
65
- else
66
- REGISTERED_FACTS_ARRAY=()
67
- fi
68
-
69
- # 确定扫描目录
70
- if [[ -n "$STORY_NAME" ]]; then
71
- CONTENT_DIR="$PROJECT_ROOT/stories/$STORY_NAME/content"
72
- if [[ ! -d "$CONTENT_DIR" ]]; then
73
- if [[ "$OUTPUT_JSON" == true ]]; then
74
- echo "{\"error\": \"story directory not found: $STORY_NAME\", \"chapters\": [], \"unreferenced_facts\": [], \"unknown_ids\": []}"
75
- else
76
- echo -e "${RED}❌ 未找到故事目录: $STORY_NAME${NC}" >&2
77
- fi
78
- exit 1
79
- fi
80
- SEARCH_PATTERN="$CONTENT_DIR/*.md"
81
- else
82
- SEARCH_PATTERN="$PROJECT_ROOT/stories/*/content/*.md"
83
- fi
84
-
85
- # 初始化数据结构
86
- declare -A chapter_facts # key: 文件路径, value: fact IDs (逗号分隔)
87
- declare -A fact_referenced # key: fact ID, value: 1 if referenced
88
- declare -A unknown_ids_map # key: unknown ID, value: 1
89
-
90
- # 扫描章节文件
91
- shopt -s nullglob # 如果没有匹配文件,glob 返回空而非原始字符串
92
- for chapter_file in $SEARCH_PATTERN; do
93
- # 提取 <!-- story-facts: ... --> 注释
94
- # 正则:<!-- story-facts: (.+?) -->
95
- facts_line=$(grep -oP '<!--\s*story-facts:\s*\K[^-]+(?=\s*-->)' "$chapter_file" || true)
96
-
97
- if [[ -n "$facts_line" ]]; then
98
- # 去除空格,分割为数组
99
- IFS=',' read -ra fact_ids <<< "$facts_line"
100
-
101
- # 处理每个 fact ID
102
- cleaned_ids=()
103
- for id in "${fact_ids[@]}"; do
104
- # 去除前后空格
105
- id=$(echo "$id" | xargs)
106
- if [[ -n "$id" ]]; then
107
- cleaned_ids+=("$id")
108
-
109
- # 检查是否已注册
110
- if printf '%s\n' "${REGISTERED_FACTS_ARRAY[@]}" | grep -q "^${id}$"; then
111
- fact_referenced["$id"]=1
112
- else
113
- unknown_ids_map["$id"]=1
114
- fi
115
- fi
116
- done
117
-
118
- # 保存到 chapter_facts
119
- if [[ ${#cleaned_ids[@]} -gt 0 ]]; then
120
- chapter_facts["$chapter_file"]=$(IFS=,; echo "${cleaned_ids[*]}")
121
- fi
122
- fi
123
- done
124
-
125
- # 计算未被引用的事实
126
- unreferenced_facts=()
127
- for fact_id in "${REGISTERED_FACTS_ARRAY[@]}"; do
128
- if [[ ! -v fact_referenced["$fact_id"] ]]; then
129
- unreferenced_facts+=("$fact_id")
130
- fi
131
- done
132
-
133
- # 收集 unknown IDs
134
- unknown_ids=("${!unknown_ids_map[@]}")
135
-
136
- # 输出结果
137
- if [[ "$OUTPUT_JSON" == true ]]; then
138
- # JSON 输出
139
- echo "{"
140
- echo ' "chapters": ['
141
-
142
- first=true
143
- for file in "${!chapter_facts[@]}"; do
144
- if [[ "$first" == false ]]; then
145
- echo ","
146
- fi
147
- first=false
148
-
149
- # 转换为相对路径
150
- rel_path="${file#$PROJECT_ROOT/}"
151
-
152
- # 转换 fact IDs 为 JSON 数组
153
- IFS=',' read -ra ids <<< "${chapter_facts[$file]}"
154
- ids_json=$(printf '"%s",' "${ids[@]}" | sed 's/,$//')
155
-
156
- echo -n " {\"file\": \"$rel_path\", \"facts\": [$ids_json]}"
157
- done
158
-
159
- if [[ "$first" == false ]]; then
160
- echo ""
161
- fi
162
- echo " ],"
163
-
164
- # unreferenced_facts
165
- echo -n ' "unreferenced_facts": ['
166
- if [[ ${#unreferenced_facts[@]} -gt 0 ]]; then
167
- printf '"%s",' "${unreferenced_facts[@]}" | sed 's/,$//'
168
- fi
169
- echo "],"
170
-
171
- # unknown_ids
172
- echo -n ' "unknown_ids": ['
173
- if [[ ${#unknown_ids[@]} -gt 0 ]]; then
174
- printf '"%s",' "${unknown_ids[@]}" | sed 's/,$//'
175
- fi
176
- echo "]"
177
-
178
- echo "}"
179
- else
180
- # 人类可读输出
181
- echo -e "${BOLD}${BLUE}📊 Story Facts 引用报告${NC}"
182
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
183
- echo ""
184
-
185
- echo -e "${GREEN}已注册事实:${NC} ${#REGISTERED_FACTS_ARRAY[@]} 个"
186
- echo -e "${GREEN}引用章节:${NC} ${#chapter_facts[@]} 个"
187
- echo ""
188
-
189
- if [[ ${#chapter_facts[@]} -gt 0 ]]; then
190
- echo -e "${BOLD}章节引用:${NC}"
191
- for file in "${!chapter_facts[@]}"; do
192
- rel_path="${file#$PROJECT_ROOT/}"
193
- filename=$(basename "$rel_path")
194
- facts="${chapter_facts[$file]}"
195
- echo -e " ${BLUE}$filename${NC} → ${facts//,/, }"
196
- done
197
- echo ""
198
- fi
199
-
200
- if [[ ${#unreferenced_facts[@]} -gt 0 ]]; then
201
- echo -e "${YELLOW}未被引用的事实:${NC} ${unreferenced_facts[*]}"
202
- echo ""
203
- else
204
- echo -e "${GREEN}✓ 所有事实都被至少一个章节引用${NC}"
205
- echo ""
206
- fi
207
-
208
- if [[ ${#unknown_ids[@]} -gt 0 ]]; then
209
- echo -e "${RED}未知 ID (章节中引用但未注册):${NC} ${unknown_ids[*]}"
210
- echo -e " ${YELLOW}提示: 可能是拼写错误或需要注册到 story-facts.json${NC}"
211
- else
212
- echo -e "${GREEN}✓ 未检测到未知 ID${NC}"
213
- fi
214
- fi