holonovel 2026.8.22
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/LICENSE.md +21 -0
- package/bin/holonovel.js +5 -0
- package/dist/core/character-creation.d.ts +116 -0
- package/dist/core/character-creation.js +346 -0
- package/dist/core/character-creation.js.map +1 -0
- package/dist/core/enrichment.d.ts +45 -0
- package/dist/core/enrichment.js +269 -0
- package/dist/core/enrichment.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/macros.d.ts +21 -0
- package/dist/core/macros.js +50 -0
- package/dist/core/macros.js.map +1 -0
- package/dist/core/rng.d.ts +17 -0
- package/dist/core/rng.js +72 -0
- package/dist/core/rng.js.map +1 -0
- package/dist/core/server.d.ts +18 -0
- package/dist/core/server.js +40 -0
- package/dist/core/server.js.map +1 -0
- package/dist/core/state.d.ts +396 -0
- package/dist/core/state.js +1080 -0
- package/dist/core/state.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4051 -0
- package/dist/index.js.map +1 -0
- package/dist/rulesets.d.ts +65 -0
- package/dist/rulesets.js +212 -0
- package/dist/rulesets.js.map +1 -0
- package/dist/world/index.d.ts +4 -0
- package/dist/world/index.js +3 -0
- package/dist/world/index.js.map +1 -0
- package/dist/world/model.d.ts +125 -0
- package/dist/world/model.js +492 -0
- package/dist/world/model.js.map +1 -0
- package/dist/world/parser.d.ts +18 -0
- package/dist/world/parser.js +462 -0
- package/dist/world/parser.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { WorldModel } from "../world/model.js";
|
|
2
|
+
export type Badge = "player" | "game_master" | "observer" | "none";
|
|
3
|
+
export declare function normalizeBadge(raw: unknown): Badge;
|
|
4
|
+
export declare function migrateNovelData(data: any): any;
|
|
5
|
+
export interface NovelEntity {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
personality?: {
|
|
9
|
+
description?: string;
|
|
10
|
+
voice?: string;
|
|
11
|
+
background?: string;
|
|
12
|
+
goals?: string;
|
|
13
|
+
};
|
|
14
|
+
voice_examples?: {
|
|
15
|
+
context: string;
|
|
16
|
+
dialogue: string;
|
|
17
|
+
tag?: string;
|
|
18
|
+
}[];
|
|
19
|
+
inventory: string[];
|
|
20
|
+
current_room: string | null;
|
|
21
|
+
conditions: string[];
|
|
22
|
+
condition_rounds: Record<string, number>;
|
|
23
|
+
stats?: Record<string, any>;
|
|
24
|
+
}
|
|
25
|
+
export interface NpcState {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
disposition?: string;
|
|
30
|
+
location?: string;
|
|
31
|
+
personality?: {
|
|
32
|
+
description?: string;
|
|
33
|
+
voice?: string;
|
|
34
|
+
background?: string;
|
|
35
|
+
goals?: string;
|
|
36
|
+
};
|
|
37
|
+
voice_examples?: {
|
|
38
|
+
context: string;
|
|
39
|
+
dialogue: string;
|
|
40
|
+
tag?: string;
|
|
41
|
+
}[];
|
|
42
|
+
conditions: string[];
|
|
43
|
+
condition_rounds: Record<string, number>;
|
|
44
|
+
}
|
|
45
|
+
export interface LoreEntry {
|
|
46
|
+
key: string;
|
|
47
|
+
content: string;
|
|
48
|
+
triggers: string[];
|
|
49
|
+
badge_scope: "game_master" | "shared";
|
|
50
|
+
priority: number;
|
|
51
|
+
sticky: number;
|
|
52
|
+
sticky_remaining: number;
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
group?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface Countdown {
|
|
57
|
+
name: string;
|
|
58
|
+
ticks: number;
|
|
59
|
+
total: number;
|
|
60
|
+
type: "round" | "narrative";
|
|
61
|
+
scope?: string;
|
|
62
|
+
direction?: string;
|
|
63
|
+
clock_type?: "danger" | "racing" | "linked" | "tug_of_war" | "faction" | "mission";
|
|
64
|
+
on_scene_transition?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface CombatState {
|
|
67
|
+
participants: string[];
|
|
68
|
+
dangers: {
|
|
69
|
+
name: string;
|
|
70
|
+
ac?: number;
|
|
71
|
+
hp?: number;
|
|
72
|
+
max_hp?: number;
|
|
73
|
+
initiative_bonus?: number;
|
|
74
|
+
}[];
|
|
75
|
+
round: number;
|
|
76
|
+
turn_order: string[];
|
|
77
|
+
current_turn: number;
|
|
78
|
+
active: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface AuditEntry {
|
|
81
|
+
timestamp: string;
|
|
82
|
+
badge: Badge;
|
|
83
|
+
tool: string;
|
|
84
|
+
args: string;
|
|
85
|
+
output_prefix: string;
|
|
86
|
+
hash: string;
|
|
87
|
+
}
|
|
88
|
+
export interface StoryEntry {
|
|
89
|
+
index: number;
|
|
90
|
+
type: "decision" | "moment" | "revelation" | "bond" | "consequence";
|
|
91
|
+
entry: string;
|
|
92
|
+
scene_anchor: string;
|
|
93
|
+
entity_ids: string[];
|
|
94
|
+
timestamp: string;
|
|
95
|
+
}
|
|
96
|
+
export interface FactionState {
|
|
97
|
+
id: string;
|
|
98
|
+
name: string;
|
|
99
|
+
description: string;
|
|
100
|
+
goals: string[];
|
|
101
|
+
resources: string;
|
|
102
|
+
clock: number;
|
|
103
|
+
clock_max: number;
|
|
104
|
+
status: string;
|
|
105
|
+
}
|
|
106
|
+
export interface SecretState {
|
|
107
|
+
key: string;
|
|
108
|
+
content: string;
|
|
109
|
+
triggers: string[];
|
|
110
|
+
badge_scope: "game_master" | "shared";
|
|
111
|
+
known_by: string[];
|
|
112
|
+
}
|
|
113
|
+
export interface Relationship {
|
|
114
|
+
entity_a: string;
|
|
115
|
+
entity_b: string;
|
|
116
|
+
type: "ally" | "rival" | "neutral" | "mentor" | "dependent" | "suspicious";
|
|
117
|
+
value?: number;
|
|
118
|
+
description?: string;
|
|
119
|
+
}
|
|
120
|
+
export interface GMContext {
|
|
121
|
+
current_scene?: string;
|
|
122
|
+
immediate_situation?: string;
|
|
123
|
+
pending_player_action?: string;
|
|
124
|
+
short_term_plans?: string;
|
|
125
|
+
long_term_plans?: string;
|
|
126
|
+
active_threads?: {
|
|
127
|
+
name: string;
|
|
128
|
+
status: string;
|
|
129
|
+
urgency: string;
|
|
130
|
+
description: string;
|
|
131
|
+
}[];
|
|
132
|
+
npc_attitudes?: Record<string, string>;
|
|
133
|
+
player_goals?: string;
|
|
134
|
+
saved_at?: string;
|
|
135
|
+
story_context?: string[];
|
|
136
|
+
active_vows?: {
|
|
137
|
+
name: string;
|
|
138
|
+
difficulty: string;
|
|
139
|
+
milestone_count: number;
|
|
140
|
+
}[];
|
|
141
|
+
faction_clocks?: {
|
|
142
|
+
name: string;
|
|
143
|
+
clock: number;
|
|
144
|
+
clock_max: number;
|
|
145
|
+
status: string;
|
|
146
|
+
}[];
|
|
147
|
+
countdown_positions?: {
|
|
148
|
+
name: string;
|
|
149
|
+
ticks: number;
|
|
150
|
+
total: number;
|
|
151
|
+
}[];
|
|
152
|
+
npc_dispositions?: {
|
|
153
|
+
name: string;
|
|
154
|
+
disposition?: string;
|
|
155
|
+
location?: string;
|
|
156
|
+
}[];
|
|
157
|
+
relationships?: Relationship[];
|
|
158
|
+
}
|
|
159
|
+
export interface CodexEntry {
|
|
160
|
+
id: string;
|
|
161
|
+
kind: string;
|
|
162
|
+
visibility: "library" | "shared" | "private";
|
|
163
|
+
name: string;
|
|
164
|
+
content: Record<string, any>;
|
|
165
|
+
description?: string;
|
|
166
|
+
tags?: string[];
|
|
167
|
+
imported_at: string;
|
|
168
|
+
codex_modified_at: string;
|
|
169
|
+
}
|
|
170
|
+
export interface VowState {
|
|
171
|
+
name: string;
|
|
172
|
+
description: string;
|
|
173
|
+
parties: string[];
|
|
174
|
+
difficulty: "troublesome" | "dangerous" | "formidable" | "extreme" | "epic";
|
|
175
|
+
scope: "gm" | "shared" | "faction" | "party";
|
|
176
|
+
milestones: number;
|
|
177
|
+
rank_track: number;
|
|
178
|
+
state: "active" | "resolved" | "forsaken";
|
|
179
|
+
outcome?: string;
|
|
180
|
+
consequences?: string;
|
|
181
|
+
reason?: string;
|
|
182
|
+
}
|
|
183
|
+
export interface NoteEntry {
|
|
184
|
+
key: string;
|
|
185
|
+
content: string;
|
|
186
|
+
badge_scope: "game_master" | "player" | "shared";
|
|
187
|
+
}
|
|
188
|
+
export interface Checkpoint {
|
|
189
|
+
label: string;
|
|
190
|
+
timestamp: string;
|
|
191
|
+
state: any;
|
|
192
|
+
}
|
|
193
|
+
export interface ConditionState {
|
|
194
|
+
conditions: string[];
|
|
195
|
+
condition_rounds: Record<string, number>;
|
|
196
|
+
}
|
|
197
|
+
export interface AutonomyState {
|
|
198
|
+
level: "full" | "mechanical_prompt" | "manual";
|
|
199
|
+
confirmation: "auto" | "confirm" | "prompt";
|
|
200
|
+
safety: "safe" | "moderate" | "hardcore";
|
|
201
|
+
creativity: "predictable" | "standard" | "chaotic";
|
|
202
|
+
confirmed_safety_tiers: string[];
|
|
203
|
+
}
|
|
204
|
+
export declare const DEFAULT_AUTONOMY: AutonomyState;
|
|
205
|
+
export declare function normalizeAutonomy(raw: unknown): AutonomyState;
|
|
206
|
+
export declare function autonomyDefaultsFromEnv(): AutonomyState;
|
|
207
|
+
export declare const DIFFICULTY_TRACKS: Record<string, number>;
|
|
208
|
+
export interface NovelState {
|
|
209
|
+
slug: string;
|
|
210
|
+
name: string;
|
|
211
|
+
ruleset: string | null;
|
|
212
|
+
badge: Badge;
|
|
213
|
+
entities: Map<string, NovelEntity>;
|
|
214
|
+
active_entity_id: string | null;
|
|
215
|
+
npcs: Map<string, NpcState>;
|
|
216
|
+
scene_description: string;
|
|
217
|
+
scene_location?: string;
|
|
218
|
+
scene_time_of_day?: string;
|
|
219
|
+
scene_atmosphere?: string;
|
|
220
|
+
scene_history: {
|
|
221
|
+
timestamp: string;
|
|
222
|
+
description: string;
|
|
223
|
+
location?: string;
|
|
224
|
+
time_of_day?: string;
|
|
225
|
+
atmosphere?: string;
|
|
226
|
+
}[];
|
|
227
|
+
scene_type: ("combat" | "social" | "exploration" | "neutral")[];
|
|
228
|
+
narrative_directive: string;
|
|
229
|
+
combat: CombatState | null;
|
|
230
|
+
countdowns: Map<string, Countdown>;
|
|
231
|
+
lore: Map<string, LoreEntry>;
|
|
232
|
+
briefing_assembly_count: number;
|
|
233
|
+
player_signals: Record<string, string>;
|
|
234
|
+
adventure_slug: string | null;
|
|
235
|
+
generated_adventure: any | null;
|
|
236
|
+
audit_log: AuditEntry[];
|
|
237
|
+
undo_stacks: Record<string, NovelState[]>;
|
|
238
|
+
redo_stacks: Record<string, NovelState[]>;
|
|
239
|
+
briefing_order: string[];
|
|
240
|
+
action_patterns_enabled: boolean;
|
|
241
|
+
session_zero_completed: boolean;
|
|
242
|
+
characters_present: boolean;
|
|
243
|
+
characters_present_ids: string[];
|
|
244
|
+
adventure_set: boolean;
|
|
245
|
+
pending_workflow: {
|
|
246
|
+
decision: string;
|
|
247
|
+
snapshot: any;
|
|
248
|
+
} | {
|
|
249
|
+
decision: string;
|
|
250
|
+
snapshot: any;
|
|
251
|
+
creation?: import("./character-creation.js").CreationWorkflowState;
|
|
252
|
+
} | null;
|
|
253
|
+
connection_counter: number;
|
|
254
|
+
pending_staleness_counter: number;
|
|
255
|
+
pov_mode: "character" | "omniscient";
|
|
256
|
+
autonomy: AutonomyState;
|
|
257
|
+
help_category_overrides: Record<string, string>;
|
|
258
|
+
story_journal: StoryEntry[];
|
|
259
|
+
factions: FactionState[];
|
|
260
|
+
secrets: SecretState[];
|
|
261
|
+
relationships: Relationship[];
|
|
262
|
+
gm_context: GMContext;
|
|
263
|
+
constraint_overrides: {
|
|
264
|
+
type: string;
|
|
265
|
+
name?: string;
|
|
266
|
+
source?: string;
|
|
267
|
+
prerequisites?: string[];
|
|
268
|
+
slots_remaining?: number;
|
|
269
|
+
match_all?: boolean;
|
|
270
|
+
}[];
|
|
271
|
+
synthesis_activated: Record<string, number>;
|
|
272
|
+
synthesis_module_enabled: Record<string, boolean>;
|
|
273
|
+
notes: NoteEntry[];
|
|
274
|
+
vows: VowState[];
|
|
275
|
+
checkpoints: Checkpoint[];
|
|
276
|
+
description: string;
|
|
277
|
+
genre: string;
|
|
278
|
+
adventure_index: {
|
|
279
|
+
npcs: Array<{
|
|
280
|
+
name: string;
|
|
281
|
+
description?: string;
|
|
282
|
+
}>;
|
|
283
|
+
locations: Array<{
|
|
284
|
+
name: string;
|
|
285
|
+
description: string;
|
|
286
|
+
}>;
|
|
287
|
+
factions: Array<{
|
|
288
|
+
name: string;
|
|
289
|
+
goals?: string;
|
|
290
|
+
}>;
|
|
291
|
+
premise: string;
|
|
292
|
+
hooks: string[];
|
|
293
|
+
} | null;
|
|
294
|
+
adventure_scene_waypoint: {
|
|
295
|
+
anchor: string;
|
|
296
|
+
description: string;
|
|
297
|
+
} | null;
|
|
298
|
+
world: WorldModel;
|
|
299
|
+
metadata: {
|
|
300
|
+
created: string;
|
|
301
|
+
modified: string;
|
|
302
|
+
session_count: number;
|
|
303
|
+
total_combat_rounds: number;
|
|
304
|
+
last_scene_anchor: string;
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
export interface RosterEntity extends NovelEntity {
|
|
308
|
+
}
|
|
309
|
+
export declare class StateManager {
|
|
310
|
+
novels: Map<string, NovelState>;
|
|
311
|
+
roster: Map<string, RosterEntity>;
|
|
312
|
+
activeNovelId: string | null;
|
|
313
|
+
buildFingerprint: {
|
|
314
|
+
specVersion: string;
|
|
315
|
+
specRepoUrl: string;
|
|
316
|
+
specHash: string;
|
|
317
|
+
sourceHash: string;
|
|
318
|
+
rulesetHash: string;
|
|
319
|
+
buildTimestamp: string;
|
|
320
|
+
lastSpecReview?: string;
|
|
321
|
+
lastGauntlet?: string;
|
|
322
|
+
};
|
|
323
|
+
enriched: boolean;
|
|
324
|
+
enrichmentManifest: any;
|
|
325
|
+
maxLoreTokens: number | null;
|
|
326
|
+
serverNotes: Map<string, string>;
|
|
327
|
+
codex: Map<string, CodexEntry>;
|
|
328
|
+
private npcCounter;
|
|
329
|
+
private entityCounter;
|
|
330
|
+
private stateDir;
|
|
331
|
+
constructor(stateDir: string);
|
|
332
|
+
get activeNovel(): NovelState | undefined;
|
|
333
|
+
requireGM(badge: Badge): void;
|
|
334
|
+
requirePlayer(badge: Badge): void;
|
|
335
|
+
requireNotObserver(badge: Badge): void;
|
|
336
|
+
requireNovel(): NovelState;
|
|
337
|
+
getActiveEntity(): NovelEntity | undefined;
|
|
338
|
+
resolveEntity(entityId?: string): NovelEntity;
|
|
339
|
+
resolveEntityNullable(entityId?: string): NovelEntity | undefined;
|
|
340
|
+
createNovel(name: string, ruleset?: string | null): NovelState;
|
|
341
|
+
bindNovelRuleset(slug: string): NovelState;
|
|
342
|
+
resumeNovel(slug: string): NovelState;
|
|
343
|
+
private loadNovelFromData;
|
|
344
|
+
switchNovel(slug: string): NovelState;
|
|
345
|
+
endNovel(novel: NovelState, dispose: "yes" | "cancel"): {
|
|
346
|
+
removed: boolean;
|
|
347
|
+
};
|
|
348
|
+
cleanupExpiredTrash(): void;
|
|
349
|
+
snapshot(novel: NovelState, badge: Badge): void;
|
|
350
|
+
undo(novel: NovelState, badge: Badge): {
|
|
351
|
+
data: any;
|
|
352
|
+
} | null;
|
|
353
|
+
redo(novel: NovelState, badge: Badge): {
|
|
354
|
+
data: any;
|
|
355
|
+
} | null;
|
|
356
|
+
audit(novel: NovelState, badge: Badge, tool: string, args: any, output_prefix?: string): void;
|
|
357
|
+
auditForbidden(badge: Badge, tool: string, args: any): void;
|
|
358
|
+
verifyAuditChain(novel: NovelState): {
|
|
359
|
+
valid: boolean;
|
|
360
|
+
entries: number;
|
|
361
|
+
first_broken_index?: number;
|
|
362
|
+
};
|
|
363
|
+
getEnrichmentHealth(): any;
|
|
364
|
+
initCombat(novel: NovelState, participants: string[], dangers: {
|
|
365
|
+
name: string;
|
|
366
|
+
ac?: number;
|
|
367
|
+
hp?: number;
|
|
368
|
+
max_hp?: number;
|
|
369
|
+
initiative_bonus?: number;
|
|
370
|
+
}[], seedStr?: string): CombatState;
|
|
371
|
+
advanceCombat(novel: NovelState): CombatState;
|
|
372
|
+
endCombat(novel: NovelState, outcome: string): void;
|
|
373
|
+
addCombatParticipant(novel: NovelState, participantId: string): CombatState;
|
|
374
|
+
removeCombatParticipant(novel: NovelState, participantId: string): {
|
|
375
|
+
combat: CombatState | null;
|
|
376
|
+
ended: boolean;
|
|
377
|
+
outcome?: string;
|
|
378
|
+
};
|
|
379
|
+
combatReport(novel: NovelState): string;
|
|
380
|
+
worldHasRooms(novel: NovelState): boolean;
|
|
381
|
+
saveNovel(novel: NovelState): void;
|
|
382
|
+
saveRoster(): void;
|
|
383
|
+
loadRoster(): void;
|
|
384
|
+
addToRoster(entity: NovelEntity): string;
|
|
385
|
+
loadServerNotes(): void;
|
|
386
|
+
saveServerNotes(): void;
|
|
387
|
+
loadCodex(): void;
|
|
388
|
+
saveCodex(): void;
|
|
389
|
+
createEntity(name: string, personality?: {
|
|
390
|
+
description?: string;
|
|
391
|
+
voice?: string;
|
|
392
|
+
background?: string;
|
|
393
|
+
goals?: string;
|
|
394
|
+
}, stats?: Record<string, any>): NovelEntity;
|
|
395
|
+
addEntity(novel: NovelState, entity: NovelEntity): void;
|
|
396
|
+
}
|