novelforge-agent 0.2.0 → 0.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/README.md +16 -12
- package/dist/src/cli/index.js +10 -2
- package/dist/src/core/contextBuilder.js +32 -0
- package/dist/src/core/projectDiscovery.js +1 -0
- package/dist/src/core/projectOps.js +7 -1
- package/dist/src/core/projectStore.js +4 -1
- package/dist/src/core/prompts/en-US.js +130 -3
- package/dist/src/core/prompts/zh-CN.js +130 -3
- package/dist/src/core/schemas.js +23 -0
- package/dist/src/core/steps/architectureExtension.js +72 -0
- package/dist/src/core/steps/chapterReview.js +2 -1
- package/dist/src/core/steps/index.js +4 -0
- package/dist/src/core/steps/memoryCard.js +22 -1
- package/dist/src/core/steps/storyBible.js +1 -1
- package/dist/src/core/steps/styleGuide.js +12 -0
- package/dist/src/core/workflow.js +2 -0
- package/dist/src/mcp/tools.js +36 -8
- package/package.json +1 -1
- package/src/cli/index.ts +11 -3
- package/src/core/contextBuilder.ts +30 -0
- package/src/core/projectDiscovery.ts +2 -0
- package/src/core/projectOps.ts +9 -1
- package/src/core/projectStore.ts +8 -1
- package/src/core/prompts/en-US.ts +132 -3
- package/src/core/prompts/types.ts +2 -0
- package/src/core/prompts/zh-CN.ts +132 -3
- package/src/core/schemas.ts +25 -0
- package/src/core/steps/architectureExtension.ts +88 -0
- package/src/core/steps/chapterReview.ts +2 -1
- package/src/core/steps/index.ts +4 -0
- package/src/core/steps/memoryCard.ts +23 -1
- package/src/core/steps/storyBible.ts +1 -1
- package/src/core/steps/styleGuide.ts +13 -0
- package/src/core/types.ts +32 -0
- package/src/core/workflow.ts +2 -0
- package/src/mcp/tools.ts +35 -8
package/src/core/types.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export type WorkflowStep =
|
|
2
2
|
| 'novel_metadata'
|
|
3
3
|
| 'story_bible'
|
|
4
|
+
| 'style_guide'
|
|
4
5
|
| 'architecture'
|
|
6
|
+
| 'architecture_extension'
|
|
5
7
|
| 'chapter'
|
|
6
8
|
| 'memory_card'
|
|
7
9
|
| 'continuity_review'
|
|
@@ -44,6 +46,7 @@ export interface ChapterAcceptanceGate {
|
|
|
44
46
|
characterProgress: ChapterAcceptanceCheck;
|
|
45
47
|
foreshadowProgress: ChapterAcceptanceCheck;
|
|
46
48
|
storyBibleConsistency: ChapterAcceptanceCheck;
|
|
49
|
+
proseRhythm: ChapterAcceptanceCheck;
|
|
47
50
|
endingHook: ChapterAcceptanceCheck;
|
|
48
51
|
repetition: ChapterAcceptanceCheck;
|
|
49
52
|
}
|
|
@@ -82,6 +85,23 @@ export interface NovelMetadata {
|
|
|
82
85
|
coreCast: CoreCastMember[];
|
|
83
86
|
}
|
|
84
87
|
|
|
88
|
+
export interface StyleGuide {
|
|
89
|
+
narrativeVoice: string;
|
|
90
|
+
pacing: string;
|
|
91
|
+
diction: string;
|
|
92
|
+
dialogueRules: string[];
|
|
93
|
+
prohibitedPatterns: string[];
|
|
94
|
+
proseRhythm: {
|
|
95
|
+
sentenceRhythm: string;
|
|
96
|
+
paragraphing: string;
|
|
97
|
+
interiorityMode: string;
|
|
98
|
+
emphasisBudget: string;
|
|
99
|
+
antiPatterns: string[];
|
|
100
|
+
};
|
|
101
|
+
sampleParagraph: string;
|
|
102
|
+
consistencyChecks: string[];
|
|
103
|
+
}
|
|
104
|
+
|
|
85
105
|
export interface VolumeArchitecture {
|
|
86
106
|
id: string;
|
|
87
107
|
title: string;
|
|
@@ -121,6 +141,13 @@ export interface ArchitecturePayload {
|
|
|
121
141
|
chapters: ChapterArchitecture[];
|
|
122
142
|
}
|
|
123
143
|
|
|
144
|
+
export interface ArchitectureExtensionPayload {
|
|
145
|
+
fullUpdate?: string;
|
|
146
|
+
volumes?: VolumeArchitecture[];
|
|
147
|
+
volumePacing?: VolumePacingBoard[];
|
|
148
|
+
chapters: ChapterArchitecture[];
|
|
149
|
+
}
|
|
150
|
+
|
|
124
151
|
export type ThreadStatus = 'planted' | 'building' | 'paid' | 'dropped';
|
|
125
152
|
|
|
126
153
|
export type ThreadActionKind = 'plant' | 'build' | 'pay' | 'drop';
|
|
@@ -196,7 +223,12 @@ export interface AgentState {
|
|
|
196
223
|
projectPath: string;
|
|
197
224
|
initialPrompt: string;
|
|
198
225
|
language: 'zh-CN' | 'en-US';
|
|
226
|
+
/**
|
|
227
|
+
* Number of chapters to plan in each architecture batch.
|
|
228
|
+
* The whole-book target lives in plannedTotalChapters.
|
|
229
|
+
*/
|
|
199
230
|
targetChapters: number;
|
|
231
|
+
plannedTotalChapters: number;
|
|
200
232
|
currentStep: WorkflowStep;
|
|
201
233
|
currentChapter: number;
|
|
202
234
|
completedSteps: WorkflowStep[];
|
package/src/core/workflow.ts
CHANGED
|
@@ -37,6 +37,8 @@ export interface RequestSideTrackInput {
|
|
|
37
37
|
type ContextRecipe = (state: AgentState) => Omit<BuildContextInput, 'projectPath'>;
|
|
38
38
|
|
|
39
39
|
const CONTEXT_RECIPES: Partial<Record<WorkflowStep, ContextRecipe>> = {
|
|
40
|
+
style_guide: () => ({ purpose: 'style_guide' }),
|
|
41
|
+
architecture_extension: (s) => ({ purpose: 'architecture_extension', chapterNumber: s.currentChapter }),
|
|
40
42
|
chapter: (s) => ({ purpose: 'chapter_generation', chapterNumber: s.currentChapter }),
|
|
41
43
|
memory_card: (s) => ({ purpose: 'memory_extraction', chapterNumber: s.currentChapter }),
|
|
42
44
|
continuity_review: () => ({ purpose: 'continuity_review' }),
|
package/src/mcp/tools.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import {
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import {
|
|
5
7
|
amendStoryBible,
|
|
6
8
|
assertProjectPath,
|
|
@@ -21,7 +23,24 @@ import {
|
|
|
21
23
|
updateThread,
|
|
22
24
|
} from '../core/index.js';
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
function packageVersion(): string {
|
|
27
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
while (true) {
|
|
29
|
+
try {
|
|
30
|
+
const raw = readFileSync(join(dir, 'package.json'), 'utf8');
|
|
31
|
+
const parsed = JSON.parse(raw) as { version?: unknown };
|
|
32
|
+
if (typeof parsed.version === 'string' && parsed.version) return parsed.version;
|
|
33
|
+
} catch {
|
|
34
|
+
// keep walking upward until the package root is found
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const parent = dirname(dir);
|
|
38
|
+
if (parent === dir) return '0.0.0';
|
|
39
|
+
dir = parent;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const MCP_SERVER_VERSION = packageVersion();
|
|
25
44
|
|
|
26
45
|
export interface CreateNovelAgentServerOptions {
|
|
27
46
|
workspaceRoot: string;
|
|
@@ -59,15 +78,17 @@ export function createNovelAgentServer(options: CreateNovelAgentServerOptions):
|
|
|
59
78
|
prompt: z.string().min(1),
|
|
60
79
|
language: z.enum(['zh-CN', 'en-US']).default('zh-CN'),
|
|
61
80
|
outputDir: z.string().default('novels'),
|
|
62
|
-
targetChapters: z.number().int().positive().default(
|
|
81
|
+
targetChapters: z.number().int().positive().default(5),
|
|
82
|
+
plannedTotalChapters: z.number().int().positive().default(12),
|
|
63
83
|
},
|
|
64
|
-
async ({ prompt, language, outputDir, targetChapters }) => {
|
|
84
|
+
async ({ prompt, language, outputDir, targetChapters, plannedTotalChapters }) => {
|
|
65
85
|
const result = await createProject({
|
|
66
86
|
workspaceRoot: options.workspaceRoot,
|
|
67
87
|
prompt,
|
|
68
88
|
language,
|
|
69
89
|
outputDir,
|
|
70
90
|
targetChapters,
|
|
91
|
+
plannedTotalChapters,
|
|
71
92
|
});
|
|
72
93
|
return textResult({ state: result.state, next: await getNextStep(result.state.projectPath) });
|
|
73
94
|
}
|
|
@@ -105,7 +126,9 @@ export function createNovelAgentServer(options: CreateNovelAgentServerOptions):
|
|
|
105
126
|
step: z.enum([
|
|
106
127
|
'novel_metadata',
|
|
107
128
|
'story_bible',
|
|
129
|
+
'style_guide',
|
|
108
130
|
'architecture',
|
|
131
|
+
'architecture_extension',
|
|
109
132
|
'chapter',
|
|
110
133
|
'memory_card',
|
|
111
134
|
'continuity_review',
|
|
@@ -127,6 +150,8 @@ export function createNovelAgentServer(options: CreateNovelAgentServerOptions):
|
|
|
127
150
|
projectPath: z.string().min(1),
|
|
128
151
|
purpose: z.enum([
|
|
129
152
|
'chapter_generation',
|
|
153
|
+
'style_guide',
|
|
154
|
+
'architecture_extension',
|
|
130
155
|
'memory_extraction',
|
|
131
156
|
'continuity_review',
|
|
132
157
|
'revision',
|
|
@@ -336,6 +361,7 @@ export function createNovelAgentServer(options: CreateNovelAgentServerOptions):
|
|
|
336
361
|
step: z.enum([
|
|
337
362
|
'novel_metadata',
|
|
338
363
|
'story_bible',
|
|
364
|
+
'style_guide',
|
|
339
365
|
'architecture',
|
|
340
366
|
'chapter',
|
|
341
367
|
'memory_card',
|
|
@@ -354,14 +380,15 @@ export function createNovelAgentServer(options: CreateNovelAgentServerOptions):
|
|
|
354
380
|
'Start a brand new novel project under the configured workspace.',
|
|
355
381
|
{
|
|
356
382
|
prompt: z.string().describe('User idea / premise / genre, in any language.'),
|
|
357
|
-
chapters: z.string().optional().describe('
|
|
383
|
+
chapters: z.string().optional().describe('Planning batch size as a string. Defaults to 5.'),
|
|
384
|
+
totalChapters: z.string().optional().describe('Whole-book target chapter count as a string. Defaults to 12.'),
|
|
358
385
|
},
|
|
359
|
-
({ prompt, chapters }) => ({
|
|
386
|
+
({ prompt, chapters, totalChapters }) => ({
|
|
360
387
|
messages: [{
|
|
361
388
|
role: 'user' as const,
|
|
362
389
|
content: {
|
|
363
390
|
type: 'text' as const,
|
|
364
|
-
text: `Use the novelforge MCP server. Call start_novel_project with prompt="${prompt}", targetChapters=${chapters ?? '5'}, then enter the autonomous loop: read next.instruction, generate the requested content, call submit_step_result, repeat until currentStep is "complete". Show me the projectPath after start_novel_project returns.`,
|
|
391
|
+
text: `Use the novelforge MCP server. Call start_novel_project with prompt="${prompt}", targetChapters=${chapters ?? '5'}, plannedTotalChapters=${totalChapters ?? '12'}, then enter the autonomous loop: read next.instruction, generate the requested content, call submit_step_result, repeat until currentStep is "complete". Show me the projectPath after start_novel_project returns.`,
|
|
365
392
|
},
|
|
366
393
|
}],
|
|
367
394
|
})
|
|
@@ -393,7 +420,7 @@ export function createNovelAgentServer(options: CreateNovelAgentServerOptions):
|
|
|
393
420
|
role: 'user' as const,
|
|
394
421
|
content: {
|
|
395
422
|
type: 'text' as const,
|
|
396
|
-
text: 'Use the novelforge MCP server: call list_projects with no arguments. Show me the result in a compact table (title, currentStep, chaptersWritten/
|
|
423
|
+
text: 'Use the novelforge MCP server: call list_projects with no arguments. Show me the result in a compact table (title, currentStep, chaptersWritten/plannedTotalChapters, updatedAt, projectPath).',
|
|
397
424
|
},
|
|
398
425
|
}],
|
|
399
426
|
})
|