@thijshakkenberg/valkyrie-mom-mcp 2.1.0 → 2.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/.claude-plugin/plugin.json +1 -1
- package/README.md +47 -7
- package/agents/scenario-designer.md +9 -3
- package/dist/artwork/comfyui.d.ts +146 -0
- package/dist/artwork/comfyui.d.ts.map +1 -0
- package/dist/artwork/comfyui.js +214 -0
- package/dist/artwork/comfyui.js.map +1 -0
- package/dist/catalogs/extract-catalogs.js +4 -1
- package/dist/catalogs/extract-catalogs.js.map +1 -1
- package/dist/io/package-manifest.d.ts +18 -0
- package/dist/io/package-manifest.d.ts.map +1 -0
- package/dist/io/package-manifest.js +57 -0
- package/dist/io/package-manifest.js.map +1 -0
- package/dist/resources/format-docs.d.ts +1 -1
- package/dist/resources/format-docs.d.ts.map +1 -1
- package/dist/resources/format-docs.js +17 -9
- package/dist/resources/format-docs.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +96 -7
- package/dist/server.js.map +1 -1
- package/dist/story/story-graph.d.ts +55 -0
- package/dist/story/story-graph.d.ts.map +1 -0
- package/dist/story/story-graph.js +391 -0
- package/dist/story/story-graph.js.map +1 -0
- package/dist/validation/rules/custom-images.d.ts.map +1 -1
- package/dist/validation/rules/custom-images.js +24 -2
- package/dist/validation/rules/custom-images.js.map +1 -1
- package/dist/validation/rules/package-name.d.ts +9 -0
- package/dist/validation/rules/package-name.d.ts.map +1 -0
- package/dist/validation/rules/package-name.js +32 -0
- package/dist/validation/rules/package-name.js.map +1 -0
- package/dist/validation/rules/puzzles.d.ts +15 -0
- package/dist/validation/rules/puzzles.d.ts.map +1 -0
- package/dist/validation/rules/puzzles.js +76 -0
- package/dist/validation/rules/puzzles.js.map +1 -0
- package/dist/validation/validator.d.ts.map +1 -1
- package/dist/validation/validator.js +4 -0
- package/dist/validation/validator.js.map +1 -1
- package/package.json +3 -2
- package/skills/artwork/SKILL.md +120 -0
- package/skills/scenario/SKILL.md +5 -1
- package/skills/ui-and-puzzles/SKILL.md +50 -133
- package/src/artwork/comfyui.ts +289 -0
- package/src/catalogs/extract-catalogs.ts +4 -4
- package/src/io/package-manifest.ts +59 -0
- package/src/resources/format-docs.ts +17 -9
- package/src/server.ts +115 -7
- package/src/story/story-graph.ts +392 -0
- package/src/validation/rules/custom-images.ts +23 -2
- package/src/validation/rules/package-name.ts +33 -0
- package/src/validation/rules/puzzles.ts +79 -0
- package/src/validation/validator.ts +4 -0
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ MCP (Model Context Protocol) server and Claude Code plugin for AI-assisted Mansi
|
|
|
8
8
|
|
|
9
9
|
This server exposes Valkyrie scenario editing as MCP tools, enabling AI assistants (Claude, etc.) to create, modify, validate, and build complete MoM scenarios. It auto-detects the Valkyrie editor directory so scenarios appear directly in the app.
|
|
10
10
|
|
|
11
|
-
The plugin bundles
|
|
11
|
+
The plugin bundles 8 skills covering advanced patterns (event loops, mythos scaling, tile placement chains, custom puzzles, generated artwork, etc.) and an autonomous scenario designer agent.
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -21,7 +21,7 @@ claude plugin install valkyrie-mom
|
|
|
21
21
|
|
|
22
22
|
This gives you:
|
|
23
23
|
- **MCP server** with 25 tools for scenario editing (auto-started)
|
|
24
|
-
- **
|
|
24
|
+
- **8 skills**: `/scenario`, `/event-patterns`, `/tile-placement`, `/variables-and-mythos`, `/custom-monsters`, `/ui-and-puzzles`, `/items-and-distribution`, `/artwork`
|
|
25
25
|
- **Scenario designer agent** for autonomous scenario creation
|
|
26
26
|
- **5 MCP resources** for format documentation
|
|
27
27
|
|
|
@@ -53,6 +53,16 @@ Add to your MCP client config (e.g., `~/.claude/mcp.json` or Claude Desktop sett
|
|
|
53
53
|
|
|
54
54
|
This gives you the MCP tools and resources, but not the skills or agent (those require Claude Code).
|
|
55
55
|
|
|
56
|
+
### As a Hermes Agent plugin
|
|
57
|
+
|
|
58
|
+
[Hermes Agent](https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins) installs the repository as a plugin with every tool and all skills:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
hermes plugins install thijs-hakkenberg/ValkyrieMCP --enable
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The plugin registers the MCP tools as native Hermes tools (toolset `valkyrie-mom`) and the skills as `valkyrie-mom:<skill>` (e.g. `skill_view("valkyrie-mom:artwork")`). On the first tool call it starts the matching `@thijshakkenberg/valkyrie-mom-mcp` version with `npx` (Node.js 20+ required) and keeps it running for the session, since the scenario being edited lives there. Pictures that tools return, such as `render_map`, are saved under `~/.hermes/cache/valkyrie-mom/` and their paths are given in the result. For a local checkout, set `VALKYRIE_MCP_COMMAND="npx tsx /path/to/ValkyrieMCP/src/index.ts"`.
|
|
65
|
+
|
|
56
66
|
### From source
|
|
57
67
|
|
|
58
68
|
```bash
|
|
@@ -73,6 +83,7 @@ npx tsx src/index.ts # Run MCP server via stdio
|
|
|
73
83
|
| `/custom-monsters` | Custom activations, evade/horror events, round-based spawn triggering |
|
|
74
84
|
| `/ui-and-puzzles` | Prologues, interactive journals, combination locks, built-in puzzle types |
|
|
75
85
|
| `/items-and-distribution` | Random items, unique items, starting items, inspection events |
|
|
86
|
+
| `/artwork` | Generate pictures with a local ComfyUI (FLUX.2 [klein] 4B) and show them: cover, intro cutscene, handouts, scenes, monsters, tokens, image puzzles |
|
|
76
87
|
|
|
77
88
|
## MCP Tools
|
|
78
89
|
|
|
@@ -84,7 +95,8 @@ npx tsx src/index.ts # Run MCP server via stdio
|
|
|
84
95
|
| `load_scenario` | Load an existing scenario from a directory |
|
|
85
96
|
| `get_scenario_state` | Get current scenario component/localization summary |
|
|
86
97
|
| `validate_scenario` | Run all validation rules |
|
|
87
|
-
| `
|
|
98
|
+
| `save_scenario` | Write the scenario to its folder (edits stay in memory until saved or built) |
|
|
99
|
+
| `build_scenario` | Save and build the `.valkyrie` package with Valkyrie's manifest `.ini` and cover image (default: `Desktop/<Package>/`, like Valkyrie's Create Package) |
|
|
88
100
|
| `set_quest_config` | Set difficulty, play time, investigator count, cover image |
|
|
89
101
|
|
|
90
102
|
### Components
|
|
@@ -111,6 +123,29 @@ npx tsx src/index.ts # Run MCP server via stdio
|
|
|
111
123
|
| `suggest_tile_layout` | Suggest coordinates for large (7x7) tiles in linear, L-shape, or hub-spoke layouts |
|
|
112
124
|
| `place_tile_relative` | Position and rotation for a new tile against an existing one, with a door lined up |
|
|
113
125
|
|
|
126
|
+
### Story
|
|
127
|
+
| Tool | Description |
|
|
128
|
+
|------|-------------|
|
|
129
|
+
| `story_graph` | Project the storyline as a graph: a condensed text outline (buttons, conditions, effects, placed tokens, puzzles, monster events, endings, never-reached events), Mermaid, or an HTML page with the rendered flowchart |
|
|
130
|
+
|
|
131
|
+
### Artwork
|
|
132
|
+
| Tool | Description |
|
|
133
|
+
|------|-------------|
|
|
134
|
+
| `artwork_status` | Check a local ComfyUI server and the FLUX.2 [klein] 4B model files; prints comfy-cli setup and download commands for anything missing |
|
|
135
|
+
| `generate_artwork` | Generate an image (4 steps, CFG 1, size presets per use) and save it into the scenario folder, with a preview |
|
|
136
|
+
|
|
137
|
+
Artwork is optional and runs entirely on your machine. Setup with [comfy-cli](https://github.com/Comfy-Org/comfy-cli):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
pip install comfy-cli && comfy install
|
|
141
|
+
comfy model download --url https://huggingface.co/Comfy-Org/flux2-klein-4B/resolve/main/split_files/diffusion_models/flux-2-klein-4b.safetensors --relative-path models/diffusion_models
|
|
142
|
+
comfy model download --url https://huggingface.co/Comfy-Org/flux2-klein-4B/resolve/main/split_files/text_encoders/qwen_3_4b.safetensors --relative-path models/text_encoders
|
|
143
|
+
comfy model download --url https://huggingface.co/Comfy-Org/flux2-dev/resolve/main/split_files/vae/flux2-vae.safetensors --relative-path models/vae
|
|
144
|
+
comfy launch --background
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
On NVIDIA GPUs with less VRAM, the fp8 model (`black-forest-labs/FLUX.2-klein-4b-fp8`) is smaller. Set `VALKYRIE_COMFYUI_URL` if ComfyUI runs somewhere other than `http://127.0.0.1:8188`. The `/artwork` skill covers prompts and where Valkyrie shows images.
|
|
148
|
+
|
|
114
149
|
### Reference
|
|
115
150
|
| Tool | Description |
|
|
116
151
|
|------|-------------|
|
|
@@ -191,24 +226,29 @@ The server validates scenarios against 18 rule categories, checked against Valky
|
|
|
191
226
|
## Development
|
|
192
227
|
|
|
193
228
|
```bash
|
|
194
|
-
npm test
|
|
229
|
+
npm test # Run all tests
|
|
195
230
|
npm run test:watch # Watch mode
|
|
196
231
|
npm run lint # Type check
|
|
197
232
|
npm run build # Compile to dist/
|
|
233
|
+
npm run hermes:tools # Re-export the Hermes plugin tool list after changing tools or the version
|
|
198
234
|
```
|
|
199
235
|
|
|
200
236
|
## Project Structure
|
|
201
237
|
|
|
202
238
|
```
|
|
203
|
-
.claude-plugin/
|
|
204
|
-
|
|
239
|
+
.claude-plugin/ Claude Code plugin manifest
|
|
240
|
+
plugin.yaml Hermes Agent plugin manifest (+ __init__.py entry point)
|
|
241
|
+
hermes_bridge/ Hermes plugin: MCP stdio client, tool registration, exported tools.json
|
|
242
|
+
skills/ 8 skill SKILL.md files (Claude Code and Hermes)
|
|
205
243
|
agents/ Scenario designer agent
|
|
206
244
|
src/
|
|
207
245
|
io/ INI parser/writer, localization CSV, ZIP packager
|
|
208
246
|
model/ ScenarioModel, LocalizationStore, component types
|
|
209
|
-
validation/
|
|
247
|
+
validation/ Rules + orchestrator
|
|
210
248
|
rules/ Individual validation rule implementations
|
|
211
249
|
tools/ MCP tool implementations
|
|
250
|
+
story/ Storyline graph: outline, Mermaid, HTML
|
|
251
|
+
artwork/ ComfyUI (FLUX.2 [klein]) artwork generation
|
|
212
252
|
resources/ Format documentation resources
|
|
213
253
|
catalogs/ 846-entry game content catalog
|
|
214
254
|
diagnostics/ Bug report builder, session trace, ring buffer
|
|
@@ -27,6 +27,7 @@ skills:
|
|
|
27
27
|
- custom-monsters
|
|
28
28
|
- ui-and-puzzles
|
|
29
29
|
- items-and-distribution
|
|
30
|
+
- artwork
|
|
30
31
|
---
|
|
31
32
|
|
|
32
33
|
# Scenario Designer Agent
|
|
@@ -40,9 +41,11 @@ You are an autonomous Mansions of Madness 2nd Edition scenario designer. You cre
|
|
|
40
41
|
- Place tokens for exploration, searches, and encounters
|
|
41
42
|
- Configure monster spawns with appropriate difficulty scaling
|
|
42
43
|
- Build custom puzzles and UI overlays
|
|
44
|
+
- Generate scenario artwork (cover, intro, handouts) when a local ComfyUI is available (`artwork_status`)
|
|
43
45
|
- Set up mythos scaling for tension progression
|
|
44
46
|
- Write atmospheric narrative text in the Lovecraftian horror style
|
|
45
47
|
- Validate scenarios for correctness and completeness
|
|
48
|
+
- Review the storyline as a condensed event tree (`story_graph`) and explain it to the user
|
|
46
49
|
|
|
47
50
|
## Available Skills
|
|
48
51
|
|
|
@@ -54,6 +57,7 @@ Use these skills for detailed pattern guidance:
|
|
|
54
57
|
- `/custom-monsters` — Custom activations, evade/horror events, spawn triggering
|
|
55
58
|
- `/ui-and-puzzles` — Prologues, interactive journals, combination locks, built-in puzzles
|
|
56
59
|
- `/items-and-distribution` — Random items, unique items, starting items, inspection events
|
|
60
|
+
- `/artwork` — Generate pictures with ComfyUI (FLUX.2 [klein]) and show them: cover, intro cutscene, handouts, scenes, monsters, tokens, image puzzles
|
|
57
61
|
|
|
58
62
|
## Design Principles
|
|
59
63
|
|
|
@@ -93,7 +97,8 @@ Use these skills for detailed pattern guidance:
|
|
|
93
97
|
- Use `{rnd:hero}` for random hero selection, `{c:EventName}` for recall
|
|
94
98
|
|
|
95
99
|
### UI & Puzzles
|
|
96
|
-
- Always use `vunits=True` for resolution independence
|
|
100
|
+
- Always use `vunits=True` for resolution independence; positions are offsets from the screen centre
|
|
101
|
+
- A puzzle is an event started from a button (`event1=PuzzleX`); tell its story in the event before it
|
|
97
102
|
- Layering order matters: background first, buttons LAST
|
|
98
103
|
- Clean up all UI elements when dismissing overlays
|
|
99
104
|
|
|
@@ -108,8 +113,9 @@ Use these skills for detailed pattern guidance:
|
|
|
108
113
|
7. Add spawns with `upsert_spawn`
|
|
109
114
|
8. Configure items with `upsert_item`
|
|
110
115
|
9. Write all narrative with `set_localization`
|
|
111
|
-
10. Validate with `validate_scenario`
|
|
112
|
-
11.
|
|
116
|
+
10. Validate with `validate_scenario`, then read the plot back with `story_graph` (outline) to check branches, endings and never-reached events
|
|
117
|
+
11. Save with `save_scenario` (edits stay in memory until saved or built)
|
|
118
|
+
12. Build with `build_scenario`
|
|
113
119
|
|
|
114
120
|
## Available MCP Tools
|
|
115
121
|
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenario artwork through a local ComfyUI server running FLUX.2 [klein] 4B.
|
|
3
|
+
* The workflow is ComfyUI's API format; the settings are the ones the distilled
|
|
4
|
+
* model is built for (4 steps, CFG 1, euler), which take ~25 s per image on an M1 Pro
|
|
5
|
+
* once the model is loaded (the first image also loads ~15 GB of weights).
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_COMFYUI_URL: string;
|
|
8
|
+
/** Image sizes per use in a scenario (width x height, multiples of 16) */
|
|
9
|
+
export declare const ARTWORK_PRESETS: {
|
|
10
|
+
/** Scenario list picture (quest.ini image=) and the intro cutscene's left panel */
|
|
11
|
+
readonly cover: {
|
|
12
|
+
readonly width: 896;
|
|
13
|
+
readonly height: 896;
|
|
14
|
+
};
|
|
15
|
+
readonly intro: {
|
|
16
|
+
readonly width: 896;
|
|
17
|
+
readonly height: 896;
|
|
18
|
+
};
|
|
19
|
+
/** Letters, parchments, photographs, journal pages: portrait handouts shown during play */
|
|
20
|
+
readonly handout: {
|
|
21
|
+
readonly width: 768;
|
|
22
|
+
readonly height: 1024;
|
|
23
|
+
};
|
|
24
|
+
/** Landscape pictures shown during play (a room, a revelation, the ending) */
|
|
25
|
+
readonly scene: {
|
|
26
|
+
readonly width: 1024;
|
|
27
|
+
readonly height: 768;
|
|
28
|
+
};
|
|
29
|
+
/** Custom monster portrait (CustomMonster image=) */
|
|
30
|
+
readonly monster: {
|
|
31
|
+
readonly width: 768;
|
|
32
|
+
readonly height: 768;
|
|
33
|
+
};
|
|
34
|
+
/** Board token artwork (Token customImage=) */
|
|
35
|
+
readonly token: {
|
|
36
|
+
readonly width: 512;
|
|
37
|
+
readonly height: 512;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export type ArtworkPreset = keyof typeof ARTWORK_PRESETS;
|
|
41
|
+
/** Appended to every prompt unless a style is given, so a scenario's pictures look like one set */
|
|
42
|
+
export declare const DEFAULT_STYLE: string;
|
|
43
|
+
/** The three files of the FLUX.2 [klein] 4B setup and where to get them */
|
|
44
|
+
export declare const FLUX2_KLEIN_MODELS: {
|
|
45
|
+
readonly diffusion: {
|
|
46
|
+
readonly folder: "diffusion_models";
|
|
47
|
+
readonly match: RegExp;
|
|
48
|
+
readonly downloads: readonly [{
|
|
49
|
+
readonly file: "flux-2-klein-4b.safetensors";
|
|
50
|
+
readonly note: "bf16, 7.2 GB; use this on Apple Silicon (MPS has no fp8)";
|
|
51
|
+
readonly url: "https://huggingface.co/Comfy-Org/flux2-klein-4B/resolve/main/split_files/diffusion_models/flux-2-klein-4b.safetensors";
|
|
52
|
+
}, {
|
|
53
|
+
readonly file: "flux-2-klein-4b-fp8.safetensors";
|
|
54
|
+
readonly note: "fp8, ~4 GB; for NVIDIA GPUs with less VRAM";
|
|
55
|
+
readonly url: "https://huggingface.co/black-forest-labs/FLUX.2-klein-4b-fp8/resolve/main/flux-2-klein-4b-fp8.safetensors";
|
|
56
|
+
}];
|
|
57
|
+
};
|
|
58
|
+
readonly textEncoder: {
|
|
59
|
+
readonly folder: "text_encoders";
|
|
60
|
+
readonly match: RegExp;
|
|
61
|
+
readonly downloads: readonly [{
|
|
62
|
+
readonly file: "qwen_3_4b.safetensors";
|
|
63
|
+
readonly note: "7.5 GB";
|
|
64
|
+
readonly url: "https://huggingface.co/Comfy-Org/flux2-klein-4B/resolve/main/split_files/text_encoders/qwen_3_4b.safetensors";
|
|
65
|
+
}];
|
|
66
|
+
};
|
|
67
|
+
readonly vae: {
|
|
68
|
+
readonly folder: "vae";
|
|
69
|
+
readonly match: RegExp;
|
|
70
|
+
readonly downloads: readonly [{
|
|
71
|
+
readonly file: "flux2-vae.safetensors";
|
|
72
|
+
readonly note: "321 MB; FLUX.1 and SDXL VAEs give distorted colours";
|
|
73
|
+
readonly url: "https://huggingface.co/Comfy-Org/flux2-dev/resolve/main/split_files/vae/flux2-vae.safetensors";
|
|
74
|
+
}];
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export interface Flux2KleinSettings {
|
|
78
|
+
diffusionModel: string;
|
|
79
|
+
textEncoder: string;
|
|
80
|
+
vae: string;
|
|
81
|
+
prompt: string;
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
seed: number;
|
|
85
|
+
steps: number;
|
|
86
|
+
cfg: number;
|
|
87
|
+
filenamePrefix: string;
|
|
88
|
+
}
|
|
89
|
+
/** Recommended sampling for the distilled model; the undistilled "base" model needs more steps and real CFG */
|
|
90
|
+
export declare function recommendedSampling(diffusionModel: string): {
|
|
91
|
+
steps: number;
|
|
92
|
+
cfg: number;
|
|
93
|
+
};
|
|
94
|
+
/** ComfyUI API-format workflow: FLUX.2 [klein] text-to-image */
|
|
95
|
+
export declare function buildFlux2KleinWorkflow(s: Flux2KleinSettings): Record<string, unknown>;
|
|
96
|
+
type Fetch = typeof fetch;
|
|
97
|
+
export interface ArtworkStatus {
|
|
98
|
+
reachable: boolean;
|
|
99
|
+
url: string;
|
|
100
|
+
error?: string;
|
|
101
|
+
comfyuiVersion?: string;
|
|
102
|
+
device?: string;
|
|
103
|
+
models: {
|
|
104
|
+
diffusion?: string;
|
|
105
|
+
textEncoder?: string;
|
|
106
|
+
vae?: string;
|
|
107
|
+
};
|
|
108
|
+
missing: Array<keyof typeof FLUX2_KLEIN_MODELS>;
|
|
109
|
+
}
|
|
110
|
+
/** Checks the ComfyUI server and which of the FLUX.2 [klein] files it can load */
|
|
111
|
+
export declare function getArtworkStatus(url?: string, fetchFn?: Fetch): Promise<ArtworkStatus>;
|
|
112
|
+
/** Human-readable setup instructions for what getArtworkStatus found missing */
|
|
113
|
+
export declare function setupInstructions(status: ArtworkStatus): string;
|
|
114
|
+
export interface GenerateArtworkOptions {
|
|
115
|
+
prompt: string;
|
|
116
|
+
/** Where to save the image; .jpg/.jpeg saves a JPEG (much smaller in the package), otherwise PNG */
|
|
117
|
+
outputFile: string;
|
|
118
|
+
preset?: ArtworkPreset;
|
|
119
|
+
width?: number;
|
|
120
|
+
height?: number;
|
|
121
|
+
seed?: number;
|
|
122
|
+
steps?: number;
|
|
123
|
+
cfg?: number;
|
|
124
|
+
/** Replaces DEFAULT_STYLE; pass '' for no style suffix */
|
|
125
|
+
style?: string;
|
|
126
|
+
url?: string;
|
|
127
|
+
timeoutMs?: number;
|
|
128
|
+
pollMs?: number;
|
|
129
|
+
fetchFn?: Fetch;
|
|
130
|
+
}
|
|
131
|
+
export interface GenerateArtworkResult {
|
|
132
|
+
file: string;
|
|
133
|
+
width: number;
|
|
134
|
+
height: number;
|
|
135
|
+
seed: number;
|
|
136
|
+
steps: number;
|
|
137
|
+
cfg: number;
|
|
138
|
+
diffusionModel: string;
|
|
139
|
+
seconds: number;
|
|
140
|
+
/** Compact JPEG of the result, for showing the image back to the caller */
|
|
141
|
+
preview: Buffer;
|
|
142
|
+
}
|
|
143
|
+
/** Generates one image with FLUX.2 [klein] on a running ComfyUI and saves it to outputFile */
|
|
144
|
+
export declare function generateArtwork(opts: GenerateArtworkOptions): Promise<GenerateArtworkResult>;
|
|
145
|
+
export {};
|
|
146
|
+
//# sourceMappingURL=comfyui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comfyui.d.ts","sourceRoot":"","sources":["../../src/artwork/comfyui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Scenario artwork through a local ComfyUI server running FLUX.2 [klein] 4B.
|
|
5
|
+
* The workflow is ComfyUI's API format; the settings are the ones the distilled
|
|
6
|
+
* model is built for (4 steps, CFG 1, euler), which take ~25 s per image on an M1 Pro
|
|
7
|
+
* once the model is loaded (the first image also loads ~15 GB of weights).
|
|
8
|
+
*/
|
|
9
|
+
export const DEFAULT_COMFYUI_URL = process.env.VALKYRIE_COMFYUI_URL ?? 'http://127.0.0.1:8188';
|
|
10
|
+
/** Image sizes per use in a scenario (width x height, multiples of 16) */
|
|
11
|
+
export const ARTWORK_PRESETS = {
|
|
12
|
+
/** Scenario list picture (quest.ini image=) and the intro cutscene's left panel */
|
|
13
|
+
cover: { width: 896, height: 896 },
|
|
14
|
+
intro: { width: 896, height: 896 },
|
|
15
|
+
/** Letters, parchments, photographs, journal pages: portrait handouts shown during play */
|
|
16
|
+
handout: { width: 768, height: 1024 },
|
|
17
|
+
/** Landscape pictures shown during play (a room, a revelation, the ending) */
|
|
18
|
+
scene: { width: 1024, height: 768 },
|
|
19
|
+
/** Custom monster portrait (CustomMonster image=) */
|
|
20
|
+
monster: { width: 768, height: 768 },
|
|
21
|
+
/** Board token artwork (Token customImage=) */
|
|
22
|
+
token: { width: 512, height: 512 },
|
|
23
|
+
};
|
|
24
|
+
/** Appended to every prompt unless a style is given, so a scenario's pictures look like one set */
|
|
25
|
+
export const DEFAULT_STYLE = 'Dark painterly Lovecraftian horror illustration in the style of a 1920s Mansions of Madness board game card, '
|
|
26
|
+
+ 'muted desaturated palette, deep shadows, eerie atmosphere, no text, no letters, no watermark.';
|
|
27
|
+
/** The three files of the FLUX.2 [klein] 4B setup and where to get them */
|
|
28
|
+
export const FLUX2_KLEIN_MODELS = {
|
|
29
|
+
diffusion: {
|
|
30
|
+
folder: 'diffusion_models',
|
|
31
|
+
match: /flux-?2-klein-4b/i,
|
|
32
|
+
downloads: [
|
|
33
|
+
{ file: 'flux-2-klein-4b.safetensors', note: 'bf16, 7.2 GB; use this on Apple Silicon (MPS has no fp8)', url: 'https://huggingface.co/Comfy-Org/flux2-klein-4B/resolve/main/split_files/diffusion_models/flux-2-klein-4b.safetensors' },
|
|
34
|
+
{ file: 'flux-2-klein-4b-fp8.safetensors', note: 'fp8, ~4 GB; for NVIDIA GPUs with less VRAM', url: 'https://huggingface.co/black-forest-labs/FLUX.2-klein-4b-fp8/resolve/main/flux-2-klein-4b-fp8.safetensors' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
textEncoder: {
|
|
38
|
+
folder: 'text_encoders',
|
|
39
|
+
match: /qwen_?3_?4b/i,
|
|
40
|
+
downloads: [
|
|
41
|
+
{ file: 'qwen_3_4b.safetensors', note: '7.5 GB', url: 'https://huggingface.co/Comfy-Org/flux2-klein-4B/resolve/main/split_files/text_encoders/qwen_3_4b.safetensors' },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
vae: {
|
|
45
|
+
folder: 'vae',
|
|
46
|
+
match: /flux2-vae/i,
|
|
47
|
+
downloads: [
|
|
48
|
+
{ file: 'flux2-vae.safetensors', note: '321 MB; FLUX.1 and SDXL VAEs give distorted colours', url: 'https://huggingface.co/Comfy-Org/flux2-dev/resolve/main/split_files/vae/flux2-vae.safetensors' },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
/** Recommended sampling for the distilled model; the undistilled "base" model needs more steps and real CFG */
|
|
53
|
+
export function recommendedSampling(diffusionModel) {
|
|
54
|
+
return /base/i.test(diffusionModel) ? { steps: 20, cfg: 4 } : { steps: 4, cfg: 1 };
|
|
55
|
+
}
|
|
56
|
+
/** ComfyUI API-format workflow: FLUX.2 [klein] text-to-image */
|
|
57
|
+
export function buildFlux2KleinWorkflow(s) {
|
|
58
|
+
return {
|
|
59
|
+
'1': { class_type: 'UNETLoader', inputs: { unet_name: s.diffusionModel, weight_dtype: 'default' } },
|
|
60
|
+
'2': { class_type: 'CLIPLoader', inputs: { clip_name: s.textEncoder, type: 'flux2' } },
|
|
61
|
+
'3': { class_type: 'VAELoader', inputs: { vae_name: s.vae } },
|
|
62
|
+
'4': { class_type: 'CLIPTextEncode', inputs: { clip: ['2', 0], text: s.prompt } },
|
|
63
|
+
'5': { class_type: 'ConditioningZeroOut', inputs: { conditioning: ['4', 0] } },
|
|
64
|
+
'6': { class_type: 'EmptyFlux2LatentImage', inputs: { width: s.width, height: s.height, batch_size: 1 } },
|
|
65
|
+
'7': { class_type: 'Flux2Scheduler', inputs: { steps: s.steps, width: s.width, height: s.height } },
|
|
66
|
+
'8': { class_type: 'KSamplerSelect', inputs: { sampler_name: 'euler' } },
|
|
67
|
+
'9': { class_type: 'RandomNoise', inputs: { noise_seed: s.seed } },
|
|
68
|
+
'10': { class_type: 'CFGGuider', inputs: { model: ['1', 0], positive: ['4', 0], negative: ['5', 0], cfg: s.cfg } },
|
|
69
|
+
'11': { class_type: 'SamplerCustomAdvanced', inputs: { noise: ['9', 0], guider: ['10', 0], sampler: ['8', 0], sigmas: ['7', 0], latent_image: ['6', 0] } },
|
|
70
|
+
'12': { class_type: 'VAEDecode', inputs: { samples: ['11', 0], vae: ['3', 0] } },
|
|
71
|
+
'13': { class_type: 'SaveImage', inputs: { images: ['12', 0], filename_prefix: s.filenamePrefix } },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function getJson(fetchFn, url) {
|
|
75
|
+
const res = await fetchFn(url, { signal: AbortSignal.timeout(10_000) });
|
|
76
|
+
if (!res.ok)
|
|
77
|
+
throw new Error(`${url} answered ${res.status}`);
|
|
78
|
+
return res.json();
|
|
79
|
+
}
|
|
80
|
+
/** Picks the preferred file: the distilled model over "base", then the first match */
|
|
81
|
+
function pickModel(files, match) {
|
|
82
|
+
const candidates = files.filter(f => match.test(f));
|
|
83
|
+
return candidates.find(f => !/base/i.test(f)) ?? candidates[0];
|
|
84
|
+
}
|
|
85
|
+
/** Checks the ComfyUI server and which of the FLUX.2 [klein] files it can load */
|
|
86
|
+
export async function getArtworkStatus(url = DEFAULT_COMFYUI_URL, fetchFn = fetch) {
|
|
87
|
+
const status = { reachable: false, url, models: {}, missing: [] };
|
|
88
|
+
try {
|
|
89
|
+
const stats = await getJson(fetchFn, `${url}/system_stats`);
|
|
90
|
+
status.reachable = true;
|
|
91
|
+
status.comfyuiVersion = stats.system?.comfyui_version;
|
|
92
|
+
status.device = stats.devices?.[0]?.name;
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
status.error = e.message;
|
|
96
|
+
status.missing = ['diffusion', 'textEncoder', 'vae'];
|
|
97
|
+
return status;
|
|
98
|
+
}
|
|
99
|
+
for (const key of ['diffusion', 'textEncoder', 'vae']) {
|
|
100
|
+
const spec = FLUX2_KLEIN_MODELS[key];
|
|
101
|
+
let files = [];
|
|
102
|
+
try {
|
|
103
|
+
files = await getJson(fetchFn, `${url}/models/${spec.folder}`);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Older ComfyUI without /models/<folder>: treat as missing so the setup hint is shown
|
|
107
|
+
}
|
|
108
|
+
const found = pickModel(files, spec.match);
|
|
109
|
+
if (found)
|
|
110
|
+
status.models[key] = found;
|
|
111
|
+
else
|
|
112
|
+
status.missing.push(key);
|
|
113
|
+
}
|
|
114
|
+
return status;
|
|
115
|
+
}
|
|
116
|
+
/** Human-readable setup instructions for what getArtworkStatus found missing */
|
|
117
|
+
export function setupInstructions(status) {
|
|
118
|
+
const lines = [];
|
|
119
|
+
if (!status.reachable) {
|
|
120
|
+
lines.push(`ComfyUI is not reachable at ${status.url}${status.error ? ` (${status.error})` : ''}. With comfy-cli:`, ' pip install comfy-cli (or: uv tool install comfy-cli)', ' comfy install (once; installs ComfyUI into a workspace)', ' comfy launch --background', 'Models kept elsewhere: comfy launch --background -- --extra-model-paths-config <yaml listing diffusion_models, text_encoders, vae>.', 'Set VALKYRIE_COMFYUI_URL if ComfyUI runs on another address.');
|
|
121
|
+
}
|
|
122
|
+
for (const key of status.missing) {
|
|
123
|
+
const spec = FLUX2_KLEIN_MODELS[key];
|
|
124
|
+
lines.push(`Missing ${spec.folder} model. Download one of:`);
|
|
125
|
+
for (const d of spec.downloads) {
|
|
126
|
+
lines.push(` ${d.file} (${d.note}):`, ` comfy model download --url ${d.url} --relative-path models/${spec.folder}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return lines.join('\n');
|
|
130
|
+
}
|
|
131
|
+
function roundTo16(n) {
|
|
132
|
+
return Math.max(256, Math.round(n / 16) * 16);
|
|
133
|
+
}
|
|
134
|
+
/** Generates one image with FLUX.2 [klein] on a running ComfyUI and saves it to outputFile */
|
|
135
|
+
export async function generateArtwork(opts) {
|
|
136
|
+
const url = opts.url ?? DEFAULT_COMFYUI_URL;
|
|
137
|
+
const fetchFn = opts.fetchFn ?? fetch;
|
|
138
|
+
const status = await getArtworkStatus(url, fetchFn);
|
|
139
|
+
if (!status.reachable || status.missing.length > 0) {
|
|
140
|
+
throw new Error(`ComfyUI is not ready for FLUX.2 [klein].\n${setupInstructions(status)}`);
|
|
141
|
+
}
|
|
142
|
+
const diffusionModel = status.models.diffusion;
|
|
143
|
+
const size = ARTWORK_PRESETS[opts.preset ?? 'scene'];
|
|
144
|
+
const width = roundTo16(opts.width ?? size.width);
|
|
145
|
+
const height = roundTo16(opts.height ?? size.height);
|
|
146
|
+
const sampling = recommendedSampling(diffusionModel);
|
|
147
|
+
const style = opts.style ?? DEFAULT_STYLE;
|
|
148
|
+
const settings = {
|
|
149
|
+
diffusionModel,
|
|
150
|
+
textEncoder: status.models.textEncoder,
|
|
151
|
+
vae: status.models.vae,
|
|
152
|
+
prompt: style ? `${opts.prompt.trim()} ${style}` : opts.prompt.trim(),
|
|
153
|
+
width,
|
|
154
|
+
height,
|
|
155
|
+
seed: opts.seed ?? Math.floor(Math.random() * 2 ** 32),
|
|
156
|
+
steps: opts.steps ?? sampling.steps,
|
|
157
|
+
cfg: opts.cfg ?? sampling.cfg,
|
|
158
|
+
filenamePrefix: `valkyrie_${path.basename(opts.outputFile, path.extname(opts.outputFile)).replace(/[^\w-]/g, '_')}`,
|
|
159
|
+
};
|
|
160
|
+
const started = Date.now();
|
|
161
|
+
const submit = await fetchFn(`${url}/prompt`, {
|
|
162
|
+
method: 'POST',
|
|
163
|
+
headers: { 'Content-Type': 'application/json' },
|
|
164
|
+
body: JSON.stringify({ prompt: buildFlux2KleinWorkflow(settings) }),
|
|
165
|
+
signal: AbortSignal.timeout(30_000),
|
|
166
|
+
});
|
|
167
|
+
const submitted = await submit.json();
|
|
168
|
+
if (!submit.ok || !submitted.prompt_id) {
|
|
169
|
+
throw new Error(`ComfyUI rejected the workflow: ${submitted.error?.message ?? submit.status} ${JSON.stringify(submitted.node_errors ?? {})}`);
|
|
170
|
+
}
|
|
171
|
+
// The first image of a session also loads the models, which can take minutes
|
|
172
|
+
const timeoutMs = opts.timeoutMs ?? 15 * 60_000;
|
|
173
|
+
const pollMs = opts.pollMs ?? 2000;
|
|
174
|
+
let image;
|
|
175
|
+
while (!image) {
|
|
176
|
+
if (Date.now() - started > timeoutMs)
|
|
177
|
+
throw new Error(`ComfyUI did not finish within ${Math.round(timeoutMs / 1000)} s (prompt ${submitted.prompt_id})`);
|
|
178
|
+
await new Promise(r => setTimeout(r, pollMs));
|
|
179
|
+
const history = await getJson(fetchFn, `${url}/history/${submitted.prompt_id}`);
|
|
180
|
+
const entry = history[submitted.prompt_id];
|
|
181
|
+
if (!entry)
|
|
182
|
+
continue;
|
|
183
|
+
if (entry.status?.status_str === 'error') {
|
|
184
|
+
throw new Error(`ComfyUI failed: ${JSON.stringify(entry.status.messages ?? []).slice(0, 1000)}`);
|
|
185
|
+
}
|
|
186
|
+
image = Object.values(entry.outputs ?? {}).flatMap(o => o.images ?? [])[0];
|
|
187
|
+
if (!image && entry.status?.status_str === 'success')
|
|
188
|
+
throw new Error('ComfyUI finished without an image');
|
|
189
|
+
}
|
|
190
|
+
const view = (extra = '') => `${url}/view?filename=${encodeURIComponent(image.filename)}&subfolder=${encodeURIComponent(image.subfolder)}&type=${image.type}${extra}`;
|
|
191
|
+
const download = async (u) => {
|
|
192
|
+
const res = await fetchFn(u, { signal: AbortSignal.timeout(60_000) });
|
|
193
|
+
if (!res.ok)
|
|
194
|
+
throw new Error(`Could not download the image from ComfyUI (${res.status})`);
|
|
195
|
+
return Buffer.from(await res.arrayBuffer());
|
|
196
|
+
};
|
|
197
|
+
const jpeg = /\.jpe?g$/i.test(opts.outputFile);
|
|
198
|
+
const full = await download(view(jpeg ? '&preview=jpeg;90' : ''));
|
|
199
|
+
const preview = jpeg ? full : await download(view('&preview=jpeg;80'));
|
|
200
|
+
fs.mkdirSync(path.dirname(opts.outputFile), { recursive: true });
|
|
201
|
+
fs.writeFileSync(opts.outputFile, full);
|
|
202
|
+
return {
|
|
203
|
+
file: opts.outputFile,
|
|
204
|
+
width,
|
|
205
|
+
height,
|
|
206
|
+
seed: settings.seed,
|
|
207
|
+
steps: settings.steps,
|
|
208
|
+
cfg: settings.cfg,
|
|
209
|
+
diffusionModel,
|
|
210
|
+
seconds: Math.round((Date.now() - started) / 1000),
|
|
211
|
+
preview,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=comfyui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comfyui.js","sourceRoot":"","sources":["../../src/artwork/comfyui.ts"],"names":[],"mappings":"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"}
|
|
@@ -105,7 +105,10 @@ function generateCatalogSource(catalogs) {
|
|
|
105
105
|
const isMainModule = process.argv[1] && (process.argv[1].endsWith('extract-catalogs.ts') ||
|
|
106
106
|
process.argv[1].endsWith('extract-catalogs.js'));
|
|
107
107
|
if (isMainModule) {
|
|
108
|
-
|
|
108
|
+
// The Valkyrie source checkout, by default next to this repository
|
|
109
|
+
const valkyrieRepo = process.env.VALKYRIE_SOURCE_DIR
|
|
110
|
+
?? path.join(path.dirname(path.dirname(path.dirname(import.meta.dirname ?? '.'))), 'valkyrie');
|
|
111
|
+
const valkyrieContentDir = path.join(valkyrieRepo, 'unity', 'Assets', 'StreamingAssets', 'content', 'MoM');
|
|
109
112
|
if (!fs.existsSync(valkyrieContentDir)) {
|
|
110
113
|
console.error(`Valkyrie content not found at: ${valkyrieContentDir}`);
|
|
111
114
|
console.error('Make sure the Valkyrie repo is cloned at the expected path.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-catalogs.js","sourceRoot":"","sources":["../../src/catalogs/extract-catalogs.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"extract-catalogs.js","sourceRoot":"","sources":["../../src/catalogs/extract-catalogs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ScenarioModel } from '../model/scenario-model.js';
|
|
2
|
+
/**
|
|
3
|
+
* Package name Valkyrie can publish: the scenario folder name, which must not contain spaces
|
|
4
|
+
* (it becomes the package and manifest file name, and the key in the download list).
|
|
5
|
+
* "The Wrath of Elder Claude" → "TheWrathOfElderClaude".
|
|
6
|
+
*/
|
|
7
|
+
export declare function toPackageName(name: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Writes what Valkyrie's editor "Create Package" writes next to the .valkyrie file
|
|
10
|
+
* (EditorTools.CreatePackage): <Package>.ini, the manifest a scenario list entry is made from,
|
|
11
|
+
* and a copy of the cover image. version is the SHA-256 of the package, as .NET's
|
|
12
|
+
* BitConverter.ToString prints it ("AB-CD-...").
|
|
13
|
+
*/
|
|
14
|
+
export declare function writePackageManifest(model: ScenarioModel, packagePath: string): {
|
|
15
|
+
manifest: string;
|
|
16
|
+
icon?: string;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=package-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manifest.d.ts","sourceRoot":"","sources":["../../src/io/package-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAoCnH"}
|