Add bundled-bestiary mechanism for shipping creatures with the app
D&D creatures listed in data/bestiary/dnd-bundled.json are now merged into the search index and pre-loaded into creatureMap, so they appear alongside 5etools creatures with no "Load source" step. Source codes are derived from the JSON itself (each creature carries source + sourceDisplayName), so adding a new book is a pure data change. Bundled sources are excluded from getAllSourceCodes() so bulk-import skips them, and they never appear in the source manager (which only lists cached sources). Includes a reference extractor (scripts/extract-great-labors.py) for the 5.5e revised stat-block format and a /bundle-bestiary skill that future agents can follow to add monsters from other PDF books. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import type { BestiaryIndex, BestiaryIndexEntry } from "@initiative/domain";
|
||||
|
||||
import rawIndex from "../../../../data/bestiary/index.json";
|
||||
import {
|
||||
getBundledDndSources,
|
||||
loadBundledDndIndexEntries,
|
||||
} from "./dnd-bundled-adapter.js";
|
||||
|
||||
interface CompactCreature {
|
||||
readonly n: string;
|
||||
@@ -55,23 +59,32 @@ export function loadBestiaryIndex(): BestiaryIndex {
|
||||
if (cachedIndex) return cachedIndex;
|
||||
|
||||
const compact = rawIndex as unknown as CompactIndex;
|
||||
const sources = Object.fromEntries(
|
||||
const sources: Record<string, string> = Object.fromEntries(
|
||||
Object.entries(compact.sources).filter(
|
||||
([code]) => !EXCLUDED_SOURCES.has(code),
|
||||
),
|
||||
);
|
||||
for (const [code, name] of getBundledDndSources()) {
|
||||
sources[code] = name;
|
||||
}
|
||||
cachedIndex = {
|
||||
sources,
|
||||
creatures: compact.creatures
|
||||
.filter((c) => !EXCLUDED_SOURCES.has(c.s))
|
||||
.map(mapCreature),
|
||||
creatures: [
|
||||
...compact.creatures
|
||||
.filter((c) => !EXCLUDED_SOURCES.has(c.s))
|
||||
.map(mapCreature),
|
||||
...loadBundledDndIndexEntries(),
|
||||
],
|
||||
};
|
||||
return cachedIndex;
|
||||
}
|
||||
|
||||
export function getAllSourceCodes(): string[] {
|
||||
const index = loadBestiaryIndex();
|
||||
return Object.keys(index.sources).filter((c) => !EXCLUDED_SOURCES.has(c));
|
||||
const bundled = getBundledDndSources();
|
||||
return Object.keys(index.sources).filter(
|
||||
(c) => !EXCLUDED_SOURCES.has(c) && !bundled.has(c),
|
||||
);
|
||||
}
|
||||
|
||||
function sourceCodeToFilename(sourceCode: string): string {
|
||||
|
||||
Reference in New Issue
Block a user