run-dmcp 0.1.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/LICENSE +22 -0
- package/README.md +79 -0
- package/dist/__tests__/engineVocabulary.test.d.ts +1 -0
- package/dist/__tests__/engineVocabulary.test.js +147 -0
- package/dist/db/__tests__/connection.test.d.ts +1 -0
- package/dist/db/__tests__/connection.test.js +72 -0
- package/dist/db/__tests__/testDb.d.ts +33 -0
- package/dist/db/__tests__/testDb.js +41 -0
- package/dist/db/connection.d.ts +22 -0
- package/dist/db/connection.js +107 -0
- package/dist/db/schema.d.ts +1 -0
- package/dist/db/schema.js +725 -0
- package/dist/events/emitter.d.ts +22 -0
- package/dist/events/emitter.js +71 -0
- package/dist/http/server.d.ts +3 -0
- package/dist/http/server.js +649 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +92 -0
- package/dist/register/abilities.d.ts +2 -0
- package/dist/register/abilities.js +165 -0
- package/dist/register/audio.d.ts +2 -0
- package/dist/register/audio.js +326 -0
- package/dist/register/batch.d.ts +2 -0
- package/dist/register/batch.js +343 -0
- package/dist/register/character.d.ts +2 -0
- package/dist/register/character.js +324 -0
- package/dist/register/combat.d.ts +2 -0
- package/dist/register/combat.js +207 -0
- package/dist/register/core.d.ts +2 -0
- package/dist/register/core.js +1040 -0
- package/dist/register/display.d.ts +2 -0
- package/dist/register/display.js +263 -0
- package/dist/register/factions.d.ts +2 -0
- package/dist/register/factions.js +186 -0
- package/dist/register/images.d.ts +2 -0
- package/dist/register/images.js +400 -0
- package/dist/register/inventory.d.ts +2 -0
- package/dist/register/inventory.js +115 -0
- package/dist/register/mcp-prompts.d.ts +2 -0
- package/dist/register/mcp-prompts.js +684 -0
- package/dist/register/mcp-resources.d.ts +2 -0
- package/dist/register/mcp-resources.js +335 -0
- package/dist/register/narrative.d.ts +2 -0
- package/dist/register/narrative.js +242 -0
- package/dist/register/notes.d.ts +2 -0
- package/dist/register/notes.js +170 -0
- package/dist/register/pause.d.ts +2 -0
- package/dist/register/pause.js +580 -0
- package/dist/register/quests.d.ts +2 -0
- package/dist/register/quests.js +118 -0
- package/dist/register/relationships.d.ts +2 -0
- package/dist/register/relationships.js +147 -0
- package/dist/register/resources.d.ts +2 -0
- package/dist/register/resources.js +277 -0
- package/dist/register/secrets.d.ts +2 -0
- package/dist/register/secrets.js +192 -0
- package/dist/register/status.d.ts +2 -0
- package/dist/register/status.js +130 -0
- package/dist/register/tables.d.ts +2 -0
- package/dist/register/tables.js +146 -0
- package/dist/register/tags.d.ts +2 -0
- package/dist/register/tags.js +114 -0
- package/dist/register/time.d.ts +2 -0
- package/dist/register/time.js +281 -0
- package/dist/register/world.d.ts +2 -0
- package/dist/register/world.js +127 -0
- package/dist/schemas/index.d.ts +921 -0
- package/dist/schemas/index.js +121 -0
- package/dist/test-setup.d.ts +1 -0
- package/dist/test-setup.js +13 -0
- package/dist/tools/__tests__/audio.test.d.ts +1 -0
- package/dist/tools/__tests__/audio.test.js +59 -0
- package/dist/tools/__tests__/conserved.test.d.ts +1 -0
- package/dist/tools/__tests__/conserved.test.js +488 -0
- package/dist/tools/__tests__/constraint.test.d.ts +1 -0
- package/dist/tools/__tests__/constraint.test.js +212 -0
- package/dist/tools/__tests__/expiry-consequences.test.d.ts +1 -0
- package/dist/tools/__tests__/expiry-consequences.test.js +110 -0
- package/dist/tools/__tests__/images.test.d.ts +1 -0
- package/dist/tools/__tests__/images.test.js +59 -0
- package/dist/tools/__tests__/relationship.test.d.ts +1 -0
- package/dist/tools/__tests__/relationship.test.js +132 -0
- package/dist/tools/__tests__/resource-constraints.test.d.ts +1 -0
- package/dist/tools/__tests__/resource-constraints.test.js +131 -0
- package/dist/tools/__tests__/resource.test.d.ts +1 -0
- package/dist/tools/__tests__/resource.test.js +190 -0
- package/dist/tools/__tests__/time.test.d.ts +1 -0
- package/dist/tools/__tests__/time.test.js +404 -0
- package/dist/tools/__tests__/timers.test.d.ts +1 -0
- package/dist/tools/__tests__/timers.test.js +426 -0
- package/dist/tools/__tests__/world.test.d.ts +1 -0
- package/dist/tools/__tests__/world.test.js +70 -0
- package/dist/tools/ability.d.ts +48 -0
- package/dist/tools/ability.js +238 -0
- package/dist/tools/audio.d.ts +24 -0
- package/dist/tools/audio.js +365 -0
- package/dist/tools/character.d.ts +70 -0
- package/dist/tools/character.js +309 -0
- package/dist/tools/combat.d.ts +13 -0
- package/dist/tools/combat.js +195 -0
- package/dist/tools/constraint.d.ts +132 -0
- package/dist/tools/constraint.js +269 -0
- package/dist/tools/dice.d.ts +23 -0
- package/dist/tools/dice.js +111 -0
- package/dist/tools/display.d.ts +120 -0
- package/dist/tools/display.js +528 -0
- package/dist/tools/faction.d.ts +61 -0
- package/dist/tools/faction.js +269 -0
- package/dist/tools/game.d.ts +96 -0
- package/dist/tools/game.js +526 -0
- package/dist/tools/image-prompt.d.ts +49 -0
- package/dist/tools/image-prompt.js +479 -0
- package/dist/tools/images.d.ts +47 -0
- package/dist/tools/images.js +449 -0
- package/dist/tools/inventory.d.ts +20 -0
- package/dist/tools/inventory.js +145 -0
- package/dist/tools/narrative.d.ts +58 -0
- package/dist/tools/narrative.js +237 -0
- package/dist/tools/notes.d.ts +41 -0
- package/dist/tools/notes.js +220 -0
- package/dist/tools/pause.d.ts +110 -0
- package/dist/tools/pause.js +1254 -0
- package/dist/tools/quest.d.ts +34 -0
- package/dist/tools/quest.js +164 -0
- package/dist/tools/relationship.d.ts +74 -0
- package/dist/tools/relationship.js +324 -0
- package/dist/tools/resource.d.ts +93 -0
- package/dist/tools/resource.js +374 -0
- package/dist/tools/rules.d.ts +4 -0
- package/dist/tools/rules.js +30 -0
- package/dist/tools/secrets.d.ts +49 -0
- package/dist/tools/secrets.js +195 -0
- package/dist/tools/status.d.ts +36 -0
- package/dist/tools/status.js +218 -0
- package/dist/tools/tables.d.ts +33 -0
- package/dist/tools/tables.js +209 -0
- package/dist/tools/tags.d.ts +52 -0
- package/dist/tools/tags.js +176 -0
- package/dist/tools/time.d.ts +33 -0
- package/dist/tools/time.js +276 -0
- package/dist/tools/timers.d.ts +41 -0
- package/dist/tools/timers.js +215 -0
- package/dist/tools/world.d.ts +78 -0
- package/dist/tools/world.js +331 -0
- package/dist/types/index.d.ts +969 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/__tests__/json.test.d.ts +1 -0
- package/dist/utils/__tests__/json.test.js +55 -0
- package/dist/utils/__tests__/validation.test.d.ts +1 -0
- package/dist/utils/__tests__/validation.test.js +90 -0
- package/dist/utils/errors.d.ts +44 -0
- package/dist/utils/errors.js +121 -0
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.js +23 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/output-schemas.d.ts +594 -0
- package/dist/utils/output-schemas.js +331 -0
- package/dist/utils/tool-annotations.d.ts +147 -0
- package/dist/utils/tool-annotations.js +98 -0
- package/dist/utils/validation.d.ts +34 -0
- package/dist/utils/validation.js +52 -0
- package/dist/utils/verbosity.d.ts +57 -0
- package/dist/utils/verbosity.js +67 -0
- package/dist/utils/webui.d.ts +20 -0
- package/dist/utils/webui.js +35 -0
- package/package.json +75 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import { getDatabase } from "../db/connection.js";
|
|
2
|
+
const defaultConfig = {
|
|
3
|
+
// Colors - neutral paper theme
|
|
4
|
+
bgColor: "#f5f3ef",
|
|
5
|
+
bgSecondary: "#ebe8e2",
|
|
6
|
+
bgElevated: "#ffffff",
|
|
7
|
+
textColor: "#2a2a2a",
|
|
8
|
+
textMuted: "#6b6b6b",
|
|
9
|
+
accentColor: "#4a5568",
|
|
10
|
+
accentHover: "#2d3748",
|
|
11
|
+
borderColor: "#d4d0c8",
|
|
12
|
+
successColor: "#2f855a",
|
|
13
|
+
warningColor: "#b7791f",
|
|
14
|
+
dangerColor: "#c53030",
|
|
15
|
+
// Code block colors
|
|
16
|
+
codeBackground: "#e8e5df",
|
|
17
|
+
codeText: "#4a4a4a",
|
|
18
|
+
// Visual style
|
|
19
|
+
borderRadius: "rounded",
|
|
20
|
+
cardStyle: "clean",
|
|
21
|
+
// Fonts
|
|
22
|
+
fontDisplay: "Libre Baskerville",
|
|
23
|
+
fontBody: "Source Sans Pro",
|
|
24
|
+
fontMono: "IBM Plex Mono",
|
|
25
|
+
// Display options
|
|
26
|
+
showHealthBars: true,
|
|
27
|
+
showConditionTags: true,
|
|
28
|
+
showImages: true,
|
|
29
|
+
// Title
|
|
30
|
+
appTitle: "DMCP Game Viewer",
|
|
31
|
+
};
|
|
32
|
+
// Preset themes for different game genres
|
|
33
|
+
// Each preset provides a complete visual identity appropriate for the genre
|
|
34
|
+
export const themePresets = {
|
|
35
|
+
// Classic medieval fantasy with gold accents and parchment feel
|
|
36
|
+
"high-fantasy": {
|
|
37
|
+
bgColor: "#1a1610",
|
|
38
|
+
bgSecondary: "#252015",
|
|
39
|
+
bgElevated: "#302a1f",
|
|
40
|
+
textColor: "#f5e6c8",
|
|
41
|
+
textMuted: "#a09070",
|
|
42
|
+
accentColor: "#daa520",
|
|
43
|
+
accentHover: "#ffd700",
|
|
44
|
+
borderColor: "#4a4030",
|
|
45
|
+
successColor: "#6b8e23",
|
|
46
|
+
warningColor: "#cd853f",
|
|
47
|
+
dangerColor: "#8b0000",
|
|
48
|
+
codeBackground: "#151208",
|
|
49
|
+
codeText: "#c0b090",
|
|
50
|
+
borderRadius: "rounded",
|
|
51
|
+
cardStyle: "parchment",
|
|
52
|
+
fontDisplay: "Cinzel",
|
|
53
|
+
fontBody: "Lora",
|
|
54
|
+
fontMono: "Fira Code",
|
|
55
|
+
appTitle: "High Fantasy Adventures",
|
|
56
|
+
},
|
|
57
|
+
// Dark, gritty fantasy with purple/blood red tones
|
|
58
|
+
"dark-fantasy": {
|
|
59
|
+
bgColor: "#0d0a10",
|
|
60
|
+
bgSecondary: "#15101a",
|
|
61
|
+
bgElevated: "#201825",
|
|
62
|
+
textColor: "#d0c8d8",
|
|
63
|
+
textMuted: "#706878",
|
|
64
|
+
accentColor: "#9d174d",
|
|
65
|
+
accentHover: "#be185d",
|
|
66
|
+
borderColor: "#3d2848",
|
|
67
|
+
successColor: "#4a5568",
|
|
68
|
+
warningColor: "#92400e",
|
|
69
|
+
dangerColor: "#991b1b",
|
|
70
|
+
codeBackground: "#08050a",
|
|
71
|
+
codeText: "#8b7090",
|
|
72
|
+
borderRadius: "sharp",
|
|
73
|
+
cardStyle: "grungy",
|
|
74
|
+
fontDisplay: "Uncial Antiqua",
|
|
75
|
+
fontBody: "Crimson Text",
|
|
76
|
+
fontMono: "Fira Code",
|
|
77
|
+
appTitle: "Dark Fantasy Campaign",
|
|
78
|
+
},
|
|
79
|
+
// Futuristic sci-fi with cyan/chrome aesthetic
|
|
80
|
+
"sci-fi": {
|
|
81
|
+
bgColor: "#050810",
|
|
82
|
+
bgSecondary: "#0a1020",
|
|
83
|
+
bgElevated: "#101830",
|
|
84
|
+
textColor: "#e0e8f0",
|
|
85
|
+
textMuted: "#6080a0",
|
|
86
|
+
accentColor: "#06b6d4",
|
|
87
|
+
accentHover: "#22d3ee",
|
|
88
|
+
borderColor: "#1e3a5f",
|
|
89
|
+
successColor: "#10b981",
|
|
90
|
+
warningColor: "#f59e0b",
|
|
91
|
+
dangerColor: "#ef4444",
|
|
92
|
+
codeBackground: "#020508",
|
|
93
|
+
codeText: "#4ecdc4",
|
|
94
|
+
borderRadius: "sharp",
|
|
95
|
+
cardStyle: "tech",
|
|
96
|
+
fontDisplay: "Orbitron",
|
|
97
|
+
fontBody: "Exo 2",
|
|
98
|
+
fontMono: "Share Tech Mono",
|
|
99
|
+
appTitle: "Sci-Fi Chronicles",
|
|
100
|
+
},
|
|
101
|
+
// Neon-drenched cyberpunk with pink/yellow highlights
|
|
102
|
+
cyberpunk: {
|
|
103
|
+
bgColor: "#0a0a0f",
|
|
104
|
+
bgSecondary: "#121218",
|
|
105
|
+
bgElevated: "#1a1a24",
|
|
106
|
+
textColor: "#e0e0e8",
|
|
107
|
+
textMuted: "#6b6b80",
|
|
108
|
+
accentColor: "#f72585",
|
|
109
|
+
accentHover: "#ff4d9d",
|
|
110
|
+
borderColor: "#2d2d40",
|
|
111
|
+
successColor: "#39ff14",
|
|
112
|
+
warningColor: "#ffee00",
|
|
113
|
+
dangerColor: "#ff0055",
|
|
114
|
+
codeBackground: "#050508",
|
|
115
|
+
codeText: "#00ffff",
|
|
116
|
+
borderRadius: "sharp",
|
|
117
|
+
cardStyle: "tech",
|
|
118
|
+
fontDisplay: "Orbitron",
|
|
119
|
+
fontBody: "Share Tech",
|
|
120
|
+
fontMono: "Fira Code",
|
|
121
|
+
appTitle: "Cyberpunk Chronicles",
|
|
122
|
+
},
|
|
123
|
+
// Wild west with tan/rust/leather tones
|
|
124
|
+
western: {
|
|
125
|
+
bgColor: "#1a1510",
|
|
126
|
+
bgSecondary: "#252018",
|
|
127
|
+
bgElevated: "#302820",
|
|
128
|
+
textColor: "#e8dcc8",
|
|
129
|
+
textMuted: "#a09080",
|
|
130
|
+
accentColor: "#b45309",
|
|
131
|
+
accentHover: "#d97706",
|
|
132
|
+
borderColor: "#4a3828",
|
|
133
|
+
successColor: "#65a30d",
|
|
134
|
+
warningColor: "#ca8a04",
|
|
135
|
+
dangerColor: "#b91c1c",
|
|
136
|
+
codeBackground: "#100c08",
|
|
137
|
+
codeText: "#9a8060",
|
|
138
|
+
borderRadius: "soft",
|
|
139
|
+
cardStyle: "wooden",
|
|
140
|
+
fontDisplay: "Rye",
|
|
141
|
+
fontBody: "Bitter",
|
|
142
|
+
fontMono: "Courier Prime",
|
|
143
|
+
appTitle: "Wild West Adventures",
|
|
144
|
+
},
|
|
145
|
+
// Black and white noir with red accents
|
|
146
|
+
noir: {
|
|
147
|
+
bgColor: "#0a0a0a",
|
|
148
|
+
bgSecondary: "#141414",
|
|
149
|
+
bgElevated: "#1e1e1e",
|
|
150
|
+
textColor: "#e0e0e0",
|
|
151
|
+
textMuted: "#707070",
|
|
152
|
+
accentColor: "#dc2626",
|
|
153
|
+
accentHover: "#ef4444",
|
|
154
|
+
borderColor: "#333333",
|
|
155
|
+
successColor: "#6b7280",
|
|
156
|
+
warningColor: "#9ca3af",
|
|
157
|
+
dangerColor: "#b91c1c",
|
|
158
|
+
codeBackground: "#050505",
|
|
159
|
+
codeText: "#808080",
|
|
160
|
+
borderRadius: "sharp",
|
|
161
|
+
cardStyle: "clean",
|
|
162
|
+
fontDisplay: "Playfair Display",
|
|
163
|
+
fontBody: "Source Serif Pro",
|
|
164
|
+
fontMono: "IBM Plex Mono",
|
|
165
|
+
appTitle: "Noir Detective Story",
|
|
166
|
+
},
|
|
167
|
+
// Eldritch cosmic horror with deep purple/green void colors
|
|
168
|
+
"cosmic-horror": {
|
|
169
|
+
bgColor: "#08060d",
|
|
170
|
+
bgSecondary: "#100d18",
|
|
171
|
+
bgElevated: "#181324",
|
|
172
|
+
textColor: "#c8c0d8",
|
|
173
|
+
textMuted: "#605870",
|
|
174
|
+
accentColor: "#7c3aed",
|
|
175
|
+
accentHover: "#8b5cf6",
|
|
176
|
+
borderColor: "#2d2840",
|
|
177
|
+
successColor: "#4b5563",
|
|
178
|
+
warningColor: "#78716c",
|
|
179
|
+
dangerColor: "#7f1d1d",
|
|
180
|
+
codeBackground: "#040308",
|
|
181
|
+
codeText: "#6b21a8",
|
|
182
|
+
borderRadius: "soft",
|
|
183
|
+
cardStyle: "grungy",
|
|
184
|
+
fontDisplay: "Special Elite",
|
|
185
|
+
fontBody: "Alegreya",
|
|
186
|
+
fontMono: "Fira Code",
|
|
187
|
+
appTitle: "Cosmic Horror Campaign",
|
|
188
|
+
},
|
|
189
|
+
// Victorian steampunk with brass/copper/sepia tones
|
|
190
|
+
steampunk: {
|
|
191
|
+
bgColor: "#1a1512",
|
|
192
|
+
bgSecondary: "#251f18",
|
|
193
|
+
bgElevated: "#302820",
|
|
194
|
+
textColor: "#e0d0b8",
|
|
195
|
+
textMuted: "#908068",
|
|
196
|
+
accentColor: "#b87333",
|
|
197
|
+
accentHover: "#cd853f",
|
|
198
|
+
borderColor: "#4a3c2c",
|
|
199
|
+
successColor: "#6b8e23",
|
|
200
|
+
warningColor: "#b8860b",
|
|
201
|
+
dangerColor: "#8b4513",
|
|
202
|
+
codeBackground: "#100c08",
|
|
203
|
+
codeText: "#b87333",
|
|
204
|
+
borderRadius: "rounded",
|
|
205
|
+
cardStyle: "metallic",
|
|
206
|
+
fontDisplay: "IM Fell English SC",
|
|
207
|
+
fontBody: "IM Fell English",
|
|
208
|
+
fontMono: "Courier Prime",
|
|
209
|
+
appTitle: "Steampunk Adventures",
|
|
210
|
+
},
|
|
211
|
+
// Post-apocalyptic wasteland with grey/rust/warning colors
|
|
212
|
+
"post-apocalyptic": {
|
|
213
|
+
bgColor: "#12100e",
|
|
214
|
+
bgSecondary: "#1a1815",
|
|
215
|
+
bgElevated: "#24201c",
|
|
216
|
+
textColor: "#c8c0b0",
|
|
217
|
+
textMuted: "#787068",
|
|
218
|
+
accentColor: "#ea580c",
|
|
219
|
+
accentHover: "#f97316",
|
|
220
|
+
borderColor: "#3a3428",
|
|
221
|
+
successColor: "#65a30d",
|
|
222
|
+
warningColor: "#eab308",
|
|
223
|
+
dangerColor: "#dc2626",
|
|
224
|
+
codeBackground: "#0a0908",
|
|
225
|
+
codeText: "#808070",
|
|
226
|
+
borderRadius: "sharp",
|
|
227
|
+
cardStyle: "grungy",
|
|
228
|
+
fontDisplay: "Bangers",
|
|
229
|
+
fontBody: "Oswald",
|
|
230
|
+
fontMono: "Share Tech Mono",
|
|
231
|
+
appTitle: "Wasteland Chronicles",
|
|
232
|
+
},
|
|
233
|
+
// Pirate/nautical theme with ocean blue/gold/wood
|
|
234
|
+
pirate: {
|
|
235
|
+
bgColor: "#0d1418",
|
|
236
|
+
bgSecondary: "#141e24",
|
|
237
|
+
bgElevated: "#1c2830",
|
|
238
|
+
textColor: "#e0dcd0",
|
|
239
|
+
textMuted: "#7890a0",
|
|
240
|
+
accentColor: "#d4a017",
|
|
241
|
+
accentHover: "#f0c020",
|
|
242
|
+
borderColor: "#2a4050",
|
|
243
|
+
successColor: "#22c55e",
|
|
244
|
+
warningColor: "#eab308",
|
|
245
|
+
dangerColor: "#dc2626",
|
|
246
|
+
codeBackground: "#080c10",
|
|
247
|
+
codeText: "#6890a0",
|
|
248
|
+
borderRadius: "rounded",
|
|
249
|
+
cardStyle: "wooden",
|
|
250
|
+
fontDisplay: "Pirata One",
|
|
251
|
+
fontBody: "Merriweather",
|
|
252
|
+
fontMono: "Fira Code",
|
|
253
|
+
appTitle: "Pirate Adventures",
|
|
254
|
+
},
|
|
255
|
+
// Modern/contemporary urban setting
|
|
256
|
+
modern: {
|
|
257
|
+
bgColor: "#0f0f14",
|
|
258
|
+
bgSecondary: "#18181f",
|
|
259
|
+
bgElevated: "#22222c",
|
|
260
|
+
textColor: "#e8e8ec",
|
|
261
|
+
textMuted: "#8888a0",
|
|
262
|
+
accentColor: "#3b82f6",
|
|
263
|
+
accentHover: "#60a5fa",
|
|
264
|
+
borderColor: "#333340",
|
|
265
|
+
successColor: "#22c55e",
|
|
266
|
+
warningColor: "#f59e0b",
|
|
267
|
+
dangerColor: "#ef4444",
|
|
268
|
+
codeBackground: "#08080c",
|
|
269
|
+
codeText: "#9090a8",
|
|
270
|
+
borderRadius: "rounded",
|
|
271
|
+
cardStyle: "clean",
|
|
272
|
+
fontDisplay: "Inter",
|
|
273
|
+
fontBody: "Inter",
|
|
274
|
+
fontMono: "JetBrains Mono",
|
|
275
|
+
appTitle: "Modern Adventures",
|
|
276
|
+
},
|
|
277
|
+
// Superhero comic book style
|
|
278
|
+
superhero: {
|
|
279
|
+
bgColor: "#0a0c15",
|
|
280
|
+
bgSecondary: "#101525",
|
|
281
|
+
bgElevated: "#182035",
|
|
282
|
+
textColor: "#f0f0f8",
|
|
283
|
+
textMuted: "#7080a0",
|
|
284
|
+
accentColor: "#dc2626",
|
|
285
|
+
accentHover: "#ef4444",
|
|
286
|
+
borderColor: "#253050",
|
|
287
|
+
successColor: "#22c55e",
|
|
288
|
+
warningColor: "#fbbf24",
|
|
289
|
+
dangerColor: "#b91c1c",
|
|
290
|
+
codeBackground: "#050810",
|
|
291
|
+
codeText: "#6080c0",
|
|
292
|
+
borderRadius: "rounded",
|
|
293
|
+
cardStyle: "clean",
|
|
294
|
+
fontDisplay: "Bangers",
|
|
295
|
+
fontBody: "Open Sans",
|
|
296
|
+
fontMono: "Fira Code",
|
|
297
|
+
appTitle: "Superhero Adventures",
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* Get the current display configuration
|
|
302
|
+
*/
|
|
303
|
+
export function getDisplayConfig() {
|
|
304
|
+
const db = getDatabase();
|
|
305
|
+
const row = db
|
|
306
|
+
.prepare("SELECT config FROM display_config WHERE id = 1")
|
|
307
|
+
.get();
|
|
308
|
+
if (row) {
|
|
309
|
+
return { ...defaultConfig, ...JSON.parse(row.config) };
|
|
310
|
+
}
|
|
311
|
+
return { ...defaultConfig };
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Set the display configuration (full or partial update)
|
|
315
|
+
*/
|
|
316
|
+
export function setDisplayConfig(config) {
|
|
317
|
+
const db = getDatabase();
|
|
318
|
+
const current = getDisplayConfig();
|
|
319
|
+
const updated = { ...current, ...config };
|
|
320
|
+
db.prepare(`
|
|
321
|
+
INSERT INTO display_config (id, config, updated_at)
|
|
322
|
+
VALUES (1, ?, datetime('now'))
|
|
323
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
324
|
+
config = excluded.config,
|
|
325
|
+
updated_at = excluded.updated_at
|
|
326
|
+
`).run(JSON.stringify(updated));
|
|
327
|
+
return updated;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Reset display configuration to defaults
|
|
331
|
+
*/
|
|
332
|
+
export function resetDisplayConfig() {
|
|
333
|
+
const db = getDatabase();
|
|
334
|
+
db.prepare("DELETE FROM display_config WHERE id = 1").run();
|
|
335
|
+
return { ...defaultConfig };
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Apply a preset theme
|
|
339
|
+
*/
|
|
340
|
+
export function applyThemePreset(presetName) {
|
|
341
|
+
const preset = themePresets[presetName];
|
|
342
|
+
if (!preset) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
return setDisplayConfig(preset);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* List available theme presets
|
|
349
|
+
*/
|
|
350
|
+
export function listThemePresets() {
|
|
351
|
+
return Object.entries(themePresets).map(([name, preview]) => ({
|
|
352
|
+
name,
|
|
353
|
+
preview,
|
|
354
|
+
}));
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Set specific display options (convenience function)
|
|
358
|
+
*/
|
|
359
|
+
export function setDisplayOptions(options) {
|
|
360
|
+
return setDisplayConfig(options);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Set theme colors (convenience function)
|
|
364
|
+
*/
|
|
365
|
+
export function setThemeColors(colors) {
|
|
366
|
+
return setDisplayConfig(colors);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Set the app title
|
|
370
|
+
*/
|
|
371
|
+
export function setAppTitle(title) {
|
|
372
|
+
return setDisplayConfig({ appTitle: title });
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Set fonts (Google Fonts names)
|
|
376
|
+
*/
|
|
377
|
+
export function setFonts(fonts) {
|
|
378
|
+
return setDisplayConfig(fonts);
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Set visual style options
|
|
382
|
+
*/
|
|
383
|
+
export function setVisualStyle(style) {
|
|
384
|
+
return setDisplayConfig(style);
|
|
385
|
+
}
|
|
386
|
+
// ============================================
|
|
387
|
+
// Per-Game Theme Support
|
|
388
|
+
// ============================================
|
|
389
|
+
/**
|
|
390
|
+
* Get display configuration for a specific game
|
|
391
|
+
* Falls back to global config if no game theme exists
|
|
392
|
+
*/
|
|
393
|
+
export function getGameDisplayConfig(gameId) {
|
|
394
|
+
const db = getDatabase();
|
|
395
|
+
const row = db
|
|
396
|
+
.prepare("SELECT config FROM game_themes WHERE game_id = ?")
|
|
397
|
+
.get(gameId);
|
|
398
|
+
if (row) {
|
|
399
|
+
return { ...defaultConfig, ...JSON.parse(row.config) };
|
|
400
|
+
}
|
|
401
|
+
// Fall back to global config
|
|
402
|
+
return getDisplayConfig();
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Set display configuration for a specific game
|
|
406
|
+
*/
|
|
407
|
+
export function setGameDisplayConfig(gameId, config) {
|
|
408
|
+
const db = getDatabase();
|
|
409
|
+
const current = getGameDisplayConfig(gameId);
|
|
410
|
+
const updated = { ...current, ...config };
|
|
411
|
+
db.prepare(`
|
|
412
|
+
INSERT INTO game_themes (game_id, config, updated_at)
|
|
413
|
+
VALUES (?, ?, datetime('now'))
|
|
414
|
+
ON CONFLICT(game_id) DO UPDATE SET
|
|
415
|
+
config = excluded.config,
|
|
416
|
+
updated_at = excluded.updated_at
|
|
417
|
+
`).run(gameId, JSON.stringify(updated));
|
|
418
|
+
return updated;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Apply a preset theme to a specific game
|
|
422
|
+
*/
|
|
423
|
+
export function applyGameThemePreset(gameId, presetName) {
|
|
424
|
+
const preset = themePresets[presetName];
|
|
425
|
+
if (!preset) {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
return setGameDisplayConfig(gameId, preset);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Reset game theme (removes game-specific config, falls back to global)
|
|
432
|
+
*/
|
|
433
|
+
export function resetGameTheme(gameId) {
|
|
434
|
+
const db = getDatabase();
|
|
435
|
+
db.prepare("DELETE FROM game_themes WHERE game_id = ?").run(gameId);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Check if a game has a custom theme
|
|
439
|
+
*/
|
|
440
|
+
export function hasGameTheme(gameId) {
|
|
441
|
+
const db = getDatabase();
|
|
442
|
+
const row = db
|
|
443
|
+
.prepare("SELECT 1 FROM game_themes WHERE game_id = ?")
|
|
444
|
+
.get(gameId);
|
|
445
|
+
return !!row;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Infer and apply theme based on game genre/setting
|
|
449
|
+
*/
|
|
450
|
+
export function inferAndApplyTheme(gameId, genre, setting) {
|
|
451
|
+
const genreLower = genre.toLowerCase();
|
|
452
|
+
const settingLower = (setting || "").toLowerCase();
|
|
453
|
+
const combined = `${genreLower} ${settingLower}`;
|
|
454
|
+
// Map common genre keywords to presets
|
|
455
|
+
let presetName = null;
|
|
456
|
+
if (combined.includes("cyberpunk") ||
|
|
457
|
+
combined.includes("neon") ||
|
|
458
|
+
combined.includes("hacker")) {
|
|
459
|
+
presetName = "cyberpunk";
|
|
460
|
+
}
|
|
461
|
+
else if (combined.includes("sci-fi") ||
|
|
462
|
+
combined.includes("science fiction") ||
|
|
463
|
+
combined.includes("space") ||
|
|
464
|
+
combined.includes("futuristic")) {
|
|
465
|
+
presetName = "sci-fi";
|
|
466
|
+
}
|
|
467
|
+
else if (combined.includes("western") ||
|
|
468
|
+
combined.includes("wild west") ||
|
|
469
|
+
combined.includes("frontier") ||
|
|
470
|
+
combined.includes("cowboy")) {
|
|
471
|
+
presetName = "western";
|
|
472
|
+
}
|
|
473
|
+
else if (combined.includes("noir") ||
|
|
474
|
+
combined.includes("detective") ||
|
|
475
|
+
combined.includes("mystery") ||
|
|
476
|
+
combined.includes("hardboiled")) {
|
|
477
|
+
presetName = "noir";
|
|
478
|
+
}
|
|
479
|
+
else if (combined.includes("cosmic horror") ||
|
|
480
|
+
combined.includes("lovecraft") ||
|
|
481
|
+
combined.includes("eldritch") ||
|
|
482
|
+
combined.includes("cthulhu")) {
|
|
483
|
+
presetName = "cosmic-horror";
|
|
484
|
+
}
|
|
485
|
+
else if (combined.includes("steampunk") ||
|
|
486
|
+
combined.includes("victorian") ||
|
|
487
|
+
combined.includes("clockwork")) {
|
|
488
|
+
presetName = "steampunk";
|
|
489
|
+
}
|
|
490
|
+
else if (combined.includes("post-apocalyptic") ||
|
|
491
|
+
combined.includes("wasteland") ||
|
|
492
|
+
combined.includes("apocalypse") ||
|
|
493
|
+
combined.includes("survival")) {
|
|
494
|
+
presetName = "post-apocalyptic";
|
|
495
|
+
}
|
|
496
|
+
else if (combined.includes("pirate") ||
|
|
497
|
+
combined.includes("nautical") ||
|
|
498
|
+
combined.includes("sailing") ||
|
|
499
|
+
combined.includes("ocean")) {
|
|
500
|
+
presetName = "pirate";
|
|
501
|
+
}
|
|
502
|
+
else if (combined.includes("superhero") ||
|
|
503
|
+
combined.includes("comic") ||
|
|
504
|
+
combined.includes("hero")) {
|
|
505
|
+
presetName = "superhero";
|
|
506
|
+
}
|
|
507
|
+
else if (combined.includes("modern") ||
|
|
508
|
+
combined.includes("contemporary") ||
|
|
509
|
+
combined.includes("urban")) {
|
|
510
|
+
presetName = "modern";
|
|
511
|
+
}
|
|
512
|
+
else if (combined.includes("dark fantasy") ||
|
|
513
|
+
combined.includes("grimdark") ||
|
|
514
|
+
combined.includes("dark")) {
|
|
515
|
+
presetName = "dark-fantasy";
|
|
516
|
+
}
|
|
517
|
+
else if (combined.includes("fantasy") ||
|
|
518
|
+
combined.includes("medieval") ||
|
|
519
|
+
combined.includes("magic") ||
|
|
520
|
+
combined.includes("dragon")) {
|
|
521
|
+
presetName = "high-fantasy";
|
|
522
|
+
}
|
|
523
|
+
if (presetName) {
|
|
524
|
+
return applyGameThemePreset(gameId, presetName) || getDisplayConfig();
|
|
525
|
+
}
|
|
526
|
+
// No match - use default
|
|
527
|
+
return getDisplayConfig();
|
|
528
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Faction } from "../types/index.js";
|
|
2
|
+
export declare function createFaction(params: {
|
|
3
|
+
gameId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
leaderId?: string;
|
|
7
|
+
headquartersId?: string;
|
|
8
|
+
resources?: Record<string, number>;
|
|
9
|
+
goals?: string[];
|
|
10
|
+
traits?: string[];
|
|
11
|
+
status?: "active" | "disbanded" | "hidden";
|
|
12
|
+
}): Faction;
|
|
13
|
+
export declare function getFaction(id: string): Faction | null;
|
|
14
|
+
export declare function updateFaction(id: string, updates: {
|
|
15
|
+
name?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
leaderId?: string | null;
|
|
18
|
+
headquartersId?: string | null;
|
|
19
|
+
traits?: string[];
|
|
20
|
+
status?: "active" | "disbanded" | "hidden";
|
|
21
|
+
}): Faction | null;
|
|
22
|
+
export declare function deleteFaction(id: string): boolean;
|
|
23
|
+
export declare function listFactions(gameId: string, filter?: {
|
|
24
|
+
status?: "active" | "disbanded" | "hidden";
|
|
25
|
+
}): Faction[];
|
|
26
|
+
export declare function modifyFactionResource(params: {
|
|
27
|
+
factionId: string;
|
|
28
|
+
resource: string;
|
|
29
|
+
delta: number;
|
|
30
|
+
}): Faction | null;
|
|
31
|
+
export declare function setFactionResource(params: {
|
|
32
|
+
factionId: string;
|
|
33
|
+
resource: string;
|
|
34
|
+
value: number;
|
|
35
|
+
}): Faction | null;
|
|
36
|
+
export declare function addFactionGoal(factionId: string, goal: string): Faction | null;
|
|
37
|
+
export declare function completeFactionGoal(factionId: string, goalIndex: number): Faction | null;
|
|
38
|
+
export declare function addFactionTrait(factionId: string, trait: string): Faction | null;
|
|
39
|
+
export declare function removeFactionTrait(factionId: string, trait: string): Faction | null;
|
|
40
|
+
export declare function modifyFactionTraits(factionId: string, params: {
|
|
41
|
+
add?: string[];
|
|
42
|
+
remove?: string[];
|
|
43
|
+
}): {
|
|
44
|
+
faction: Faction;
|
|
45
|
+
added: string[];
|
|
46
|
+
removed: string[];
|
|
47
|
+
} | null;
|
|
48
|
+
export declare function modifyFactionGoals(factionId: string, params: {
|
|
49
|
+
add?: string[];
|
|
50
|
+
complete?: number[];
|
|
51
|
+
}): {
|
|
52
|
+
faction: Faction;
|
|
53
|
+
added: string[];
|
|
54
|
+
completed: string[];
|
|
55
|
+
} | null;
|
|
56
|
+
export declare function updateFactionResource(params: {
|
|
57
|
+
factionId: string;
|
|
58
|
+
resource: string;
|
|
59
|
+
mode: "delta" | "set";
|
|
60
|
+
value: number;
|
|
61
|
+
}): Faction | null;
|