novelws 5.1.0 → 5.3.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 +52 -0
- package/README.md +54 -3
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +42 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +18 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +23 -0
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/core/config.d.ts +4 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +5 -2
- package/dist/core/config.js.map +1 -1
- package/dist/server/datasource/db.d.ts +38 -0
- package/dist/server/datasource/db.d.ts.map +1 -0
- package/dist/server/datasource/db.js +323 -0
- package/dist/server/datasource/db.js.map +1 -0
- package/dist/server/datasource/fs.d.ts +30 -0
- package/dist/server/datasource/fs.d.ts.map +1 -0
- package/dist/server/datasource/fs.js +308 -0
- package/dist/server/datasource/fs.js.map +1 -0
- package/dist/server/datasource/index.d.ts +11 -0
- package/dist/server/datasource/index.d.ts.map +1 -0
- package/dist/server/datasource/index.js +33 -0
- package/dist/server/datasource/index.js.map +1 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +69 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/characters.d.ts +4 -0
- package/dist/server/routes/characters.d.ts.map +1 -0
- package/dist/server/routes/characters.js +27 -0
- package/dist/server/routes/characters.js.map +1 -0
- package/dist/server/routes/plots.d.ts +4 -0
- package/dist/server/routes/plots.d.ts.map +1 -0
- package/dist/server/routes/plots.js +36 -0
- package/dist/server/routes/plots.js.map +1 -0
- package/dist/server/routes/protagonist.d.ts +4 -0
- package/dist/server/routes/protagonist.d.ts.map +1 -0
- package/dist/server/routes/protagonist.js +46 -0
- package/dist/server/routes/protagonist.js.map +1 -0
- package/dist/server/routes/relationships.d.ts +4 -0
- package/dist/server/routes/relationships.d.ts.map +1 -0
- package/dist/server/routes/relationships.js +27 -0
- package/dist/server/routes/relationships.js.map +1 -0
- package/dist/server/routes/stats.d.ts +4 -0
- package/dist/server/routes/stats.d.ts.map +1 -0
- package/dist/server/routes/stats.js +21 -0
- package/dist/server/routes/stats.js.map +1 -0
- package/dist/server/routes/stories.d.ts +4 -0
- package/dist/server/routes/stories.d.ts.map +1 -0
- package/dist/server/routes/stories.js +80 -0
- package/dist/server/routes/stories.js.map +1 -0
- package/dist/server/routes/timeline.d.ts +4 -0
- package/dist/server/routes/timeline.d.ts.map +1 -0
- package/dist/server/routes/timeline.js +17 -0
- package/dist/server/routes/timeline.js.map +1 -0
- package/dist/server/types.d.ts +199 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/utils/diagnostics.d.ts +2 -2
- package/dist/utils/diagnostics.d.ts.map +1 -1
- package/dist/utils/diagnostics.js +46 -59
- package/dist/utils/diagnostics.js.map +1 -1
- package/package.json +13 -3
- package/templates/commands/analyze.md +20 -8
- package/templates/commands/expand.md +46 -20
- package/templates/commands/plan.md +3 -2
- package/templates/commands/specify.md +6 -2
- package/templates/commands/write.md +77 -24
- package/templates/dot-claude/CLAUDE.md +48 -8
- package/templates/resources/anti-ai.md +92 -13
- package/templates/resources/constitution.md +83 -140
- package/templates/resources/style-reference.md +30 -6
- package/templates/scripts/db_context.py +609 -0
- package/templates/scripts/db_init_protagonist.py +343 -0
- package/templates/scripts/db_sync.py +611 -0
- package/templates/scripts/db_volume_switch.py +278 -0
- package/templates/scripts/phase_a_init_db.py +428 -0
- package/templates/scripts/requirements.txt +1 -0
- package/templates/tracking/character-state.json +1 -3
- package/templates/tracking/plot-tracker.json +1 -5
- package/templates/tracking/relationships.json +1 -3
- package/templates/tracking/timeline.json +1 -3
- package/templates/volume-outline.md +31 -0
- package/templates/volume-summary.md +20 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../../src/server/routes/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAyBhE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
export function createRelationshipsRouter(ds) {
|
|
3
|
+
const router = Router({ mergeParams: true });
|
|
4
|
+
// GET /api/stories/:story/relationships?vol=X
|
|
5
|
+
router.get('/', async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const vol = req.query.vol ? parseInt(req.query.vol, 10) : undefined;
|
|
8
|
+
const graph = await ds.getRelationships(req.params.story, vol);
|
|
9
|
+
res.json(graph);
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
res.status(500).json({ error: err.message });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
// GET /api/stories/:story/relationships/history
|
|
16
|
+
router.get('/history', async (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const history = await ds.getRelationshipHistory(req.params.story);
|
|
19
|
+
res.json(history);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
res.status(500).json({ error: err.message });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return router;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=relationships.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../../src/server/routes/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAGpD,MAAM,UAAU,yBAAyB,CAAC,EAAc;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,8CAA8C;IAC9C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAA+B,EAAE,GAAa,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC9E,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/D,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gDAAgD;IAChD,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,GAA+B,EAAE,GAAa,EAAE,EAAE;QAC9E,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/server/routes/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAmBxD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
export function createStatsRouter(ds) {
|
|
3
|
+
const router = Router();
|
|
4
|
+
// GET /api/stats/dashboard?story=X
|
|
5
|
+
router.get('/dashboard', async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const story = req.query.story;
|
|
8
|
+
if (!story) {
|
|
9
|
+
res.status(400).json({ error: '缺少 story 参数' });
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const stats = await ds.getDashboardStats(story);
|
|
13
|
+
res.json(stats);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
res.status(500).json({ error: err.message });
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return router;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/server/routes/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,MAAM,UAAU,iBAAiB,CAAC,EAAc;IAC9C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,mCAAmC;IACnC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAe,CAAC;YACxC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;gBAC/C,OAAO;YACT,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stories.d.ts","sourceRoot":"","sources":["../../../src/server/routes/stories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CA8E1D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
export function createStoriesRouter(ds) {
|
|
3
|
+
const router = Router();
|
|
4
|
+
// GET /api/stories
|
|
5
|
+
router.get('/', async (_req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const stories = await ds.getStories();
|
|
8
|
+
res.json(stories);
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
res.status(500).json({ error: err.message });
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
// GET /api/stories/:story/overview
|
|
15
|
+
router.get('/:story/overview', async (req, res) => {
|
|
16
|
+
try {
|
|
17
|
+
const overview = await ds.getOverview(req.params.story);
|
|
18
|
+
res.json(overview);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
res.status(500).json({ error: err.message });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
// GET /api/stories/:story/volumes
|
|
25
|
+
router.get('/:story/volumes', async (req, res) => {
|
|
26
|
+
try {
|
|
27
|
+
const volumes = await ds.getVolumes(req.params.story);
|
|
28
|
+
res.json(volumes);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
res.status(500).json({ error: err.message });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
// GET /api/stories/:story/volumes/:vol/stats
|
|
35
|
+
router.get('/:story/volumes/:vol/stats', async (req, res) => {
|
|
36
|
+
try {
|
|
37
|
+
const vol = parseInt(req.params.vol, 10);
|
|
38
|
+
const chapters = await ds.getChapters(req.params.story, vol);
|
|
39
|
+
const characters = await ds.getCharacters(req.params.story, vol);
|
|
40
|
+
res.json({
|
|
41
|
+
volume: vol,
|
|
42
|
+
chapters: chapters.length,
|
|
43
|
+
words: chapters.reduce((sum, c) => sum + c.words, 0),
|
|
44
|
+
characters: characters.length,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
res.status(500).json({ error: err.message });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// GET /api/stories/:story/chapters?vol=X
|
|
52
|
+
router.get('/:story/chapters', async (req, res) => {
|
|
53
|
+
try {
|
|
54
|
+
const vol = req.query.vol ? parseInt(req.query.vol, 10) : undefined;
|
|
55
|
+
const chapters = await ds.getChapters(req.params.story, vol);
|
|
56
|
+
res.json(chapters);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
res.status(500).json({ error: err.message });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// GET /api/stories/:story/chapters/:ch
|
|
63
|
+
router.get('/:story/chapters/:ch', async (req, res) => {
|
|
64
|
+
try {
|
|
65
|
+
const chNum = parseInt(req.params.ch, 10);
|
|
66
|
+
const chapters = await ds.getChapters(req.params.story);
|
|
67
|
+
const chapter = chapters.find(c => c.globalNumber === chNum);
|
|
68
|
+
if (!chapter) {
|
|
69
|
+
res.status(404).json({ error: '章节不存在' });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
res.json(chapter);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
res.status(500).json({ error: err.message });
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return router;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stories.js","sourceRoot":"","sources":["../../../src/server/routes/stories.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../../src/server/routes/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAe3D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
export function createTimelineRouter(ds) {
|
|
3
|
+
const router = Router({ mergeParams: true });
|
|
4
|
+
// GET /api/stories/:story/timeline?vol=X
|
|
5
|
+
router.get('/', async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const vol = req.query.vol ? parseInt(req.query.vol, 10) : undefined;
|
|
8
|
+
const events = await ds.getTimeline(req.params.story, vol);
|
|
9
|
+
res.json(events);
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
res.status(500).json({ error: err.message });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return router;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../../src/server/routes/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAGpD,MAAM,UAAU,oBAAoB,CAAC,EAAc;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,yCAAyC;IACzC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAA+B,EAAE,GAAa,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC9E,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC3D,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/** 故事基础信息 */
|
|
2
|
+
export interface Story {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
}
|
|
6
|
+
/** 故事总览 */
|
|
7
|
+
export interface StoryOverview {
|
|
8
|
+
name: string;
|
|
9
|
+
totalVolumes: number;
|
|
10
|
+
totalChapters: number;
|
|
11
|
+
totalWords: number;
|
|
12
|
+
currentVolume: number;
|
|
13
|
+
}
|
|
14
|
+
/** 卷信息 */
|
|
15
|
+
export interface Volume {
|
|
16
|
+
number: number;
|
|
17
|
+
title: string;
|
|
18
|
+
chapters: number;
|
|
19
|
+
words: number;
|
|
20
|
+
progress: number;
|
|
21
|
+
}
|
|
22
|
+
/** 章节信息 */
|
|
23
|
+
export interface Chapter {
|
|
24
|
+
globalNumber: number;
|
|
25
|
+
volumeNumber: number;
|
|
26
|
+
chapterInVolume: number;
|
|
27
|
+
title: string;
|
|
28
|
+
words: number;
|
|
29
|
+
pov: string;
|
|
30
|
+
participants: string[];
|
|
31
|
+
hasSynopsis: boolean;
|
|
32
|
+
hasContent: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** 角色信息 */
|
|
35
|
+
export interface Character {
|
|
36
|
+
name: string;
|
|
37
|
+
aliases: string[];
|
|
38
|
+
role: string;
|
|
39
|
+
firstVolume: number;
|
|
40
|
+
firstChapter: number;
|
|
41
|
+
cultivation: string;
|
|
42
|
+
faction: string;
|
|
43
|
+
status: string;
|
|
44
|
+
}
|
|
45
|
+
/** 角色状态快照(按卷) */
|
|
46
|
+
export interface CharacterState {
|
|
47
|
+
volume: number;
|
|
48
|
+
cultivation: string;
|
|
49
|
+
location: string;
|
|
50
|
+
summary: string;
|
|
51
|
+
lastChapter: number;
|
|
52
|
+
}
|
|
53
|
+
/** 关系图节点 */
|
|
54
|
+
export interface RelationshipNode {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
faction: string;
|
|
58
|
+
role: string;
|
|
59
|
+
appearances: number;
|
|
60
|
+
}
|
|
61
|
+
/** 关系图边 */
|
|
62
|
+
export interface RelationshipEdge {
|
|
63
|
+
source: string;
|
|
64
|
+
target: string;
|
|
65
|
+
type: string;
|
|
66
|
+
status: string;
|
|
67
|
+
lastChapter: number;
|
|
68
|
+
}
|
|
69
|
+
/** 关系网络图 */
|
|
70
|
+
export interface RelationshipGraph {
|
|
71
|
+
nodes: RelationshipNode[];
|
|
72
|
+
edges: RelationshipEdge[];
|
|
73
|
+
}
|
|
74
|
+
/** 关系变迁事件 */
|
|
75
|
+
export interface RelationshipEvent {
|
|
76
|
+
chapter: number;
|
|
77
|
+
source: string;
|
|
78
|
+
target: string;
|
|
79
|
+
type: string;
|
|
80
|
+
oldStatus: string;
|
|
81
|
+
newStatus: string;
|
|
82
|
+
}
|
|
83
|
+
/** 时间线事件 */
|
|
84
|
+
export interface TimelineEvent {
|
|
85
|
+
id: number;
|
|
86
|
+
chapter: number;
|
|
87
|
+
storyTime: string;
|
|
88
|
+
location: string;
|
|
89
|
+
description: string;
|
|
90
|
+
tags: string[];
|
|
91
|
+
}
|
|
92
|
+
/** 情节线 */
|
|
93
|
+
export interface PlotThread {
|
|
94
|
+
name: string;
|
|
95
|
+
type: string;
|
|
96
|
+
status: string;
|
|
97
|
+
description: string;
|
|
98
|
+
keyEvents: string[];
|
|
99
|
+
}
|
|
100
|
+
/** 伏笔 */
|
|
101
|
+
export interface Foreshadow {
|
|
102
|
+
code: string;
|
|
103
|
+
description: string;
|
|
104
|
+
plantedChapter: number;
|
|
105
|
+
hintedChapters: number[];
|
|
106
|
+
resolvedChapter: number | null;
|
|
107
|
+
status: string;
|
|
108
|
+
importance: string;
|
|
109
|
+
}
|
|
110
|
+
/** 伏笔矩阵单元格 */
|
|
111
|
+
export interface ForeshadowCell {
|
|
112
|
+
chapter: number;
|
|
113
|
+
action: 'plant' | 'hint' | 'resolve' | null;
|
|
114
|
+
}
|
|
115
|
+
/** 伏笔矩阵 */
|
|
116
|
+
export interface ForeshadowMatrix {
|
|
117
|
+
chapters: number[];
|
|
118
|
+
rows: Array<{
|
|
119
|
+
code: string;
|
|
120
|
+
description: string;
|
|
121
|
+
cells: ForeshadowCell[];
|
|
122
|
+
}>;
|
|
123
|
+
}
|
|
124
|
+
/** 卷级统计 */
|
|
125
|
+
export interface VolumeStat {
|
|
126
|
+
volume: number;
|
|
127
|
+
title: string;
|
|
128
|
+
words: number;
|
|
129
|
+
chapters: number;
|
|
130
|
+
progress: number;
|
|
131
|
+
}
|
|
132
|
+
/** 仪表盘聚合统计 */
|
|
133
|
+
export interface DashboardStats {
|
|
134
|
+
totalWords: number;
|
|
135
|
+
totalChapters: number;
|
|
136
|
+
totalVolumes: number;
|
|
137
|
+
totalCharacters: number;
|
|
138
|
+
activePlotThreads: number;
|
|
139
|
+
unresolvedForeshadowing: number;
|
|
140
|
+
volumeStats: VolumeStat[];
|
|
141
|
+
}
|
|
142
|
+
/** 主角技能 */
|
|
143
|
+
export interface ProtagonistSkill {
|
|
144
|
+
name: string;
|
|
145
|
+
category: string;
|
|
146
|
+
level: string;
|
|
147
|
+
description: string;
|
|
148
|
+
acquiredChapter: number;
|
|
149
|
+
useCount: number;
|
|
150
|
+
status: string;
|
|
151
|
+
}
|
|
152
|
+
/** 主角道具 */
|
|
153
|
+
export interface ProtagonistItem {
|
|
154
|
+
name: string;
|
|
155
|
+
type: string;
|
|
156
|
+
quantity: number;
|
|
157
|
+
quality: string;
|
|
158
|
+
description: string;
|
|
159
|
+
acquiredChapter: number;
|
|
160
|
+
status: string;
|
|
161
|
+
}
|
|
162
|
+
/** 修炼进度节点 */
|
|
163
|
+
export interface CultivationNode {
|
|
164
|
+
chapter: number;
|
|
165
|
+
level: string;
|
|
166
|
+
progressPct: number;
|
|
167
|
+
breakthroughType: string | null;
|
|
168
|
+
detail: string;
|
|
169
|
+
}
|
|
170
|
+
/** 主角总览 */
|
|
171
|
+
export interface ProtagonistOverview {
|
|
172
|
+
currentLevel: string;
|
|
173
|
+
currentProgress: number;
|
|
174
|
+
totalSkills: number;
|
|
175
|
+
activeSkills: number;
|
|
176
|
+
totalItems: number;
|
|
177
|
+
heldItems: number;
|
|
178
|
+
}
|
|
179
|
+
/** 数据源抽象接口 */
|
|
180
|
+
export interface DataSource {
|
|
181
|
+
getStories(): Promise<Story[]>;
|
|
182
|
+
getOverview(story: string): Promise<StoryOverview>;
|
|
183
|
+
getVolumes(story: string): Promise<Volume[]>;
|
|
184
|
+
getChapters(story: string, vol?: number): Promise<Chapter[]>;
|
|
185
|
+
getCharacters(story: string, vol?: number): Promise<Character[]>;
|
|
186
|
+
getCharacterArc(story: string, name: string): Promise<CharacterState[]>;
|
|
187
|
+
getRelationships(story: string, vol?: number): Promise<RelationshipGraph>;
|
|
188
|
+
getRelationshipHistory(story: string): Promise<RelationshipEvent[]>;
|
|
189
|
+
getTimeline(story: string, vol?: number): Promise<TimelineEvent[]>;
|
|
190
|
+
getPlotThreads(story: string): Promise<PlotThread[]>;
|
|
191
|
+
getForeshadowing(story: string): Promise<Foreshadow[]>;
|
|
192
|
+
getForeshadowingMatrix(story: string): Promise<ForeshadowMatrix>;
|
|
193
|
+
getDashboardStats(story: string): Promise<DashboardStats>;
|
|
194
|
+
getProtagonistOverview(story: string): Promise<ProtagonistOverview>;
|
|
195
|
+
getProtagonistSkills(story: string): Promise<ProtagonistSkill[]>;
|
|
196
|
+
getProtagonistInventory(story: string): Promise<ProtagonistItem[]>;
|
|
197
|
+
getCultivationCurve(story: string): Promise<CultivationNode[]>;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":""}
|
|
@@ -34,11 +34,11 @@ export declare class ProjectDiagnostics {
|
|
|
34
34
|
*/
|
|
35
35
|
checkProjectStructure(projectRoot: string): Promise<CheckResult>;
|
|
36
36
|
/**
|
|
37
|
-
* 检查 2: tracking
|
|
37
|
+
* 检查 2: tracking 文件是否存在(卷级分片架构下按需创建)
|
|
38
38
|
*/
|
|
39
39
|
checkTrackingFiles(projectRoot: string): Promise<CheckResult>;
|
|
40
40
|
/**
|
|
41
|
-
* 检查 3: JSON
|
|
41
|
+
* 检查 3: JSON 文件完整性(已合并到检查 2 的卷级扫描中)
|
|
42
42
|
*/
|
|
43
43
|
checkFileIntegrity(projectRoot: string): Promise<CheckResult>;
|
|
44
44
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/utils/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,aAAa;AACb,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,WAAW;AACX,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,YAAY;AACZ,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAAa,kBAAkB;IAC7B;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmBrF;;OAEG;IACG,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA2BtE;;OAEG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsCnE;;OAEG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/utils/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,aAAa;AACb,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,WAAW;AACX,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,YAAY;AACZ,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAAa,kBAAkB;IAC7B;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmBrF;;OAEG;IACG,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA2BtE;;OAEG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsCnE;;OAEG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBnE;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;IAuB9C,OAAO,CAAC,eAAe;CAWxB"}
|
|
@@ -54,76 +54,63 @@ export class ProjectDiagnostics {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
-
* 检查 2: tracking
|
|
57
|
+
* 检查 2: tracking 文件是否存在(卷级分片架构下按需创建)
|
|
58
58
|
*/
|
|
59
59
|
async checkTrackingFiles(projectRoot) {
|
|
60
|
-
const
|
|
61
|
-
if (!await fs.pathExists(
|
|
62
|
-
return {
|
|
63
|
-
name: 'Tracking 文件',
|
|
64
|
-
passed: false,
|
|
65
|
-
message: 'tracking 目录不存在',
|
|
66
|
-
fix: 'novelws init',
|
|
67
|
-
};
|
|
60
|
+
const storiesDir = path.join(projectRoot, 'stories');
|
|
61
|
+
if (!await fs.pathExists(storiesDir)) {
|
|
62
|
+
return { name: 'Tracking 文件', passed: true, message: 'tracking 文件在 /write 首次执行时按需创建' };
|
|
68
63
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
// 扫描 stories/*/volumes/*/tracking/ 是否有损坏的 JSON
|
|
65
|
+
const stories = await fs.readdir(storiesDir).catch(() => []);
|
|
66
|
+
for (const story of stories) {
|
|
67
|
+
const volumesDir = path.join(storiesDir, story, 'volumes');
|
|
68
|
+
if (!await fs.pathExists(volumesDir))
|
|
69
|
+
continue;
|
|
70
|
+
const volumes = await fs.readdir(volumesDir).catch(() => []);
|
|
71
|
+
for (const vol of volumes) {
|
|
72
|
+
const trackingDir = path.join(volumesDir, vol, 'tracking');
|
|
73
|
+
if (!await fs.pathExists(trackingDir))
|
|
74
|
+
continue;
|
|
75
|
+
const jsonFiles = await fs.readdir(trackingDir).catch(() => []);
|
|
76
|
+
for (const file of jsonFiles.filter(f => f.endsWith('.json'))) {
|
|
77
|
+
try {
|
|
78
|
+
const content = await fs.readFile(path.join(trackingDir, file), 'utf-8');
|
|
79
|
+
JSON.parse(content);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return {
|
|
83
|
+
name: 'Tracking 文件',
|
|
84
|
+
passed: false,
|
|
85
|
+
message: `JSON 格式损坏: ${story}/volumes/${vol}/tracking/${file}`,
|
|
86
|
+
fix: '手动修复损坏的 JSON 文件',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
79
90
|
}
|
|
80
91
|
}
|
|
81
|
-
|
|
82
|
-
return { name: 'Tracking 文件', passed: true, message: 'tracking 文件存在' };
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
name: 'Tracking 文件',
|
|
86
|
-
passed: false,
|
|
87
|
-
message: `缺少 tracking 文件: ${missing.join(', ')}`,
|
|
88
|
-
fix: 'novelws init',
|
|
89
|
-
};
|
|
92
|
+
return { name: 'Tracking 文件', passed: true, message: 'tracking 文件正常' };
|
|
90
93
|
}
|
|
91
94
|
/**
|
|
92
|
-
* 检查 3: JSON
|
|
95
|
+
* 检查 3: JSON 文件完整性(已合并到检查 2 的卷级扫描中)
|
|
93
96
|
*/
|
|
94
97
|
async checkFileIntegrity(projectRoot) {
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (await fs.pathExists(filePath)) {
|
|
109
|
-
try {
|
|
110
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
111
|
-
JSON.parse(content);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
corrupted.push(file);
|
|
115
|
-
}
|
|
98
|
+
const configPath = path.join(projectRoot, 'resources', 'config.json');
|
|
99
|
+
if (await fs.pathExists(configPath)) {
|
|
100
|
+
try {
|
|
101
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
102
|
+
JSON.parse(content);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return {
|
|
106
|
+
name: '文件完整性',
|
|
107
|
+
passed: false,
|
|
108
|
+
message: 'config.json 格式损坏',
|
|
109
|
+
fix: '手动修复 resources/config.json',
|
|
110
|
+
};
|
|
116
111
|
}
|
|
117
112
|
}
|
|
118
|
-
|
|
119
|
-
return { name: '文件完整性', passed: true, message: 'JSON 文件格式正确' };
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
name: '文件完整性',
|
|
123
|
-
passed: false,
|
|
124
|
-
message: `JSON 格式损坏: ${corrupted.join(', ')}`,
|
|
125
|
-
fix: '手动修复损坏的 JSON 文件',
|
|
126
|
-
};
|
|
113
|
+
return { name: '文件完整性', passed: true, message: '配置文件格式正确' };
|
|
127
114
|
}
|
|
128
115
|
/**
|
|
129
116
|
* 格式化诊断报告为用户友好的字符串
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/utils/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAyBpD,MAAM,OAAO,kBAAkB;IAC7B;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,KAAY,EAAE,OAAuB;QACvD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC/B,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,WAAW,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC;YAC5C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC;SAC7C,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,MAAM;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;aAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC;QAEpB,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,MAAM;YACN,KAAK;YACL,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;SACtC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,WAAmB;QAC7C,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG;YACnB,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE;YAC7C,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;YACxC,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,kBAAkB,EAAE;SACpD,CAAC;QAEF,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC3D,CAAC;QAED,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,SAAS,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtC,GAAG,EAAE,cAAc;SACpB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB,CAAC,WAAmB;QAC1C,MAAM,
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/utils/diagnostics.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "novelws",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Claude Code 专用的 AI 小说创作工具 - 深度集成 Slash Commands 和 Agent Skills",
|
|
6
6
|
"keywords": [
|
|
@@ -33,22 +33,29 @@
|
|
|
33
33
|
"test:watch": "jest --config jest.config.cjs --watch",
|
|
34
34
|
"test:coverage": "jest --config jest.config.cjs --coverage",
|
|
35
35
|
"test:unit": "jest --config jest.config.cjs tests/unit",
|
|
36
|
-
"test:integration": "jest --config jest.config.cjs tests/integration"
|
|
36
|
+
"test:integration": "jest --config jest.config.cjs tests/integration",
|
|
37
|
+
"build:dashboard": "cd dashboard && npm run build",
|
|
38
|
+
"dashboard": "node dist/cli.js dashboard"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
41
|
"@commander-js/extra-typings": "^12.0.0",
|
|
40
42
|
"chalk": "^5.3.0",
|
|
43
|
+
"express": "^5.2.1",
|
|
41
44
|
"fs-extra": "^11.2.0",
|
|
42
45
|
"inquirer": "^9.2.12",
|
|
43
46
|
"js-yaml": "^4.1.0",
|
|
44
|
-
"
|
|
47
|
+
"open": "^11.0.0",
|
|
48
|
+
"ora": "^8.0.1",
|
|
49
|
+
"pg": "^8.18.0"
|
|
45
50
|
},
|
|
46
51
|
"devDependencies": {
|
|
52
|
+
"@types/express": "^5.0.6",
|
|
47
53
|
"@types/fs-extra": "^11.0.4",
|
|
48
54
|
"@types/inquirer": "^9.0.9",
|
|
49
55
|
"@types/jest": "^30.0.0",
|
|
50
56
|
"@types/js-yaml": "^4.0.9",
|
|
51
57
|
"@types/node": "^20.10.0",
|
|
58
|
+
"@types/pg": "^8.16.0",
|
|
52
59
|
"jest": "^30.2.0",
|
|
53
60
|
"ts-jest": "^29.4.6",
|
|
54
61
|
"tsx": "^4.7.0",
|
|
@@ -71,5 +78,8 @@
|
|
|
71
78
|
"homepage": "https://github.com/binlee1990/novel-writer-skills#readme",
|
|
72
79
|
"bugs": {
|
|
73
80
|
"url": "https://github.com/binlee1990/novel-writer-skills/issues"
|
|
81
|
+
},
|
|
82
|
+
"overrides": {
|
|
83
|
+
"yoctocolors-cjs": "2.1.2"
|
|
74
84
|
}
|
|
75
85
|
}
|