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,490 @@
1
+ # 检查写作状态脚本
2
+ # 用于 /write 命令
3
+
4
+ param(
5
+ [switch]$Json
6
+ )
7
+
8
+ # ============================================
9
+ # Phase 1: 文件时间戳缓存
10
+ # ============================================
11
+ #
12
+ # 缓存值约定:
13
+ # - LastWriteTime 对象: 文件存在,值为修改时间
14
+ # - $null: 文件不存在(预加载时已确认)
15
+ # - 未缓存: 键不存在于 HashTable 中
16
+
17
+ # 缓存存储(HashTable)
18
+ $script:FileMTimeCache = @{}
19
+ $script:PreloadCompleted = $false
20
+
21
+ # ============================================
22
+ # Phase 2: 资源去重机制
23
+ # ============================================
24
+ #
25
+ # 用于避免在单次脚本执行中重复检查同一资源文件
26
+
27
+ # Phase 2: 资源去重 HashTable
28
+ $script:loadedResourcesSet = @{}
29
+
30
+ # Phase 2: 检查资源是否已加载
31
+ # 参数: Path (string) - 资源路径
32
+ # 返回: $true(已加载),$false(未加载)
33
+ function Is-ResourceLoaded {
34
+ param([string]$path)
35
+ return $script:loadedResourcesSet.ContainsKey($path)
36
+ }
37
+
38
+ # Phase 2: 标记资源为已加载
39
+ # 参数: Path (string) - 资源路径
40
+ function Mark-ResourceLoaded {
41
+ param([string]$path)
42
+ $script:loadedResourcesSet[$path] = $true
43
+ }
44
+
45
+ # ============================================
46
+ # Phase 3: 缓存文件清理机制
47
+ # ============================================
48
+ #
49
+ # 清理超过 24 小时的旧缓存文件,避免磁盘空间浪费
50
+ # 防御性设计:缓存目录不存在时直接返回
51
+
52
+ function Cleanup-OldCache {
53
+ $cacheDir = Join-Path $ProjectRoot ".specify" ".cache"
54
+
55
+ # 缓存目录不存在,无需清理
56
+ if (-not (Test-Path $cacheDir)) {
57
+ return
58
+ }
59
+
60
+ # 删除超过 24 小时的缓存文件
61
+ $cutoffTime = (Get-Date).AddDays(-1)
62
+ Get-ChildItem -Path $cacheDir -Filter "*.json" -File -ErrorAction SilentlyContinue |
63
+ Where-Object { $_.LastWriteTime -lt $cutoffTime } |
64
+ Remove-Item -Force -ErrorAction SilentlyContinue
65
+
66
+ # 删除空目录
67
+ Get-ChildItem -Path $cacheDir -Directory -ErrorAction SilentlyContinue |
68
+ Where-Object { (Get-ChildItem $_.FullName -ErrorAction SilentlyContinue).Count -eq 0 } |
69
+ Remove-Item -Force -ErrorAction SilentlyContinue
70
+ }
71
+
72
+ # 预加载文件修改时间到缓存
73
+ # 参数: FilePathList (string[]) - 文件路径列表
74
+ # 说明: 预加载策略避免多次磁盘访问
75
+ function Preload-FileMTimes {
76
+ param(
77
+ [Parameter(Mandatory=$true)]
78
+ [string[]]$FilePathList
79
+ )
80
+
81
+ foreach ($filePath in $FilePathList) {
82
+ # 文件不存在:记录为 $null
83
+ if (-not (Test-Path $filePath -PathType Leaf)) {
84
+ $script:FileMTimeCache[$filePath] = $null
85
+ continue
86
+ }
87
+
88
+ # 读取文件时间戳
89
+ try {
90
+ $fileInfo = Get-Item $filePath -ErrorAction Stop
91
+ $script:FileMTimeCache[$filePath] = $fileInfo.LastWriteTime
92
+ } catch {
93
+ # Get-Item 失败:记录为空 DateTime
94
+ $script:FileMTimeCache[$filePath] = [DateTime]::MinValue
95
+ }
96
+ }
97
+ }
98
+
99
+ # 获取文件修改时间(从缓存)
100
+ # 参数: FilePath (string) - 文件路径
101
+ # 返回: DateTime 对象,或 $null(文件不存在),或 MinValue(读取失败)
102
+ function Get-FileMTimeFromCache {
103
+ param(
104
+ [Parameter(Mandatory=$true)]
105
+ [string]$FilePath
106
+ )
107
+
108
+ if ($script:FileMTimeCache.ContainsKey($FilePath)) {
109
+ return $script:FileMTimeCache[$FilePath]
110
+ }
111
+
112
+ # 未缓存:返回 MinValue
113
+ return [DateTime]::MinValue
114
+ }
115
+
116
+ # 检查文件是否存在(基于缓存)
117
+ # 参数: FilePath (string) - 文件路径
118
+ # 返回: $true(文件存在),$false(文件不存在或未缓存)
119
+ function Test-FileExistsCached {
120
+ param(
121
+ [Parameter(Mandatory=$true)]
122
+ [string]$FilePath
123
+ )
124
+
125
+ $mtime = Get-FileMTimeFromCache $FilePath
126
+
127
+ # $null: 文件不存在
128
+ # MinValue: Get-Item 失败或未缓存
129
+ # 其他 DateTime: 文件存在
130
+ return ($null -ne $mtime -and $mtime -ne [DateTime]::MinValue)
131
+ }
132
+
133
+ # 导入通用函数
134
+ . "$PSScriptRoot\common.ps1"
135
+
136
+ # 获取项目根目录
137
+ $ProjectRoot = Get-ProjectRoot
138
+ Set-Location $ProjectRoot
139
+
140
+ # 获取当前故事
141
+ $StoryName = Get-ActiveStory
142
+ $StoryDir = Join-Path "stories" $StoryName
143
+
144
+ # 预加载文件时间戳(性能优化)
145
+ if (-not $script:PreloadCompleted) {
146
+ $preloadFileList = @(
147
+ # 知识库文件
148
+ (Join-Path $ProjectRoot "templates/knowledge-base/craft/dialogue.md")
149
+ (Join-Path $ProjectRoot "templates/knowledge-base/craft/scene-structure.md")
150
+ (Join-Path $ProjectRoot "templates/knowledge-base/craft/character-arc.md")
151
+ (Join-Path $ProjectRoot "templates/knowledge-base/craft/pacing.md")
152
+ (Join-Path $ProjectRoot "templates/knowledge-base/craft/show-not-tell.md")
153
+ # Skill 文件
154
+ (Join-Path $ProjectRoot "templates/skills/writing-techniques/dialogue-techniques/SKILL.md")
155
+ (Join-Path $ProjectRoot "templates/skills/writing-techniques/scene-structure/SKILL.md")
156
+ (Join-Path $ProjectRoot "templates/skills/writing-techniques/character-arc/SKILL.md")
157
+ (Join-Path $ProjectRoot "templates/skills/writing-techniques/pacing-control/SKILL.md")
158
+ (Join-Path $ProjectRoot "templates/skills/quality-assurance/consistency-checker/SKILL.md")
159
+ # 规格文件
160
+ (Join-Path $StoryDir "specification.md")
161
+ )
162
+
163
+ Preload-FileMTimes -FilePathList $preloadFileList
164
+ $script:PreloadCompleted = $true
165
+ }
166
+
167
+ # Phase 3: 清理旧缓存(轻量级,不影响性能)
168
+ Cleanup-OldCache
169
+
170
+ # ==================== 资源加载报告生成函数 ====================
171
+
172
+ function Generate-LoadReport {
173
+ param (
174
+ [string]$StoryDir
175
+ )
176
+
177
+ # Phase 3: 性能监控
178
+ $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
179
+
180
+ $specFile = Join-Path $StoryDir "specification.md"
181
+ $warnings = @()
182
+
183
+ # 默认加载所有资源
184
+ $knowledgeBaseFiles = @(
185
+ "craft/dialogue.md",
186
+ "craft/scene-structure.md",
187
+ "craft/character-arc.md",
188
+ "craft/pacing.md",
189
+ "craft/show-not-tell.md"
190
+ )
191
+
192
+ $skillsFiles = @(
193
+ "writing-techniques/dialogue-techniques",
194
+ "writing-techniques/scene-structure",
195
+ "writing-techniques/character-arc",
196
+ "writing-techniques/pacing-control",
197
+ "quality-assurance/consistency-checker"
198
+ )
199
+
200
+ $disabledResources = @()
201
+ $hasConfig = $false
202
+
203
+ if (Test-Path $specFile) {
204
+ $content = Get-Content $specFile -Raw
205
+ if ($content -match "resource-loading:") {
206
+ $hasConfig = $true
207
+ }
208
+ }
209
+
210
+ # 检查文件存在性(使用缓存 + Phase 2: 资源去重)
211
+ foreach ($kb in $knowledgeBaseFiles) {
212
+ $kbPath = "templates/knowledge-base/$kb"
213
+
214
+ # Phase 2: 资源去重检查
215
+ if (Is-ResourceLoaded $kbPath) {
216
+ # 资源已检查过,跳过
217
+ continue
218
+ }
219
+
220
+ # 标记为已加载
221
+ Mark-ResourceLoaded $kbPath
222
+
223
+ # 检查文件是否存在(使用完整路径)
224
+ $fullPath = Join-Path $ProjectRoot $kbPath
225
+ if (-not (Test-FileExistsCached $fullPath)) {
226
+ $warnings += "知识库文件不存在: $kb"
227
+ }
228
+ }
229
+
230
+ foreach ($skill in $skillsFiles) {
231
+ $skillPath = "templates/skills/$skill/SKILL.md"
232
+
233
+ # Phase 2: 资源去重检查
234
+ if (Is-ResourceLoaded $skillPath) {
235
+ # 资源已检查过,跳过
236
+ continue
237
+ }
238
+
239
+ # 标记为已加载
240
+ Mark-ResourceLoaded $skillPath
241
+
242
+ # 检查文件是否存在(使用完整路径)
243
+ $fullPath = Join-Path $ProjectRoot $skillPath
244
+ if (-not (Test-FileExistsCached $fullPath)) {
245
+ $warnings += "Skill 文件不存在: $skill/SKILL.md"
246
+ }
247
+ }
248
+
249
+ # Phase 2: 检测缓存命中(基于 specification.md 是否已被缓存加载且有效)
250
+ # 仅当文件在缓存中且成功读取时,才视为"缓存命中"
251
+ # 缓存语义: $null = 文件不存在, MinValue = stat 失败, DateTime = 成功读取
252
+ $cached = $script:FileMTimeCache.ContainsKey($specFile) -and
253
+ $script:FileMTimeCache[$specFile] -ne $null -and
254
+ $script:FileMTimeCache[$specFile] -ne [DateTime]::MinValue
255
+ $cacheHint = "此报告基于缓存生成(specification.md 未修改)。AI 可复用本次会话中已加载的资源。"
256
+
257
+ # 生成 JSON
258
+ $report = @{
259
+ status = "ready"
260
+ timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
261
+ has_config = $hasConfig
262
+ cached = $cached
263
+ session_cache_enabled = $true
264
+ resources = @{
265
+ "knowledge-base" = $knowledgeBaseFiles
266
+ skills = $skillsFiles
267
+ disabled = $disabledResources
268
+ }
269
+ warnings = $warnings
270
+ }
271
+
272
+ # 仅在缓存命中时添加 cache_hint
273
+ if ($cached) {
274
+ $report.cache_hint = $cacheHint
275
+ }
276
+
277
+ # Phase 3: 性能指标
278
+ $stopwatch.Stop()
279
+ $report.performance = @{
280
+ generation_time_ms = $stopwatch.ElapsedMilliseconds
281
+ cache_hit = $cached
282
+ }
283
+
284
+ return $report | ConvertTo-Json -Depth 10
285
+ }
286
+
287
+ # JSON 模式
288
+ if ($Json) {
289
+ try {
290
+ $report = Generate-LoadReport -StoryDir $StoryDir
291
+ Write-Output $report
292
+ exit 0
293
+ } catch {
294
+ Write-Error "生成资源加载报告失败: $_"
295
+ exit 1
296
+ }
297
+ }
298
+
299
+ Write-Host "写作状态检查"
300
+ Write-Host "============"
301
+ Write-Host "当前故事:$StoryName"
302
+ Write-Host ""
303
+
304
+ # 检查方法论文档
305
+ function Test-MethodologyDocs {
306
+ $missing = @()
307
+
308
+ if (-not (Test-Path ".specify\memory\constitution.md")) {
309
+ $missing += "宪法"
310
+ }
311
+ if (-not (Test-Path "$StoryDir\specification.md")) {
312
+ $missing += "规格"
313
+ }
314
+ if (-not (Test-Path "$StoryDir\creative-plan.md")) {
315
+ $missing += "计划"
316
+ }
317
+ if (-not (Test-Path "$StoryDir\tasks.md")) {
318
+ $missing += "任务"
319
+ }
320
+
321
+ if ($missing.Count -gt 0) {
322
+ Write-Host "⚠️ 缺少以下基准文档:" -ForegroundColor Yellow
323
+ foreach ($doc in $missing) {
324
+ Write-Host " - $doc"
325
+ }
326
+ Write-Host ""
327
+ Write-Host "建议按照七步方法论完成前置步骤:"
328
+ Write-Host "1. /constitution - 创建创作宪法"
329
+ Write-Host "2. /specify - 定义故事规格"
330
+ Write-Host "3. /clarify - 澄清关键决策"
331
+ Write-Host "4. /plan - 制定创作计划"
332
+ Write-Host "5. /tasks - 生成任务清单"
333
+ return $false
334
+ }
335
+
336
+ Write-Host "✅ 方法论文档完整" -ForegroundColor Green
337
+ return $true
338
+ }
339
+
340
+ # 检查待写作任务
341
+ function Test-PendingTasks {
342
+ $tasksFile = "$StoryDir\tasks.md"
343
+
344
+ if (-not (Test-Path $tasksFile)) {
345
+ Write-Host "❌ 任务文件不存在" -ForegroundColor Red
346
+ return $false
347
+ }
348
+
349
+ # 统计任务状态
350
+ $content = Get-Content $tasksFile -Raw
351
+ $pending = ([regex]::Matches($content, '^- \[ \]', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
352
+ $inProgress = ([regex]::Matches($content, '^- \[~\]', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
353
+ $completed = ([regex]::Matches($content, '^- \[x\]', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
354
+
355
+ Write-Host ""
356
+ Write-Host "任务状态:"
357
+ Write-Host " 待开始:$pending"
358
+ Write-Host " 进行中:$inProgress"
359
+ Write-Host " 已完成:$completed"
360
+
361
+ if ($pending -eq 0 -and $inProgress -eq 0) {
362
+ Write-Host ""
363
+ Write-Host "🎉 所有任务已完成!" -ForegroundColor Green
364
+ Write-Host "建议运行 /analyze 进行综合验证"
365
+ return $true
366
+ }
367
+
368
+ # 显示下一个待写作任务
369
+ Write-Host ""
370
+ Write-Host "下一个写作任务:"
371
+ $lines = $content -split "`n"
372
+ foreach ($line in $lines) {
373
+ if ($line -match '^- \[ \]') {
374
+ Write-Host $line
375
+ break
376
+ }
377
+ }
378
+
379
+ return $true
380
+ }
381
+
382
+ # 检查已完成内容
383
+ function Test-CompletedContent {
384
+ $contentDir = "$StoryDir\content"
385
+
386
+ if (Test-Path $contentDir) {
387
+ $mdFiles = Get-ChildItem "$contentDir\*.md" -ErrorAction SilentlyContinue
388
+ $chapterCount = $mdFiles.Count
389
+
390
+ if ($chapterCount -gt 0) {
391
+ Write-Host ""
392
+ Write-Host "已完成章节:$chapterCount"
393
+ Write-Host "最近写作:"
394
+
395
+ $recentFiles = $mdFiles |
396
+ Sort-Object LastWriteTime -Descending |
397
+ Select-Object -First 3
398
+
399
+ foreach ($file in $recentFiles) {
400
+ Write-Host " - $($file.Name)"
401
+ }
402
+ }
403
+ }
404
+ else {
405
+ Write-Host ""
406
+ Write-Host "尚未开始写作"
407
+ }
408
+ }
409
+
410
+ # ==================== 新增:资源加载检查函数 ====================
411
+
412
+ function Check-KnowledgeBaseAvailable {
413
+ $missing = @()
414
+ $available = @()
415
+
416
+ $craftFiles = @(
417
+ "templates/knowledge-base/craft/dialogue.md",
418
+ "templates/knowledge-base/craft/scene-structure.md",
419
+ "templates/knowledge-base/craft/character-arc.md",
420
+ "templates/knowledge-base/craft/pacing.md",
421
+ "templates/knowledge-base/craft/show-not-tell.md"
422
+ )
423
+
424
+ foreach ($file in $craftFiles) {
425
+ $fullPath = Join-Path $ProjectRoot $file
426
+
427
+ # 使用缓存检查文件是否存在
428
+ if (Test-FileExistsCached $fullPath) {
429
+ $available += $file
430
+ } else {
431
+ $missing += $file
432
+ }
433
+ }
434
+
435
+ if ($missing.Count -gt 0) {
436
+ Write-Host "⚠️ 缺少以下 knowledge-base 文件:"
437
+ foreach ($file in $missing) {
438
+ Write-Host " - $file"
439
+ }
440
+ return $false
441
+ }
442
+
443
+ Write-Host "✅ Knowledge-base 文件完整 ($($available.Count) 个)"
444
+ return $true
445
+ }
446
+
447
+ function Check-SkillsAvailable {
448
+ $missing = @()
449
+ $available = @()
450
+
451
+ $skillDirs = @(
452
+ "templates/skills/writing-techniques/dialogue-techniques",
453
+ "templates/skills/writing-techniques/scene-structure",
454
+ "templates/skills/writing-techniques/character-arc",
455
+ "templates/skills/writing-techniques/pacing-control"
456
+ )
457
+
458
+ foreach ($dir in $skillDirs) {
459
+ $skillPath = Join-Path $ProjectRoot "$dir/SKILL.md"
460
+
461
+ # 使用缓存检查文件是否存在
462
+ if (Test-FileExistsCached $skillPath) {
463
+ $available += $dir
464
+ } else {
465
+ $missing += $dir
466
+ }
467
+ }
468
+
469
+ if ($missing.Count -gt 0) {
470
+ Write-Host "⚠️ 缺少以下 skills:"
471
+ foreach ($dir in $missing) {
472
+ Write-Host " - $dir/SKILL.md"
473
+ }
474
+ return $false
475
+ }
476
+
477
+ Write-Host "✅ Skills 完整 ($($available.Count) 个)"
478
+ return $true
479
+ }
480
+
481
+ # 主流程
482
+ if (-not (Test-MethodologyDocs)) {
483
+ exit 1
484
+ }
485
+
486
+ Test-PendingTasks | Out-Null
487
+ Test-CompletedContent
488
+
489
+ Write-Host ""
490
+ Write-Host "准备就绪,可以开始写作"
@@ -0,0 +1,135 @@
1
+ # 检查写作状态脚本
2
+ # 用于 /write 命令
3
+
4
+ # 导入通用函数
5
+ . "$PSScriptRoot\common.ps1"
6
+
7
+ # 获取项目根目录
8
+ $ProjectRoot = Get-ProjectRoot
9
+ Set-Location $ProjectRoot
10
+
11
+ # 获取当前故事
12
+ $StoryName = Get-ActiveStory
13
+ $StoryDir = "stories\$StoryName"
14
+
15
+ Write-Host "写作状态检查"
16
+ Write-Host "============"
17
+ Write-Host "当前故事:$StoryName"
18
+ Write-Host ""
19
+
20
+ # 检查方法论文档
21
+ function Test-MethodologyDocs {
22
+ $missing = @()
23
+
24
+ if (-not (Test-Path ".specify\memory\constitution.md")) {
25
+ $missing += "宪法"
26
+ }
27
+ if (-not (Test-Path "$StoryDir\specification.md")) {
28
+ $missing += "规格"
29
+ }
30
+ if (-not (Test-Path "$StoryDir\creative-plan.md")) {
31
+ $missing += "计划"
32
+ }
33
+ if (-not (Test-Path "$StoryDir\tasks.md")) {
34
+ $missing += "任务"
35
+ }
36
+
37
+ if ($missing.Count -gt 0) {
38
+ Write-Host "⚠️ 缺少以下基准文档:" -ForegroundColor Yellow
39
+ foreach ($doc in $missing) {
40
+ Write-Host " - $doc"
41
+ }
42
+ Write-Host ""
43
+ Write-Host "建议按照七步方法论完成前置步骤:"
44
+ Write-Host "1. /constitution - 创建创作宪法"
45
+ Write-Host "2. /specify - 定义故事规格"
46
+ Write-Host "3. /clarify - 澄清关键决策"
47
+ Write-Host "4. /plan - 制定创作计划"
48
+ Write-Host "5. /tasks - 生成任务清单"
49
+ return $false
50
+ }
51
+
52
+ Write-Host "✅ 方法论文档完整" -ForegroundColor Green
53
+ return $true
54
+ }
55
+
56
+ # 检查待写作任务
57
+ function Test-PendingTasks {
58
+ $tasksFile = "$StoryDir\tasks.md"
59
+
60
+ if (-not (Test-Path $tasksFile)) {
61
+ Write-Host "❌ 任务文件不存在" -ForegroundColor Red
62
+ return $false
63
+ }
64
+
65
+ # 统计任务状态
66
+ $content = Get-Content $tasksFile -Raw
67
+ $pending = ([regex]::Matches($content, '^- \[ \]', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
68
+ $inProgress = ([regex]::Matches($content, '^- \[~\]', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
69
+ $completed = ([regex]::Matches($content, '^- \[x\]', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
70
+
71
+ Write-Host ""
72
+ Write-Host "任务状态:"
73
+ Write-Host " 待开始:$pending"
74
+ Write-Host " 进行中:$inProgress"
75
+ Write-Host " 已完成:$completed"
76
+
77
+ if ($pending -eq 0 -and $inProgress -eq 0) {
78
+ Write-Host ""
79
+ Write-Host "🎉 所有任务已完成!" -ForegroundColor Green
80
+ Write-Host "建议运行 /analyze 进行综合验证"
81
+ return $true
82
+ }
83
+
84
+ # 显示下一个待写作任务
85
+ Write-Host ""
86
+ Write-Host "下一个写作任务:"
87
+ $lines = $content -split "`n"
88
+ foreach ($line in $lines) {
89
+ if ($line -match '^- \[ \]') {
90
+ Write-Host $line
91
+ break
92
+ }
93
+ }
94
+
95
+ return $true
96
+ }
97
+
98
+ # 检查已完成内容
99
+ function Test-CompletedContent {
100
+ $contentDir = "$StoryDir\content"
101
+
102
+ if (Test-Path $contentDir) {
103
+ $mdFiles = Get-ChildItem "$contentDir\*.md" -ErrorAction SilentlyContinue
104
+ $chapterCount = $mdFiles.Count
105
+
106
+ if ($chapterCount -gt 0) {
107
+ Write-Host ""
108
+ Write-Host "已完成章节:$chapterCount"
109
+ Write-Host "最近写作:"
110
+
111
+ $recentFiles = $mdFiles |
112
+ Sort-Object LastWriteTime -Descending |
113
+ Select-Object -First 3
114
+
115
+ foreach ($file in $recentFiles) {
116
+ Write-Host " - $($file.Name)"
117
+ }
118
+ }
119
+ }
120
+ else {
121
+ Write-Host ""
122
+ Write-Host "尚未开始写作"
123
+ }
124
+ }
125
+
126
+ # 主流程
127
+ if (-not (Test-MethodologyDocs)) {
128
+ exit 1
129
+ }
130
+
131
+ Test-PendingTasks | Out-Null
132
+ Test-CompletedContent
133
+
134
+ Write-Host ""
135
+ Write-Host "准备就绪,可以开始写作"