@zooique/memora 4.0.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.
- package/CHANGELOG.md +165 -1743
- package/README.en.md +43 -36
- package/README.md +308 -303
- package/dist/agent/agent.d.ts +46 -82
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +153 -220
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts +3 -16
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +46 -35
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/backgroundTasks.d.ts +8 -1
- package/dist/agent/backgroundTasks.d.ts.map +1 -1
- package/dist/agent/backgroundTasks.js +8 -1
- package/dist/agent/backgroundTasks.js.map +1 -1
- package/dist/agent/budget.d.ts +23 -5
- package/dist/agent/budget.d.ts.map +1 -1
- package/dist/agent/budget.js +8 -2
- package/dist/agent/budget.js.map +1 -1
- package/dist/agent/builtinToolHandlers.d.ts +27 -8
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
- package/dist/agent/builtinToolHandlers.js +45 -9
- package/dist/agent/builtinToolHandlers.js.map +1 -1
- package/dist/agent/builtinTools.d.ts.map +1 -1
- package/dist/agent/builtinTools.js +4 -3
- package/dist/agent/builtinTools.js.map +1 -1
- package/dist/agent/constants.d.ts +0 -6
- package/dist/agent/constants.d.ts.map +1 -1
- package/dist/agent/constants.js +7 -8
- package/dist/agent/constants.js.map +1 -1
- package/dist/agent/contextManager.d.ts +8 -0
- package/dist/agent/contextManager.d.ts.map +1 -1
- package/dist/agent/contextManager.js +45 -3
- package/dist/agent/contextManager.js.map +1 -1
- package/dist/agent/contextPreparer.d.ts +1 -1
- package/dist/agent/contextPreparer.d.ts.map +1 -1
- package/dist/agent/contextPreparer.js +15 -10
- package/dist/agent/contextPreparer.js.map +1 -1
- package/dist/agent/guardRail.d.ts +1 -1
- package/dist/agent/guardRail.d.ts.map +1 -1
- package/dist/agent/guardRail.js +1 -1
- package/dist/agent/guardRail.js.map +1 -1
- package/dist/agent/loop.d.ts +46 -13
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +128 -25
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/managers/archiveCoordinator.d.ts +15 -3
- package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
- package/dist/agent/managers/archiveCoordinator.js +13 -7
- package/dist/agent/managers/archiveCoordinator.js.map +1 -1
- package/dist/agent/managers/chatLockManager.d.ts +3 -9
- package/dist/agent/managers/chatLockManager.d.ts.map +1 -1
- package/dist/agent/managers/chatLockManager.js +7 -25
- package/dist/agent/managers/chatLockManager.js.map +1 -1
- package/dist/agent/managers/llmCaller.d.ts.map +1 -1
- package/dist/agent/managers/llmCaller.js +27 -1
- package/dist/agent/managers/llmCaller.js.map +1 -1
- package/dist/agent/managers/memoryInspector.d.ts +12 -7
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
- package/dist/agent/managers/memoryInspector.js +32 -19
- package/dist/agent/managers/memoryInspector.js.map +1 -1
- package/dist/agent/managers/roundSummaryGenerator.d.ts +3 -1
- package/dist/agent/managers/roundSummaryGenerator.d.ts.map +1 -1
- package/dist/agent/managers/roundSummaryGenerator.js +14 -4
- package/dist/agent/managers/roundSummaryGenerator.js.map +1 -1
- package/dist/agent/managers/sessionArchiver.d.ts +20 -6
- package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
- package/dist/agent/managers/sessionArchiver.js +19 -5
- package/dist/agent/managers/sessionArchiver.js.map +1 -1
- package/dist/agent/managers/sessionManager.d.ts +21 -88
- package/dist/agent/managers/sessionManager.d.ts.map +1 -1
- package/dist/agent/managers/sessionManager.js +77 -278
- package/dist/agent/managers/sessionManager.js.map +1 -1
- package/dist/agent/seed/orchestrator.d.ts.map +1 -1
- package/dist/agent/seed/orchestrator.js +3 -3
- package/dist/agent/seed/orchestrator.js.map +1 -1
- package/dist/agent/seed/prepare.d.ts.map +1 -1
- package/dist/agent/seed/prepare.js +9 -4
- package/dist/agent/seed/prepare.js.map +1 -1
- package/dist/agent/seed/types.d.ts +11 -4
- package/dist/agent/seed/types.d.ts.map +1 -1
- package/dist/agent/seed/types.js +2 -2
- package/dist/agent/toolExecutor.d.ts +51 -6
- package/dist/agent/toolExecutor.d.ts.map +1 -1
- package/dist/agent/toolExecutor.js +74 -9
- package/dist/agent/toolExecutor.js.map +1 -1
- package/dist/agent/toolResultCache.js +1 -1
- package/dist/agent/toolRunner.d.ts +4 -2
- package/dist/agent/toolRunner.d.ts.map +1 -1
- package/dist/agent/toolRunner.js +7 -4
- package/dist/agent/toolRunner.js.map +1 -1
- package/dist/agent/types.d.ts +8 -25
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/index.d.ts +9 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -32
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts +4 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +5 -2
- package/dist/logging/logger.js.map +1 -1
- package/dist/memory/gcService.d.ts.map +1 -1
- package/dist/memory/gcService.js +3 -5
- package/dist/memory/gcService.js.map +1 -1
- package/dist/memory/inMemorySessionStore.d.ts +2 -2
- package/dist/memory/inMemorySessionStore.js +2 -2
- package/dist/memory/inMemoryStorage.d.ts +4 -3
- package/dist/memory/inMemoryStorage.d.ts.map +1 -1
- package/dist/memory/inMemoryStorage.js +2 -2
- package/dist/memory/inMemoryStorage.js.map +1 -1
- package/dist/memory/nodeSqliteStorage.d.ts +17 -0
- package/dist/memory/nodeSqliteStorage.d.ts.map +1 -0
- package/dist/memory/nodeSqliteStorage.js +393 -0
- package/dist/memory/nodeSqliteStorage.js.map +1 -0
- package/dist/memory/projectManager.d.ts +10 -20
- package/dist/memory/projectManager.d.ts.map +1 -1
- package/dist/memory/projectManager.js +27 -41
- package/dist/memory/projectManager.js.map +1 -1
- package/dist/memory/roundStore.d.ts +76 -1
- package/dist/memory/roundStore.d.ts.map +1 -1
- package/dist/memory/roundStore.js.map +1 -1
- package/dist/memory/roundSummaryLookup.d.ts +26 -0
- package/dist/memory/roundSummaryLookup.d.ts.map +1 -0
- package/dist/memory/roundSummaryLookup.js +19 -0
- package/dist/memory/roundSummaryLookup.js.map +1 -0
- package/dist/memory/sessionStore.d.ts +19 -2
- package/dist/memory/sessionStore.d.ts.map +1 -1
- package/dist/memory/sessionStore.js.map +1 -1
- package/dist/memory/sourceValidation.d.ts +2 -13
- package/dist/memory/sourceValidation.d.ts.map +1 -1
- package/dist/memory/sourceValidation.js +5 -16
- package/dist/memory/sourceValidation.js.map +1 -1
- package/dist/memory/storageInterface.d.ts +26 -16
- package/dist/memory/storageInterface.d.ts.map +1 -1
- package/dist/memory/supersedeResolve.d.ts +39 -0
- package/dist/memory/supersedeResolve.d.ts.map +1 -0
- package/dist/memory/supersedeResolve.js +16 -0
- package/dist/memory/supersedeResolve.js.map +1 -0
- package/dist/memory/types.d.ts +3 -2
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +2 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/role-pack/rolePackManager.d.ts +33 -24
- package/dist/role-pack/rolePackManager.d.ts.map +1 -1
- package/dist/role-pack/rolePackManager.js +48 -42
- package/dist/role-pack/rolePackManager.js.map +1 -1
- package/dist/role-pack/strategyKeys.d.ts +8 -0
- package/dist/role-pack/strategyKeys.d.ts.map +1 -1
- package/dist/role-pack/strategyKeys.js +10 -0
- package/dist/role-pack/strategyKeys.js.map +1 -1
- package/dist/role-pack/strategyResolver.d.ts +6 -1
- package/dist/role-pack/strategyResolver.d.ts.map +1 -1
- package/dist/role-pack/strategyResolver.js +20 -2
- package/dist/role-pack/strategyResolver.js.map +1 -1
- package/dist/role-pack/types.d.ts +5 -1
- package/dist/role-pack/types.d.ts.map +1 -1
- package/dist/security/pathGuard.d.ts +1 -1
- package/dist/security/pathGuard.d.ts.map +1 -1
- package/dist/security/pathGuard.js +1 -1
- package/dist/security/pathGuard.js.map +1 -1
- package/dist/utils/backgroundTask.d.ts +56 -34
- package/dist/utils/backgroundTask.d.ts.map +1 -1
- package/dist/utils/backgroundTask.js +130 -99
- package/dist/utils/backgroundTask.js.map +1 -1
- package/dist/utils/errors.d.ts +3 -2
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +3 -2
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/eventEmitter.d.ts +20 -22
- package/dist/utils/eventEmitter.d.ts.map +1 -1
- package/dist/utils/eventEmitter.js +0 -3
- package/dist/utils/eventEmitter.js.map +1 -1
- package/dist/utils/time.d.ts +3 -3
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +3 -3
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/toError.d.ts +1 -1
- package/dist/utils/toError.js +1 -1
- package/dist/web-fetch/loginWall.d.ts +39 -0
- package/dist/web-fetch/loginWall.d.ts.map +1 -0
- package/dist/web-fetch/loginWall.js +78 -0
- package/dist/web-fetch/loginWall.js.map +1 -0
- package/dist/web-fetch/types.d.ts +8 -0
- package/dist/web-fetch/types.d.ts.map +1 -1
- package/dist/web-fetch/webFetchProvider.d.ts.map +1 -1
- package/dist/web-fetch/webFetchProvider.js +3 -1
- package/dist/web-fetch/webFetchProvider.js.map +1 -1
- package/dist/web-search/fetchWebSearchProvider.js +28 -23
- package/dist/web-search/fetchWebSearchProvider.js.map +1 -1
- package/docs/architecture/role-pack-authoring-guide.md +3 -1
- package/docs/architecture/role-pack-spec.md +2 -1
- package/docs/memora-api-reference.md +1349 -1276
- package/docs/memora-/345/215/207/347/272/247/346/214/207/345/215/227-4.x-/345/210/260-5.0.0.md +385 -0
- package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +87 -49
- package/docs/role-pack-/345/274/200/346/224/276/351/224/256/346/214/207/345/215/227.md +148 -148
- package/package.json +9 -4
- package/role-packs/README.md +41 -40
- package/role-packs/memora/345/212/251/346/211/213/rules.md +4 -4
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/manifest.json +1 -0
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/persona.md +46 -46
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/rules.md +16 -16
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/emotion-wave.md +46 -46
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/foreshadow.md +29 -29
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/outline-expand.md +73 -48
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/scripts/init-novel-project.mjs +445 -441
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-bible.md +62 -62
- package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/manifest.json +1 -0
- package/dist/agent/managers/dedupManager.d.ts +0 -85
- package/dist/agent/managers/dedupManager.d.ts.map +0 -1
- package/dist/agent/managers/dedupManager.js +0 -248
- package/dist/agent/managers/dedupManager.js.map +0 -1
- package/dist/agent/managers/goalConsistencyChecker.d.ts +0 -42
- package/dist/agent/managers/goalConsistencyChecker.d.ts.map +0 -1
- package/dist/agent/managers/goalConsistencyChecker.js +0 -178
- package/dist/agent/managers/goalConsistencyChecker.js.map +0 -1
- package/dist/agent/managers/llmJudgeHelper.d.ts +0 -21
- package/dist/agent/managers/llmJudgeHelper.d.ts.map +0 -1
- package/dist/agent/managers/llmJudgeHelper.js +0 -32
- package/dist/agent/managers/llmJudgeHelper.js.map +0 -1
- package/dist/agent/managers/memoryAdvisor.d.ts +0 -105
- package/dist/agent/managers/memoryAdvisor.d.ts.map +0 -1
- package/dist/agent/managers/memoryAdvisor.js +0 -322
- package/dist/agent/managers/memoryAdvisor.js.map +0 -1
- package/dist/agent/managers/memoryGovernance.d.ts +0 -24
- package/dist/agent/managers/memoryGovernance.d.ts.map +0 -1
- package/dist/agent/managers/memoryGovernance.js +0 -46
- package/dist/agent/managers/memoryGovernance.js.map +0 -1
- package/dist/memory/governance.d.ts +0 -17
- package/dist/memory/governance.d.ts.map +0 -1
- package/dist/memory/governance.js +0 -17
- package/dist/memory/governance.js.map +0 -1
- package/dist/memory/projectRegistry.d.ts +0 -47
- package/dist/memory/projectRegistry.d.ts.map +0 -1
- package/dist/memory/projectRegistry.js +0 -151
- package/dist/memory/projectRegistry.js.map +0 -1
- package/dist/utils/recallDefaults.d.ts +0 -16
- package/dist/utils/recallDefaults.d.ts.map +0 -1
- package/dist/utils/recallDefaults.js +0 -16
- package/dist/utils/recallDefaults.js.map +0 -1
|
@@ -1,441 +1,445 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* 小说工程目录初始化(共鸣小说家 · project-init 技能 · L3 scripts)
|
|
4
|
-
*
|
|
5
|
-
* 目录规范:编号目录 = 角色包七阶段流水线(00-需求 … 07-归档)。
|
|
6
|
-
* 设定权威源 = 03-组织/设定圣经/(承接 story-bible 四卷;正文与圣经冲突时,正文是错的)。
|
|
7
|
-
*
|
|
8
|
-
* 用法:
|
|
9
|
-
* node init-novel-project.mjs <书名> [--dir <父目录>] [--minimal] [--force]
|
|
10
|
-
*
|
|
11
|
-
* 参数:
|
|
12
|
-
* <书名> 必填。项目目录名(同时写入 README)。
|
|
13
|
-
* --dir 父目录,默认当前工作目录。
|
|
14
|
-
* --minimal 精简子集(短篇/中篇):只建 README + 设定圣经四卷 + 人物卡 + 大纲 + 正文。
|
|
15
|
-
* --force 目标目录已存在且非空时仍继续(默认中止,防覆盖已有工程)。
|
|
16
|
-
*
|
|
17
|
-
* 约定:
|
|
18
|
-
* - 中文路径一律无空格 —— Windows + git 处理含空格中文路径会乱码(血训)。
|
|
19
|
-
* - 纯 Node 内置模块,零第三方依赖(与内核同哲学)。
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { mkdir, writeFile, readdir } from 'node:fs/promises';
|
|
23
|
-
import { join, resolve, dirname } from 'node:path';
|
|
24
|
-
import { existsSync } from 'node:fs';
|
|
25
|
-
|
|
26
|
-
// ─────────────────────────────────────────────────────────────
|
|
27
|
-
// 模板(SSOT:与 story-bible / craft-review / hotspot-mapping 等技能字段对齐)
|
|
28
|
-
// 约定:模板内不使用反引号,避免与 JS 模板字面量冲突。
|
|
29
|
-
// ─────────────────────────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
const T_README = (name) => `# 《${name}》
|
|
32
|
-
|
|
33
|
-
> 由「共鸣小说家」角色包的 project-init 技能初始化。
|
|
34
|
-
|
|
35
|
-
## 一句话 logline
|
|
36
|
-
|
|
37
|
-
(待填:谁 + 想要什么 + 障碍 + 代价)
|
|
38
|
-
|
|
39
|
-
## 三层定位
|
|
40
|
-
|
|
41
|
-
- **需求层**:回应什么痛点 / 读者的什么精神缺口 →
|
|
42
|
-
- **内核层**:经典人性内核(不随时代变)→
|
|
43
|
-
- **形式层**:题材 / 设定 / 文风 →
|
|
44
|
-
|
|
45
|
-
## 当前进度
|
|
46
|
-
|
|
47
|
-
- [ ] 阶段1 需求洞察与事件转换(need-finder + hotspot-mapping)
|
|
48
|
-
- [ ] 阶段2 内核锁定(core-extractor)
|
|
49
|
-
- [ ] 阶段3 一致性闸门(three-layer-check)
|
|
50
|
-
- [ ] 阶段4 概念包装(logline-craft + idea-lever)
|
|
51
|
-
- [ ] 阶段5 组织搭建(story-structure / relationship-web / character-sheet / world-builder / story-bible)
|
|
52
|
-
- [ ] 阶段6 大纲与成文(outline-expand → scene-craft)
|
|
53
|
-
- [ ] 阶段7 打磨与体检(polish-method / longform-guard / craft-review)
|
|
54
|
-
|
|
55
|
-
## 目录约定
|
|
56
|
-
|
|
57
|
-
编号目录 = 角色包七阶段流水线。设定权威源 = 03-组织/设定圣经/ —— 正文与圣经冲突时,正文是错的。
|
|
58
|
-
`;
|
|
59
|
-
|
|
60
|
-
const T_HOTSPOT = `# 热点与情绪内核
|
|
61
|
-
|
|
62
|
-
> 来源技能:need-finder + hotspot-mapping。AI 不想象共鸣——只搬运事件里已经存在的情绪。
|
|
63
|
-
|
|
64
|
-
## 热点现象
|
|
65
|
-
|
|
66
|
-
- 事件:
|
|
67
|
-
- 时间范围(须最近一周到一个月,过时热点不用):
|
|
68
|
-
- 来源平台(微博 / 知乎 / 小红书 / B 站…):
|
|
69
|
-
|
|
70
|
-
## 情绪内核(一句话感受,不是事件描述)
|
|
71
|
-
|
|
72
|
-
- 事件是壳,壳下面的情绪才带走 →
|
|
73
|
-
- 判据:是读者也在感受的(是「老实人总吃亏」,不是「某案判错了」)→
|
|
74
|
-
|
|
75
|
-
## 映射到小说世界(换事件、留内核)
|
|
76
|
-
|
|
77
|
-
- 原事件外壳 → 换成的虚构设定:
|
|
78
|
-
- 保留的人的属性(贪婪 / 恐惧 / 被看见的渴望 / 守护 / 不甘…):
|
|
79
|
-
|
|
80
|
-
## 验证三问
|
|
81
|
-
|
|
82
|
-
- [ ] 读者感到「这种情绪我熟悉」?
|
|
83
|
-
- [ ] 读者认不出原新闻(外壳换干净)?
|
|
84
|
-
- [ ] 删掉映射故事仍完整(非喧宾夺主)?
|
|
85
|
-
`;
|
|
86
|
-
|
|
87
|
-
const T_READER = `# 读者画像
|
|
88
|
-
|
|
89
|
-
- 痛点属于谁(Z世代 / 中老年 / 女性 / 男性 / 下沉市场…):
|
|
90
|
-
- 精神需求缺口(解压 / 治愈 / 共鸣 / 代偿 / 爽感):
|
|
91
|
-
- 读者在什么场景读(通勤 / 睡前 / 碎片):
|
|
92
|
-
- 验证依据(榜单 / 评论 / 标签热度):
|
|
93
|
-
- 时效性:当下红利 / 长期底色
|
|
94
|
-
`;
|
|
95
|
-
|
|
96
|
-
const T_CORE = `# 人性内核卡
|
|
97
|
-
|
|
98
|
-
> 来源技能:core-extractor。内核不随时代变——从经典提炼骨架,不抄故事。
|
|
99
|
-
|
|
100
|
-
- 内核(一句话人性命题):
|
|
101
|
-
- 经典出处与提炼方式(换时代 / 换人物 / 换冲突具象):
|
|
102
|
-
- 与需求层痛点的匹配理由:
|
|
103
|
-
- 情绪价值承诺(读者读完得到什么):
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
const T_GATE = `# 三层一致性检查(闸门)
|
|
107
|
-
|
|
108
|
-
> 来源技能:three-layer-check。**硬关卡**——不过闸不进入大纲成文。
|
|
109
|
-
|
|
110
|
-
| 检查 | 判定 |
|
|
111
|
-
| --- | --- |
|
|
112
|
-
| 内核 ↔ 需求(内核回应的就是这个痛点?) | |
|
|
113
|
-
| 题材 ↔ 内核(形式由内核决定,不反过来) | |
|
|
114
|
-
| 形式 ↔ 读者(这个形式这个读者群吃得下?) | |
|
|
115
|
-
| 情绪价值 ↔ 需求缺口(交付的就是承诺的?) | |
|
|
116
|
-
|
|
117
|
-
- 结论:通过 / 不通过(不通过则回需求层或内核层重来,不许硬写)
|
|
118
|
-
`;
|
|
119
|
-
|
|
120
|
-
const T_LOGLINE = `# logline
|
|
121
|
-
|
|
122
|
-
- 一句话卖点(谁 + 想要什么 + 障碍 + 代价):
|
|
123
|
-
- 开篇方向:
|
|
124
|
-
- 候选版本(A / B / C,用 idea-lever 展开后挑):
|
|
125
|
-
`;
|
|
126
|
-
|
|
127
|
-
const T_LEVER = `# 创意杠杆候选
|
|
128
|
-
|
|
129
|
-
> 来源技能:idea-lever。方向性岔路口先穷举,作者挑选或融合——穷举不替代判断。
|
|
130
|
-
|
|
131
|
-
## 岔路口
|
|
132
|
-
|
|
133
|
-
(写明是哪一处:内核 / 开头 / 转折)
|
|
134
|
-
|
|
135
|
-
## 候选(≥3 个异质候选,各带优缺点与代价)
|
|
136
|
-
|
|
137
|
-
1. 方向:
|
|
138
|
-
- 优点:
|
|
139
|
-
- 代价:
|
|
140
|
-
2. 方向:
|
|
141
|
-
- 优点:
|
|
142
|
-
- 代价:
|
|
143
|
-
3. 方向:
|
|
144
|
-
- 优点:
|
|
145
|
-
- 代价:
|
|
146
|
-
`;
|
|
147
|
-
|
|
148
|
-
const T_STRUCTURE = `# 三幕骨架
|
|
149
|
-
|
|
150
|
-
> 来源技能:story-structure。
|
|
151
|
-
|
|
152
|
-
- **激励事件**(第一幕末,打破平衡):
|
|
153
|
-
- **中点**(第二幕中,真假胜负 / 认知反转):
|
|
154
|
-
- **高潮**(第三幕,代价最大的抉择):
|
|
155
|
-
- 纪律:每一章自问「这章冲突是升级、反转还是收束」,答不出即重写。
|
|
156
|
-
`;
|
|
157
|
-
|
|
158
|
-
const T_RELATION = `# 人物关系网
|
|
159
|
-
|
|
160
|
-
> 来源技能:relationship-web。
|
|
161
|
-
|
|
162
|
-
- 主角 ↔ 对手:价值观镜像(对手是主角的另一种可能):
|
|
163
|
-
- 关系张力清单(谁对谁有未清的账):
|
|
164
|
-
- 阵营与利益流向:
|
|
165
|
-
`;
|
|
166
|
-
|
|
167
|
-
const T_WORLD = `# 世界观
|
|
168
|
-
|
|
169
|
-
> 来源技能:world-builder。设计期工作稿——定稿后并入 03-组织/设定圣经/卷2-世界观设定.md;正文一致性以设定圣经为准。
|
|
170
|
-
|
|
171
|
-
- 时代 / 期限 / 地点 / 冲突层面(四维):
|
|
172
|
-
- 规则清单(每条规则 + 它产生的冲突):
|
|
173
|
-
- 修订记录(何时改了什么):
|
|
174
|
-
`;
|
|
175
|
-
|
|
176
|
-
const T_CHAR_TEMPLATE = `# 人物卡模板
|
|
177
|
-
|
|
178
|
-
> 来源技能:character-sheet。复制本文件为每个角色新建一份。设计期工作稿——定稿后并入 03-组织/设定圣经/卷1-人物档案.md;正文一致性以设定圣经为准。
|
|
179
|
-
|
|
180
|
-
## 人物:<名字>
|
|
181
|
-
|
|
182
|
-
- **目标(想要什么)**:
|
|
183
|
-
- **需求(真正需要什么,与目标冲突)**:
|
|
184
|
-
- **障碍(什么挡着)**:
|
|
185
|
-
- **代价(得到要付出什么)**:
|
|
186
|
-
- **缺陷(具体化,不是形容词)**:
|
|
187
|
-
- **压力下的反应方式**(幽默 / 照顾 / 外化 / 内化 / 沉默):
|
|
188
|
-
- **语言指纹**(遮住名字能认出是谁):
|
|
189
|
-
- **弧光事件**(哪几件事让他变了):
|
|
190
|
-
`;
|
|
191
|
-
|
|
192
|
-
const T_BIBLE_1 = `# 卷 1 · 人物档案
|
|
193
|
-
|
|
194
|
-
> 来源技能:story-bible。**一致性权威源**——正文与圣经冲突时,正文是错的。(设计期人物卡在 ../人物卡/,定稿后并入本卷)
|
|
195
|
-
|
|
196
|
-
## <人物名>
|
|
197
|
-
|
|
198
|
-
- 目标(当前):
|
|
199
|
-
- 动机(深层):
|
|
200
|
-
- 压力下的反应方式:
|
|
201
|
-
- 关系:<谁>(连接 / 张力 / 弧线)
|
|
202
|
-
- 状态变化:<章节> 发生了什么 → 状态如何变
|
|
203
|
-
`;
|
|
204
|
-
|
|
205
|
-
const T_BIBLE_2 = `# 卷 2 · 世界观设定
|
|
206
|
-
|
|
207
|
-
> 来源技能:story-bible。**一致性权威源**。(设计期世界观稿在 ../../世界观.md,定稿后并入本卷)
|
|
208
|
-
|
|
209
|
-
- 时代 / 期限 / 地点 / 冲突层面(四维):
|
|
210
|
-
- 规则清单:每条规则 + 它产生的冲突
|
|
211
|
-
- 修订记录:何时改了什么(防设定漂移后读者对不上)
|
|
212
|
-
`;
|
|
213
|
-
|
|
214
|
-
const T_BIBLE_3 = `# 卷 3 · 时间线
|
|
215
|
-
|
|
216
|
-
| 章节 | 关键事件 | 人物状态 | 伏笔 |
|
|
217
|
-
| --- | --- | --- | --- |
|
|
218
|
-
`;
|
|
219
|
-
|
|
220
|
-
const T_BIBLE_4 = `# 卷 4 · 伏笔台账
|
|
221
|
-
|
|
222
|
-
> 来源技能:foreshadow。埋得轻、收得重、埋收必对。未落正文前只标事件不标章,成文后回填章号。
|
|
223
|
-
|
|
224
|
-
| 伏笔 | 埋设点(事件/场景) | 计划回收点(事件/场景) | 当前状态(待回收 / 已回收 / 悬置) |
|
|
225
|
-
| --- | --- | --- | --- |
|
|
226
|
-
`;
|
|
227
|
-
|
|
228
|
-
const T_OUTLINE = `# 大纲索引
|
|
229
|
-
|
|
230
|
-
> 来源技能:outline-expand(五级展开:三层结构 → 大纲 → 细纲 → 场景清单 → 成文)。细纲只排事件序列,不排章节——章在成文装箱时才诞生。
|
|
231
|
-
|
|
232
|
-
| 卷 | 事件 | 定位(升级 / 反转 / 收束) | 状态 |
|
|
233
|
-
| --- | --- | --- | --- |
|
|
234
|
-
`;
|
|
235
|
-
|
|
236
|
-
const T_CHAPTERS = `# 正文
|
|
237
|
-
|
|
238
|
-
- 命名:第001章-标题.md(三位数补零、标题无空格)。
|
|
239
|
-
- 动笔前先读 ../03-组织/设定圣经/ 四卷 —— 不靠对话记忆,承接前文以圣经为准。
|
|
240
|
-
- 新增设定先入册再写;矛盾以圣经为准,改正文。
|
|
241
|
-
- 长篇每 5 章复盘一次:时间线 / 伏笔台账对一遍,防漂移。
|
|
242
|
-
`;
|
|
243
|
-
|
|
244
|
-
const T_REVIEW = `# 体检报告
|
|
245
|
-
|
|
246
|
-
> 来源技能:craft-review / polish-method / longform-guard。
|
|
247
|
-
|
|
248
|
-
## 四道自检
|
|
249
|
-
|
|
250
|
-
- [ ] 价值转变(每场景有好→坏 / 坏→好 / 信息揭晓)
|
|
251
|
-
- [ ] 情绪价值达成(对照需求层承诺)
|
|
252
|
-
- [ ] 留存思维(开头 3 章留人、章末有钩)
|
|
253
|
-
- [ ] 三层一致性在正文中维持
|
|
254
|
-
|
|
255
|
-
## 反 AI 叙事特征(结构层)
|
|
256
|
-
|
|
257
|
-
- [ ] 无说教点题句
|
|
258
|
-
- [ ] 有留白与支线(非闭环单线)
|
|
259
|
-
- [ ] 句长有参差(非节拍器)
|
|
260
|
-
- [ ] 主角非全能(配角 / 环境 / 巧合偶尔主导)
|
|
261
|
-
|
|
262
|
-
## 微层去AI味(字句级)
|
|
263
|
-
|
|
264
|
-
- [ ] 无「然而 / 因此 / 与此同时 / 值得注意的是」等过渡词套路
|
|
265
|
-
- [ ] 无「首先…其次…最后」规整句式
|
|
266
|
-
- [ ] 无 ≥3 个形容词堆砌
|
|
267
|
-
- [ ] 对话标签不规整(无「他微微一笑,开口说道」)
|
|
268
|
-
- [ ] 叙述者留有犹豫(结论没给满、承认不确定、克制收尾)
|
|
269
|
-
|
|
270
|
-
## 问题清单(按严重度)
|
|
271
|
-
|
|
272
|
-
1.
|
|
273
|
-
`;
|
|
274
|
-
|
|
275
|
-
const T_ARCHIVE = `# 归档
|
|
276
|
-
|
|
277
|
-
废稿与旧版本放这里,不删 —— 写作的退路。
|
|
278
|
-
`;
|
|
279
|
-
|
|
280
|
-
// ─────────────────────────────────────────────────────────────
|
|
281
|
-
// 目录规范(唯一可执行真源;SKILL.md 为其说明文档)
|
|
282
|
-
// min=true 表示 --minimal 精简子集也包含
|
|
283
|
-
// ─────────────────────────────────────────────────────────────
|
|
284
|
-
|
|
285
|
-
const STRUCTURE = [
|
|
286
|
-
{ p: '00-需求', dir: true },
|
|
287
|
-
{ p: '00-需求/热点与情绪内核.md', c: T_HOTSPOT },
|
|
288
|
-
{ p: '00-需求/读者画像.md', c: T_READER },
|
|
289
|
-
{ p: '01-内核', dir: true },
|
|
290
|
-
{ p: '01-内核/人性内核卡.md', c: T_CORE },
|
|
291
|
-
{ p: '01-内核/三层一致性检查.md', c: T_GATE },
|
|
292
|
-
{ p: '02-概念', dir: true },
|
|
293
|
-
{ p: '02-概念/logline.md', c: T_LOGLINE },
|
|
294
|
-
{ p: '02-概念/创意杠杆候选.md', c: T_LEVER },
|
|
295
|
-
{ p: '03-组织', dir: true, min: true },
|
|
296
|
-
{ p: '03-组织/三幕骨架.md', c: T_STRUCTURE },
|
|
297
|
-
{ p: '03-组织/人物关系网.md', c: T_RELATION },
|
|
298
|
-
{ p: '03-组织/世界观.md', c: T_WORLD },
|
|
299
|
-
{ p: '03-组织/人物卡', dir: true, min: true },
|
|
300
|
-
{ p: '03-组织/人物卡/人物卡模板.md', c: T_CHAR_TEMPLATE, min: true },
|
|
301
|
-
{ p: '03-组织/设定圣经', dir: true, min: true },
|
|
302
|
-
{ p: '03-组织/设定圣经/卷1-人物档案.md', c: T_BIBLE_1, min: true },
|
|
303
|
-
{ p: '03-组织/设定圣经/卷2-世界观设定.md', c: T_BIBLE_2, min: true },
|
|
304
|
-
{ p: '03-组织/设定圣经/卷3-时间线.md', c: T_BIBLE_3, min: true },
|
|
305
|
-
{ p: '03-组织/设定圣经/卷4-伏笔台账.md', c: T_BIBLE_4, min: true },
|
|
306
|
-
{ p: '04-大纲', dir: true, min: true },
|
|
307
|
-
{ p: '04-大纲/大纲索引.md', c: T_OUTLINE, min: true },
|
|
308
|
-
{ p: '05-正文', dir: true, min: true },
|
|
309
|
-
{ p: '05-正文/README.md', c: T_CHAPTERS, min: true },
|
|
310
|
-
{ p: '06-体检', dir: true },
|
|
311
|
-
{ p: '06-体检/体检报告模板.md', c: T_REVIEW },
|
|
312
|
-
{ p: '07-归档', dir: true },
|
|
313
|
-
{ p: '07-归档/README.md', c: T_ARCHIVE },
|
|
314
|
-
];
|
|
315
|
-
|
|
316
|
-
// ─────────────────────────────────────────────────────────────
|
|
317
|
-
// 参数解析
|
|
318
|
-
// ─────────────────────────────────────────────────────────────
|
|
319
|
-
|
|
320
|
-
const argv = process.argv.slice(2);
|
|
321
|
-
|
|
322
|
-
if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {
|
|
323
|
-
printUsage();
|
|
324
|
-
process.exit(argv.length === 0 ? 1 : 0);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
const flags = new Set();
|
|
328
|
-
const options = {};
|
|
329
|
-
const positional = [];
|
|
330
|
-
|
|
331
|
-
for (let i = 0; i < argv.length; i++) {
|
|
332
|
-
const arg = argv[i];
|
|
333
|
-
if (arg === '--minimal' || arg === '--force') {
|
|
334
|
-
flags.add(arg);
|
|
335
|
-
} else if (arg === '--dir') {
|
|
336
|
-
options.dir = argv[++i];
|
|
337
|
-
} else {
|
|
338
|
-
positional.push(arg);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const bookName = positional[0];
|
|
343
|
-
if (!bookName) {
|
|
344
|
-
console.error('✗ 缺少书名。用法见 --help');
|
|
345
|
-
process.exit(1);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// 安全校验:书名不含空格 / 路径分隔符(Windows + git 中文空格路径会乱码)
|
|
349
|
-
if (/\s/.test(bookName)) {
|
|
350
|
-
console.error(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
--dir
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 小说工程目录初始化(共鸣小说家 · project-init 技能 · L3 scripts)
|
|
4
|
+
*
|
|
5
|
+
* 目录规范:编号目录 = 角色包七阶段流水线(00-需求 … 07-归档)。
|
|
6
|
+
* 设定权威源 = 03-组织/设定圣经/(承接 story-bible 四卷;正文与圣经冲突时,正文是错的)。
|
|
7
|
+
*
|
|
8
|
+
* 用法:
|
|
9
|
+
* node init-novel-project.mjs <书名> [--dir <父目录>] [--minimal] [--force]
|
|
10
|
+
*
|
|
11
|
+
* 参数:
|
|
12
|
+
* <书名> 必填。项目目录名(同时写入 README)。
|
|
13
|
+
* --dir 父目录,默认当前工作目录。
|
|
14
|
+
* --minimal 精简子集(短篇/中篇):只建 README + 设定圣经四卷 + 人物卡 + 大纲 + 正文。
|
|
15
|
+
* --force 目标目录已存在且非空时仍继续(默认中止,防覆盖已有工程)。
|
|
16
|
+
*
|
|
17
|
+
* 约定:
|
|
18
|
+
* - 中文路径一律无空格 —— Windows + git 处理含空格中文路径会乱码(血训)。
|
|
19
|
+
* - 纯 Node 内置模块,零第三方依赖(与内核同哲学)。
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { mkdir, writeFile, readdir } from 'node:fs/promises';
|
|
23
|
+
import { join, resolve, dirname } from 'node:path';
|
|
24
|
+
import { existsSync } from 'node:fs';
|
|
25
|
+
|
|
26
|
+
// ─────────────────────────────────────────────────────────────
|
|
27
|
+
// 模板(SSOT:与 story-bible / craft-review / hotspot-mapping 等技能字段对齐)
|
|
28
|
+
// 约定:模板内不使用反引号,避免与 JS 模板字面量冲突。
|
|
29
|
+
// ─────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
const T_README = (name) => `# 《${name}》
|
|
32
|
+
|
|
33
|
+
> 由「共鸣小说家」角色包的 project-init 技能初始化。
|
|
34
|
+
|
|
35
|
+
## 一句话 logline
|
|
36
|
+
|
|
37
|
+
(待填:谁 + 想要什么 + 障碍 + 代价)
|
|
38
|
+
|
|
39
|
+
## 三层定位
|
|
40
|
+
|
|
41
|
+
- **需求层**:回应什么痛点 / 读者的什么精神缺口 →
|
|
42
|
+
- **内核层**:经典人性内核(不随时代变)→
|
|
43
|
+
- **形式层**:题材 / 设定 / 文风 →
|
|
44
|
+
|
|
45
|
+
## 当前进度
|
|
46
|
+
|
|
47
|
+
- [ ] 阶段1 需求洞察与事件转换(need-finder + hotspot-mapping)
|
|
48
|
+
- [ ] 阶段2 内核锁定(core-extractor)
|
|
49
|
+
- [ ] 阶段3 一致性闸门(three-layer-check)
|
|
50
|
+
- [ ] 阶段4 概念包装(logline-craft + idea-lever)
|
|
51
|
+
- [ ] 阶段5 组织搭建(story-structure / relationship-web / character-sheet / world-builder / story-bible)
|
|
52
|
+
- [ ] 阶段6 大纲与成文(outline-expand → scene-craft)
|
|
53
|
+
- [ ] 阶段7 打磨与体检(polish-method / longform-guard / craft-review)
|
|
54
|
+
|
|
55
|
+
## 目录约定
|
|
56
|
+
|
|
57
|
+
编号目录 = 角色包七阶段流水线。设定权威源 = 03-组织/设定圣经/ —— 正文与圣经冲突时,正文是错的。
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
const T_HOTSPOT = `# 热点与情绪内核
|
|
61
|
+
|
|
62
|
+
> 来源技能:need-finder + hotspot-mapping。AI 不想象共鸣——只搬运事件里已经存在的情绪。
|
|
63
|
+
|
|
64
|
+
## 热点现象
|
|
65
|
+
|
|
66
|
+
- 事件:
|
|
67
|
+
- 时间范围(须最近一周到一个月,过时热点不用):
|
|
68
|
+
- 来源平台(微博 / 知乎 / 小红书 / B 站…):
|
|
69
|
+
|
|
70
|
+
## 情绪内核(一句话感受,不是事件描述)
|
|
71
|
+
|
|
72
|
+
- 事件是壳,壳下面的情绪才带走 →
|
|
73
|
+
- 判据:是读者也在感受的(是「老实人总吃亏」,不是「某案判错了」)→
|
|
74
|
+
|
|
75
|
+
## 映射到小说世界(换事件、留内核)
|
|
76
|
+
|
|
77
|
+
- 原事件外壳 → 换成的虚构设定:
|
|
78
|
+
- 保留的人的属性(贪婪 / 恐惧 / 被看见的渴望 / 守护 / 不甘…):
|
|
79
|
+
|
|
80
|
+
## 验证三问
|
|
81
|
+
|
|
82
|
+
- [ ] 读者感到「这种情绪我熟悉」?
|
|
83
|
+
- [ ] 读者认不出原新闻(外壳换干净)?
|
|
84
|
+
- [ ] 删掉映射故事仍完整(非喧宾夺主)?
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
const T_READER = `# 读者画像
|
|
88
|
+
|
|
89
|
+
- 痛点属于谁(Z世代 / 中老年 / 女性 / 男性 / 下沉市场…):
|
|
90
|
+
- 精神需求缺口(解压 / 治愈 / 共鸣 / 代偿 / 爽感):
|
|
91
|
+
- 读者在什么场景读(通勤 / 睡前 / 碎片):
|
|
92
|
+
- 验证依据(榜单 / 评论 / 标签热度):
|
|
93
|
+
- 时效性:当下红利 / 长期底色
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
const T_CORE = `# 人性内核卡
|
|
97
|
+
|
|
98
|
+
> 来源技能:core-extractor。内核不随时代变——从经典提炼骨架,不抄故事。
|
|
99
|
+
|
|
100
|
+
- 内核(一句话人性命题):
|
|
101
|
+
- 经典出处与提炼方式(换时代 / 换人物 / 换冲突具象):
|
|
102
|
+
- 与需求层痛点的匹配理由:
|
|
103
|
+
- 情绪价值承诺(读者读完得到什么):
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
const T_GATE = `# 三层一致性检查(闸门)
|
|
107
|
+
|
|
108
|
+
> 来源技能:three-layer-check。**硬关卡**——不过闸不进入大纲成文。
|
|
109
|
+
|
|
110
|
+
| 检查 | 判定 |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| 内核 ↔ 需求(内核回应的就是这个痛点?) | |
|
|
113
|
+
| 题材 ↔ 内核(形式由内核决定,不反过来) | |
|
|
114
|
+
| 形式 ↔ 读者(这个形式这个读者群吃得下?) | |
|
|
115
|
+
| 情绪价值 ↔ 需求缺口(交付的就是承诺的?) | |
|
|
116
|
+
|
|
117
|
+
- 结论:通过 / 不通过(不通过则回需求层或内核层重来,不许硬写)
|
|
118
|
+
`;
|
|
119
|
+
|
|
120
|
+
const T_LOGLINE = `# logline
|
|
121
|
+
|
|
122
|
+
- 一句话卖点(谁 + 想要什么 + 障碍 + 代价):
|
|
123
|
+
- 开篇方向:
|
|
124
|
+
- 候选版本(A / B / C,用 idea-lever 展开后挑):
|
|
125
|
+
`;
|
|
126
|
+
|
|
127
|
+
const T_LEVER = `# 创意杠杆候选
|
|
128
|
+
|
|
129
|
+
> 来源技能:idea-lever。方向性岔路口先穷举,作者挑选或融合——穷举不替代判断。
|
|
130
|
+
|
|
131
|
+
## 岔路口
|
|
132
|
+
|
|
133
|
+
(写明是哪一处:内核 / 开头 / 转折)
|
|
134
|
+
|
|
135
|
+
## 候选(≥3 个异质候选,各带优缺点与代价)
|
|
136
|
+
|
|
137
|
+
1. 方向:
|
|
138
|
+
- 优点:
|
|
139
|
+
- 代价:
|
|
140
|
+
2. 方向:
|
|
141
|
+
- 优点:
|
|
142
|
+
- 代价:
|
|
143
|
+
3. 方向:
|
|
144
|
+
- 优点:
|
|
145
|
+
- 代价:
|
|
146
|
+
`;
|
|
147
|
+
|
|
148
|
+
const T_STRUCTURE = `# 三幕骨架
|
|
149
|
+
|
|
150
|
+
> 来源技能:story-structure。
|
|
151
|
+
|
|
152
|
+
- **激励事件**(第一幕末,打破平衡):
|
|
153
|
+
- **中点**(第二幕中,真假胜负 / 认知反转):
|
|
154
|
+
- **高潮**(第三幕,代价最大的抉择):
|
|
155
|
+
- 纪律:每一章自问「这章冲突是升级、反转还是收束」,答不出即重写。
|
|
156
|
+
`;
|
|
157
|
+
|
|
158
|
+
const T_RELATION = `# 人物关系网
|
|
159
|
+
|
|
160
|
+
> 来源技能:relationship-web。
|
|
161
|
+
|
|
162
|
+
- 主角 ↔ 对手:价值观镜像(对手是主角的另一种可能):
|
|
163
|
+
- 关系张力清单(谁对谁有未清的账):
|
|
164
|
+
- 阵营与利益流向:
|
|
165
|
+
`;
|
|
166
|
+
|
|
167
|
+
const T_WORLD = `# 世界观
|
|
168
|
+
|
|
169
|
+
> 来源技能:world-builder。设计期工作稿——定稿后并入 03-组织/设定圣经/卷2-世界观设定.md;正文一致性以设定圣经为准。
|
|
170
|
+
|
|
171
|
+
- 时代 / 期限 / 地点 / 冲突层面(四维):
|
|
172
|
+
- 规则清单(每条规则 + 它产生的冲突):
|
|
173
|
+
- 修订记录(何时改了什么):
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
const T_CHAR_TEMPLATE = `# 人物卡模板
|
|
177
|
+
|
|
178
|
+
> 来源技能:character-sheet。复制本文件为每个角色新建一份。设计期工作稿——定稿后并入 03-组织/设定圣经/卷1-人物档案.md;正文一致性以设定圣经为准。
|
|
179
|
+
|
|
180
|
+
## 人物:<名字>
|
|
181
|
+
|
|
182
|
+
- **目标(想要什么)**:
|
|
183
|
+
- **需求(真正需要什么,与目标冲突)**:
|
|
184
|
+
- **障碍(什么挡着)**:
|
|
185
|
+
- **代价(得到要付出什么)**:
|
|
186
|
+
- **缺陷(具体化,不是形容词)**:
|
|
187
|
+
- **压力下的反应方式**(幽默 / 照顾 / 外化 / 内化 / 沉默):
|
|
188
|
+
- **语言指纹**(遮住名字能认出是谁):
|
|
189
|
+
- **弧光事件**(哪几件事让他变了):
|
|
190
|
+
`;
|
|
191
|
+
|
|
192
|
+
const T_BIBLE_1 = `# 卷 1 · 人物档案
|
|
193
|
+
|
|
194
|
+
> 来源技能:story-bible。**一致性权威源**——正文与圣经冲突时,正文是错的。(设计期人物卡在 ../人物卡/,定稿后并入本卷)
|
|
195
|
+
|
|
196
|
+
## <人物名>
|
|
197
|
+
|
|
198
|
+
- 目标(当前):
|
|
199
|
+
- 动机(深层):
|
|
200
|
+
- 压力下的反应方式:
|
|
201
|
+
- 关系:<谁>(连接 / 张力 / 弧线)
|
|
202
|
+
- 状态变化:<章节> 发生了什么 → 状态如何变
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
const T_BIBLE_2 = `# 卷 2 · 世界观设定
|
|
206
|
+
|
|
207
|
+
> 来源技能:story-bible。**一致性权威源**。(设计期世界观稿在 ../../世界观.md,定稿后并入本卷)
|
|
208
|
+
|
|
209
|
+
- 时代 / 期限 / 地点 / 冲突层面(四维):
|
|
210
|
+
- 规则清单:每条规则 + 它产生的冲突
|
|
211
|
+
- 修订记录:何时改了什么(防设定漂移后读者对不上)
|
|
212
|
+
`;
|
|
213
|
+
|
|
214
|
+
const T_BIBLE_3 = `# 卷 3 · 时间线
|
|
215
|
+
|
|
216
|
+
| 章节 | 关键事件 | 人物状态 | 伏笔 |
|
|
217
|
+
| --- | --- | --- | --- |
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
const T_BIBLE_4 = `# 卷 4 · 伏笔台账
|
|
221
|
+
|
|
222
|
+
> 来源技能:foreshadow。埋得轻、收得重、埋收必对。未落正文前只标事件不标章,成文后回填章号。
|
|
223
|
+
|
|
224
|
+
| 伏笔 | 埋设点(事件/场景) | 计划回收点(事件/场景) | 当前状态(待回收 / 已回收 / 悬置) |
|
|
225
|
+
| --- | --- | --- | --- |
|
|
226
|
+
`;
|
|
227
|
+
|
|
228
|
+
const T_OUTLINE = `# 大纲索引
|
|
229
|
+
|
|
230
|
+
> 来源技能:outline-expand(五级展开:三层结构 → 大纲 → 细纲 → 场景清单 → 成文)。细纲只排事件序列,不排章节——章在成文装箱时才诞生。
|
|
231
|
+
|
|
232
|
+
| 卷 | 事件 | 定位(升级 / 反转 / 收束) | 状态 |
|
|
233
|
+
| --- | --- | --- | --- |
|
|
234
|
+
`;
|
|
235
|
+
|
|
236
|
+
const T_CHAPTERS = `# 正文
|
|
237
|
+
|
|
238
|
+
- 命名:第001章-标题.md(三位数补零、标题无空格)。
|
|
239
|
+
- 动笔前先读 ../03-组织/设定圣经/ 四卷 —— 不靠对话记忆,承接前文以圣经为准。
|
|
240
|
+
- 新增设定先入册再写;矛盾以圣经为准,改正文。
|
|
241
|
+
- 长篇每 5 章复盘一次:时间线 / 伏笔台账对一遍,防漂移。
|
|
242
|
+
`;
|
|
243
|
+
|
|
244
|
+
const T_REVIEW = `# 体检报告
|
|
245
|
+
|
|
246
|
+
> 来源技能:craft-review / polish-method / longform-guard。
|
|
247
|
+
|
|
248
|
+
## 四道自检
|
|
249
|
+
|
|
250
|
+
- [ ] 价值转变(每场景有好→坏 / 坏→好 / 信息揭晓)
|
|
251
|
+
- [ ] 情绪价值达成(对照需求层承诺)
|
|
252
|
+
- [ ] 留存思维(开头 3 章留人、章末有钩)
|
|
253
|
+
- [ ] 三层一致性在正文中维持
|
|
254
|
+
|
|
255
|
+
## 反 AI 叙事特征(结构层)
|
|
256
|
+
|
|
257
|
+
- [ ] 无说教点题句
|
|
258
|
+
- [ ] 有留白与支线(非闭环单线)
|
|
259
|
+
- [ ] 句长有参差(非节拍器)
|
|
260
|
+
- [ ] 主角非全能(配角 / 环境 / 巧合偶尔主导)
|
|
261
|
+
|
|
262
|
+
## 微层去AI味(字句级)
|
|
263
|
+
|
|
264
|
+
- [ ] 无「然而 / 因此 / 与此同时 / 值得注意的是」等过渡词套路
|
|
265
|
+
- [ ] 无「首先…其次…最后」规整句式
|
|
266
|
+
- [ ] 无 ≥3 个形容词堆砌
|
|
267
|
+
- [ ] 对话标签不规整(无「他微微一笑,开口说道」)
|
|
268
|
+
- [ ] 叙述者留有犹豫(结论没给满、承认不确定、克制收尾)
|
|
269
|
+
|
|
270
|
+
## 问题清单(按严重度)
|
|
271
|
+
|
|
272
|
+
1.
|
|
273
|
+
`;
|
|
274
|
+
|
|
275
|
+
const T_ARCHIVE = `# 归档
|
|
276
|
+
|
|
277
|
+
废稿与旧版本放这里,不删 —— 写作的退路。
|
|
278
|
+
`;
|
|
279
|
+
|
|
280
|
+
// ─────────────────────────────────────────────────────────────
|
|
281
|
+
// 目录规范(唯一可执行真源;SKILL.md 为其说明文档)
|
|
282
|
+
// min=true 表示 --minimal 精简子集也包含
|
|
283
|
+
// ─────────────────────────────────────────────────────────────
|
|
284
|
+
|
|
285
|
+
const STRUCTURE = [
|
|
286
|
+
{ p: '00-需求', dir: true },
|
|
287
|
+
{ p: '00-需求/热点与情绪内核.md', c: T_HOTSPOT },
|
|
288
|
+
{ p: '00-需求/读者画像.md', c: T_READER },
|
|
289
|
+
{ p: '01-内核', dir: true },
|
|
290
|
+
{ p: '01-内核/人性内核卡.md', c: T_CORE },
|
|
291
|
+
{ p: '01-内核/三层一致性检查.md', c: T_GATE },
|
|
292
|
+
{ p: '02-概念', dir: true },
|
|
293
|
+
{ p: '02-概念/logline.md', c: T_LOGLINE },
|
|
294
|
+
{ p: '02-概念/创意杠杆候选.md', c: T_LEVER },
|
|
295
|
+
{ p: '03-组织', dir: true, min: true },
|
|
296
|
+
{ p: '03-组织/三幕骨架.md', c: T_STRUCTURE },
|
|
297
|
+
{ p: '03-组织/人物关系网.md', c: T_RELATION },
|
|
298
|
+
{ p: '03-组织/世界观.md', c: T_WORLD },
|
|
299
|
+
{ p: '03-组织/人物卡', dir: true, min: true },
|
|
300
|
+
{ p: '03-组织/人物卡/人物卡模板.md', c: T_CHAR_TEMPLATE, min: true },
|
|
301
|
+
{ p: '03-组织/设定圣经', dir: true, min: true },
|
|
302
|
+
{ p: '03-组织/设定圣经/卷1-人物档案.md', c: T_BIBLE_1, min: true },
|
|
303
|
+
{ p: '03-组织/设定圣经/卷2-世界观设定.md', c: T_BIBLE_2, min: true },
|
|
304
|
+
{ p: '03-组织/设定圣经/卷3-时间线.md', c: T_BIBLE_3, min: true },
|
|
305
|
+
{ p: '03-组织/设定圣经/卷4-伏笔台账.md', c: T_BIBLE_4, min: true },
|
|
306
|
+
{ p: '04-大纲', dir: true, min: true },
|
|
307
|
+
{ p: '04-大纲/大纲索引.md', c: T_OUTLINE, min: true },
|
|
308
|
+
{ p: '05-正文', dir: true, min: true },
|
|
309
|
+
{ p: '05-正文/README.md', c: T_CHAPTERS, min: true },
|
|
310
|
+
{ p: '06-体检', dir: true },
|
|
311
|
+
{ p: '06-体检/体检报告模板.md', c: T_REVIEW },
|
|
312
|
+
{ p: '07-归档', dir: true },
|
|
313
|
+
{ p: '07-归档/README.md', c: T_ARCHIVE },
|
|
314
|
+
];
|
|
315
|
+
|
|
316
|
+
// ─────────────────────────────────────────────────────────────
|
|
317
|
+
// 参数解析
|
|
318
|
+
// ─────────────────────────────────────────────────────────────
|
|
319
|
+
|
|
320
|
+
const argv = process.argv.slice(2);
|
|
321
|
+
|
|
322
|
+
if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {
|
|
323
|
+
printUsage();
|
|
324
|
+
process.exit(argv.length === 0 ? 1 : 0);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const flags = new Set();
|
|
328
|
+
const options = {};
|
|
329
|
+
const positional = [];
|
|
330
|
+
|
|
331
|
+
for (let i = 0; i < argv.length; i++) {
|
|
332
|
+
const arg = argv[i];
|
|
333
|
+
if (arg === '--minimal' || arg === '--force') {
|
|
334
|
+
flags.add(arg);
|
|
335
|
+
} else if (arg === '--dir') {
|
|
336
|
+
options.dir = argv[++i];
|
|
337
|
+
} else {
|
|
338
|
+
positional.push(arg);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const bookName = positional[0];
|
|
343
|
+
if (!bookName) {
|
|
344
|
+
console.error('✗ 缺少书名。用法见 --help');
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// 安全校验:书名不含空格 / 路径分隔符(Windows + git 中文空格路径会乱码)
|
|
349
|
+
if (/\s/.test(bookName)) {
|
|
350
|
+
console.error(
|
|
351
|
+
`✗ 书名不能含空格(Windows + git 处理含空格中文路径会乱码)→ 建议改用:${bookName.replace(/\s+/g, '-')}`,
|
|
352
|
+
);
|
|
353
|
+
process.exit(1);
|
|
354
|
+
}
|
|
355
|
+
if (bookName.includes('/') || bookName.includes('\\') || bookName === '.' || bookName === '..') {
|
|
356
|
+
console.error('✗ 书名不能含路径分隔符或为 . / ..');
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const parentDir = options.dir ? resolve(options.dir) : process.cwd();
|
|
361
|
+
const targetDir = join(parentDir, bookName);
|
|
362
|
+
|
|
363
|
+
// 目标目录非空保护
|
|
364
|
+
if (existsSync(targetDir)) {
|
|
365
|
+
const existing = await readdir(targetDir);
|
|
366
|
+
if (existing.length > 0 && !flags.has('--force')) {
|
|
367
|
+
console.error(
|
|
368
|
+
`✗ 目标目录已存在且非空:${targetDir}\n 加 --force 可继续(已存在文件会跳过,不覆盖)。`,
|
|
369
|
+
);
|
|
370
|
+
process.exit(1);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// ─────────────────────────────────────────────────────────────
|
|
375
|
+
// 生成
|
|
376
|
+
// ─────────────────────────────────────────────────────────────
|
|
377
|
+
|
|
378
|
+
const minimal = flags.has('--minimal');
|
|
379
|
+
const plan = minimal ? STRUCTURE.filter((e) => e.min) : STRUCTURE;
|
|
380
|
+
|
|
381
|
+
const created = [];
|
|
382
|
+
const skipped = [];
|
|
383
|
+
|
|
384
|
+
// 项目根目录
|
|
385
|
+
await mkdir(targetDir, { recursive: true });
|
|
386
|
+
|
|
387
|
+
// README(门面,两种模式都要)
|
|
388
|
+
const readmePath = join(targetDir, 'README.md');
|
|
389
|
+
if (existsSync(readmePath) && !flags.has('--force')) {
|
|
390
|
+
skipped.push('README.md');
|
|
391
|
+
} else {
|
|
392
|
+
await writeFile(readmePath, T_README(bookName), 'utf-8');
|
|
393
|
+
created.push('README.md');
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
for (const entry of plan) {
|
|
397
|
+
const full = join(targetDir, entry.p);
|
|
398
|
+
if (entry.dir) {
|
|
399
|
+
await mkdir(full, { recursive: true });
|
|
400
|
+
created.push(entry.p + '/');
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
await mkdir(dirname(full), { recursive: true });
|
|
404
|
+
if (existsSync(full) && !flags.has('--force')) {
|
|
405
|
+
skipped.push(entry.p);
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
await writeFile(full, entry.c, 'utf-8');
|
|
409
|
+
created.push(entry.p);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// ─────────────────────────────────────────────────────────────
|
|
413
|
+
// 输出
|
|
414
|
+
// ─────────────────────────────────────────────────────────────
|
|
415
|
+
|
|
416
|
+
console.log(`\n✓ 小说工程已初始化:${targetDir}`);
|
|
417
|
+
console.log(` 模式:${minimal ? '精简(--minimal)' : '完整(七阶段)'}`);
|
|
418
|
+
console.log(`\n 已创建 ${created.length} 项:`);
|
|
419
|
+
for (const c of created) console.log(` + ${c}`);
|
|
420
|
+
if (skipped.length > 0) {
|
|
421
|
+
console.log(`\n 跳过 ${skipped.length} 项(已存在,未覆盖):`);
|
|
422
|
+
for (const s of skipped) console.log(` - ${s}`);
|
|
423
|
+
}
|
|
424
|
+
const nextStep = minimal
|
|
425
|
+
? '先填 03-组织/设定圣经/ 四卷(人物档案 / 世界观 / 时间线 / 伏笔台账),再进 04-大纲 与 05-正文。'
|
|
426
|
+
: '先填 00-需求/热点与情绪内核.md(搜热点 → 提情绪内核 → 映射进小说世界)。';
|
|
427
|
+
console.log(`\n 下一步:${nextStep}\n`);
|
|
428
|
+
|
|
429
|
+
function printUsage() {
|
|
430
|
+
console.log(`小说工程目录初始化(共鸣小说家 · project-init)
|
|
431
|
+
|
|
432
|
+
用法:
|
|
433
|
+
node init-novel-project.mjs <书名> [--dir <父目录>] [--minimal] [--force]
|
|
434
|
+
|
|
435
|
+
参数:
|
|
436
|
+
<书名> 必填。项目目录名,不得含空格(Windows + git 中文空格路径会乱码)。
|
|
437
|
+
--dir 父目录,默认当前工作目录。
|
|
438
|
+
--minimal 精简子集(短篇/中篇):README + 人物卡 + 设定圣经四卷 + 大纲 + 正文。
|
|
439
|
+
--force 目标目录非空时仍继续(已存在文件跳过,不覆盖)。
|
|
440
|
+
|
|
441
|
+
示例:
|
|
442
|
+
node init-novel-project.mjs 长夜将尽 --dir ./novels
|
|
443
|
+
node init-novel-project.mjs 春雨 --minimal
|
|
444
|
+
`);
|
|
445
|
+
}
|