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
package/dist/rulesets.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Ruleset package manager — declarative ruleset packages (REQ-389, REQ-390).
|
|
2
|
+
//
|
|
3
|
+
// A ruleset package is a self-contained declarative artifact in the install
|
|
4
|
+
// directory (REQ-389): six JSON files — manifest.json, index.json, model.json,
|
|
5
|
+
// tools.json, resources.json, prompts.json. The host loads a package without
|
|
6
|
+
// reading or re-parsing ruleset Markdown source, using only the prebuilt index
|
|
7
|
+
// and model the package ships.
|
|
8
|
+
import * as fs from "fs";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
import * as crypto from "crypto";
|
|
11
|
+
import { createRng, sessionRoll } from "./core/rng.js";
|
|
12
|
+
export const HOST_VERSION = "2026.08.18";
|
|
13
|
+
// The content hash covers the canonical JSON of the five content files,
|
|
14
|
+
// concatenated in this fixed order (REQ-389). "Canonical" is minified JSON
|
|
15
|
+
// with the properties serialized exactly as they appear in the source object.
|
|
16
|
+
export function computeContentHash(index, model, tools, resources, prompts) {
|
|
17
|
+
const canonical = (obj) => JSON.stringify(JSON.parse(JSON.stringify(obj)));
|
|
18
|
+
const h = crypto.createHash("sha256");
|
|
19
|
+
for (const obj of [index, model, tools, resources, prompts]) {
|
|
20
|
+
h.update(canonical(obj));
|
|
21
|
+
}
|
|
22
|
+
return h.digest("hex");
|
|
23
|
+
}
|
|
24
|
+
// NdM[+|-X] dice parser. Returns total, per-die results, and modifier.
|
|
25
|
+
// Accepts an optional seed for a deterministic isolated draw (REQ-050).
|
|
26
|
+
export function rollDice(notation, seed) {
|
|
27
|
+
const m = String(notation).trim().match(/^(\d+)d(\d+)(?:([+-])(\d+))?$/i);
|
|
28
|
+
if (!m) {
|
|
29
|
+
throw new Error(`Invalid dice notation '${notation}'. Use NdM, e.g. 1d20, 3d6, 4d6+2.`);
|
|
30
|
+
}
|
|
31
|
+
const count = parseInt(m[1], 10);
|
|
32
|
+
const sides = parseInt(m[2], 10);
|
|
33
|
+
if (count < 1 || count > 1000 || sides < 2 || sides > 100000) {
|
|
34
|
+
throw new Error(`Dice notation '${notation}' out of range.`);
|
|
35
|
+
}
|
|
36
|
+
const dice = [];
|
|
37
|
+
if (seed !== undefined) {
|
|
38
|
+
const rng = createRng(seed);
|
|
39
|
+
for (let i = 0; i < count; i++)
|
|
40
|
+
dice.push(rng.roll(sides));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
for (let i = 0; i < count; i++)
|
|
44
|
+
dice.push(sessionRoll(sides));
|
|
45
|
+
}
|
|
46
|
+
const sign = m[3] === "-" ? -1 : 1;
|
|
47
|
+
const modifier = m[4] ? sign * parseInt(m[4], 10) : 0;
|
|
48
|
+
const total = dice.reduce((a, b) => a + b, 0) + modifier;
|
|
49
|
+
return { total, dice, modifier, notation: notation.trim() };
|
|
50
|
+
}
|
|
51
|
+
export class RulesetManager {
|
|
52
|
+
installDir;
|
|
53
|
+
hostVersion;
|
|
54
|
+
installed = new Map();
|
|
55
|
+
hydrated = new Map();
|
|
56
|
+
constructor(installDir, hostVersion = HOST_VERSION) {
|
|
57
|
+
this.installDir = installDir;
|
|
58
|
+
this.hostVersion = hostVersion;
|
|
59
|
+
}
|
|
60
|
+
// Scan the install directory and record installed package metadata, WITHOUT
|
|
61
|
+
// loading index/model (lazy hydration — REQ-390). Returns an array of
|
|
62
|
+
// per-slug validation errors (empty means clean).
|
|
63
|
+
scan() {
|
|
64
|
+
this.installed.clear();
|
|
65
|
+
const errors = [];
|
|
66
|
+
if (!fs.existsSync(this.installDir))
|
|
67
|
+
return errors;
|
|
68
|
+
const entries = fs.readdirSync(this.installDir, { withFileTypes: true });
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
if (!entry.isDirectory())
|
|
71
|
+
continue;
|
|
72
|
+
const slug = entry.name;
|
|
73
|
+
const manifestPath = path.join(this.installDir, slug, "manifest.json");
|
|
74
|
+
if (!fs.existsSync(manifestPath)) {
|
|
75
|
+
errors.push(`${slug}: missing manifest.json`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
80
|
+
if (manifest.slug !== slug) {
|
|
81
|
+
errors.push(`${slug}: manifest slug mismatch ('${manifest.slug}')`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (manifest.host_version !== this.hostVersion) {
|
|
85
|
+
errors.push(`${slug}: incompatible host_version '${manifest.host_version}' (expected '${this.hostVersion}')`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
this.installed.set(slug, manifest);
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
errors.push(`${slug}: unreadable manifest — ${e.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return errors;
|
|
95
|
+
}
|
|
96
|
+
installedSlugs() {
|
|
97
|
+
return [...this.installed.keys()];
|
|
98
|
+
}
|
|
99
|
+
isInstalled(slug) {
|
|
100
|
+
return this.installed.has(slug);
|
|
101
|
+
}
|
|
102
|
+
isHydrated(slug) {
|
|
103
|
+
return this.hydrated.has(slug);
|
|
104
|
+
}
|
|
105
|
+
prefixMap() {
|
|
106
|
+
const map = {};
|
|
107
|
+
for (const slug of this.installed.keys())
|
|
108
|
+
map[slug] = slug;
|
|
109
|
+
return map;
|
|
110
|
+
}
|
|
111
|
+
// Load a package fully (index + model + tools + resources + prompts) after
|
|
112
|
+
// validating its content hash against the host algorithm. Returns the loaded
|
|
113
|
+
// package, cached for subsequent calls.
|
|
114
|
+
hydrate(slug) {
|
|
115
|
+
if (this.hydrated.has(slug))
|
|
116
|
+
return this.hydrated.get(slug);
|
|
117
|
+
const manifest = this.installed.get(slug);
|
|
118
|
+
if (!manifest) {
|
|
119
|
+
throw new Error(`Ruleset '${slug}' is not installed.`);
|
|
120
|
+
}
|
|
121
|
+
const dir = path.join(this.installDir, slug);
|
|
122
|
+
const read = (name) => {
|
|
123
|
+
const p = path.join(dir, name);
|
|
124
|
+
if (!fs.existsSync(p))
|
|
125
|
+
throw new Error(`Ruleset '${slug}' is missing ${name}.`);
|
|
126
|
+
return JSON.parse(fs.readFileSync(p, "utf-8"));
|
|
127
|
+
};
|
|
128
|
+
const index = read("index.json");
|
|
129
|
+
const model = read("model.json");
|
|
130
|
+
const tools = read("tools.json");
|
|
131
|
+
const resources = read("resources.json");
|
|
132
|
+
const prompts = read("prompts.json");
|
|
133
|
+
const hash = computeContentHash(index, model, tools, resources, prompts);
|
|
134
|
+
if (hash !== manifest.content_hash) {
|
|
135
|
+
throw new Error(`Ruleset '${slug}' content hash mismatch. Expected ${manifest.content_hash}, received ${hash}.`);
|
|
136
|
+
}
|
|
137
|
+
const pkg = { slug, manifest, index, model, tools, resources, prompts };
|
|
138
|
+
this.hydrated.set(slug, pkg);
|
|
139
|
+
return pkg;
|
|
140
|
+
}
|
|
141
|
+
toolSchemas(slug) {
|
|
142
|
+
const pkg = this.hydrate(slug);
|
|
143
|
+
return pkg.tools;
|
|
144
|
+
}
|
|
145
|
+
// Full-text search over the hydrated index. Simple normalized substring
|
|
146
|
+
// scoring across id/anchor/content/category.
|
|
147
|
+
search(slug, query, maxResults = 10) {
|
|
148
|
+
const pkg = this.hydrate(slug);
|
|
149
|
+
const q = query.trim().toLowerCase();
|
|
150
|
+
if (!q)
|
|
151
|
+
return pkg.index.slice(0, maxResults);
|
|
152
|
+
const scored = [];
|
|
153
|
+
for (const entry of pkg.index) {
|
|
154
|
+
const hay = `${entry.id} ${entry.anchor} ${entry.category} ${entry.content}`.toLowerCase();
|
|
155
|
+
let score = 0;
|
|
156
|
+
if (hay.includes(q))
|
|
157
|
+
score += 10;
|
|
158
|
+
for (const term of q.split(/\s+/)) {
|
|
159
|
+
if (term && hay.includes(term))
|
|
160
|
+
score += 2;
|
|
161
|
+
}
|
|
162
|
+
if (entry.id.includes(q) || entry.anchor.toLowerCase().includes(q))
|
|
163
|
+
score += 5;
|
|
164
|
+
if (score > 0)
|
|
165
|
+
scored.push({ entry, score });
|
|
166
|
+
}
|
|
167
|
+
scored.sort((a, b) => b.score - a.score);
|
|
168
|
+
return scored.slice(0, maxResults).map((s) => s.entry);
|
|
169
|
+
}
|
|
170
|
+
// Install a package bundle (the six files) under the install dir, validating
|
|
171
|
+
// slug uniqueness, host-version compatibility, and content-hash integrity.
|
|
172
|
+
installPackage(slug, files) {
|
|
173
|
+
if (this.installed.has(slug)) {
|
|
174
|
+
throw new Error(`[STATE_CONFLICT] Ruleset '${slug}' is already installed.`);
|
|
175
|
+
}
|
|
176
|
+
const manifest = files.manifest;
|
|
177
|
+
if (!manifest || manifest.slug !== slug) {
|
|
178
|
+
throw new Error(`[INVALID_INPUT] manifest.slug must equal '${slug}'.`);
|
|
179
|
+
}
|
|
180
|
+
if (manifest.host_version !== this.hostVersion) {
|
|
181
|
+
throw new Error(`[INVALID_INPUT] incompatible host_version '${manifest.host_version}' (expected '${this.hostVersion}').`);
|
|
182
|
+
}
|
|
183
|
+
const hash = computeContentHash(files.index ?? [], files.model ?? {}, files.tools ?? [], files.resources ?? [], files.prompts ?? []);
|
|
184
|
+
if (hash !== manifest.content_hash) {
|
|
185
|
+
throw new Error(`[INVALID_INPUT] content hash mismatch. Expected ${manifest.content_hash}, received ${hash}.`);
|
|
186
|
+
}
|
|
187
|
+
const dir = path.join(this.installDir, slug);
|
|
188
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
189
|
+
for (const [name, obj] of Object.entries({
|
|
190
|
+
"manifest.json": files.manifest,
|
|
191
|
+
"index.json": files.index ?? [],
|
|
192
|
+
"model.json": files.model ?? {},
|
|
193
|
+
"tools.json": files.tools ?? [],
|
|
194
|
+
"resources.json": files.resources ?? [],
|
|
195
|
+
"prompts.json": files.prompts ?? [],
|
|
196
|
+
})) {
|
|
197
|
+
fs.writeFileSync(path.join(dir, name), JSON.stringify(obj, null, 2) + "\n");
|
|
198
|
+
}
|
|
199
|
+
this.scan();
|
|
200
|
+
return this.hydrate(slug);
|
|
201
|
+
}
|
|
202
|
+
removePackage(slug) {
|
|
203
|
+
if (!this.installed.has(slug)) {
|
|
204
|
+
throw new Error(`[STATE_CONFLICT] Ruleset '${slug}' is not installed.`);
|
|
205
|
+
}
|
|
206
|
+
const dir = path.join(this.installDir, slug);
|
|
207
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
208
|
+
this.installed.delete(slug);
|
|
209
|
+
this.hydrated.delete(slug);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=rulesets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rulesets.js","sourceRoot":"","sources":["../src/rulesets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { WORLD_MODEL_KINDS, ROOM_DIRECTIONS, oppositeDirection, createEmptyWorldModel, convertSource, worldMap, worldKinds, BASE_PARSER_COMMANDS, resolveThingName, resolveThingInInventory, } from "./model.js";
|
|
2
|
+
export type { WorldKind, Direction, WorldModel, WorldRoom, WorldThing, } from "./model.js";
|
|
3
|
+
export { dispatchCommand, resolveGoMovement } from "./parser.js";
|
|
4
|
+
export type { ParserContext, ParserResult } from "./parser.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { WORLD_MODEL_KINDS, ROOM_DIRECTIONS, oppositeDirection, createEmptyWorldModel, convertSource, worldMap, worldKinds, BASE_PARSER_COMMANDS, resolveThingName, resolveThingInInventory, } from "./model.js";
|
|
2
|
+
export { dispatchCommand, resolveGoMovement } from "./parser.js";
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/world/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AAQpB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export declare const WORLD_MODEL_KINDS: {
|
|
2
|
+
readonly thing: {
|
|
3
|
+
readonly parent: null;
|
|
4
|
+
readonly description: "A physical object in the world.";
|
|
5
|
+
};
|
|
6
|
+
readonly container: {
|
|
7
|
+
readonly parent: "thing";
|
|
8
|
+
readonly description: "A thing that can hold other things. Portable by default. When closed, contents are blocked.";
|
|
9
|
+
};
|
|
10
|
+
readonly supporter: {
|
|
11
|
+
readonly parent: "thing";
|
|
12
|
+
readonly description: "A thing that other things can rest on. Fixed by default.";
|
|
13
|
+
};
|
|
14
|
+
readonly door: {
|
|
15
|
+
readonly parent: "thing";
|
|
16
|
+
readonly description: "A thing that connects two rooms and may be opened or closed. Blocks passage when closed. Lockable.";
|
|
17
|
+
};
|
|
18
|
+
readonly device: {
|
|
19
|
+
readonly parent: "thing";
|
|
20
|
+
readonly description: "A thing that can be switched on or off. Portable by default.";
|
|
21
|
+
};
|
|
22
|
+
readonly vehicle: {
|
|
23
|
+
readonly parent: "thing";
|
|
24
|
+
readonly description: "An enterable thing with a virtual interior room. Moves between rooms. Fixed by default.";
|
|
25
|
+
};
|
|
26
|
+
readonly person: {
|
|
27
|
+
readonly parent: "thing";
|
|
28
|
+
readonly description: "An animate being. Visible and examinable in rooms.";
|
|
29
|
+
};
|
|
30
|
+
readonly backdrop: {
|
|
31
|
+
readonly parent: "thing";
|
|
32
|
+
readonly description: "A thing present in multiple rooms; scenery-level.";
|
|
33
|
+
};
|
|
34
|
+
readonly region: {
|
|
35
|
+
readonly parent: null;
|
|
36
|
+
readonly description: "A named area spanning multiple rooms.";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export type WorldKind = keyof typeof WORLD_MODEL_KINDS;
|
|
40
|
+
export declare const ROOM_DIRECTIONS: readonly ["north", "south", "east", "west", "northeast", "northwest", "southeast", "southwest", "up", "down", "in", "out"];
|
|
41
|
+
export type Direction = (typeof ROOM_DIRECTIONS)[number];
|
|
42
|
+
export declare function oppositeDirection(dir: Direction): Direction;
|
|
43
|
+
export interface WorldThing {
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
kind: WorldKind;
|
|
47
|
+
location: string | null;
|
|
48
|
+
locationType: "room" | "container" | "supporter" | "vehicle" | null;
|
|
49
|
+
portable: boolean;
|
|
50
|
+
openable: boolean;
|
|
51
|
+
open: boolean;
|
|
52
|
+
lockable: boolean;
|
|
53
|
+
locked: boolean;
|
|
54
|
+
lit: boolean;
|
|
55
|
+
capacity?: number;
|
|
56
|
+
doorConnects?: {
|
|
57
|
+
roomA: string;
|
|
58
|
+
roomB: string;
|
|
59
|
+
};
|
|
60
|
+
switchable: boolean;
|
|
61
|
+
switched_on: boolean;
|
|
62
|
+
enterable: boolean;
|
|
63
|
+
vehicleInterior?: string;
|
|
64
|
+
vehiclePassengers: string[];
|
|
65
|
+
wearable: boolean;
|
|
66
|
+
worn_by: string | null;
|
|
67
|
+
readable: boolean;
|
|
68
|
+
read_text: string | null;
|
|
69
|
+
edible: boolean;
|
|
70
|
+
drinkable: boolean;
|
|
71
|
+
climbable: boolean;
|
|
72
|
+
transparent: boolean;
|
|
73
|
+
annotations: {
|
|
74
|
+
encounter?: string;
|
|
75
|
+
trap?: string;
|
|
76
|
+
npc?: string;
|
|
77
|
+
lore?: string;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export interface WorldRoom {
|
|
81
|
+
name: string;
|
|
82
|
+
description: string;
|
|
83
|
+
exits: Map<string, string>;
|
|
84
|
+
doorRefs: Map<string, string>;
|
|
85
|
+
annotations: {
|
|
86
|
+
encounter?: string;
|
|
87
|
+
trap?: string;
|
|
88
|
+
npc?: string;
|
|
89
|
+
lore?: string;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export interface WorldModel {
|
|
93
|
+
rooms: Map<string, WorldRoom>;
|
|
94
|
+
things: Map<string, WorldThing>;
|
|
95
|
+
}
|
|
96
|
+
export declare function createEmptyWorldModel(): WorldModel;
|
|
97
|
+
export declare const BASE_PARSER_COMMANDS: {
|
|
98
|
+
verb: string;
|
|
99
|
+
category: string;
|
|
100
|
+
args: string[];
|
|
101
|
+
}[];
|
|
102
|
+
export declare function resolveThingName(input: string, thingsInRoom: WorldThing[], inventory: string[]): WorldThing[];
|
|
103
|
+
export declare function resolveThingInInventory(input: string, heldThings: WorldThing[]): WorldThing[];
|
|
104
|
+
export interface ConvertResult {
|
|
105
|
+
rooms: number;
|
|
106
|
+
things: number;
|
|
107
|
+
exits: number;
|
|
108
|
+
annotations: {
|
|
109
|
+
encounters: number;
|
|
110
|
+
npcs: number;
|
|
111
|
+
traps: number;
|
|
112
|
+
lore: number;
|
|
113
|
+
};
|
|
114
|
+
warnings: {
|
|
115
|
+
line: number;
|
|
116
|
+
pattern: string;
|
|
117
|
+
message: string;
|
|
118
|
+
}[];
|
|
119
|
+
}
|
|
120
|
+
export declare function convertSource(source: string, existingWorld: WorldModel): {
|
|
121
|
+
world: WorldModel;
|
|
122
|
+
result: ConvertResult;
|
|
123
|
+
};
|
|
124
|
+
export declare function worldMap(world: WorldModel): string;
|
|
125
|
+
export declare function worldKinds(): string;
|