dsh-novel-write-engine 0.2.4 → 0.2.6
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 +51 -0
- package/README.md +25 -18
- package/briefs/P3.md +2 -0
- package/briefs/P5.md +2 -0
- package/briefs/P6.md +3 -2
- package/briefs/P8.md +5 -4
- package/lib/client.js +148 -16
- package/lib/index.d.ts +244 -4
- package/lib/index.js +1608 -311
- package/lib/types/client/dto.d.ts +19 -0
- package/lib/types/client/viewmodel.d.ts +30 -1
- package/lib/types/constants.d.ts +1 -1
- package/lib/types/panel-contract.d.ts +125 -0
- package/lib/types/types.d.ts +29 -1
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PanelBookData } from '../panel-contract.js';
|
|
1
2
|
/** Wire DTOs of the panel route. Versioned so a stale tab can say "refresh". */
|
|
2
3
|
export interface PhaseDto {
|
|
3
4
|
id: string;
|
|
@@ -84,6 +85,7 @@ export interface SummaryDto {
|
|
|
84
85
|
ok: boolean;
|
|
85
86
|
blocking: number;
|
|
86
87
|
stateErrors: number;
|
|
88
|
+
pending?: boolean;
|
|
87
89
|
};
|
|
88
90
|
activity?: Array<{
|
|
89
91
|
at: string;
|
|
@@ -102,6 +104,14 @@ export interface SummaryDto {
|
|
|
102
104
|
code: string;
|
|
103
105
|
detail: string;
|
|
104
106
|
}>;
|
|
107
|
+
/** Crash-left pending transaction; read-only diagnostics. */
|
|
108
|
+
pending?: {
|
|
109
|
+
state: string;
|
|
110
|
+
txid: string;
|
|
111
|
+
detail: string;
|
|
112
|
+
};
|
|
113
|
+
/** v6 read-only book data; v5 payloads omit it and are rejected by the client. */
|
|
114
|
+
bookData?: PanelBookData;
|
|
105
115
|
}
|
|
106
116
|
export interface ChapterRowDto {
|
|
107
117
|
num: number;
|
|
@@ -111,6 +121,15 @@ export interface ChapterRowDto {
|
|
|
111
121
|
stage: string;
|
|
112
122
|
status: 'passed' | 'blocked' | 'draft';
|
|
113
123
|
details?: string;
|
|
124
|
+
sceneType?: string;
|
|
125
|
+
dialogueRatio?: number;
|
|
126
|
+
hookStrength?: number;
|
|
127
|
+
finalCheck?: 'pass' | 'fail' | null;
|
|
128
|
+
reviews?: number;
|
|
129
|
+
revisions?: number;
|
|
130
|
+
checks?: number;
|
|
131
|
+
rollbacks?: number;
|
|
132
|
+
archivedAt?: string | null;
|
|
114
133
|
}
|
|
115
134
|
export interface ChaptersDto {
|
|
116
135
|
schemaVersion: number;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PanelPayloadDto } from './dto.js';
|
|
2
|
+
import type { PanelBookData } from '../panel-contract.js';
|
|
2
3
|
/** One human-facing progress step. */
|
|
3
4
|
export interface PanelPhase {
|
|
4
5
|
id: string;
|
|
@@ -19,6 +20,15 @@ export interface PanelChapter {
|
|
|
19
20
|
tone: 'ok' | 'bad' | 'muted';
|
|
20
21
|
details: string;
|
|
21
22
|
stageLabel: string;
|
|
23
|
+
sceneType: string;
|
|
24
|
+
dialogueRatio: number | null;
|
|
25
|
+
hookStrength: number | null;
|
|
26
|
+
finalCheck: 'pass' | 'fail' | null;
|
|
27
|
+
reviews: number;
|
|
28
|
+
revisions: number;
|
|
29
|
+
checks: number;
|
|
30
|
+
rollbacks: number;
|
|
31
|
+
archivedAt: string | null;
|
|
22
32
|
}
|
|
23
33
|
export interface PanelProject {
|
|
24
34
|
root: string;
|
|
@@ -79,6 +89,7 @@ export interface PanelView {
|
|
|
79
89
|
present: boolean;
|
|
80
90
|
strict: boolean;
|
|
81
91
|
premise: string;
|
|
92
|
+
logline: string;
|
|
82
93
|
target: number | null;
|
|
83
94
|
planned: number;
|
|
84
95
|
outlineTotal: number;
|
|
@@ -106,6 +117,15 @@ export interface PanelView {
|
|
|
106
117
|
};
|
|
107
118
|
quality: {
|
|
108
119
|
averageScore: number;
|
|
120
|
+
lastTenAverage: number;
|
|
121
|
+
bookMedian: number;
|
|
122
|
+
bookMin: number;
|
|
123
|
+
bookMax: number;
|
|
124
|
+
dimensions: Array<{
|
|
125
|
+
id: string;
|
|
126
|
+
average: number;
|
|
127
|
+
samples: number;
|
|
128
|
+
}>;
|
|
109
129
|
scores: number[];
|
|
110
130
|
trend: number | null;
|
|
111
131
|
trendText: string;
|
|
@@ -116,6 +136,7 @@ export interface PanelView {
|
|
|
116
136
|
ok: boolean;
|
|
117
137
|
blocking: number;
|
|
118
138
|
stateErrors: number;
|
|
139
|
+
pending: boolean;
|
|
119
140
|
};
|
|
120
141
|
activity: Array<{
|
|
121
142
|
at: string;
|
|
@@ -136,6 +157,14 @@ export interface PanelView {
|
|
|
136
157
|
code: string;
|
|
137
158
|
detail: string;
|
|
138
159
|
}>;
|
|
160
|
+
/** Crash-left pending transaction, read-only. */
|
|
161
|
+
pending: {
|
|
162
|
+
state: string;
|
|
163
|
+
txid: string;
|
|
164
|
+
detail: string;
|
|
165
|
+
} | null;
|
|
166
|
+
/** v6 book data; null on a payload that predates it. */
|
|
167
|
+
bookData: PanelBookData | null;
|
|
139
168
|
nextTitle: string;
|
|
140
169
|
nextDetail: string;
|
|
141
170
|
nextTool: string;
|
|
@@ -144,7 +173,7 @@ export interface PanelView {
|
|
|
144
173
|
revision: string;
|
|
145
174
|
next: string;
|
|
146
175
|
}
|
|
147
|
-
export declare const PANEL_SCHEMA_VERSION =
|
|
176
|
+
export declare const PANEL_SCHEMA_VERSION = 6;
|
|
148
177
|
/**
|
|
149
178
|
* Project the wire payload into strings. Version mismatch wins over everything
|
|
150
179
|
* else: a stale panel must never render data from another schema as if it were
|
package/lib/types/constants.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const PLUGIN_NAME = "dsh-novel-write-engine";
|
|
|
4
4
|
export declare const PANEL_ID = "novel-workshop";
|
|
5
5
|
export declare const PANEL_ROUTE = "/api/novel-write-engine/panel";
|
|
6
6
|
export declare const SKILL_NAME = "novel-write-engine";
|
|
7
|
-
export declare const REMOTE_VERSION =
|
|
7
|
+
export declare const REMOTE_VERSION = 6;
|
|
8
8
|
/** The panel is a recent-history view; the wire payload and UI use one cap. */
|
|
9
9
|
export declare const PANEL_CHAPTER_LIMIT = 30;
|
|
10
10
|
/** Project-relative locations. Every write goes through these constants. */
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { BookReport, Stage, WordMetrics } from './types.js';
|
|
2
|
+
/** v6 read-only book data. All windows are explicit in the field names. */
|
|
3
|
+
export interface PanelCardData {
|
|
4
|
+
num: number;
|
|
5
|
+
title: string;
|
|
6
|
+
scene_type: string;
|
|
7
|
+
goal: string;
|
|
8
|
+
conflict: string;
|
|
9
|
+
hook: string;
|
|
10
|
+
cast: string[];
|
|
11
|
+
target_words: [number, number];
|
|
12
|
+
status: 'planned' | 'archived';
|
|
13
|
+
}
|
|
14
|
+
export interface PanelWorldEntry {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
anchors?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface PanelBookData {
|
|
20
|
+
identity: {
|
|
21
|
+
author: string;
|
|
22
|
+
description: string;
|
|
23
|
+
created_at: string;
|
|
24
|
+
targets: {
|
|
25
|
+
words_per_chapter: [number, number];
|
|
26
|
+
total_chapters: number | null;
|
|
27
|
+
dialogue_ratio: [number, number];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
blueprint: {
|
|
31
|
+
premise: string;
|
|
32
|
+
logline: string;
|
|
33
|
+
themes: string[];
|
|
34
|
+
tone: string;
|
|
35
|
+
pov: string;
|
|
36
|
+
audience: string;
|
|
37
|
+
selling_points: string[];
|
|
38
|
+
ending: string;
|
|
39
|
+
};
|
|
40
|
+
progress: {
|
|
41
|
+
archived: number;
|
|
42
|
+
target: number | null;
|
|
43
|
+
words_archived: number;
|
|
44
|
+
words_with_draft: number;
|
|
45
|
+
average_words: number;
|
|
46
|
+
remaining_words: number | null;
|
|
47
|
+
remaining_words_basis: 'actual_average' | 'minimum_target' | 'none';
|
|
48
|
+
percent: number;
|
|
49
|
+
};
|
|
50
|
+
current: {
|
|
51
|
+
card: PanelCardData | null;
|
|
52
|
+
chapter: number;
|
|
53
|
+
stage: Stage;
|
|
54
|
+
rounds: {
|
|
55
|
+
review: number;
|
|
56
|
+
revise: number;
|
|
57
|
+
check: number;
|
|
58
|
+
};
|
|
59
|
+
manuscript_hash: string | null;
|
|
60
|
+
metrics: WordMetrics | null;
|
|
61
|
+
};
|
|
62
|
+
worldbook: {
|
|
63
|
+
counts: Omit<BookReport['worldbook'], 'anchors'>;
|
|
64
|
+
locations: PanelWorldEntry[];
|
|
65
|
+
factions: PanelWorldEntry[];
|
|
66
|
+
rules: PanelWorldEntry[];
|
|
67
|
+
facts: Array<{
|
|
68
|
+
alias: string;
|
|
69
|
+
value: number;
|
|
70
|
+
unit: string;
|
|
71
|
+
}>;
|
|
72
|
+
};
|
|
73
|
+
cast: {
|
|
74
|
+
total: number;
|
|
75
|
+
top: Array<{
|
|
76
|
+
name: string;
|
|
77
|
+
role: string;
|
|
78
|
+
appearances: number;
|
|
79
|
+
last_seen: number;
|
|
80
|
+
}>;
|
|
81
|
+
};
|
|
82
|
+
relationships: {
|
|
83
|
+
total: number;
|
|
84
|
+
types: Record<string, number>;
|
|
85
|
+
};
|
|
86
|
+
foreshadows: BookReport['foreshadows'];
|
|
87
|
+
timeline: BookReport['timeline'];
|
|
88
|
+
outline: {
|
|
89
|
+
drift: BookReport['outline']['drift'];
|
|
90
|
+
};
|
|
91
|
+
quality: {
|
|
92
|
+
average: number;
|
|
93
|
+
median: number;
|
|
94
|
+
min: number;
|
|
95
|
+
max: number;
|
|
96
|
+
last_ten_average: number;
|
|
97
|
+
trend: number | null;
|
|
98
|
+
trend_basis: BookReport['quality']['trend_basis'];
|
|
99
|
+
samples: number;
|
|
100
|
+
attempts: number;
|
|
101
|
+
dimensions: BookReport['quality']['dimensions'];
|
|
102
|
+
};
|
|
103
|
+
pacing: BookReport['pacing'];
|
|
104
|
+
effort: BookReport['effort'];
|
|
105
|
+
health: {
|
|
106
|
+
state_errors: Array<{
|
|
107
|
+
path: string;
|
|
108
|
+
code: string;
|
|
109
|
+
message: string;
|
|
110
|
+
}>;
|
|
111
|
+
outline: {
|
|
112
|
+
present: boolean;
|
|
113
|
+
error: string | null;
|
|
114
|
+
};
|
|
115
|
+
worldbook: {
|
|
116
|
+
present: boolean;
|
|
117
|
+
error: string | null;
|
|
118
|
+
};
|
|
119
|
+
pending: {
|
|
120
|
+
state: string;
|
|
121
|
+
txid: string;
|
|
122
|
+
detail: string;
|
|
123
|
+
} | null;
|
|
124
|
+
};
|
|
125
|
+
}
|
package/lib/types/types.d.ts
CHANGED
|
@@ -66,6 +66,9 @@ export declare const ERROR_CODES: {
|
|
|
66
66
|
/** The exact same keyed submission already failed in the same context. */
|
|
67
67
|
readonly RETRY_UNCHANGED: "ENGINE_RETRY_UNCHANGED";
|
|
68
68
|
readonly GATE_BLOCKED: "ENGINE_GATE_BLOCKED";
|
|
69
|
+
readonly CHECK_SUBMISSION_INVALID: "ENGINE_CHECK_SUBMISSION_INVALID";
|
|
70
|
+
readonly PENDING_PARTIAL: "ENGINE_PENDING_PARTIAL";
|
|
71
|
+
readonly IO_PERMISSION: "ENGINE_IO_PERMISSION";
|
|
69
72
|
readonly READING_PROOF_INVALID: "ENGINE_READING_PROOF_INVALID";
|
|
70
73
|
readonly SCORE_MISMATCH: "ENGINE_SCORE_MISMATCH";
|
|
71
74
|
/** A revision tried to rewrite reviewer-owned issue fields. */
|
|
@@ -178,13 +181,18 @@ export interface CheckDocument {
|
|
|
178
181
|
evidence: string;
|
|
179
182
|
note: string;
|
|
180
183
|
}>;
|
|
184
|
+
/** 0.2.5: explain a persisted content failure; historical checks omit it. */
|
|
185
|
+
findings?: BlockingItem[];
|
|
181
186
|
};
|
|
182
187
|
/** Advisory codes the author has explicitly acknowledged for this content. */
|
|
183
188
|
acknowledged?: string[];
|
|
189
|
+
/** 0.2.5: content failures consume the check budget; submission errors never persist. */
|
|
190
|
+
failure_class?: 'submission' | 'content';
|
|
191
|
+
counted?: boolean;
|
|
184
192
|
verdict: 'pass' | 'fail';
|
|
185
193
|
}
|
|
186
194
|
/** Every persisted document whose damage status/panel can report. */
|
|
187
|
-
export type StateErrorCode = 'PROJECT_UNREADABLE' | 'PLAN_UNREADABLE' | 'WORLD_PLAN_UNREADABLE' | 'REVIEW_UNREADABLE' | 'CHECK_UNREADABLE' | 'CHAPTERS_UNREADABLE' | 'CHARACTERS_UNREADABLE' | 'WORLD_UNREADABLE' | 'LOCKS_UNREADABLE' | 'TIMELINE_UNREADABLE' | 'FORESHADOWS_UNREADABLE' | 'RELATIONSHIPS_UNREADABLE' | 'HANDOFF_UNREADABLE' | 'OUTLINE_UNREADABLE' | 'WORLDBOOK_UNREADABLE';
|
|
195
|
+
export type StateErrorCode = 'PROJECT_UNREADABLE' | 'PIPELINE_UNREADABLE' | 'PLAN_UNREADABLE' | 'WORLD_PLAN_UNREADABLE' | 'REVIEW_UNREADABLE' | 'CHECK_UNREADABLE' | 'CHAPTERS_UNREADABLE' | 'CHARACTERS_UNREADABLE' | 'WORLD_UNREADABLE' | 'LOCKS_UNREADABLE' | 'TIMELINE_UNREADABLE' | 'FORESHADOWS_UNREADABLE' | 'RELATIONSHIPS_UNREADABLE' | 'HANDOFF_UNREADABLE' | 'OUTLINE_UNREADABLE' | 'WORLDBOOK_UNREADABLE';
|
|
188
196
|
/** A state document that exists but cannot be read safely. */
|
|
189
197
|
export interface StateError {
|
|
190
198
|
path: string;
|
|
@@ -255,6 +263,12 @@ export interface ChapterSummary {
|
|
|
255
263
|
abilities: string[];
|
|
256
264
|
artifacts: string[];
|
|
257
265
|
};
|
|
266
|
+
/** Optional P3/P5 verbatim manuscript anchors for readable entity names. */
|
|
267
|
+
new_element_anchors?: {
|
|
268
|
+
locations?: Record<string, string[]>;
|
|
269
|
+
abilities?: Record<string, string[]>;
|
|
270
|
+
artifacts?: Record<string, string[]>;
|
|
271
|
+
};
|
|
258
272
|
resource_changes: Array<{
|
|
259
273
|
character: string;
|
|
260
274
|
resource: string;
|
|
@@ -423,6 +437,8 @@ export interface WorldDocument {
|
|
|
423
437
|
schema_version: 1;
|
|
424
438
|
locations: Array<{
|
|
425
439
|
name: string;
|
|
440
|
+
/** 0.2.6 additive: readable-name anchors; old ledgers omit this. */
|
|
441
|
+
anchors?: string[];
|
|
426
442
|
first_appearance: number;
|
|
427
443
|
locked: boolean;
|
|
428
444
|
description: string;
|
|
@@ -785,6 +801,12 @@ export interface BookReport {
|
|
|
785
801
|
glossary: number;
|
|
786
802
|
backstory: number;
|
|
787
803
|
facts?: number;
|
|
804
|
+
/** 0.2.6 persisted world-ledger anchors, capped for report payloads. */
|
|
805
|
+
anchors?: Array<{
|
|
806
|
+
name: string;
|
|
807
|
+
kind: string;
|
|
808
|
+
anchors: string[];
|
|
809
|
+
}>;
|
|
788
810
|
};
|
|
789
811
|
quality: {
|
|
790
812
|
average: number;
|
|
@@ -953,6 +975,10 @@ export interface GateInput {
|
|
|
953
975
|
summary: ChapterSummary | null;
|
|
954
976
|
/** P5 may omit `summary`; when omitted, the previous plan summary is reused. */
|
|
955
977
|
summaryProvided?: boolean;
|
|
978
|
+
/** Summary-only repair: no manuscript change, no P4/P6 proof requirement. */
|
|
979
|
+
summaryOnly?: boolean;
|
|
980
|
+
/** The last write was a summary-only repair; P6 may continue without a new brief. */
|
|
981
|
+
summaryOnlyRevision?: boolean;
|
|
956
982
|
review: ReviewDocument | null;
|
|
957
983
|
check: CheckDocument | null;
|
|
958
984
|
/** When set, result-bearing gates run only the named check scopes. */
|
|
@@ -1030,6 +1056,8 @@ export interface StatusReport {
|
|
|
1030
1056
|
stage: Stage;
|
|
1031
1057
|
rounds: RoundCounters;
|
|
1032
1058
|
blocking: BlockingItem[];
|
|
1059
|
+
/** Non-blocking recovery notes, e.g. a recoverable pending transaction. */
|
|
1060
|
+
warnings?: Warning[];
|
|
1033
1061
|
/** plan/review/check/ledger files that exist but cannot be read safely. */
|
|
1034
1062
|
state_errors: StateError[];
|
|
1035
1063
|
metrics: WordMetrics | null;
|
package/package.json
CHANGED