novel-writer-cli 0.3.0 → 0.5.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 (75) hide show
  1. package/README.md +1 -1
  2. package/agents/chapter-writer.md +43 -14
  3. package/agents/character-weaver.md +7 -1
  4. package/agents/plot-architect.md +20 -7
  5. package/agents/quality-judge.md +199 -20
  6. package/agents/style-analyzer.md +14 -8
  7. package/agents/style-refiner.md +10 -3
  8. package/agents/world-builder.md +8 -1
  9. package/dist/__tests__/agent-prompts-anti-ai-upgrade.test.js +194 -6
  10. package/dist/__tests__/agent-prompts-platform-expansion.test.js +33 -0
  11. package/dist/__tests__/anti-ai-infrastructure.test.js +548 -0
  12. package/dist/__tests__/anti-ai-templates.test.js +2 -2
  13. package/dist/__tests__/canon-status-lifecycle.test.js +481 -0
  14. package/dist/__tests__/commit-gate-decision.test.js +65 -0
  15. package/dist/__tests__/commit-prototype-pollution.test.js +1 -1
  16. package/dist/__tests__/excitement-type-annotation.test.js +240 -0
  17. package/dist/__tests__/excitement-type.test.js +21 -0
  18. package/dist/__tests__/gate-decision.test.js +62 -15
  19. package/dist/__tests__/genre-excitement-mapping.test.js +355 -0
  20. package/dist/__tests__/golden-chapter-gates.test.js +79 -0
  21. package/dist/__tests__/golden-chapter-mini-planning.test.js +485 -0
  22. package/dist/__tests__/helpers/quickstart-mini-planning.js +61 -0
  23. package/dist/__tests__/init.test.js +57 -5
  24. package/dist/__tests__/instructions-platform-expansion.test.js +125 -0
  25. package/dist/__tests__/next-step-gate-decision-routing.test.js +98 -0
  26. package/dist/__tests__/orchestrator-state-write-path.test.js +1 -1
  27. package/dist/__tests__/platform-profile.test.js +57 -1
  28. package/dist/__tests__/quickstart-pipeline.test.js +73 -6
  29. package/dist/__tests__/scoring-weights.test.js +193 -0
  30. package/dist/__tests__/steps-id.test.js +2 -0
  31. package/dist/__tests__/validate-quickstart-prereqs.test.js +2 -0
  32. package/dist/advance.js +27 -2
  33. package/dist/anti-ai-context.js +535 -0
  34. package/dist/cli.js +3 -1
  35. package/dist/commit.js +22 -0
  36. package/dist/excitement-type.js +12 -0
  37. package/dist/gate-decision.js +98 -2
  38. package/dist/golden-chapter-gates.js +143 -0
  39. package/dist/init.js +76 -7
  40. package/dist/instructions.js +552 -6
  41. package/dist/next-step.js +124 -88
  42. package/dist/platform-profile.js +20 -8
  43. package/dist/quickstart-mini-planning.js +30 -0
  44. package/dist/scoring-weights.js +38 -3
  45. package/dist/steps.js +1 -1
  46. package/dist/validate.js +293 -214
  47. package/dist/volume-commit.js +271 -5
  48. package/dist/volume-planning.js +78 -3
  49. package/docs/user/README.md +1 -0
  50. package/docs/user/migration-guide.md +166 -0
  51. package/docs/user/novel-cli.md +4 -3
  52. package/docs/user/quick-start.md +354 -57
  53. package/package.json +1 -1
  54. package/schemas/platform-profile.schema.json +2 -2
  55. package/scripts/lint-blacklist.sh +221 -76
  56. package/scripts/lint-structural.sh +538 -0
  57. package/skills/continue/SKILL.md +6 -0
  58. package/skills/continue/references/context-contracts.md +71 -6
  59. package/skills/continue/references/periodic-maintenance.md +12 -1
  60. package/skills/novel-writing/references/quality-rubric.md +79 -26
  61. package/skills/novel-writing/references/style-guide.md +129 -19
  62. package/skills/start/SKILL.md +23 -3
  63. package/skills/start/references/vol-planning.md +12 -3
  64. package/templates/ai-blacklist.json +1024 -246
  65. package/templates/ai-sentence-patterns.json +167 -0
  66. package/templates/genre-excitement-map.json +48 -0
  67. package/templates/genre-golden-standards.json +80 -0
  68. package/templates/genre-weight-profiles.json +15 -0
  69. package/templates/golden-chapter-gates.json +230 -0
  70. package/templates/novel-ask/example.question.json +3 -2
  71. package/templates/platform-profile.json +141 -1
  72. package/templates/platforms/fanqie.md +35 -0
  73. package/templates/platforms/jinjiang.md +35 -0
  74. package/templates/platforms/qidian.md +35 -0
  75. package/templates/style-profile-template.json +3 -0
@@ -0,0 +1,167 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "description": "结构级 AI 句式模式定义 -- 依赖 LLM 语义理解识别,无法正则匹配。供 ChapterWriter(生成时避免)、StyleRefiner(后处理检测替换)、QualityJudge(评分扣分)消费。",
4
+ "last_updated": "2026-03-06",
5
+ "patterns": [
6
+ {
7
+ "id": "SP-01",
8
+ "name": "解释型旁白句",
9
+ "severity": "high",
10
+ "per_chapter_max": 0,
11
+ "description": "作者替人物翻译潜台词,用旁白显式解释角色的言外之意或行为动机。读者本可从动作、对话、上下文自行推断的信息,被作者替读者'翻译'了一遍。",
12
+ "examples": {
13
+ "bad": [
14
+ "她知道他是在用这种方式表达关心。",
15
+ "他这么做,其实是想让她安心。",
16
+ "这句话的言外之意是,他已经不打算回来了。"
17
+ ],
18
+ "good": [
19
+ "她没接话,把围巾往他脖子上绕了一圈。",
20
+ "他把药放在桌上,转身就走,门带得很轻。",
21
+ "她盯着那把钥匙看了很久,最后塞进了抽屉最深处。"
22
+ ]
23
+ },
24
+ "replacement_strategy": "删除解释性旁白,改为动作、表情、停顿或对话暗示,让读者自行推断。"
25
+ },
26
+ {
27
+ "id": "SP-02",
28
+ "name": "模板转折句",
29
+ "severity": "high",
30
+ "per_chapter_max": 0,
31
+ "description": "机械性的'先负后正'或'先正后负'平衡句式,用固定模板连接两个对立面。常见标志词:'听上去……可……'、'看似……实则……'、'虽然……但……'(非自然口语转折)。",
32
+ "examples": {
33
+ "bad": [
34
+ "听上去是在安慰,可语气里透着一股子不耐烦。",
35
+ "看似平静的表面下,实则暗流涌动。",
36
+ "话虽然说得轻松,但谁都看得出他在强撑。"
37
+ ],
38
+ "good": [
39
+ "\u201c没事。\u201d他说。手指却在桌下攥得指节发白。",
40
+ "他笑了一声,笑声没到眼睛。",
41
+ "她拍了拍他的肩,力气大得像是要把什么东西拍碎。"
42
+ ]
43
+ },
44
+ "replacement_strategy": "拆掉对称句式,用前后两个独立动作/细节的并置制造张力,让读者自己感受矛盾。"
45
+ },
46
+ {
47
+ "id": "SP-03",
48
+ "name": "抽象判词句",
49
+ "severity": "medium",
50
+ "per_chapter_max": 2,
51
+ "description": "用抽象概念词代替具体画面,给读者一个'标签'而非一个'场景'。常见形式:'那股XX劲'、'一种XX的感觉'、'某种XX的气质'。",
52
+ "examples": {
53
+ "bad": [
54
+ "他身上有一股不怒自威的劲儿。",
55
+ "空气里弥漫着一种紧张的感觉。",
56
+ "她散发着某种让人不敢靠近的气质。"
57
+ ],
58
+ "good": [
59
+ "他往那一站,周围说话的人声音就自动矮了半截。",
60
+ "没人动筷子,菜凉了也没人敢先夹。",
61
+ "路过的人看她一眼就绕道,连问路的都没有。"
62
+ ]
63
+ },
64
+ "replacement_strategy": "把抽象标签翻译成可观察的具体动作、反应或细节,让读者通过画面得出结论。"
65
+ },
66
+ {
67
+ "id": "SP-04",
68
+ "name": "管理/项目腔",
69
+ "severity": "medium",
70
+ "per_chapter_max": 2,
71
+ "description": "PRD/汇报/管理文档的用语和句式侵入小说叙事。角色对话或旁白中出现'可被执行'、'核心诉求'、'关键节点'、'从根本上'等非文学用语。",
72
+ "examples": {
73
+ "bad": [
74
+ "这个计划的核心诉求是在三天内完成撤离。",
75
+ "他意识到,自己正处于一个关键的转折节点。",
76
+ "从根本上来说,这件事是可以被解决的。"
77
+ ],
78
+ "good": [
79
+ "三天,把人全撤出去。他在纸上画了条线。",
80
+ "再往前走一步,就回不了头了。",
81
+ "能办。他把烟掐灭,就是麻烦点。"
82
+ ]
83
+ },
84
+ "replacement_strategy": "用角色会说的口语、动作或具体场景替换管理术语,让语言回到叙事语域。"
85
+ },
86
+ {
87
+ "id": "SP-05",
88
+ "name": "重复解释",
89
+ "severity": "high",
90
+ "per_chapter_max": 0,
91
+ "description": "前句已经通过动作/对话暗示了某个信息,后句又用旁白显式重述同一信息。造成信息冗余和'读者智商被低估'的感觉。",
92
+ "examples": {
93
+ "bad": [
94
+ "他猛地站起来,椅子向后滑出半米。他显然被这个消息激怒了。",
95
+ "\u201c滚。\u201d她把门摔上。她不想再见到他。",
96
+ "他的手在发抖。他害怕了。"
97
+ ],
98
+ "good": [
99
+ "他猛地站起来,椅子向后滑出半米。",
100
+ "\u201c滚。\u201d门框震了一下。",
101
+ "他把手插进口袋里,掌心全是汗。"
102
+ ]
103
+ },
104
+ "replacement_strategy": "删除重复解释的后句,信任读者的理解能力。如果担心暗示不够明确,强化前句的动作/细节而非追加旁白。"
105
+ },
106
+ {
107
+ "id": "SP-06",
108
+ "name": "因果说明句",
109
+ "severity": "medium",
110
+ "per_chapter_max": 2,
111
+ "description": "用显式因果连接词串联前后文,把本该隐含在叙事节奏中的因果关系写成论文式推理链。常见标志词:'毕竟'、'之所以……是因为'、'正因如此'。",
112
+ "examples": {
113
+ "bad": [
114
+ "他没有追上去。毕竟,再追下去也没有意义了。",
115
+ "她之所以不肯开口,是因为她知道一旦说了就收不回来。",
116
+ "正因如此,他选择了沉默。"
117
+ ],
118
+ "good": [
119
+ "他停在原地,看着她的背影消失在拐角。脚底像生了根。",
120
+ "她咬着嘴唇,把要说的话又咽了回去。有些话一出口就是刀。",
121
+ "他什么也没说。沉默比什么都好用。"
122
+ ]
123
+ },
124
+ "replacement_strategy": "删除因果连接词,用动作/画面/节奏暗示因果关系,让逻辑藏在叙事里而非显式陈述。"
125
+ },
126
+ {
127
+ "id": "SP-07",
128
+ "name": "情绪标签句",
129
+ "severity": "high",
130
+ "per_chapter_max": 0,
131
+ "description": "直接给角色的情绪贴标签('感到愤怒'、'心中涌起悲伤'),而非通过身体反应、动作、语气或环境映射来展示情绪。与 ai-blacklist 的 emotion_cliche 类别互补:黑名单抓固定短语,本模式抓'感到/涌起/充满+情绪名词'的句式结构。",
132
+ "examples": {
133
+ "bad": [
134
+ "她感到一阵愤怒涌上心头。",
135
+ "他心中充满了悲伤和无奈。",
136
+ "一种深深的恐惧笼罩着他。"
137
+ ],
138
+ "good": [
139
+ "她把筷子往桌上一拍,碗里的汤溅出来也没管。",
140
+ "他坐在床边,鞋子穿了一半就不动了,盯着地板上那道裂缝。",
141
+ "后背的汗还没干,他已经开始往回跑了。"
142
+ ]
143
+ },
144
+ "replacement_strategy": "用 Show Don't Tell:身体反应(手抖/冒汗/喉咙发紧)、动作(摔东西/转身就走)、语气变化(声音变冷/说话断断续续)代替直接命名情绪。"
145
+ },
146
+ {
147
+ "id": "SP-08",
148
+ "name": "全知评论句",
149
+ "severity": "medium",
150
+ "per_chapter_max": 2,
151
+ "description": "叙述者跳出当前 POV,以上帝视角做评论或预告。在限定视角叙事中尤其违和。常见形式:'他不知道的是'、'注定不会平静'、'如果他知道接下来会发生什么'。",
152
+ "examples": {
153
+ "bad": [
154
+ "他不知道的是,这将是他最后一次见到她。",
155
+ "这个夜晚注定不会平静。",
156
+ "如果她知道接下来会发生什么,一定不会走进那扇门。"
157
+ ],
158
+ "good": [
159
+ "他冲她挥了挥手,转身走进雨里。",
160
+ "夜风把窗户吹得啪啪响,她起身去关,看见院子里的灯灭了。",
161
+ "她推开门的时候,鞋底踩到了什么黏糊糊的东西。"
162
+ ]
163
+ },
164
+ "replacement_strategy": "删除全知评论,回到 POV 角色的感知范围内叙事。用细节和氛围暗示'有事要发生',而不是直接告诉读者。"
165
+ }
166
+ ]
167
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "schema_version": 1,
3
+ "description": "题材差异化的黄金三章爽点分配建议:按 brief.md 的题材字段匹配 genre key,仅作为 PlotArchitect 的默认参考。",
4
+ "genres": {
5
+ "xuanhuan": {
6
+ "chapters": {
7
+ "1": "setup",
8
+ "2": "power_up",
9
+ "3": "face_slap"
10
+ }
11
+ },
12
+ "dushi": {
13
+ "chapters": {
14
+ "1": "setup",
15
+ "2": "reversal",
16
+ "3": "face_slap"
17
+ }
18
+ },
19
+ "scifi": {
20
+ "chapters": {
21
+ "1": "reveal",
22
+ "2": "setup",
23
+ "3": "cliffhanger"
24
+ }
25
+ },
26
+ "history": {
27
+ "chapters": {
28
+ "1": "setup",
29
+ "2": "reveal",
30
+ "3": "reversal"
31
+ }
32
+ },
33
+ "suspense": {
34
+ "chapters": {
35
+ "1": "reveal",
36
+ "2": "setup",
37
+ "3": "cliffhanger"
38
+ }
39
+ },
40
+ "romance": {
41
+ "chapters": {
42
+ "1": "setup",
43
+ "2": "reveal",
44
+ "3": "reversal"
45
+ }
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "schema_version": 1,
3
+ "description": "题材特定的黄金三章评审标准:仅在 chapter 1-3 且 brief.md 的题材字段匹配时注入 QualityJudge。",
4
+ "genres": {
5
+ "xuanhuan": {
6
+ "focus_dimensions": ["immersion", "foreshadowing"],
7
+ "criteria": [
8
+ "前三章要让世界观/力量体系有明显存在感,不能只有空泛名词堆叠。",
9
+ "升级、资源、境界或代价机制至少要出现一次可感知展示。"
10
+ ],
11
+ "minimum_thresholds": {
12
+ "immersion": 3.5
13
+ }
14
+ },
15
+ "dushi": {
16
+ "focus_dimensions": ["pacing", "hook_strength"],
17
+ "criteria": [
18
+ "都市开篇要尽快建立身份反差、社会张力或现实压迫。",
19
+ "前三章应给出足够快的逆转/立威预期,避免纯背景介绍。"
20
+ ],
21
+ "minimum_thresholds": {
22
+ "pacing": 3.5
23
+ }
24
+ },
25
+ "scifi": {
26
+ "focus_dimensions": ["plot_logic", "immersion"],
27
+ "criteria": [
28
+ "设定揭示必须兼顾可信度与可理解性,避免只抛概念不落地。",
29
+ "科技/规则说明要与情节推进绑定,不能牺牲逻辑一致性。"
30
+ ],
31
+ "minimum_thresholds": {
32
+ "plot_logic": 3.5,
33
+ "immersion": 3.5
34
+ }
35
+ },
36
+ "history": {
37
+ "focus_dimensions": ["plot_logic", "immersion"],
38
+ "criteria": [
39
+ "时代氛围、礼制或历史 plausibility 要稳定成立。",
40
+ "人物处境与时代约束之间需要有可验证的因果关系。"
41
+ ],
42
+ "minimum_thresholds": {
43
+ "plot_logic": 3.5
44
+ }
45
+ },
46
+ "suspense": {
47
+ "focus_dimensions": ["plot_logic", "hook_strength"],
48
+ "criteria": [
49
+ "线索铺设、误导和悬念升级必须逻辑自洽,不能靠强行藏信息。",
50
+ "前三章至少建立一个会驱动读者追更的核心疑问。"
51
+ ],
52
+ "minimum_thresholds": {
53
+ "plot_logic": 4.0
54
+ }
55
+ },
56
+ "romance": {
57
+ "focus_dimensions": ["character", "style_naturalness", "emotional_impact"],
58
+ "criteria": [
59
+ "人物性格与关系张力要通过动作、对白和情绪反应落地,不能只靠旁白概括。",
60
+ "CP 化学反应、情绪钩子或关系预期必须在前三章站住。"
61
+ ],
62
+ "minimum_thresholds": {
63
+ "character": 4.0,
64
+ "style_naturalness": 3.5
65
+ }
66
+ }
67
+ },
68
+ "invalid_combinations": [
69
+ {
70
+ "genre": "romance",
71
+ "platform": "qidian",
72
+ "warning": "起点以男频为主,言情题材建议优先考虑晋江或番茄;若坚持选择起点,请尽早补强主线承诺与差异点。"
73
+ },
74
+ {
75
+ "genre": "xuanhuan",
76
+ "platform": "jinjiang",
77
+ "warning": "晋江以女频为主,玄幻题材建议优先考虑起点或番茄;若坚持选择晋江,请提前明确关系张力与情绪卖点。"
78
+ }
79
+ ]
80
+ }
@@ -29,6 +29,21 @@
29
29
  "slice_of_life": "slice_of_life:v1"
30
30
  },
31
31
 
32
+ "platform_multipliers": {
33
+ "fanqie": {
34
+ "hook_strength": 1.5,
35
+ "pacing": 1.3
36
+ },
37
+ "qidian": {
38
+ "immersion": 1.3
39
+ },
40
+ "jinjiang": {
41
+ "character": 1.3,
42
+ "style_naturalness": 1.3,
43
+ "emotional_impact": 1.2
44
+ }
45
+ },
46
+
32
47
  "profiles": {
33
48
  "plot:v1": {
34
49
  "drive_type": "plot",
@@ -0,0 +1,230 @@
1
+ {
2
+ "schema_version": 1,
3
+ "description": "黄金三章平台硬门控模板:仅适用于 chapter 1-3;平台查找使用 canonical platform id。",
4
+ "platforms": {
5
+ "fanqie": {
6
+ "chapters": {
7
+ "1": {
8
+ "gates": [
9
+ {
10
+ "id": "protagonist_within_200_words",
11
+ "requirement": "主角必须在前 200 字内出场(行动、台词或明确 POV 均可)。",
12
+ "evaluation_hint": "若前 200 字内只有背景铺陈或旁白,没有主角存在感,则判 fail。",
13
+ "threshold": { "metric": "protagonist_first_appearance_word_index", "operator": "<=", "value": 200 }
14
+ },
15
+ {
16
+ "id": "conflict_present",
17
+ "requirement": "本章必须至少出现 1 个明确冲突点(危机、对抗、目标受阻三者之一)。",
18
+ "evaluation_hint": "若整章只有信息介绍或氛围铺陈,没有显性阻力或冲突推进,则判 fail。"
19
+ },
20
+ {
21
+ "id": "hook_present",
22
+ "requirement": "章末必须有明确钩子,不能以平铺收尾。",
23
+ "evaluation_hint": "若结尾为总结、回望或纯收束,没有未解问题/威胁/反转/下一目标承诺,则判 fail."
24
+ },
25
+ {
26
+ "id": "excitement_type_allowed",
27
+ "requirement": "爽点类型需落在 reversal / face_slap / power_up 之一。",
28
+ "evaluation_hint": "结合章节主冲突与高潮段,判断核心爽点类型是否匹配番茄偏好。",
29
+ "allowed_values": ["reversal", "face_slap", "power_up"]
30
+ }
31
+ ],
32
+ "notes": ["优先快起冲突、快给反馈,设置描写要嵌在行动里。"]
33
+ },
34
+ "2": {
35
+ "gates": [
36
+ {
37
+ "id": "conflict_present",
38
+ "requirement": "本章必须至少出现 1 个明确冲突点(危机、对抗、目标受阻三者之一)。",
39
+ "evaluation_hint": "若整章只有信息介绍或氛围铺陈,没有显性阻力或冲突推进,则判 fail。"
40
+ },
41
+ {
42
+ "id": "hook_present",
43
+ "requirement": "章末必须有明确钩子,不能以平铺收尾。",
44
+ "evaluation_hint": "若结尾为总结、回望或纯收束,没有未解问题/威胁/反转/下一目标承诺,则判 fail."
45
+ },
46
+ {
47
+ "id": "excitement_type_allowed",
48
+ "requirement": "爽点类型需落在 reversal / face_slap / power_up 之一。",
49
+ "evaluation_hint": "结合章节主冲突与高潮段,判断核心爽点类型是否匹配番茄偏好。",
50
+ "allowed_values": ["reversal", "face_slap", "power_up"]
51
+ }
52
+ ],
53
+ "notes": ["第二章要拉高追读预期,避免单纯补设定。"]
54
+ },
55
+ "3": {
56
+ "gates": [
57
+ {
58
+ "id": "conflict_present",
59
+ "requirement": "本章必须至少出现 1 个明确冲突点(危机、对抗、目标受阻三者之一)。",
60
+ "evaluation_hint": "若整章只有信息介绍或氛围铺陈,没有显性阻力或冲突推进,则判 fail。"
61
+ },
62
+ {
63
+ "id": "hook_present",
64
+ "requirement": "章末必须有明确钩子,不能以平铺收尾。",
65
+ "evaluation_hint": "若结尾为总结、回望或纯收束,没有未解问题/威胁/反转/下一目标承诺,则判 fail."
66
+ },
67
+ {
68
+ "id": "excitement_type_allowed",
69
+ "requirement": "爽点类型需落在 reversal / face_slap / power_up 之一。",
70
+ "evaluation_hint": "结合章节主冲突与高潮段,判断核心爽点类型是否匹配番茄偏好。",
71
+ "allowed_values": ["reversal", "face_slap", "power_up"]
72
+ }
73
+ ],
74
+ "notes": ["第三章要把留存预期打牢,至少形成一个清晰的短期爽点承诺。"]
75
+ }
76
+ }
77
+ },
78
+ "qidian": {
79
+ "chapters": {
80
+ "1": {
81
+ "gates": [
82
+ {
83
+ "id": "system_or_world_present",
84
+ "requirement": "系统线索或世界观关键差异必须被建立。",
85
+ "evaluation_hint": "若第一章仍无法判断核心设定、世界规则或系统入口,判 fail。"
86
+ },
87
+ {
88
+ "id": "immersion_min_score",
89
+ "requirement": "immersion 评分必须 >= 3.5。",
90
+ "evaluation_hint": "若画面、氛围、世界规则体验感不足,且难以形成代入,则判 fail。",
91
+ "threshold": { "metric": "scores.immersion.score", "operator": ">=", "value": 3.5 }
92
+ }
93
+ ],
94
+ "notes": ["开篇允许较多设定,但必须服务于代入与悬念。"]
95
+ },
96
+ "2": {
97
+ "gates": [
98
+ {
99
+ "id": "system_or_world_present",
100
+ "requirement": "系统线索或世界观关键差异必须持续推进。",
101
+ "evaluation_hint": "若第二章对核心设定没有新增抓手,判 fail。"
102
+ },
103
+ {
104
+ "id": "immersion_min_score",
105
+ "requirement": "immersion 评分必须 >= 3.5。",
106
+ "evaluation_hint": "若画面、氛围、世界规则体验感不足,且难以形成代入,则判 fail。",
107
+ "threshold": { "metric": "scores.immersion.score", "operator": ">=", "value": 3.5 }
108
+ }
109
+ ],
110
+ "notes": ["第二章继续加深世界可信度,而不是只讲概念。"]
111
+ },
112
+ "3": {
113
+ "gates": [
114
+ {
115
+ "id": "system_or_world_present",
116
+ "requirement": "系统线索或世界观关键差异必须持续推进。",
117
+ "evaluation_hint": "若第三章后读者仍抓不到作品的独特规则,判 fail。"
118
+ },
119
+ {
120
+ "id": "immersion_min_score",
121
+ "requirement": "immersion 评分必须 >= 3.5。",
122
+ "evaluation_hint": "若画面、氛围、世界规则体验感不足,且难以形成代入,则判 fail。",
123
+ "threshold": { "metric": "scores.immersion.score", "operator": ">=", "value": 3.5 }
124
+ }
125
+ ],
126
+ "notes": ["第三章要让读者对世界与主线有继续探索的动力。"]
127
+ }
128
+ }
129
+ },
130
+ "jinjiang": {
131
+ "chapters": {
132
+ "1": {
133
+ "gates": [
134
+ {
135
+ "id": "personality_through_behavior",
136
+ "requirement": "主要角色个性必须通过动作、对话、反应体现,不能只靠旁白直述。",
137
+ "evaluation_hint": "若个性结论只存在于解说句,没有行为证据支撑,则判 fail。"
138
+ },
139
+ {
140
+ "id": "cp_appears",
141
+ "requirement": "CP(主感情对手或核心关系对象)必须在前三章早期出现,本章优先建立存在感。",
142
+ "evaluation_hint": "若第一章完全没有 CP 本人、名字、互动或强关联线索,则判 fail。"
143
+ },
144
+ {
145
+ "id": "emotional_tone_established",
146
+ "requirement": "情感基调必须清晰建立(拉扯、暧昧、压迫、治愈等至少一种)。",
147
+ "evaluation_hint": "若读者无法感知情感走向,只剩事件流水账,则判 fail。"
148
+ },
149
+ {
150
+ "id": "style_naturalness_min_score",
151
+ "requirement": "style_naturalness 评分必须 >= 3.5。",
152
+ "evaluation_hint": "若文风生硬、腔调重、人物情绪不贴身,则判 fail。",
153
+ "threshold": { "metric": "scores.style_naturalness.score", "operator": ">=", "value": 3.5 }
154
+ }
155
+ ],
156
+ "notes": ["晋江开篇重人物化学反应与情绪落点,不要把吸引力全押在外部设定。"]
157
+ },
158
+ "2": {
159
+ "gates": [
160
+ {
161
+ "id": "personality_through_behavior",
162
+ "requirement": "主要角色个性必须通过动作、对话、反应体现,不能只靠旁白直述。",
163
+ "evaluation_hint": "若个性结论只存在于解说句,没有行为证据支撑,则判 fail。"
164
+ },
165
+ {
166
+ "id": "cp_appears",
167
+ "requirement": "CP 必须在第二章前后形成可感知互动或强关联线索。",
168
+ "evaluation_hint": "若第二章仍没有 CP 本人、互动或强关系推进,则判 fail。"
169
+ },
170
+ {
171
+ "id": "emotional_tone_established",
172
+ "requirement": "情感基调必须清晰建立(拉扯、暧昧、压迫、治愈等至少一种)。",
173
+ "evaluation_hint": "若读者无法感知情感走向,只剩事件流水账,则判 fail。"
174
+ },
175
+ {
176
+ "id": "style_naturalness_min_score",
177
+ "requirement": "style_naturalness 评分必须 >= 3.5。",
178
+ "evaluation_hint": "若文风生硬、腔调重、人物情绪不贴身,则判 fail。",
179
+ "threshold": { "metric": "scores.style_naturalness.score", "operator": ">=", "value": 3.5 }
180
+ }
181
+ ],
182
+ "notes": ["第二章要让关系张力继续升温,而不是只做剧情搬运。"]
183
+ },
184
+ "3": {
185
+ "gates": [
186
+ {
187
+ "id": "personality_through_behavior",
188
+ "requirement": "主要角色个性必须通过动作、对话、反应体现,不能只靠旁白直述。",
189
+ "evaluation_hint": "若个性结论只存在于解说句,没有行为证据支撑,则判 fail。"
190
+ },
191
+ {
192
+ "id": "cp_appears",
193
+ "requirement": "CP 必须在第三章前建立稳定存在感。",
194
+ "evaluation_hint": "若第三章后感情主轴仍无明确关系对象或对象存在感极弱,则判 fail。"
195
+ },
196
+ {
197
+ "id": "emotional_tone_established",
198
+ "requirement": "情感基调必须清晰建立(拉扯、暧昧、压迫、治愈等至少一种)。",
199
+ "evaluation_hint": "若读者无法感知情感走向,只剩事件流水账,则判 fail。"
200
+ },
201
+ {
202
+ "id": "style_naturalness_min_score",
203
+ "requirement": "style_naturalness 评分必须 >= 3.5。",
204
+ "evaluation_hint": "若文风生硬、腔调重、人物情绪不贴身,则判 fail。",
205
+ "threshold": { "metric": "scores.style_naturalness.score", "operator": ">=", "value": 3.5 }
206
+ }
207
+ ],
208
+ "notes": ["第三章要让关系方向和情绪回报预期都站住。"]
209
+ }
210
+ }
211
+ }
212
+ },
213
+ "invalid_combinations": [
214
+ {
215
+ "genre": "slow_burn_literary",
216
+ "platform": "fanqie",
217
+ "warning": "番茄对慢热纯文学开篇容忍度较低,需尽快补足冲突与爽点反馈。"
218
+ },
219
+ {
220
+ "genre": "male_power_fantasy",
221
+ "platform": "jinjiang",
222
+ "warning": "晋江对单线男性爽文天然不占优势,建议提前明确关系张力与情绪卖点。"
223
+ },
224
+ {
225
+ "genre": "pure_romance_slice_of_life",
226
+ "platform": "qidian",
227
+ "warning": "起点对纯日常恋爱开篇要求更强的世界差异点或主线承诺,需防止留存不足。"
228
+ }
229
+ ]
230
+ }
@@ -5,12 +5,13 @@
5
5
  {
6
6
  "id": "platform",
7
7
  "header": "Platform",
8
- "question": "Choose your target platform.",
8
+ "question": "Choose your target platform. Legacy \"tomato\" remains accepted for existing projects.",
9
9
  "kind": "single_choice",
10
10
  "required": true,
11
11
  "options": [
12
12
  { "label": "qidian", "description": "Qidian / 起点中文网" },
13
- { "label": "tomato", "description": "Tomato / 番茄小说" }
13
+ { "label": "fanqie", "description": "Fanqie / 番茄小说" },
14
+ { "label": "jinjiang", "description": "Jinjiang / 晋江文学城" }
14
15
  ],
15
16
  "default": "qidian"
16
17
  },